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 相关文章推荐
js的闭包的一个示例说明
Nov 18 Javascript
javawscript 三级菜单的实现原理
Jul 01 Javascript
基本jquery的控制tabs打开的数量的代码
Oct 17 Javascript
js如何获取object类型里的键值
Feb 18 Javascript
JS父页面与子页面相互传值方法
Mar 05 Javascript
jQuery版本升级踩坑大全
Jan 12 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
Apr 17 Javascript
基于jQuery实现弹出可关闭遮罩提示框实例代码
Jul 18 Javascript
巧用Vue.js+Vuex制作专门收藏微信公众号的app
Nov 03 Javascript
深入浅析Vue.js 中的 v-for 列表渲染指令
Nov 19 Javascript
基于JavaScript实现贪吃蛇游戏
Mar 16 Javascript
基于JavaScript实现随机点名器
Feb 25 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
PHP实现上传图片到 zimg 服务器
2016/10/19 PHP
JavaScript 无符号右移运算符
2009/04/17 Javascript
javascript 实现键盘上下左右功能的小例子
2013/09/15 Javascript
巧用jquery解决下拉菜单被Div遮挡的相关问题
2014/02/13 Javascript
更高效的使用JQuery 这里总结了8个小技巧
2016/04/13 Javascript
JS使用onerror捕获异常示例
2016/08/03 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
angular-ui-sortable实现可拖拽排序列表
2016/12/28 Javascript
Angular 2.x学习教程之结构指令详解
2017/05/25 Javascript
Three.js中网格对象MESH的属性与方法详解
2017/09/27 Javascript
JS控制鼠标拒绝点击某一按钮的实例
2017/12/29 Javascript
es6数值的扩展方法
2019/03/11 Javascript
tsconfig.json配置详解
2019/05/17 Javascript
浅入深出Vue之自动化路由
2019/08/06 Javascript
vue cli3 调用百度翻译API翻译页面的实现示例
2019/09/13 Javascript
JavaScript实现轮播图效果代码实例
2019/09/28 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
[01:27:30]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
haskell实现多线程服务器实例代码
2013/11/26 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
2019/01/08 Python
python读csv文件时指定行为表头或无表头的方法
2019/06/26 Python
python的移位操作实现详解
2019/08/21 Python
Python进程Multiprocessing模块原理解析
2020/02/28 Python
python中前缀运算符 *和 **的用法示例详解
2020/05/28 Python
CSS3实现内凹圆角的实例代码
2017/05/04 HTML / CSS
Canvas图片分割效果的实现
2019/07/29 HTML / CSS
介绍一下grep命令的使用
2012/06/28 面试题
研究生自荐信
2013/10/09 职场文书
公司市场部岗位职责
2013/12/02 职场文书
无工作经验者个人求职信范文
2013/12/22 职场文书
公司活动总结范文
2014/07/01 职场文书
主题党日活动总结
2014/07/08 职场文书
运动会演讲稿100字
2014/08/25 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
redis哨兵常用命令和监控示例详解
2021/05/27 Redis
解析MySQL binlog
2021/06/11 MySQL