zoukankan      html  css  js  c++  java
  • mouseup模拟drag与click事件冲突

    今天要说一个很隐晦的东西,一般可能很难碰到,碰到了可能很难解决。就是当我们自己用mousestart,mousemove,mouseup做自定义拖拽效果的时候,如果这个时候配上click就会引发一个拖拽穿透的bug。

    mouseup模拟drag与click事件冲突(二维码)    

    点击上面的链接,用鼠标拖住上下拖拽可滚动列表,然后你会发现,如果你的鼠标在某一个具体的列表项上,就会触发查看详情,其实查看详情是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

  • 相关阅读:
    【AtCoder】AGC002
    【AtCoder】ARC059
    【AtCoder】AGC003
    【AtCoder】ARC060
    ES6学习总结之Set和Map的使用
    phaser学习总结之Text详解
    javascript实现数组排序的方法
    phaser学习总结之phaser入门教程
    javascript中字符串常用的方法和属性
    javascript中数组常用的方法和属性
  • 原文地址:https://www.cnblogs.com/fangsmile/p/14183657.html
Copyright © 2011-2022 走看看