zoukankan      html  css  js  c++  java
  • React阻止事件冒泡失效

    两个在React组件上绑定的事件,产生冲突后,使用e.stopPropagation(),阻止冒泡和捕获,即可防止事件冲突,毫无问题。

    今天是踩了个React事件的坑,需求可以简化为:点击框体以外的部分则隐藏框体。最直接的想法,document上绑定个事件,设置控制显示隐藏的state为false,在框体上绑定个事件,阻止冒泡。这样点击框体内部就不会触发document上的事件。

    等写完了,发现一个问题,无法阻止冒泡,一搜索,好家伙,好多人问e.stopPropagation()为什么无法阻止事件冒泡,但是鲜有靠谱的回答。我第一个想法是原生事件和React事件产生冲突。明显绑定原生事件是不符合React精神的,但我决定在探索真理的路上走下去了。

    为了直观的调试,把需求转化为,点击框体内 alert(1)点击框体外 alert(2)。

    在document上绑定 alert(2),框体上(框体为React组件,下同)绑定 alert(1),不做特殊处理,点击框体内,根据事件冒泡,先弹 1 再弹 2 。这一点符合预期。此时e.stopPropagation()无法阻止冒泡。

    class Test extends React.Component{
        componentDidMount(){
            document.onclick=this.two;
        }
        one(e){
            e.stopPropagation();
            // e.nativeEvent.stopImmediatePropagation();
            alert(1)
        }
        two(){
            alert(2)
        }
        render(){
            return(<div style={{height:150,150,backgroundColor:"#000"}} onClick={this.one}/>)
        }
    }
    
    ReactDOM.render(
        <Test/>,
        document.getElementById("test")
    );
    

    经过 Stack Overflow 解惑 e.nativeEvent.stopImmediatePropagation() 可以完美实现预期。

    下面进入探索环节,经查阅资料,得出以下结论:

    React为了提高效率,把事件都委托给了document,所以 e.stopPropagation() 并非是不能阻止冒泡,而是等他阻止冒泡的时侯,事件已经传递给document了,没东西可阻止了。可以通过在document.body上绑定 alert(3),直观的了解这一点,3 是优先于 1 弹出的。
    e.stopPropagation()不行,浏览器支持一个好东西,e.stopImmediatePropagation() 他不光阻止冒泡,还能阻止在当前事件触发元素上,触发其它事件。这样即使你都绑定到document上也阻止不了我了吧。
    这样做还不行,React对原生事件封装,提供了很多好东西,但也省略了某些特性。e.stopImmediatePropagation() 就是被省略的部分,然而,他给了开口:e.nativeEvent ,从原生的事件对象里找到stopImmediatePropagation(),完活。

  • 相关阅读:
    select应用于read函数 超时非阻塞方式
    取文本索引所执向的值(简单)
    linux c函数指针的应用
    解决vsftp无法启动问题(转)
    Could not chdir to home directory /home/USER: Permission denied
    sscanf和正则表达式
    存储过程重置SEQUENCE值从新开始。
    Signal ()函数详细介绍 Linux函数(转)
    linux 环境NTP配置与开机自启动(转)
    linux下iconv()函数的用法(转载并修改)
  • 原文地址:https://www.cnblogs.com/qiqi715/p/12721698.html
Copyright © 2011-2022 走看看