您现在的位置:首页 >> 前端 >> 内容

html元素双击事件触发机制猜想及疑惑

时间:2014/3/4 8:16:33 点击:

  核心提示:1 !DOCTYPE html2 html3 head4 style type=text/css5 p{position: absolute;top: 0;left: 0;height: 50px}6...
1 <!DOCTYPE html>

 2 <html>

 3 <head>

 4     <style type="text/css">

 5         p{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     <p id="back"></p>

12     <p id="front"></p>

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         p{width: 10px;height: 200px;background-color: blue;display: inline-block;float: left;}

 7     </style>

 8 </head>

 9 <body>

10     <p id="p_00"></p>

11     <p id="p_01"></p>

12     <p id="p_02"></p>

13     <p id="p_03"></p>

14     <p id="p_04"></p>

15     <p id="p_05"></p>

16     <p id="p_06"></p>

17     <p id="p_07"></p>

18     <p id="p_08"></p>

19     <p id="p_09"></p>

20     <p id="p_10"></p>

21     <p id="p_11"></p>

22     <p id="p_12"></p>

23     <p id="p_13"></p>

24     <p id="p_14"></p>

25     <p id="p_15"></p>

26     <p id="p_16"></p>

27     <p id="p_17"></p>

28     <p id="p_18"></p>

29     <p id="p_19"></p>

30     <p id="p_20"></p>

31     <p id="p_21"></p>

32     <p id="p_22"></p>

33     <p id="p_23"></p>

34     <p id="p_24"></p>

35     <p id="p_25"></p>

36     <p id="p_26"></p>

37     <p id="p_27"></p>

38     <p id="p_28"></p>

39     <p id="p_29"></p>

40     <script type="text/javascript">

41         var ps = document.getElementsByTagName("p");

42         for(var i = 0, length = ps.length; i < length; i++){

43             ps[i].addEventListener("click", function () {

44                 console.log("clicked", this.id);

45             });

46             ps[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>

复制代码

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

 

 

 

可以看到,p_26、p_22两次双击事件分别是由p27、p26和p23、p22的两次单击触发的。

 

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

 

 

 

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

 

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

 

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

 

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

Tags:HT TM ML L元 
作者:网络 来源:不详
  • 上一篇:CSS BOX 回顾
  • 下一篇:CSS常用代码