react 点击空白区域隐藏弹窗,无法阻止事件冒泡,stopImmediatePropagation无效的解决办法

蛰伏已久 蛰伏已久 2018-10-26

入坑react,最近写一个小功能,希望点击空白区域隐藏弹窗,本来很简单的事情,可以发现无法阻止事件冒泡,导致显示错乱。

简单看下js的冒泡事件

如果不做任何处理,点击按钮后 先弹出“内层”,然后事件冒泡到外层,弹出“外层”

<div onClick={()=>{alert('外层')}}>
    <div onClick={()=>{alert('内层')}}>
        点击冒泡测试
    </div>

</div>

通过e.stopPropagation()阻止事件冒泡

如下只会弹出“内层”,阻止事件了冒泡,不会再弹出外层

<div onClick={()=>{alert('外层')}}>
    <div onClick={(e)=>{e.stopPropagation();alert('内层')}}>
        点击冒泡测试
    </div>

</div>

如果想点击网页空白区域,实现隐藏,刚开始我是想添加document.body的点击事件

结果发现点击之后先弹出“body”,再弹出“内层”

render(){
    document.body.addEventListener('click',function () {
        alert('body')
    },false)
    return(
        <div>Trade
            <div onClick={()=>{alert('外层')}}>
                <div onClick={(e)=>{e.stopPropagation();alert('内层')}}>
                    点击冒泡测试
                </div>

            </div>
        </div>
    )
}

网上查找很多文档,有的说添加e.nativeEvent.stopImmediatePropagation()

结果还是不行,还是先弹出“body”,再弹出“内层”

render(){
    document.body.addEventListener('click',function () {
        alert('body')
    },false)
    return(
        <div>Trade
            <div onClick={()=>{alert('外层')}}>
                <div onClick={(e)=>{e.stopPropagation();e.nativeEvent.stopImmediatePropagation();alert('内层')}}>
                    点击冒泡测试
                </div>

            </div>
        </div>
    )
}

最后试了下把点击事件直接加在document上

终于好使了,此时只会弹出“内层”,没有冒泡到外层,也没有冒泡到document

render(){
    document.addEventListener('click',function () {
        alert('body')
    },false)
    return(
        <div>Trade
            <div onClick={()=>{alert('外层')}}>
                <div onClick={(e)=>{e.stopPropagation();e.nativeEvent.stopImmediatePropagation();alert('内层')}}>
                    点击冒泡测试
                </div>

            </div>
        </div>
    )
}

除此之外,也有别的办法实现,就是比较麻烦,就是在document.body事件中判断e.target,进行不同的操作

document.body.addEventListener('click',function (e) {
   if(e.target&&e.target.matches('a')){
       ...
   }else {
       ....
   }
},false)

阻止冒泡对IE浏览器的兼容

function stopPropagation(e) {    
    var e = e || window.event;    
    if ( e && e.stopPropagation ){
        e.stopPropagation();
    }else{
        e.cancelBubble = true;  //兼容
    }
}


分享到

点赞(1)