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 相关文章推荐
关于图片验证码设计的思考
Jan 29 Javascript
iframe父页面获取子页面参数的方法
Feb 21 Javascript
JavaScript中的Array 对象(数组对象)
Jun 02 Javascript
深入理解jQuery.data() 的实现方式
Nov 30 Javascript
javascript中闭包概念与用法深入理解
Dec 15 Javascript
JS实现的简单图片切换功能示例【测试可用】
Feb 14 Javascript
整理一些最近经常遇到的前端面试题
Apr 25 Javascript
详解webpack解惑:require的五种用法
Jun 09 Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 Javascript
javaScript 连接打印机,打印小票的实例
Dec 29 Javascript
Vue 实现前端权限控制的示例代码
Jul 09 Javascript
vue router 动态路由清除方式
May 25 Vue.js
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
全国FM电台频率大全 - 4 山西省
2020/03/11 无线电
php录入页面中动态从数据库中提取数据的实现
2006/10/09 PHP
用session做客户验证时的注意事项
2006/10/09 PHP
php将数据库中的电话号码读取出来并生成图片
2008/08/31 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
js读取本地excel文档数据的代码
2010/11/11 Javascript
JQuery获取各种宽度、高度(format函数)实例
2013/03/04 Javascript
谈谈关于JavaScript 中的 MVC 模式
2013/04/11 Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
2014/08/10 Javascript
jquery禁止回车触发表单提交
2014/12/12 Javascript
jQuery实现仿路边灯箱广告图片轮播效果
2015/04/15 Javascript
Bootstrap登陆注册页面开发教程
2016/07/12 Javascript
详解能在多种前端框架下使用的表格控件
2017/01/11 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
2017/05/11 Javascript
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
jQuery实现基本动画效果的方法详解
2018/09/06 jQuery
通过vue-cli3构建一个SSR应用程序的方法
2018/09/13 Javascript
vue3.0 CLI - 2.1 -  component 组件入门教程
2018/09/14 Javascript
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
如何使用Javascript中的this关键字
2020/05/28 Javascript
使用Python生成随机密码的示例分享
2016/02/18 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
Python何时应该使用Lambda函数
2019/07/02 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
Oracle性能调优原则
2012/05/03 面试题
医学专业个人求职自荐信格式
2013/09/23 职场文书
农村婚庆司仪主持词
2014/03/15 职场文书
个人综合鉴定材料
2014/05/23 职场文书
董事长助理工作职责
2014/06/08 职场文书
党建目标管理责任书
2014/07/25 职场文书
报效祖国演讲稿
2014/09/15 职场文书
瘦西湖导游词
2015/02/03 职场文书
庭外和解协议书
2016/03/23 职场文书
PostgreSQL 插入INSERT、删除DELETE、更新UPDATE、事务transaction
2022/04/12 PostgreSQL
SQL语句多表联合查询的方法示例
2022/04/18 MySQL
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
2022/06/01 Java/Android