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 28 Javascript
javascript 学习笔记(一)DOM基本操作
Apr 08 Javascript
JSON 必知必会 观后记
Oct 27 Javascript
js数组与字符串常用方法总结
Jan 13 Javascript
微信小程序 devtool隐藏的秘密
Jan 21 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
Aug 31 Javascript
基于Cookie常用操作以及属性介绍
Sep 07 Javascript
Vue 中的受控与非受控组件的实现
Dec 17 Javascript
Vue CLI3基础学习之pages构建多页应用
Jun 02 Javascript
vue 实现走马灯效果
Oct 28 Javascript
webpack中的模式(mode)使用详解
Feb 20 Javascript
JavaScript组合继承详解
Nov 07 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
杏林同学录(四)
2006/10/09 PHP
利用 fsockopen() 函数开放端口扫描器的实例
2017/08/19 PHP
kindeditor 加入七牛云上传的实例讲解
2017/11/12 PHP
PHP封装的完整分页类示例
2018/08/21 PHP
PHP 实现链式操作
2021/03/09 PHP
javascript实现的动态文字变换
2007/07/28 Javascript
javascript数组的使用
2013/03/28 Javascript
验证码按回车不变解决方法
2013/03/29 Javascript
JavaScript prototype 使用介绍
2013/08/29 Javascript
javascript屏蔽右键代码
2014/05/15 Javascript
jQuery事件绑定方法学习总结(推荐)
2016/11/21 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
vue 出现data-v-xxx的原因及解决
2020/08/04 Javascript
Vue如何循环提取对象数组中的值
2020/11/18 Vue.js
对vue生命周期的深入理解
2020/12/03 Vue.js
Vue中ref和$refs的介绍以及使用方法示例
2021/01/11 Vue.js
python使用beautifulsoup从爱奇艺网抓取视频播放
2014/01/23 Python
解决Pandas to_json()中文乱码,转化为json数组的问题
2018/05/10 Python
python使用turtle库绘制时钟
2020/03/25 Python
python文件拆分与重组实例
2018/12/10 Python
Python Selenium参数配置方法解析
2020/01/19 Python
Python中文分词库jieba,pkusegwg性能准确度比较
2020/02/11 Python
Jupyter notebook 启动闪退问题的解决
2020/04/13 Python
keras的ImageDataGenerator和flow()的用法说明
2020/07/03 Python
python RSA加密的示例
2020/12/09 Python
国际知名设计师时装商店:Coggles
2016/09/05 全球购物
JD Sports荷兰:英国领先的运动时尚零售商
2020/03/13 全球购物
关键字throw与throws的用法差异
2016/11/22 面试题
大型活动策划方案
2014/01/12 职场文书
幼儿园五一活动方案
2014/02/07 职场文书
和谐社区口号
2014/06/19 职场文书
民政局标准版离婚协议书
2014/12/01 职场文书
企业法人代表证明书
2015/06/18 职场文书
CSS3 制作精美的定价表
2021/04/06 HTML / CSS