mouseup模拟drag与click事件冲突
今天要说一个很隐晦的东西,一般可能很难碰到,碰到了可能很难解决。就是当我们自己用mousestart,mousemove,mouseup做自定义拖拽效果的时候,如果这个时候配上click就会引发一个拖拽穿透的bug。
点击上面的链接,用鼠标拖住上下拖拽可滚动列表,然后你会发现,如果你的鼠标在某一个具体的列表项上,就会触发查看详情,其实查看详情是click之后才会触发的,但是这里很明显自定义拖拽触发了click。(注:此bug pc上才有,手机端没有)
问题分析
其实这种问题一般情况下是很难遇到的,只会有某些框架里面出现这种bug,那我们看看这种问题到底是如何出现的。
首先自定义拖拽是利用mousestart,mousemove,mouseup三个事件组合形成的,但是mouseup执行之后,click是一定会执行的,是无法避免的,是无法用preventDefault,stopPropagation,stopImmediatePropagation阻止的。本例的demo中就在mouseup之后执行了上述阻止事件传播的方法,但是并没有效果。因为mouse事件和click事件本身就不是一个系列的,因此没有关系,所以当发生拖拽之后,mouseup一定会执行,click也会在mouseup执行后执行。
解决方案
首先我们可以解决最简单的一种,就是不拖拽的情况下触发只是触发click。
按照刚才的说法,mouseup事件后click必定会触发,但是如果没有发生拖拽,也就是没有触发mousemove事件,这种情况比较简单,我们可以用一个变量纪录是否触发mousemove,在mouseup的时候只触发发生拖拽的情况。
还有一种比较复杂的情况,就是在发生了拖拽的情况下如何避免click的触发?这个时候我们用一个定时去控制一个全局变量,让这个变量在200毫秒之后发生改变,因此mouseup之后click很快就触发了,不到200ms,因此可以保证变量还没有发生变化,click事件里面去检测这个变量,如果是变化之前,那么不执行。具体代码如下:
1 //mouseup事件里定时改变一个变量 2 window.mouseup_click_debug = true; 3 setTimeout(function() { 4 window.mouseup_click_debug = false; 5 }, 200); 6 //click事件里去检测这个变量是否发生改变,如果没改变,说明mouseup刚执行完,这里不执行 7 if(window.mouseup_click_debug) { 8 return false; 9 }
解决后的demo如下:
解决后demo:mouseup模拟drag与click事件冲突(二维码)
转自:http://www.qiutianaimeili.com/html/page/2018/09/5c9jxp7u6ng.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?