React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡

摘要:
然而,对于一件非常简单的事情,我们发现有几种方法无法阻止事件冒泡,导致操作逻辑混乱。有趣的是,React不直接将事件附加到子元素,而是将所有事件以单个事件侦听器的形式发送到顶层进行处理。因为像React这样的一组事件处理机制相当于将事件代理到全局进行处理,也就是说,侦听函数没有绑定到DOM元素。

  这周有一个小需求,实现一个点击图片并弹出框,具有缩放、旋转图片功能,方便审核人员审核图片。

  最开始我是想在Antd的Modal组件上更改,加上图片处理操作。后来发现很难行得通,因为官方组件是经过层层封装,暴露的api有限,想在它们的基础上增加功能的话,很难从底层上控制,于是我想着自己造个小轮子。预期效果是这样的:

点击预览图,通过 ReactDOM.createPortal 方法生成一个弹窗组件,中间为父容器元素包裹着放大的图片,右上角为工具栏,背后是遮罩层。

React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡第1张

  预期的效果是点击空白区域隐藏弹窗,但刚写出来运行时,点击图片 或点击工具栏的非“关闭”部分,也会关闭弹窗,原因是触发了事件的冒泡机制,导致点击图片时,“关闭”事件向上传递到了父元素和父元素的父元素。。

  但是,本来很简单的事情,却发现好几种办法都无法阻止事件冒泡,导致操作逻辑错乱。

  先是老办法 e.stopPropagation() ,不起作用,有人说用 e.nativeEvent.stopPropagation()原生事件方法,也不行。然后查阅资料,说React的事件处理逻辑有他特殊的地方,React 会将浏览器原生事件封装为合成事件,传入其设置的事件处理器中。整个事件机制都是基于全局的事件代理。

  另外有意思的是,React 并没有直接将事件附着到子元素上,而是以单一事件监听器的方式将所有的事件发送到顶层进行处理。这样 React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器,最终达到优化性能的目的。但这就对我们造成困惑了。

  因为React这样的一套事件处理机制,相当于将事件代理到全局进行处理,也就是说监听函数并未绑定到DOM元素上。因此,如果你阻止React事件冒泡e.stopPropagation(),你就无法阻止原生事件冒泡;你阻止原生事件冒泡e.nativeEvent.stopPropagation(),React的监听函数就调用不到了。

  所以正确的方法,应该是判断event.target对象,是否为目标对象、或包含的对象、或被包含的对象,再来决定是否触发事件。我就用下面这种方法解决问题了:

React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡第2张

React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡第3张

免责声明:文章转载自《React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇分辨率与比例尺中文分词组件:thulac及jieba试用手记下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

webpack4.x最详细使用讲解一

前言 本文主要从webpack4.x入手,会对平时常用的Webpack配置一一讲解,各个功能点都有对应的详细例子,所以本文也比较长,但如果你能动手跟着本文中的例子完整写一次,相信你会觉得Webpack也不过如此。 一、什么是webpack,为什么使用它? ​ 1.1 什么是webpack? 简单来说,它其实就是一个模块打包器。 1.2 为什么使用它? 如果...

React (redux store reducers(1个) reducer(1个组件1个 包含多个function函数 ) action(对象) dispatch)(react-redux redux-actions redux-immutable redux-thunk 异步redux )flux

//compose 组成 combine 联合 import {applyMiddleware, createStore, compose, combineReducers} from 'redux'; import { bindActionCreators } from "redux"; import {Provider} from 'react-...

react 执行 yarn build ,无法直接打开dist文件下的index

如果你使用create-react-app创建项目,执行命令 yarn build 后,直接以静态方式打开build文件夹内的index.html,会看到页面显示出现问题,打开console后会看到js、css、svg等文件的路径出现问题。 解释: 在打包之前,在 package.json 中 private 下(位置任意)添加"homepage": "....

前端利器躬行记(7)——自制脚手架

在学习了Webpack基础后,查看别人写好的脚手架总是会一头雾水,后面就上网查各种资料,一边参考一边修改,整出了一套简易的脚手架(已上传至GiuHub和npm上),借鉴了Create React App(CRA)的目录结构(如下所示),并做成了命令行工具(已上传至GiuHub和npm上)。 ├── pwu -------------------------...

react学习记录(一)

一、React是什么 声明式写法(强调结果,命令式编程强调过程) 组件化 一次学习,随处编写(多种应用场景,web程序,原生手机应用,系统应用,命令行工具) 二、为什么学习react 大公司加持-facebook 最流行,使用人数最多,被开发者喜爱 简单易懂 三、配置开发环境 官方脚手架工具Creat-react-app,类似vue-cli 脚手架工具:是...

React-Native 之 ScrollView介绍和使用

前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所偏差,在学习中如果有错会及时修改内容,也欢迎万能的朋友们批评指出,谢谢 文章第一版出自简书,如果出现图片或页面显示问题,烦请转至 简书 查看 也希望喜欢的朋...