zoukankan      html  css  js  c++  java
  • React 踩坑——点击空白区域隐藏自定义弹窗,无法阻止事件冒泡

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    输入url到页面渲染发生了什么
    echarts缓存处理
    jquery 使用mock
    vue axios的封装
    css3实现盒子宽度随文字宽度自适应
    VUE中使用bus传值时,接收页面多次触发接收方法的问题
    原生js 文件 上传 下载封装
    微信小程序使用第三方包
    为什么我们要使用Async、Await关键字
    服务大众的人工智能---认知服务
  • 原文地址:https://www.cnblogs.com/abcdecsf/p/13663701.html
Copyright © 2011-2022 走看看