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

 <!DOCTYPE html>
<html>
<head>
<style type="text/css">
div{position: absolute;top: 0;left: 0;height: 50px}
#back{background-color: blue;left: 20px;width: 200px;z-index: 0}
#front{background-color: green;top:10px;width: 100px;z-index: 1}
</style>
</head>
<body>
<div id="back"></div>
<div id="front"></div>
<script type="text/javascript">
document.getElementById("back").addEventListener("click", function () {
console.log("back clicked");
})
document.getElementById("front").addEventListener("click", function () {
console.log("front clicked");
this.setAttribute("style", "z-index:0");
document.getElementById("back").setAttribute("style", "z-index:1");
})
document.getElementById("back").addEventListener("dblclick", function () {
console.log("back double clicked");
})
document.getElementById("front").addEventListener("dblclick", function () {
console.log("front double clicked");
})
</script>
</body>
</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

 <!DOCTYPE html>
<html>
<head>
<style type="text/css">
body{transition:padding-left 8s linear;padding-left: 0}
div{width: 10px;height: 200px;background-color: blue;display: inline-block;float: left;}
</style>
</head>
<body>
<div id="div_00"></div>
<div id="div_01"></div>
<div id="div_02"></div>
<div id="div_03"></div>
<div id="div_04"></div>
<div id="div_05"></div>
<div id="div_06"></div>
<div id="div_07"></div>
<div id="div_08"></div>
<div id="div_09"></div>
<div id="div_10"></div>
<div id="div_11"></div>
<div id="div_12"></div>
<div id="div_13"></div>
<div id="div_14"></div>
<div id="div_15"></div>
<div id="div_16"></div>
<div id="div_17"></div>
<div id="div_18"></div>
<div id="div_19"></div>
<div id="div_20"></div>
<div id="div_21"></div>
<div id="div_22"></div>
<div id="div_23"></div>
<div id="div_24"></div>
<div id="div_25"></div>
<div id="div_26"></div>
<div id="div_27"></div>
<div id="div_28"></div>
<div id="div_29"></div>
<script type="text/javascript">
var divs = document.getElementsByTagName("div");
for(var i = 0, length = divs.length; i < length; i++){
divs[i].addEventListener("click", function () {
console.log("clicked", this.id);
});
divs[i].addEventListener("dblclick", function () {
console.log("double clicked", this.id);
});
} setTimeout(function(){
document.body.setAttribute("style", "padding-left:300px");
}, 1000);
</script>
</body>
</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

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

html元素双击事件触发机制猜想及疑惑的更多相关文章

  1. 【深入浅出Linux网络编程】 “基础 -- 事件触发机制”

    回顾一下“"开篇 -- 知其然,知其所以然"”中的两段代码,第一段虽然只使用1个线程但却也只能处理一个socket,第二段虽然能处理成百上千个socket但却需要创建同等数量的线程 ...

  2. C#事件触发机制

    C#的事件触发机制,类似于c++的回调函数机制 我先简单说一下,委托和事件的实质,后期再重开一篇博文来详细说 委托:指向方法的指针,类似于C的函数指针 事件:是一个可以存放0个或多个方法指针的数据结构 ...

  3. EventEmitter:nodeJs事件触发机制

    Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.r ...

  4. [转载] 理解 epoll 的事件触发机制

    原文: http://weibo.com/p/1001603862394207076573?sudaref=weibo.com epoll的I/O事件触发方式有两种模式:ET(Edge Trigger ...

  5. WinForm中的事件触发机制学习

    在一个Form窗体中拖个按钮,双击后系统自动生成代码: private void button1_Click(object sender, EventArgs e) { } 同时在窗体的Initial ...

  6. 当页面加载完成时,JQ触发添加页面的元素的事件触发不了。。

    有下代码可知: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default. ...

  7. Yii中事件触发机制

    控制器初始化中添加事件处理方法,在需要触发的地方直接触发 public function init() { parent::init(); // TODO: Change the autogenera ...

  8. python 模拟事件触发机制

    EventManager.py # -*- encoding: UTF-8 -*- # 系统模块 from queue import Queue, Empty from threading impor ...

  9. JQuery的方便之处——宽高设置、坐标值和滚动条+事件绑定机制

    1.元素的宽高 可以通过css来进行设置,例如:$("元素").css({"宽度":"值","高度":"值&q ...

随机推荐

  1. Oracle EBS 查看双节点是否做了信任

    perl $AD_TOP/patch/115/bin/txkRunSSHSetup.pl verifyssh -contextfile=$CONTEXT_FILE -hosts=erpapp1,erp ...

  2. python基础知识回顾之列表

    在python 中,主要的常用数据类型有列表,元组,字典,集合,字符串.对于这些基础知识,应该要能够足够熟练掌握. 如何创建列表: # 创建一个空列表:定义一个变量,然后在等号右边放一个中括号,就创建 ...

  3. md5sum 和 sha256sum用于 验证软件完整性

    md5sum 和 sha256sum 都用来用来校验软件安装包的完整性,本次我们将讲解如何使用两个命令进行软件安装包的校验: sha 是什么?        sha 为 安全散列算法(英语:Secur ...

  4. 事务的ACID性质

    最近在读黄健宏的<Redis设计与实现>,现在看到了事务这章,由于之前(上学)没有好好整理过数据库事务的四大性质,导致现在(工作)看到了就和第一次知道一样((lll¬ω¬)).还是要把基础 ...

  5. tomcat 闪退处理

    参考文章:https://www.cnblogs.com/lanjianhappy/p/6491436.html 首先确保JDK环境变量已经配置好! 设置jdk环境 变量:https://jingya ...

  6. October 24th, 2017 Week 43rd Tuesday

    We can't give up trying. The fight was worth it. 我们不能放弃尝试,奋斗是值得的. When doing researches in some cutt ...

  7. Android Handler 内存泄漏,文末消息机制的小总结

    1. 内存泄漏的Activity public class MainActivity extends AppCompatActivity { private static final int MESS ...

  8. [python] 修改Tkinter 的默认图标

    先上一个不修改的样式,如下: import easygui as g g.msgbox("hello","hi") 注意左上角的图标为红色的Tk字样 修改后: ...

  9. 部署weblogic遇到的问题总结

    myeclipse开发的项目,运行在tomcat7上完全正常.部署到weblogic10上就出现了问题,现把问题记录一下: 1.找不到javax/servlet/jsp/jstl/core/Condi ...

  10. BZOJ3632:外太空旅行(最大团,DFS)

    Description 在人类的触角伸向银河系的边缘之际,普通人上太空旅行已经变得稀松平常了.某理科试验班有n个人,现在班主任要从中选出尽量多的人去参加一次太空旅行活动. 可是n名同学并不是和平相处的 ...