zoukankan      html  css  js  c++  java
  • html元素双击事件触发机制猜想及疑惑

    今天有个同事遇到一个奇怪的问题,我照着他的代码做了一些简化写了这个demo

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <style type="text/css">
     5         div{position: absolute;top: 0;left: 0;height: 50px}
     6         #back{background-color: blue;left: 20px;width: 200px;z-index: 0}
     7         #front{background-color: green;top:10px;width: 100px;z-index: 1}
     8     </style>
     9 </head>
    10 <body>
    11     <div id="back"></div>
    12     <div id="front"></div>
    13     <script type="text/javascript">
    14         document.getElementById("back").addEventListener("click", function () {
    15             console.log("back clicked");
    16         })
    17         document.getElementById("front").addEventListener("click", function () {
    18             console.log("front clicked");
    19             this.setAttribute("style", "z-index:0");
    20             document.getElementById("back").setAttribute("style", "z-index:1");
    21         })
    22         document.getElementById("back").addEventListener("dblclick", function () {
    23             console.log("back double clicked");
    24         })
    25         document.getElementById("front").addEventListener("dblclick", function () {
    26             console.log("front double clicked");
    27         })
    28     </script>
    29 </body>
    30 </html>

    代码的逻辑大致是这样的:

    首先,页面中绿色方块为front,蓝色方块为back。系统的需求是,在绿色方块上单击时,切换两个方块覆盖方式(也就是点击front后back会跑到front前面)。同时,还需要在双击蓝色方块时实现另一个功能逻辑。

    于是这哥们很自然了写了类似上面的代码就提交了。没多久,测试MM提了一个bug:“双击绿色方块时,不应触发双击蓝色方块的逻辑”。

    后来我自己测了一下,果然如测试MM所说,当双击绿色和蓝色方块重叠的区域时,控制台会打印出这样的log:

    浏览器会先触发front click,然后是back click,再然后居然是back double click。按理说,在back上面只点击了一次,应该不触发double click才对,毕竟第一次click是在front上触发的。

    所以,我大胆猜想,浏览器本身并不会去判定鼠标是否触发双击事件,双击事件是由操作系统直接分发给浏览器的。当浏览器收到操作系统发来的双击消息时,直接根据该双击事件中的坐标去页面中找命中的元素,并在这个元素上触发js中的双击事件。

    操作系统在判断是否发生双击时,并不知道第一次click和第二次click的目标不是同一个元素,所以只要两次click的间隔足够短就认为构成双击事件。而浏览器在收到操作系统发来的双击事件时,并没有去检测这次双击是由那两次单击所产生,而是直接根据双击事件的坐标信息将这个事件分发到相应的html元素上了。

    为验证这个猜想,我又写了一个demo

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <style type="text/css">
     5         body{transition:padding-left 8s linear;padding-left: 0}
     6         div{width: 10px;height: 200px;background-color: blue;display: inline-block;float: left;}
     7     </style>
     8 </head>
     9 <body>
    10     <div id="div_00"></div>
    11     <div id="div_01"></div>
    12     <div id="div_02"></div>
    13     <div id="div_03"></div>
    14     <div id="div_04"></div>
    15     <div id="div_05"></div>
    16     <div id="div_06"></div>
    17     <div id="div_07"></div>
    18     <div id="div_08"></div>
    19     <div id="div_09"></div>
    20     <div id="div_10"></div>
    21     <div id="div_11"></div>
    22     <div id="div_12"></div>
    23     <div id="div_13"></div>
    24     <div id="div_14"></div>
    25     <div id="div_15"></div>
    26     <div id="div_16"></div>
    27     <div id="div_17"></div>
    28     <div id="div_18"></div>
    29     <div id="div_19"></div>
    30     <div id="div_20"></div>
    31     <div id="div_21"></div>
    32     <div id="div_22"></div>
    33     <div id="div_23"></div>
    34     <div id="div_24"></div>
    35     <div id="div_25"></div>
    36     <div id="div_26"></div>
    37     <div id="div_27"></div>
    38     <div id="div_28"></div>
    39     <div id="div_29"></div>
    40     <script type="text/javascript">
    41         var divs = document.getElementsByTagName("div");
    42         for(var i = 0, length = divs.length; i < length; i++){
    43             divs[i].addEventListener("click", function () {
    44                 console.log("clicked", this.id);
    45             });
    46             divs[i].addEventListener("dblclick", function () {
    47                 console.log("double clicked", this.id);
    48             });
    49         }
    50 
    51         setTimeout(function(){
    52             document.body.setAttribute("style", "padding-left:300px");
    53         }, 1000);
    54     </script>
    55 </body>
    56 </html>

    当页面中的蓝色方块开始移动后,在蓝色方块上双击鼠标,可以多试几次,得到下面的结果:

    可以看到,div_26、div_22两次双击事件分别是由div27、div26和div23、div22的两次单击触发的。

    从这两个结果来看,确实是符合我的猜想的。

    不过,这个demo也带来了一些疑惑:

    1、clicked div_19 这个log打印的时候,我非常确定我点击了两次鼠标,但是只打出了这一个log,为什么?

    2、double clicked div_15和double clicked div_11这两次双击事件触发前,都只触发了一次click事件,这又是为什么?

    以上所有代码测试结果都是基于 Chrome 33 和 IE 11 运行环境。

    希望有高人指导,也欢迎大家各抒己见。

    如需转载,请注明转自:http://www.cnblogs.com/silenttiger/p/3578397.html

    欢迎关注我的微信公众号:老虎的小窝
    微信公众号 老虎的小窝

  • 相关阅读:
    spring3创建RESTFul Web Service
    安装Maven
    如何使用 JSP JSTL 显示/制作树(tree) 菜单
    Eclipse EE导入maven工程
    安装PL/SQL Developer,链接本地64位Oracle
    Maven项目消除奇怪的红叉
    如何禁用Eclipse的Validating
    帮助文档总览
    MySQL下载安装、配置与使用(win7x64)
    C#知识点总结:Monitor和Lock以及区别
  • 原文地址:https://www.cnblogs.com/silenttiger/p/3578397.html
Copyright © 2011-2022 走看看