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. Windows Azure Cloud Service (1) 用户手册

    <Windows Azure Platform 系列文章目录> 下载地址 Cloud Service用户手册

  2. java设计模式(五)--建造者模式(Builder)

    转载:http://zz563143188.iteye.com/blog/1847029 工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象 ...

  3. finetuning caffe

    还没解决,以下是解释fine-tune 比如说,先设计出一个CNN结构.然后用一个大的数据集A,训练该CNN网络,得到网络a.可是在数据集B上,a网络预测效果并不理想(可能的原因是数据集A和B存在一些 ...

  4. 【Swift学习】Swift编程之旅---函数(十)

    函数是一组用于执行特定任务的独立的代码段,你用一个名字来标识函数,这个名字是用来“调用”函数来执行它的任务. swift统一函数的语法具有足够的灵活性来表达任何一个简单的不带参数的名称与本地和外部的每 ...

  5. Linux 小工具学习之(1)——Wget十例[翻译]

    在本博文中我们将学习一下wget这个工具.wget可以使用HTTP.HTTPS.和FTP等常见网络协议来从万维网(WWW)获取文件(从它的名字来源也可以看出 World Wide Web Get -& ...

  6. Wo的书单

    一个人,一生之中总要有几本证明自己的书. 2016---08 <ASP.NET MVC5 高级编程(第五版)> <数据结构(C语言第二版)>

  7. javascript设计模式之单体模式

    一入前端深似海,刚入前端,以为前端只是div+css布局外加jquery操作DOM树辣么简单.伴随着对前端学习的深入,发现前端也是博大精深,而且懂得越多,才发现自己越无知,所以一定不能停下脚步的学习. ...

  8. PHPcms 系统简单使用

    1.站点/发布点的新建 1.1 发布点的新建: 发布点是设置站点与服务器之间的链接配置. 设置 - 发布点管理 - 添加发布点 发布点名:可以与接下来的站点名称相同 ftp服务器:用于设置PHPcms ...

  9. STM32L系列单片机内部EEPROM的读写

    STM32L系列单片机内部提供了EEPROM存储区域,但实质上,其FLASH也是EEPROM类型,只不过有一块区域被开放出来专门用作EEPROM操作而已.STM32L的EEPROM使用寿命设计为100 ...

  10. Emit学习(2) - IL - 常用指令介绍

    学习Emit必不可少的, 会使用到IL中间代码. 初见IL代码, 让我有一种汇编的感觉, 让我想起了, 大学时, 学习8051的汇编语言. 多的就不扯了, 直接进入正题, OpCodes指令集是不是有 ...