1. 什么是JS事件流

  早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素;而Netscape公司的Netscape Navigator则是朝相反的方向传播,

也就是从目标元素开始向上逐级传播最终至window。

  后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是上述二者的结合。当事件发生时,最先得到通知的是window,然后是document,由上至下逐级依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。接下来,事件会从目标元素开始起泡,由下至上逐级依次传播,直到window对象为止,这个过程就是冒泡。

  如果我们有下面的HTML代码结构

 <div class="box" id="box2">
<div class="box" id="box3">
<div class="box" id="box4">
<div class="box" id="box5">
<div class="box" id="box6">
<h3>点我开始!!</h3>
</div>
</div>
</div>
</div>
</div>

  那么当我们点击box6中的HE以后,事件的触发过程也就是这样的:

  

    

    2.DEMO实例

    我在Gitbub上放了一个DEMO用于演示JS事件的传播原理,大家感兴趣的话可以前往查看。

    http://xiaoyunchen.github.io/JavaScriptEvent/

    打开页面后点击中央的"点我开始",也就是从最里层触发click事件,然后页面将演示事件是如何进行捕获和冒泡两个阶段的传播的。

    

    同样在浏览器控制中也可以清楚的看出了JS事件的传播过程:

    

    哦对了,代码源码放在了 https://github.com/xiaoyunchen/JavaScriptEvent 感兴趣的同学可以自行前往查看。

    

    3.有何用处

    了解了JS事件流的传播原理,那么对我们的实际开发过程中有什么作用呢?

    首先来看DOM2添加事件的方法申明:

element.addEventListener(event, function, useCapture);
/*
第一个参数是事件的类型 (如 "click" 或 "mousedown").
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
*/

  也就是说我们可以控制是在冒泡还是捕获阶段去处理事件,但是由于考虑浏览器兼容性的问题,这里一般我们都只是用false即冒泡阶段。

  另外,根据事件的冒泡原理,我们还可以实现另外一个很重要的功能:事件委托

  比如我们上面的代码中,有很多元素都需要添加事件,按照之前的做法,我们需要去依次获取每个元素,然后再为每个事件添加上监听事件,

  但是这样会带来一些问题:

  1.多次操作DOM获取元素,势必会降低浏览器处理性能

  2.事件不具有继承性,如果我们动态在页面中添加了一个元素,那么还需要重新走一遍上述程序为其添加监听事件

  好在我们通过JS事件的冒泡原理来解决上述问题:我们只监听最外层的元素,然后在事件函数中根据事件来源进行不同的事件处理。

  这样的话,我们添加事件监听时只需要操作一个元素,极大的降低了DOM访问,同时也方便的监听事件的移除。而且就算动态在页面添加一个元素时,也不用

  重复为其添加监听事件,因为它的事件会自动冒泡到外层被我们给截获。(这也是jquery中时间绑定的实现原理。)

  

  4.事件委托DEMO

  同样的,我创建了一个简单的DEMO用于样式事件委托: http://xiaoyunchen.github.io/JavaScriptEvent/delegate.html

   在这个页面中,我们创建了两个列表,然后在两个列表的父级添加了一个事件委托,拦截了列表元素的所有click事件。

  当我们点击两个列表的任何列表元素时,事件都能得到正确的响应,在控制台打印出对应的元素ID值,

  当然哪怕是我们后台动态添加的li元素,不用再为其单独绑定事件,也可以得到正确的响应,这就是JS事件委托的作用。

  

  (注意,并不是所有事件都支持事件委托,比如mouseover,mouseout等就不支持事件委托。)

  测试DEMO的源码同样放在了 https://github.com/xiaoyunchen/JavaScriptEvent 感兴趣的同学可以自行前往查看。

  小结:

    JavaScript中的事件流分为捕获阶段、目标阶段、冒泡阶段,我们可以JS控制需要操作捕获还是冒泡阶段的事件。

    根据事件流的原理,我们可以优化事件处理方法,比如进行事件委托。

