深入React事件系统(React点击空白部分隐藏弹出层;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()无法阻止冒泡。
经过 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")
);
感谢且不仅限于:
http://wiki.jikexueyuan.com/project/react/event-system.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation
深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)的更多相关文章
- js的事件冒泡和点击其他区域隐藏弹出层
一.前言 在编写页面的时候,我们经常使用到弹出层.对于弹出层,原本的意义就是增加与用户的交互,提升用户的好感度.如果弹出层都没有较好的体验,那何谈通过交互来提升好感... 首先提出几个弹出层的注意点: ...
- react 点击空白处隐藏弹出层
点击空白处隐藏弹出层的原理是:在 document 上绑定事件来隐藏弹出层,这样点击任何元素的时候都会冒泡到 document 上,都会执行隐藏弹出层的功能.然后我们在不需要隐藏弹出层的元素上阻止冒泡 ...
- jquery层居中,点击小图查看大图,弹出层居中代码,顶部层固定不动,滚动条滚动情况
jquery层居中,点击小图查看大图,弹出层居中代码 http://www.cnblogs.com/simpledev/p/3566280.html 见第一版,发现一个情况,如果页面内容多出一屏的情况 ...
- 在点击div中的p时,如何阻止事件冒泡?
今天整理笔记,发现在学习javaScript的过程中,遇到过一个在当时看来很棘手的问题,现在特地总结一下,也希望能帮助到曾像我一样迷惘的初学者. 我还是以一个案例来说明问题,html代码如下: < ...
- jquery层居中,点击小图查看大图,弹出层居中代码
1.层居中 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- js 点击 隐藏弹出层
document.onmousedown = function(e){ var ev = document.all ? window.event : e; var _con = $("#ci ...
- jsp html 实现隐藏输入框,点击可以取消隐藏&&弹出输入框
jsp代码: <script language="javascript" type="text/javascript"> function chg ...
- React 中阻止事件冒泡的问题
在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...
- React native 的弹出层(输入)效果
/*弹出层测试*/ import React,{Component} from 'react'; import { StyleSheet, View, Image, Text, TouchableOp ...
随机推荐
- 谈谈java的BlockingQueue
http://www.cnblogs.com/archy_yu/archive/2013/04/19/3018479.html 博客园 首页 新随笔 联系 管理 随笔- 92 文章- 0 评论- ...
- 在js中如何得到上传文件的大小。
<html> <head> <script language="javascript"> function getSize() { ...
- 控制textbook输入字符
在KeyPress事件中假如如下代码此实例表示可输入数字退格和“.”. 具体字符KeyChar见连接 http://www.cnblogs.com/linji/archive/2012/10/24/2 ...
- 设置gridcontrol的焦点行
private void gridView1_DoubleClick(object sender, EventArgs e) { try { ...
- mac ox 配置java和maven
参考http://www.cnblogs.com/iOS-mt/p/5726380.html 以及http://blog.csdn.net/done58/article/details/5113805 ...
- Laravel Auth验证
laravel自带了auth类和User模型来帮助我们很方便的实现用户登陆.判断. 首先,先配置一下相关参数 app/config/auth.php: model 指定模型 table 指定用户表 p ...
- Laravel Cache 使用
在项目中使用 laravel 的 cache 时,使用下面形式方法: $value = Cache::remember('users', $minutes, function() { return D ...
- Sping--Id, Name
bean, id/name 都可以 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...
- linux 驱动入门2
不吃苦中苦,难为人上人.努力,给老婆孩子提供个良好的生活居住环境. http://www.cnblogs.com/nan-jing/articles/5775038.html 这里提到.有这么多牛人. ...
- stm32使用LWIP实现DHCP客户端
LWIP是一款开源的嵌入式网络协议栈,支持的功能很多,而且能在多任务环境下和单任务裸机环境下跑,今天说说他的移植过程,芯片为STM32,网卡为ENC28J60,无操作系统 首先下载LWIP的源代码,我 ...