深入React事件系统(React点击空白部分隐藏弹出层;React阻止事件冒泡失效)

摘要:
在绑定到React组件冲突的两个事件之后,使用e.stopPropagation()来防止气泡,这可以毫无问题地防止事件冲突。今天是React事件的大坑。该要求可以简化为:单击框外的零件以隐藏框。我的第一个想法是本机事件与React事件冲突。将警告绑定到文档上,并将警告绑定在框上,无需特殊处理。在框中单击并根据事件弹出气泡,然后依次弹出1和2。

来源:https://www.cnblogs.com/lihuanqing/p/6295685.html

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

两个在React组件上绑定的事件,产生冲突后,使用e.stopPropagation(),阻止冒泡,即可防止事件冲突,毫无问题。

今天是踩了个React事件的坑,需求可以简化为:点击框体以外的部分则隐藏框体。最直接的想法,document上绑定个事件,设置控制显示隐藏的state为false,在框体上绑定个事件,阻止冒泡。这样点击框体内部就不会触发document上的事件。

等写完了,发现一个问题,无法阻止冒泡,一搜索,好家伙,好多人问e.stopPropagation()为什么无法阻止事件冒泡,但是鲜有靠谱的回答。我第一个想法是原生事件和React事件产生冲突。明显绑定原生事件是不符合React精神的,但我决定在探索真理的路上走下去了。

为了直观的调试,把需求转化为,点击框体内 alert1)点击框体外 alert2)。

document上绑定 alert2),框体上(框体为React组件,下同)绑定 alert1),不做特殊处理,点击框体内,根据事件冒泡,先弹 1 再弹 2 。这一点符合预期。此时e.stopPropagation()无法阻止冒泡。

经过 Stack Overflow 解惑 e.nativeEvent.stopImmediatePropagation() 可以完美实现预期。

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

  1. React为了提高效率,把事件都委托给了document,所以 e.stopPropagation() 并非是不能阻止冒泡,而是等他阻止冒泡的时侯,事件已经传递给document了,没东西可阻止了。可以通过在document.body上绑定 alert3),直观的了解这一点,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,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阻止事件冒泡失效)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇redhat6版本网卡绑定做bondCtrl+H 浪潮Raid配置文档下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

react使用echarts地图实现中国地图大区展示

   日常项目中经常会用到百度地图或者echarts图标展示,今天给大家展示的是如何在react开发项目中使用百度echars的地图展示,把中国地图分为东北大区、华东大区、华南大区、华西大区、华中大区以及华北大区并用颜色标识方便识别。     最终展示效果如下:    我是直接用的react官方提供的create-react-app快速构建开发环境,之后就...

react项目中引用amap

在调用amap的Geocoder Api 时,一直不能从AMap对象下找到Geocoder 。 结果在网上看到一个博客说的是,在index中引入链接时,需要在链接上配置plugin=AMap.Geocoder, 才能够在AMap调用Geocoder Api <script type="text/javascript" src="https://web...

解决初次使用webpack+antd-mobile时css不生效的问题

前端这块,最火的是angular、react、vue。根据你具体的业务场景,选择合适的框架或者类库。以react为例,新建一个项目时, css组件按钮,图片轮播等组件,最好不要重复造轮子,选择业内规范的,拿来用就行。这里选了一个比较火的antd-mobile。类似移动端的 bootstrap,但是UI组件要比bootstr强大丰富,且专注于结合react使...

React入门教程第一课--从零开始构建项目

工欲善其事必先利其器,现在的node环境下,有太多好用的工具能够帮助我们更好的开发和维护管理项目。 我本人不建议什么功能都自己写,我比较喜欢代码复用。只要能找到npm包来实现的功能,坚决不自己敲代码。 本次编写程序的两个原则:1、尽量使用声明式的编程风格(声明式和命令式,不是很清楚的自己查查资料)2、能复用的决不自己编写。 任何多余的繁琐的行为都是错误的...

如何触发react input change事件

页面用react来进行开发的,想触发react组件里面input的change事件,用Jquery的trigger来触发没有效果,必须使用原生的事件来进行触发。var event = new Event('input', { bubbles: true });element.dispatchEvent(event);...

vue对比其他框架

对比其他框架React React 和 Vue 有许多相似之处,它们都有: 使用 Virtual DOM 提供了响应式(Reactive)和组件化(Composable)的视图组件。 将注意力集中保持在核心库,伴随于此,有配套的路由和负责处理全局状态管理的库。 性能简介 Vue 的性能是优于 React 的。如果你对此表示怀疑,请继续阅读。我们会解释为...