React冒泡和阻止冒泡的应用详解


Posted in Javascript onAugust 18, 2020

阻止事件冒泡分三种:

1:阻止合成事件往最外层document上的事件冒泡,用e.nativeEvent.stopImmediatePropagation();

2: 合成事件间的冒泡,使用 e.stopPropagation();

3:阻止合成事件,往处理document上的其他原生事件冒泡,需要通过e.target来判断,示例代码如下。

import React,{ Component } from 'react';
import ReactDOM,{findDOMNode} from 'react-dom';

class Counter extends Component{
constructor(props){
super(props);

this.state = {
count:0,
    }
  }

handleClick(e){
this.setState({count:++this.state.count});
  }
render(){
return(
<div ref="test">
<p>{this.state.count}</p>
<a ref="update" onClick={(e)=>this.handleClick(e)}>更新</a>
</div>
    )
  }

componentDidMount() {
document.body.addEventListener('click',e=>{
// 通过e.target判断阻止冒泡
      if(e.target&&e.target.matches('a')){
return;
      }
console.log('body');
    })
  }
}

var div1 = document.getElementById('content');

ReactDOM.render(<Counter/>,div1,()=>{});

需求

最近在写react的项目,需要手写一个自定义的菜单,和antd的menu不同,需要点击一级菜单后弹出类似一个Drawer展示二级和三级菜单,且菜单样式自定义,都在一个Drawer里展示。

难点

其中难点在于点击一级菜单时弹出Drawer,点击除Drawer和一级菜单项之外的dom,Drawer收起。

问题

乍一想就是给document添加一个点击事件监听,给Drawer和一级菜单添加阻止冒泡,思路确实如此,后面实现中发现:
react为提高性能,有自己的一套事件处理机制,相当于将事件代理到全局进行处理,也就是说监听函数并未绑定到Dom上。 因此阻止react的事件冒泡e.stopPropagation(),就不发阻止原生事件的冒泡,表现为点击Drawer也会收起Drawer;禁用原生事件冒泡e.nativeEvent.stopPropagation(),React的监听函数就调用不到,表现为点击Drawer以外dom,Drawer不会收起。这些都不是我们想要的。

解决方案

正确的姿势应该是判断event.target对象是否是目标对象或包含目标对象或被包含目标对象,以此来决定是否触发事件

componentDidMount() {
  document.addEventListener('click', this.hideDrawer);
 }

 componentWillUnmount() {
  document.removeEventListener('click', this.hideDrawer);
 }

 hideDrawer = e => {
  const { closeDrawer } = this.props;
  // 找到不需要关闭的dom 一级菜单
  const tabContent = document.querySelectorAll('.ant-menu-submenu-vertical');
  // 找到不需要关闭的dom   Drawer
  const drawerContent = document.querySelector('#menuDrawer');
  // 判断当前点击的dom对象有没有包含在目标dom中
  const isHave = Array.from(tabContent).some(item => item.contains(e.target));
  // 不包含则关闭Drawer 包含就走其他的业务逻辑了
  if (tabContent !== null && !(isHave || drawerContent.contains(e.target))) {
   closeDrawer();
  }
 };

到此这篇关于React冒泡和阻止冒泡的应用详解的文章就介绍到这了,更多相关React冒泡和阻止冒泡内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Javascript 相关文章推荐
JavaScript 参考教程
Dec 29 Javascript
jQuery 源码分析笔记(2) 变量列表
May 28 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
Mar 03 Javascript
JavaScript数字和字符串转换示例
Mar 26 Javascript
编写高效jQuery代码的4个原则和5个技巧
Apr 24 Javascript
jQuery获取file控件中图片的宽高与大小
Aug 04 Javascript
详解Angular 4.x NgIf 的用法
May 22 Javascript
详解webpack提取第三方库的正确姿势
Dec 22 Javascript
jQuery实现鼠标响应式淘宝动画效果示例
Feb 13 jQuery
vue2.0使用v-for循环制作多级嵌套菜单栏
Jun 25 Javascript
JavaScript ES2019中的8个新特性详解
Feb 20 Javascript
layui的布局和表格的渲染以及动态生成表格的方法
Sep 18 Javascript
JavaScript数组排序的六种常见算法总结
Aug 18 #Javascript
js实现简单扫雷
Nov 27 #Javascript
基于JavaScript实现大文件上传后端代码实例
Aug 18 #Javascript
javascript实现扫雷简易版
Aug 18 #Javascript
详解Vue的组件中data选项为什么必须是函数
Aug 17 #Javascript
Openlayers实现扩散的动态点(水纹效果)
Aug 17 #Javascript
openLayer4实现动态改变标注图标
Aug 17 #Javascript
You might like
页面乱码问题的根源及其分析
2013/08/09 PHP
PHP使用ffmpeg给视频增加字幕显示的方法
2015/03/12 PHP
Laravel 5 框架入门(三)
2015/04/09 PHP
php学习笔记之mb_strstr的基本使用
2018/02/03 PHP
js 禁止选择功能实现代码(兼容IE/Firefox)
2010/04/23 Javascript
jQuery中调用WebService方法小结
2011/03/28 Javascript
无缝滚动js代码通俗易懂(自写)
2013/06/19 Javascript
网页防止tab键的使用快速解决方法
2013/11/07 Javascript
javascript数组操作方法小结和3个属性详细介绍
2014/07/05 Javascript
jQuery中:enabled选择器用法实例
2015/01/04 Javascript
jQuery背景插件backstretch使用指南
2015/04/21 Javascript
javascript实现五星评价代码(源码下载)
2015/08/11 Javascript
jQuery实现无限往下滚动效果代码
2016/04/16 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
js实现文字截断功能
2016/09/14 Javascript
JavaScript严格模式详解
2017/01/16 Javascript
jQuery模拟淘宝购物车功能
2017/02/27 Javascript
js实现移动端轮播图效果
2020/12/09 Javascript
canvas绘制爱心的几种方法总结(推荐)
2017/10/31 Javascript
python单例模式实例分析
2015/04/08 Python
python提取页面内url列表的方法
2015/05/25 Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
2016/04/11 Python
Django实现全文检索的方法(支持中文)
2018/05/14 Python
基于python进行桶排序与基数排序的总结
2018/05/29 Python
tensorflow: 查看 tensor详细数值方法
2018/06/13 Python
Selenium(Python web测试工具)基本用法详解
2018/08/10 Python
python 处理telnet返回的More,以及get想要的那个参数方法
2019/02/14 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
写演讲稿所需要注意的4个条件
2014/01/09 职场文书
学校节能减排方案
2014/06/13 职场文书
2015年安全教育月活动总结
2015/03/26 职场文书
英语版自我评价,35句话轻松搞定
2019/10/08 职场文书
完美处理python与anaconda环境变量的冲突问题
2021/04/07 Python
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python
以MySQL5.7为例了解一下执行计划
2022/04/13 MySQL