深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)
2017-01-18 22:14
585 查看
只关注括号内问题的同学,可直接跳转到蓝字部分。(标题起的有点大,其实只讨论一个问题)
两个在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()无法阻止冒泡。
经过 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(),完活。
测试代码如下:
感谢且不仅限于:
两个在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()无法阻止冒泡。
经过 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(),完活。
测试代码如下:
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") );
感谢且不仅限于:
相关文章推荐
- React点击空白部分隐藏弹出层;React阻止事件冒泡失效)
- js利用事件的阻止冒泡实现点击空白模态框的隐藏
- js利用事件的阻止冒泡实现点击空白模态框的隐藏
- Js阻止事件冒泡 弹出层后点击body区域层消失
- 点击其它地方隐藏div/事件冒泡/sweet-alert阻止冒泡
- 点击空白处隐藏div-阻止事件冒泡
- javascript点击空白位置关闭弹出层/点击包含指定区域但不属于指定区域的部分响应点击事件
- 行间点击事件如何阻止冒泡
- ios弹出软键盘时fixed失效及点击空白处隐藏层的解决办法
- IOS自定义系统导航栏:导航栏背景色、状态栏样式以及是否隐藏、拦截系统导航栏的返回点击事件
- JS点击子元素不触发父元素点击事件(js阻止冒泡)
- Flex里监听mouseDownOutside事件解决弹出窗口点击空白关闭功能
- 点击事件阻止缺省事件以及阻止冒泡
- Android.edittext点击时,隐藏系统弹出的键盘,显示出光标
- 解决/阻止 div层内的div层点击事件冒泡触发的小方法
- XP系统的 搜索 功能失效;IE点击链接没反应,不会弹出窗口的解决方法
- Android中点击空白区域控件自动隐藏(事件传递机制中的一个小例子)
- js层阻止页面冒泡、弹出层失去焦点就隐藏此层也是解决方案
- EditText 获取焦点时 输入法弹出 点击EditText以外的部分 输入法隐藏
- 关于jquery动态加载节点后阻止事件冒泡失效的问题