鼠标是否在元素中
import React, {VFC, useCallback, useState, useEffect} from 'react';
import {Form, InputNumber, Row, Col} from 'antd';
import {getAllInfo, updateNum, updateById} from '@/service/search';
import Personalized from '@/components/Personalized';
import styles from './index.less';
interface KeywordsProps {
content: string;
id: number;
position: number;
status: number;
}
const {log} = console;
const layout = {
labelCol: {span: 10},
wrapperCol: {span: 14},
};
const Relevant: VFC = () => {
const [keywordNum, setKeywordNum] = useState<number>(1);
const [keywords, setKeywords] = useState<KeywordsProps[]>([]);
const [form] = Form.useForm();
const getAllInfoLocal = useCallback(async () => {
const res = await getAllInfo();
const {totalNum, searchDiscoveryList} = res.data;
setKeywordNum(totalNum);
setKeywords(searchDiscoveryList);
form.setFieldsValue({searchNum: totalNum});
}, [form]);
const updateNumLocal = useCallback(
async (num: number) => {
await updateNum({content: String(num)});
await getAllInfoLocal();
},
[getAllInfoLocal]
);
useEffect(() => {
getAllInfoLocal();
}, [getAllInfoLocal]);
const onFinish = useCallback((values: any) => {
log('Success:', values);
}, []);
const numChange = useCallback(
e => {
updateNumLocal(e);
},
[updateNumLocal]
);
return (
<div className={styles.relevantWrap}>
<Form {...layout} form={form} name='num' onFinish={onFinish} initialValues={{searchNum: keywordNum}}>
<Form.Item
name='searchNum'
label='相关搜索数量设置'
extra='搜索数量1~10个'
rules={[{pattern: /^([1-9]|10)$/, message: '请输入1~10的数字'}]}
>
<InputNumber min={1} max={10} onStep={e => numChange(e)} key={keywordNum} />
</Form.Item>
<Row style={{marginBottom: 20}}>
<Col offset={5} span={7}>
搜索发现位
</Col>
<Col span={12}>个性化推荐</Col>
</Row>
{keywords.map((item: KeywordsProps, index) => (
<Personalized form={form} index={index + 1} key={item.id} data={item} updateById={updateById} />
))}
</Form>
</div>
);
};
export default Relevant;
import React, {FC, useEffect, useCallback, useState, useRef, MutableRefObject} from 'react';
import {Col, Form, FormInstance, Input, Row, Switch} from 'antd';
import _ from 'lodash';
import useSyncCallback from '@/hooks/useSyncCallback';
const layout = {
labelCol: {span: 8},
wrapperCol: {span: 16},
};
interface PersonalizedProps {
form: FormInstance;
index: number;
data: {
content: string;
id: number;
position: number;
status: number;
};
updateById: (params: any) => void;
}
const Personalized: FC<PersonalizedProps> = props => {
const {form, index, data, updateById} = props;
const [isDis, setIsDis] = useState<boolean>(false);
const [isOpen, setOpen] = useState(false);
const switchRef: MutableRefObject<any> = useRef(null);
useEffect(() => {
setIsDis(!!data.status);
}, [data.status]);
const openIt = useCallback(
async (e: any, index: number) => {
if (form.getFieldsValue()[`words${index}`]) {
setIsDis(e);
await updateById({...data, status: e ? 1 : 0, content: form.getFieldValue(`words${index}`)});
}
setOpen(false);
},
[data, form, updateById]
);
const hasViewRange = (view: any, event: MouseEvent) => {
if (view) {
const wx = event.clientX;
const wy = event.clientY;
const {left, top, bottom, right} = view.getBoundingClientRect();
if (wx >= left && wx <= right && wy >= top && wy <= bottom) return true;
else return false;
}
return false;
};
const getSyncOpen = useSyncCallback(() => {
isOpen && openIt(!isDis, index);
});
const onInputBlur = async () => {
!!form.getFieldValue(`words${index}`) &&
form.isFieldTouched(`words${index}`) &&
(await updateById({...data, status: isDis ? 1 : 0, content: form.getFieldValue(`words${index}`)}));
getSyncOpen();
};
const moveFunc = _.debounce((e: MouseEvent) => {
console.warn('检测元素', hasViewRange(switchRef.current, e));
setOpen(() => {
if (hasViewRange(switchRef.current, e)) {
return true;
}
return false;
});
}, 100);
const handelChange = _.debounce(() => {
addEventListener('mousemove', moveFunc);
}, 500);
useEffect(() => {
return () => {
removeEventListener('mousemove', moveFunc);
};
}, []);
return (
<div>
<Row align='middle'>
<Col span={12}>
<Form.Item
{...layout}
name={`words${index}`}
label={`位置${index}`}
rules={[{required: true, message: '请输入'}]}
initialValue={data.content}
>
<Input
disabled={isDis}
placeholder='请输入'
onBlur={() => onInputBlur()}
onChange={() => handelChange()}
/>
</Form.Item>
</Col>
<Col span={11} offset={1}>
<Form.Item>
<Switch
ref={switchRef}
checkedChildren='开'
unCheckedChildren='关'
checked={isDis}
onChange={e => openIt(e, index)}
/>
</Form.Item>
</Col>
</Row>
</div>
);
};
export default Personalized;
组件图片:
https://s3.bmp.ovh/imgs/2022/05/17/029b64903a16cb65.png
https://s3.bmp.ovh/imgs/2022/05/17/87dcded1c0920657.png