【javascript】如何监听在元素及其子孙元素以外的元素被点击事件

方案一

原生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;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值