记录 drawer 组件拖拽过程中 onmousemove事件 在 iframe 失效问题

写在前面

最近作者在开发了一个 ant 的 drawer 组件拖拽功能,也就是上篇文章,没看的可以先去看一下,正常情况下是没问题的,如下图

但是在后续的需求中,也就是 Drawer 组件内部放了内容之后,拖拽出现了失效,如下图

细心的朋友应该已经看出来问题了,我按下的时候是有个黄色圆圈的,但是发现松起的时候,还在移动,而且移动的很没有规律,这是个问题。

题目我相当于给到了问题根源,但是一开始没有找到问题根源,接下来来看看这个问题吧。

一开始并没有发现是什么问题,一直以为是自己事件没有处理好,自己明明在按下时增加了移动事件,松开时移除了移动事件,为什么还会触发呢?感觉很不符合逻辑啊!

const onMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    e.preventDefault()
    e.stopPropagation()
    document.addEventListener('mousemove', onMouseMove)
    document.addEventListener('mouseup', onMouseUp)
  }

const onMouseUp = useCallback(() => {
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
  }, [onMouseMove])

经过一顿调试,发现并不管移动事件,那是怎么回事呢!

最后才想起来移动到右侧时里面是一个 iframe,也就是直接嵌套进来的页面,于是便进行了思考是不是它的问题,便进行了搜索,见下图文档,很明显在 iframe 上不能使用。

那应该怎么解决呢,先进行百度搜索 onmousemove iframe 失效,果然发现有相同问题的还不少呢!

所以对百度的方法进行了尝试,有一些确实有用,所以我也把有用的一个方法分享出来供大家参考!如果有相同问题的朋友,大家可以直接进行尝试。

解决方法

那为什么会出现这个问题呢?

在涉及到 iframe 时,鼠标事件的处理会变得更加复杂,因为 iframe 是一个独立的文档。

当鼠标移入 iframe 内部时,外部文档无法继续接收鼠标事件。这就导致了在 iframe 内部,mousemove 事件会失效。

解决办法就是需要增加一个透明元素遮罩住 iframe 即可 !

为什么遮罩层可以解决呢?

iframe 上方添加一个遮罩层,该遮罩层覆盖 iframe 并捕获所有的鼠标事件(如 mousemovemouseup)。这样,鼠标事件不会进入 iframe 内部,而是直接在父页面上处理。这种方法有效地避免了 iframe 内部事件无法传递到父页面的问题。

<div>
   <iframe src="http://localhost:8080/management"></iframe>
   {isIframeVisible && <div className="iframeCover"></div>}
</div>

透明元素样式如下: 

.iframeCover {
  position: absolute;
  z-index: 1000000;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}

当 onMouseDown 的时候设置遮罩层显示,当 onMouseUp 时 设置遮罩层隐藏即可。

onMouseDown

const [isIframeVisible, setIsIframeVisible] = useState(false)
const onMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    setIsIframeVisible(true)
  }

onMouseUp

  const onMouseUp = useCallback(() => {
    setIsIframeVisible(false)
  }, [onMouseMove])

效果如下,即使松开时移到了iframe上也不会继续移动了,问题得到了解决

总结

于是乎,这个问题得到了解决,今天分享这篇文章主要是为了记录这个问题,希望可以帮助那些遇到相同问题的人,毕竟当时自己并没有第一时间发现这个问题,现在解决了,觉得挺值得保存并分享出去的。

一开始我对问题的定位不够清楚,导致浪费了很多时间,在这个过程中如果求助 ai 也是没什么效果的的,因为一开始就没有正确的把问题描述出来,ai 所提供的答案只是它所看到的问题。

所以在遇到问题时,一定要冷静下来思考代码结构,思考问题的核心,这样解决起来事半功倍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JacksonChen_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值