美文网首页
React合成事件中,如何正确阻止事件冒泡

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

作者: 小猪佩奇的王子 | 来源:发表于2019-10-09 14:27 被阅读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>
            </>
        )
    }
    
    

    相关文章

      网友评论

          本文标题:React合成事件中,如何正确阻止事件冒泡

          本文链接:https://www.haomeiwen.com/subject/wjqgpctx.html