JavaScript事件机制,也有让人深思的东西。在一开始未深入了解,我头脑里有几个问题发出:

1. 自下而上(冒泡)事件怎么写,自上而下(捕获)又是怎么写?

2. 捕获型和冒泡型同时设置,谁生效?

3. 冒泡能够阻止,那捕获能够阻止吗?

4. jquery的on或bind是冒泡,还是捕获?

5. 两种事件方式的应用场景是?

示例

<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8"/>
<title>Events</title>
<script type="text/javascript" src="jquery-3.0.0.js"></script>
<style>
html,body{
width:100%;
height:100%;
padding: 0;
margin: 0;
}
div{
float:left;
width: 200px;
height:200px;
border:1px solid blue;
}
p{
width: 100px;
height:100px;
border:1px solid red;
}
</style>
</head>
<body id="body">
<div id="J_d0">
0<p id="J_p0"></p>
</div>
<div id="J_d1">
1<p id="J_p1"></p>
</div>
<div id="J_d2">
2<p id="J_p2"></p>
</div>
<div id="J_d3">
3<p id="J_p3"></p>
</div>
<div id="J_d4">
4<p id="J_p4"></p>
</div>
</body>
<script>
var body = document.getElementById('body');
body.addEventListener('click', hello, true); //当为false时,全部在最后执行。 bindEvent_d_p(0,true,true);
//点击p,输出
//i am body
//i am J_d0
//i am J_p0 bindEvent_d_p(1,false,true);
//点击p,输出
//i am body
//i am J_p1
//i am J_d1 bindEvent_d_p(2,false,false);
//点击p,输出
//i am body
//i am J_p2
//i am J_d2 bindEvent_d_p(3,true,false);
//点击p,输出
//i am body
//i am J_d3
//i am J_p3 $("#J_d4").on("click", hello);
$("#J_p4").on("click", hello);
//点击p,输出
//i am body
//i am J_p4
//i am J_d4 function bindEvent_d_p(index, d_useCapture, p_useCapture){
var d = document.getElementById('J_d'+index);
var p = document.getElementById('J_p'+index);

//第三个参数,指定事件是在捕获阶段还是冒泡阶段执行。
d.addEventListener('click', hello, d_useCapture);
p.addEventListener('click', hello, p_useCapture);
          }
function hello() {
console.log("i am " + this.id);
}
</script>
</html>

这里关键的是第三个参数。W3CSchool解释为“指定事件是否在捕获或冒泡阶段执行”,我觉得这个说明会让人误会,搞得像捕获或冒泡都可以不选的样子。但其实不是,只是二选一,所以最好解释为“指定事件是在捕获阶段还是冒泡阶段执行”。

定义

JavaScript的事件是以一种流(回环流)的形式存在的,一个事件会有多个元素同时响应。如下图:

PS:图例来自http://www.nowamagic.net/javascript/js_EventAnalysis.php

这个图非常清楚的说明的事件的执行顺序,完全可以解释示例中的结果。事件一直从window往触发目标元素流,当父或祖先捕获事件时,就先执行,不然就在冒泡阶段执行,直到window。

Q&A

1. 自下而上(冒泡)事件怎么写,自上而下(捕获)又是怎么写?

当需要冒泡时,第三参数设为false就行;

当需要捕获时,第三参数设为true就行;

2. 捕获型和冒泡型同时设置,谁生效?

按第三参数的设置,只有二选一,并不存在可以同时设置情况。

3. 冒泡能够阻止,那捕获能够阻止吗?

冒泡事件是能够阻止,e.stopPropagation();,大家是比较清楚的,同样的捕获事件也是能阻止的。

其实就是当先触发的事件是在捕获过程的,阻止了事件传播,就是捕获阻止,当在冒泡过程中阻止,就是冒泡阻止。

结果就是,事件流不再继续流了,无论是往下还是往上。

4. jquery的on或bind是冒泡,还是捕获?

经过上面示例可以验证, jquery的on或bind是冒泡执行的。

另外在jquery3.0.0的源码4943行地方:

// Init the event handler queue if we're the first
if ( !( handlers = events[ type ] ) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false
if ( !special.setup ||
special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle );
}
}
}

这里可以很明显看到,事件的注册并没有传第三个参数,所以 jquery的on或bind肯定是冒泡执行的。

5. 两种事件方式的应用场景是?

额,这个问题并不好回答,就具体问题,具体分析了。

总结

小小的往细处想,竟然发现我其实有些细节并没明白,共勉。

本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5705541.html

