来源:https://www.cnblogs.com/lihuanqing/p/6295685.htmlhtml
只关注括号内问题的同窗,可直接跳转到蓝字部分。(标题起的有点大,其实只讨论一个问题)react
两个在React组件上绑定的事件,产生冲突后,使用e.stopPropagation(),阻止冒泡,便可防止事件冲突,毫无问题。浏览器
今天是踩了个React事件的坑,需求能够简化为:点击框体之外的部分则隐藏框体。最直接的想法,document上绑定个事件,设置控制显示隐藏的state为false,在框体上绑定个事件,阻止冒泡。这样点击框体内部就不会触发document上的事件。测试
等写完了,发现一个问题,没法阻止冒泡,一搜索,好家伙,好多人问e.stopPropagation()为何没法阻止事件冒泡,可是鲜有靠谱的回答。我第一个想法是原生事件和React事件产生冲突。明显绑定原生事件是不符合React精神的,但我决定在探索真理的路上走下去了。this
为了直观的调试,把需求转化为,点击框体内 alert(1)点击框体外 alert(2)。spa
在document上绑定 alert(2),框体上(框体为React组件,下同)绑定 alert(1),不作特殊处理,点击框体内,根据事件冒泡,先弹 1 再弹 2 。这一点符合预期。此时e.stopPropagation()没法阻止冒泡。调试
通过 Stack Overflow 解惑 e.nativeEvent.stopImmediatePropagation() 能够完美实现预期。code
下面进入探索环节,经查阅资料,得出如下结论:component
测试代码以下:htm
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,width:150,backgroundColor:"#000"}} onClick={this.one}/>) } } ReactDOM.render( <Test/>, document.getElementById("test") );
感谢且不只限于:
http://wiki.jikexueyuan.com/project/react/event-system.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation