方案一
原生js的e.target.closest()方法
方案二
... // 省略其他代码
import { useClickAway } from 'ahooks';
const MultilingualList: FC<MultilingualListProps> = (props) => {
const confirmModalWrapperRef = useRef<any>(null);
const confirmModalRef = useRef<any>(null);
...
useClickAway(
(e) => {
onClickAway?.(e);
},
[confirmModalWrapperRef],
'click'
);
return (
...
{isModalOpen ? (
<div ref={confirmModalWrapperRef}> // 需要容器,方便获得元素,因为有部分ant-design组件是挂载在全局的,或者因为渲染时机较晚,获取不到元素
<Modal
...
onOk={() => {
...
}}
onCancel={() => {
setIsModalOpen(false);
confirmModalRef.current?.onCancel();
onClickAway?.();
}}
/>
</div>
) : null}
)
方案三(注意,这种方案如果配合 ant-design的组件,可能需要设置popContainer挂载在指定父容器下,因为他们可能在全局dom树分叉上,不在容器上,这会导致识别不到包含“contains”关系)
import { useEffect, useRef } from 'react';
const MyComponent = ({}) => {
const ref = useRef(null);
const handleClick = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
console.log('111111111111');
}
};
useEffect(() => {
// 在组件挂载时添加事件监听
document.addEventListener('click', handleClick, true);
return () => {
// 在组件卸载时移除事件监听
document.removeEventListener('click', handleClick, true);
};
}, []);
return (
<div
ref={ref}
style={{ width: '50%', height: '100%', background: 'red', marginTop: -200, position: 'relative', zIndex: 99999 }}
>
<div>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
<p>dfsgsdgsdgsdgsdggsdgsdg</p>
</div>
</div>
);
};
export default MyComponent;