JavaScript事件机制——细思极恐的更多相关文章

  1. 细思极恐-你真的会写java吗?

    导语 自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗 ...

  2. 细思极恐-你真的会写java吗?

    文章核心 其实,本不想把标题写的那么恐怖,只是发现很多人干了几年java以后,都自认为是一个不错的java程序员了,可以拿着上万的工资都处宣扬自己了,写这篇文章的目的并不是嘲讽和我一样做java的同行 ...

  3. 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)

    前言 这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅, ...

  4. Javascript事件机制兼容性解决方案

    本文的解决方案可以用于Javascript native对象和宿主对象(dom元素),通过以下的方式来绑定和触发事件: 或者 var input = document.getElementsByTag ...

  5. 【探讨】javascript事件机制底层实现原理

    前言 又到了扯淡时间了,我最近在思考javascript事件机制底层的实现,但是暂时没有勇气去看chrome源码,所以今天我来猜测一把 我们今天来猜一猜,探讨探讨,javascript底层事件机制是如 ...

  6. 重温javascript事件机制

    以前用过一段时间的jquery感觉太方便,太强大了,各种动画效果,dom事件.创建节点.遍历.控件及UI库,应有尽有:开发文档也很多,网上讨论的问题更是甚多,种种迹象表明jquery是一个出色的jav ...

  7. [解惑]JavaScript事件机制

    群里童鞋问到关于事件传播的一个问题:“事件捕获的时候,阻止冒泡,事件到达目标之后,还会冒泡吗?”. 初学 JS 的童鞋经常会有诸多疑问,我在很多 QQ 群也混了好几年了,耳濡目染也也收获了不少,以后会 ...

  8. 总结JavaScript事件机制

    JavaScript事件模型 在各种浏览器中存在三种事件模型: 原始事件模型 , DOM2事件模型 , IE事件模型. 其中原始的事件模型被所有浏览器所支持,而DOM2中所定义的事件模型目前被除了IE ...

  9. javascript事件机制

    ① javascript绑定事件的方式 http://blog.iderzheng.com/dom-javascript-event-binding-comparison/ ② javascript事 ...

随机推荐

  1. Oracle Dataguard之switchover

    Oracle Dataguard的角色转换包含两类:Switchover和Failover.Switchover指主备之间角色转换,主库降为备库,备库升级为主库.而failover则是指主库出现问题时 ...

  2. 邻接矩阵有向图(一)之 C语言详解

    本章介绍邻接矩阵有向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...

  3. 微软官方提供的用于监控MS SQL Server运行状况的工具及SQL语句

    Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...

  4. adb shell 查看系统属性(用来判断特殊的操作系统)

    一般来讲,在android程序开发中进行需要判断设备类型和系统版本 1.设备类型判断(android.os.Build.MODEL) 比如判断属于Google Nexus 5,Nexus 7,MIUI ...

  5. ASP.NET MVC+EF在服务端分页使用jqGrid以及jquery Datatables的注意事项

    引言: 本人想自己个博客网站出来,技术路线是用ASN.NET MVC5+EF6(Code First)+ZUI+各种Jquery插件,有了这个想法之后就开始选择UI,看了好多bootstrap的模板之 ...

  6. Node.js系列基础学习-----回调函数,异步

    Node.js基础学习 Node.js回调函数 Node.js异步编程的直接体现就是回调,异步编程依托回调来实现,但不是异步.回调函数在完成任务后就会被调用,Node有很多的回调函数,其所有的API都 ...

  7. 自己封装的JS分页功能[用于搭配后台使用]

    * 2016.7.03 修复bug,优化代码逻辑 * 2016.5.25 修复如果找不到目标对象的错误抛出. * 2016.5.11 修复当实际页数(pageNumber)小于生成的页码间隔数时的bu ...

  8. ASP.NET Core Web API 开发-RESTful API实现

    ASP.NET Core Web API 开发-RESTful API实现 REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representa ...

  9. visual C++ 项目和解决方案的区别

    项目:         项目是构成某个程序的全部组件的容器,该程序可能是控制台程序.基于窗口的程序或某种别的程序.程序通常由一个或多个包含用户代码的源文件,可能还要加上包含其它辅助数据的文件组成.某个 ...

  10. mvc 修改 删除 linq

    Models文件夹里面可以Linq,Entity两种映射框架,也允许有ADO的操作,甚至可以ADO代码和映射代码一起操作 控制器当中允许有相同的方法名,类似在做修改时有两个Modify方法,但是MVC ...