JavaScript事件流的更多相关文章

  1. JavaScript事件流原理解析

    一.为什么会有这一篇的文章 国庆前几天由于任务比较重,要赶在国庆前把一个进度的任务开发完成,所以也就有点赶,但是却遇到了一个比较奇怪的Bug,导致了任务比预计的延迟了几个小时,对此深表遗憾,所以利用国 ...

  2. 浅析JavaScript事件流——冒泡

    一.什么是事件冒泡流 我们知道事件流指的是从页面中接受事件的顺序. 为了形象理解事件冒泡,可以想象三军主将诸葛亮,在帐内运筹帷幄,眼观六路耳听八方,这时候前方的战事情况就需要靠传令兵来传达,当第一位传 ...

  3. 【原】javascript事件流

    摘要:事件流这个东西是比较重要的,为了让自己更加理解js中的事件流,必须整理整理,梳理一下事件流的各种东西啊.本文大部分内容参考<javascript高级程序设计第三版> 先来一段书里的原 ...

  4. 深入理解javascript事件流

    摘要:事件流这个东西是比较重要的,为了让自己更加理解js中的事件流,必须整理整理,梳理一下事件流的各种东西啊.本文大部分内容参考<javascript高级程序设计第三版> 先来一段书里的原 ...

  5. 深入了解javascript事件流

    摘要:事件流这个东西是比较重要的,为了让自己更加理解js中的事件流,必须整理整理,梳理一下事件流的各种东西啊.本文大部分内容参考<javascript高级程序设计第三版> 先来一段书里的原 ...

  6. javaScript事件流是什么?

    一.事件 事件是文档或者浏览器窗口中发生的,特定的交互瞬间. 事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字. 事件是javaScript和DOM之间交 ...

  7. JavaScript事件流--事件冒泡、目标与事件捕获

    1.事件冒泡 微软提出了名为事件冒泡的事件流.事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面.也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象. 因 ...

  8. JavaScript - 事件流

    事件流 事件冒泡就是事件沿DOM树向上传播,在没一级节点上都会发生,直至传播到document对象. 事件捕获正好相反,但是老版本的浏览器不支持,因此很少有人使用事件捕获. 事件处理程序 HTMl 事 ...

  9. javascript 事件流及应用

    当页面元素触发事件的时候,该元素的容器以及整个页面都会按照特定顺序发生该元素的触发 事件,事件传播的顺序叫做事件流 1.事件流的分类: A.冒泡型事件(所有浏览器都支持)   由明确的事件源到最不确定 ...

随机推荐

  1. 异常:The absolute uri: http://www.springframework.org/security/tags cannot be resolved in either web.xml or the jar files deployed with this application

    The absolute uri: http://www.springframework.org/security/tags cannot be resolved in either web.xml ...

  2. poj1094 拓扑 Sorting It All Out

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29744   Accepted: 10 ...

  3. Linux系统管理员面试50题

    命令nslookup是做什么的? Nslookup 是一个 监测网络中 DNS 服务器是否能正确实现域名解析的命令行工具. 你如何把CPU占用率最高的进程显示出来? top -c 按照cpu排序 如果 ...

  4. php开发网站编码统一问题

    一个良好的网站代码整洁,注释适当是最基本的,也是好的习惯,这可以避免以后的非常乱了自己感觉都乱,一旦重构麻烦就大了耗时耗力,其中网站整个体系的编码是最重要的一个方面,为了网站的稳定性建议php程序,H ...

  5. Java for LeetCode 165 Compare Version Numbers

    Compare two version numbers version1 and version2.If version1 > version2 return 1, if version1 &l ...

  6. 中石油—2的幂次方(power)

    问题 E: 2的幂次方(power) 时间限制: 1 Sec  内存限制: 64 MB提交: 38  解决: 19[提交][状态][讨论版] 题目描述 任何一个正整数都可以用2的幂次方表示.例如:13 ...

  7. Jpush推送模块

      此文章已于 14:17:10 2015/3/24 重新发布到 鲸歌 Jpush推送模块     或以上版本的手机系统. SDK集成步骤 .导入 SDK 开发包到你自己的应用程序项目 •    解压 ...

  8. Android与后台数据交互学习

    摘要 任何系统在没有用户登录就可操作数据是非常危险的,链接客户端与服务器的是用户登录后的session,用户登录系 统后存在一个sessionid,这个sessionid就是客户端的cookie,客户 ...

  9. Unix系统编程_cha11.6_线程同步

    #include <stdio.h>#include <pthread.h>#include <stdlib.h> #define NHASH 29#define ...

  10. mac安装nginx

    1,http://nginx.org/en/download.html下载http://nginx.org/download/nginx-1.2.0.tar.gz 2,tar -xf nginx-1. ...