zoukankan      html  css  js  c++  java
  • 深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)

    只关注括号内问题的同学,可直接跳转到蓝字部分。(标题起的有点大,其实只讨论一个问题)

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

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

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

    为了直观的调试,把需求转化为,点击框体内 alert1)点击框体外 alert2)。

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

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

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

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

    测试代码如下:

    class Test extends React.Component{
        componentDidMount(){
            document.onclick=this.two;
        }
        one(e){
            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")
    );

    感谢且不仅限于:

    http://stackoverflow.com/questions/24415631/reactjs-syntheticevent-stoppropagation-only-works-with-react-events

    http://wiki.jikexueyuan.com/project/react/event-system.html

    https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation

  • 相关阅读:
    Path Sum II
    Convert Sorted Array to Binary Search Tree
    Construct Binary Tree from Inorder and Postorder Traversal
    Construct Binary Tree from Preorder and Inorder Traversal
    Maximum Depth of Binary Tree
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Same Tree
    Validate Binary Search Tree
    Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/lihuanqing/p/6295685.html
Copyright © 2011-2022 走看看