React合成事件中,如何正确阻止事件冒泡

2019-10-09  本文已影响0人  小猪佩奇的王子

react事件是合成事件,即最终会将事件代理到documet对象上,为了提高性能。
一个典型的场景是页面弹出对话框,点击页面其他位置需要隐藏该对话框,点击对话框本身不隐藏。

一般会在documentaddEventListener,在触发对象事件中使用stopPropagation如果你这么做,很遗憾会得到错误的结果
下面是一个使用事件冒泡模型的处理方式

将事件添加到document对象,未达预期

export default () => {
    const clickListener = e => {
        console.log("clickListener")
    }
    useEffect(() => {
              //使用事件冒泡模型
        document.addEventListener("click", clickListener, false)
        return () => document.removeEventListener("click", clickListener, false)
    }, [])

    const handleClick = e => {
        e.stopPropagation()
        console.log("click")
    }

    return (
        <>
            <button onClick={e => handleClick(e)}>test click</button>
        </>
    )
}

将事件添加到window对象上,达到预期

export default () => {
    const clickListener = e => {
        console.log("clickListener")
    }
    useEffect(() => {
              //使用事件冒泡模型
        window.addEventListener("click", clickListener, false)
        return () => window.removeEventListener("click", clickListener, false)
    }, [])

    const handleClick = e => {
        e.stopPropagation()
        console.log("click")
    }

    return (
        <>
            <button onClick={e => handleClick(e)}>test click</button>
        </>
    )
}

解释一下

因为使用事件冒泡模型,最终事件会冒泡到window对象上,我们在window对象上添加事件监听,buttonclick事件会代理到document上执行,因为添加了stopPropagation,因此不会再向上冒泡到window了,也就不会触发window的的click事件

如果非要将事件添加到document上如何破?

使用stopImmediatePropagation,阻止原生事件与document间的冒泡

export default () => {
    const clickListener = e => {
        console.log("clickListener")
    }
    useEffect(() => {
        document.addEventListener("click", clickListener, false)
        return () => document.removeEventListener("click", clickListener, false)
    }, [])

    const handleClick = e => {
        // e.stopPropagation()
        e.nativeEvent.stopImmediatePropagation()
        console.log("click")
    }

    return (
        <>
            <button onClick={e => handleClick(e)}>test click</button>
        </>
    )
}

上一篇下一篇

猜你喜欢

热点阅读