深入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 ...
随机推荐
- Python之路: socket篇
(默认)与特定的地址家族相关的协议,如果是 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议 sk import socketip_port = ()sk = socket.socket( ...
- window.location.href 和 document.location.href
document表示的是一个文档对象,window表示的是一个窗口对象,一个窗口下可以有多个文档对象. 所以一个窗口下只有一个window.location.href,但是可能有多个document. ...
- 用C语言写一个“事件”的模拟程序
源:用C语言写一个“事件”的模拟程序 Example.c //定义一个函数指针 func int (*func) (void); //调用该函数相当于触发了事件. //该事件触发后,会检查函数指针fu ...
- 产品需求文档写作方法(三)用例文档(UML用例图、流程图)
在产品和技术领域里都有UML的技能知识,而对于产品人员的UML则更多的是指用例图,也就是我所称呼的用户流程图.在讲PRD文档写作的第二篇文章里,我提到了用户流程图的制作,实际上用户流程图是我在产品规则 ...
- 比较实用的webpack配置代码
var path = require('path');var webpack = require('webpack');var ExtractTextPlugin = require('extract ...
- C socket post数据到url
#define HOST_SERVER_IP "192.168.1.15" #define HOST_PORT 80 int gsh_post_clients(const char ...
- html背景图片拉伸至全屏
本来想在body的css中设置,但发现怎么弄也无法搞定,技术水平有限吧,最后通过下面方式来达到效果: <img src = 'url' border = '0' width = '100%' h ...
- linux分区-df
转自:http://baike.baidu.com/link?url=tyonI3NCB3F-ytIQz72PY-8uAaUQgfFFXbyKAea1e2NiB_t5AsE0MLOLc2LcqOiS ...
- ERP软件数据库覆盖数据恢复成功/重装数据库系统软件,导致同名文件覆盖
ERP软件数据库覆盖数据恢复成功/重装数据库系统软件,导致同名文件覆盖 [数据恢复故障描述] 上海某酒店ERP软件原来安装在C盘上,用户误操作把软件进行了卸载,发现软件没有了, 但操作之前没有把原 ...
- bitmap 加载的时候出现OOM,nullpointer
1.OOM :对图片进行压缩,效果还不错:http://182.92.150.15:9876/static/server/topic_user/8068/201506/e5b37fec-0919-11 ...