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 相关文章推荐
ppk谈JavaScript style属性
Oct 10 Javascript
Jquery实现网页跳转或用命令打开指定网页的解决方法
Jul 09 Javascript
文档对象模型DOM通俗讲解
Nov 01 Javascript
javascript类型转换使用方法
Feb 08 Javascript
jQuery实现tab标签自动切换的方法
Feb 28 Javascript
详解angularjs实现echart图表效果最简洁教程
Nov 29 Javascript
微信小程序实现倒计时补零功能
Jul 09 Javascript
javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
Aug 01 Javascript
基于vue的验证码组件的示例代码
Jan 22 Javascript
Vue使用Proxy监听所有接口状态的方法实现
Jun 07 Javascript
vue element-ui el-date-picker限制选择时间为当天之前的代码
Nov 07 Javascript
vue抽出组件并传值实例
Jul 31 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
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
朋友网关于QQ相关的PHP代码(研究QQ的绝佳资料)
2015/01/26 PHP
php使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
PHP错误处理函数
2016/04/03 PHP
php设计模式之职责链模式定义与用法经典示例
2019/09/19 PHP
ExtJS 2.0实用简明教程 之获得ExtJS
2009/04/29 Javascript
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
浅谈Nodejs观察者模式
2015/10/13 NodeJs
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
Centos7 中安装 Node.js v4.4.4
2016/11/03 Javascript
NodeJS读取分析Nginx错误日志的方法
2019/05/14 NodeJs
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
js实现贪吃蛇游戏 canvas绘制地图
2020/09/09 Javascript
[01:03]悬念揭晓 11月26日DOTA2完美盛典不见不散
2017/11/23 DOTA
[48:31]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第二场 12.17
2020/12/19 DOTA
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
Python实现全角半角转换的方法
2014/08/18 Python
Python2.x与Python3.x的区别
2016/01/14 Python
windows下安装Python和pip终极图文教程
2017/03/05 Python
Python批量提取PDF文件中文本的脚本
2018/03/14 Python
Python3导入CSV文件的实例(跟Python2有些许的不同)
2018/06/22 Python
python保存二维数组到txt文件中的方法
2018/11/15 Python
pygame实现贪吃蛇游戏(上)
2019/10/29 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
css3 iphone玻璃透明气泡完美实现
2013/03/20 HTML / CSS
利用CSS3实现单选框动画特效示例代码
2016/09/26 HTML / CSS
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
报社实习生自荐信
2014/01/24 职场文书
个人贷款担保书
2014/04/01 职场文书
大学生求职信怎么写
2015/03/19 职场文书
违规违纪检讨书范文
2015/05/06 职场文书
停发工资证明范本
2015/06/12 职场文书
JavaWeb实现显示mysql数据库数据
2022/03/19 Java/Android