记录antd drawer 组件拖拽过程中 onmousemove 事件 在 iframe 失效问题
写在前面
但是在后续的需求中,也就是 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
并捕获所有的鼠标事件(如mousemove
和mouseup
)。这样,鼠标事件不会进入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 所提供的答案只是它所看到的问题。
所以在遇到问题时,一定要冷静下来思考代码结构,思考问题的核心,这样解决起来事半功倍。
转载自:https://juejin.cn/post/7394255414764584999