zoukankan      html  css  js  c++  java
  • 记一次多事件绑定中自己给自己设置的坑——click,dblclick,mousedown,mousemove,mouseup

    项目综述

    • 在页面中模拟某操作系统的操作界面,提供应用窗口的最大化、最小化、还原等功能

    需求

    • 对一个应用窗口标题栏双击使其铺满整个视口,再次双击还原到原来大小,和位置
    • 部分代码片段如下:
    win.addEventListener('dblclick', (event) => {
        if (cache && cache.status === 'normal') {
            Win.maximize(id);
        } else if (cache && cache.status === 'maximize') {
            Win.restore(id);
        }
    });
    
    • 在Win.restore()和Win.maximize()方法中通过id读取该应用的缓存信息
    {
        top: app.cache.pos.top,
        left: app.cache.pos.left,
         app.size.width,
        height: app.size.height,
    }
    

    问题

    • Chrome浏览器(87)

      • 使用电脑自带触摸板进行双击测试,正常
      • 使用鼠标进行双击测试,双击事件触发后cache.pos内的内容丢失,top和left属性不存在,cache中其余属性正常
    • Edge浏览器(87)

      • 表现与Chrome浏览器一致
    • Firefox浏览器(84)

      • 在使用电脑自带触摸板和鼠标测试时,双击事件触发后均出现cache.pos内的内容丢失的情况,其余属性正常

    猜想

    • 对象嵌套深度问题???毕竟嵌套最深的丢了,其他的都没事
    // 将left和top直接定义在cache,表现与之前测试结果一致,修改无效
    {
        top: app.cache.top,
        left: app.cache.left,
         app.size.width,
        height: app.size.height,
    }
    
    • 命名冲突问题???
    // 将属性名加上前缀,表现与之前测试结果一致,修改无效
    {
        top: app.cache.winTop,
        left: app.cache.winLeft,
         app.size.width,
        height: app.size.height,
    }
    
    • 事件冲突问题,该元素同时定义了单击事件,但注释掉单击事件后问题依旧存在

    • 双击事件的BUG????????

    // 使用单击事件模拟双击事件,在谷歌和Edge中使用触摸板最大化和还原也会造成数据丢失了
    function doubleclick(elem, onsingle, ondouble) {
        if (dblFlag) {
            dblFlag = true;
            setTimeout(function () {
                if (dblFlag) {
                    onsingle(elem);
                }
                dblFlag = false;
            }, 300);
        } else {
            dblFlag = false;
            ondouble(elem);
        }
    }
    

    解决

    • 就在我已经快要放弃这个功能的时候,发现这个元素还绑定了另外一个事件

    • 为了让窗口可以在页面中自由拖动,加入了mousedown,mousemove,mouseup事件模拟拖拽事件,提前声明变量currentLeft和currentTop,在mousemove时修改两个属性的值,在mouseup时保存当前位置,如下代码:

    window.onmouseup = function () {
        window.onmousemove = null;
        app.cache.pos.left = currentLeft;
        app.cache.pos.top = currentTop;
    
        return false;
    }
    
    • 在双击事件中连续触发了mouseup和mousedown,所以给top和left写入了新值

    但是,双击事件并没有触发到mousemove事件,导致currentLeft和currentTop没有值写入,还是初始的未赋值状态,并将undefined写入了缓存,也就是cache.pos内属性丢失的问题

    • 知道了问题就好解决了,加一个判空就行了
    window.onmouseup = function () {
        window.onmousemove = null;
        app.cache.pos.left = currentLeft || app.cache.pos.left;
        app.cache.pos.top = currentTop || app.cache.pos.top;
    
        return false;
    }
    
    • 至于使用触摸板和使用鼠标导致差异,大概是用鼠标手比较稳,双击不会出现位置移动,而触摸板两次点击很难都点中同一位置,或多或少有差异,触发mousemove写入了新值
    • 不同浏览器的不同表现,大概是对双击事件中两次点击的误差范围规定不同,改用了单击事件模拟双击事件后,浏览器的表现就一致了

    反思

    • 能给初始值就给初始值,不能给初始值在使用的时候一定要给默认值!
    • 别瞎想,看看自己的猜想,连边都没有摸到,在用单击事件模拟双击时就应该联想到其余的事件,然后检查是否相互影响
    • 就自己目前的水平,所有的问题都一定是自己的问题!
    • 自己坑起自己来果然是不遗余力啊!
  • 相关阅读:
    初识函数作业
    HTTP协议那些事儿(Web开发补充知识点)
    文件操作
    文件操作作业
    深浅拷贝
    深浅拷贝作业
    小数据池 is和== 再谈编码
    小数据池/is和==/再谈编码作业
    如何用好 github 中的 watch、star、fork
    Navicat Premium Mac 12 破解(亲测可用!!!)
  • 原文地址:https://www.cnblogs.com/hycstar/p/14263267.html
Copyright © 2011-2022 走看看