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

两个在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() 可以完美实现预期。

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

  1. React为了提高效率,把事件都委托给了document,所以 e.stopPropagation() 并非是不能阻止冒泡,而是等他阻止冒泡的时侯,事件已经传递给document了,没东西可阻止了。可以通过在document.body上绑定 alert(3),直观的了解这一点,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,width: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

深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)的更多相关文章

  1. js的事件冒泡和点击其他区域隐藏弹出层

    一.前言 在编写页面的时候,我们经常使用到弹出层.对于弹出层,原本的意义就是增加与用户的交互,提升用户的好感度.如果弹出层都没有较好的体验,那何谈通过交互来提升好感... 首先提出几个弹出层的注意点: ...

  2. react 点击空白处隐藏弹出层

    点击空白处隐藏弹出层的原理是:在 document 上绑定事件来隐藏弹出层,这样点击任何元素的时候都会冒泡到 document 上,都会执行隐藏弹出层的功能.然后我们在不需要隐藏弹出层的元素上阻止冒泡 ...

  3. jquery层居中,点击小图查看大图,弹出层居中代码,顶部层固定不动,滚动条滚动情况

    jquery层居中,点击小图查看大图,弹出层居中代码 http://www.cnblogs.com/simpledev/p/3566280.html 见第一版,发现一个情况,如果页面内容多出一屏的情况 ...

  4. 在点击div中的p时,如何阻止事件冒泡?

    今天整理笔记,发现在学习javaScript的过程中,遇到过一个在当时看来很棘手的问题,现在特地总结一下,也希望能帮助到曾像我一样迷惘的初学者. 我还是以一个案例来说明问题,html代码如下: < ...

  5. jquery层居中,点击小图查看大图,弹出层居中代码

    1.层居中 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  6. js 点击 隐藏弹出层

    document.onmousedown = function(e){ var ev = document.all ? window.event : e; var _con = $("#ci ...

  7. jsp html 实现隐藏输入框,点击可以取消隐藏&&弹出输入框

    jsp代码: <script language="javascript" type="text/javascript"> function chg ...

  8. React 中阻止事件冒泡的问题

    在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...

  9. React native 的弹出层(输入)效果

    /*弹出层测试*/ import React,{Component} from 'react'; import { StyleSheet, View, Image, Text, TouchableOp ...

随机推荐

  1. 写自己的一个pdo数据库操作框架

    http://stackoverflow.com/questions/20669850/pdo-database-abstraction-layer-with-multiple-queries-in- ...

  2. grep过滤搜索

    cat /proc/2666/maps | busybox grep libumcpart.so

  3. 去掉谷歌input记住账号或密码时默认出现的黄色背景

    在谷歌浏览器会默认记住账号,而记住账号之后其input的背景会变成黄色,解决的办法如下: 方法一:直接用css的内阴影来覆盖黄色,代码如下: input:-webkit-autofill { -web ...

  4. SQL复习五(索引)

    SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引 ...

  5. CodeForces 621B Wet Shark and Bishops

    记录一下每个对角线上有几个,然后就可以算了 #include<cstdio> #include<cstring> #include<cmath> #include& ...

  6. CentOS x 64 MooseFS 学习

    一.MFS 简介.... MooseFS(Moose File System,mfs)是一种分布式文件系统,它将数据分布在网络中的 不同服务器上,支持FUSE,客户端可以作为一个 普通的Unix 文件 ...

  7. 使用eclipse和JavaFX Scene Builder进行快速构建JavaFX应用程序

    http://blog.csdn.net/wingfourever/article/details/7726724 使用eclipse和JavaFX Scene Builder进行快速构建JavaFX ...

  8. [Unity Shader]光照模型对物体的假设

    什么是光照模型 光照模型就是模拟光在物体间的传递过程,以确保物体可见表面每一点的亮度和颜色. 当光照射到一个物体表面时,光可能被吸收.反射或折射.反射和折射的光使物体可见.如果入射光全部被吸收,物体将 ...

  9. FZU 1054 阅读顺序

    水题,倒着输出. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm& ...

  10. STM32驱动TEA5767收音机模块

    Tea5767是飞利浦公司出的一款集成化的收音机芯片,大四的时候机缘巧合遇到了这个芯片,用了一下,写点资料 主要特性 TEA5767HN是一款低功耗立体声收音IC,广泛应用于手机MP3 .MP 4 播 ...