理解DOM事件流的三个阶段
本文主要解决两个问题:
1.什么是事件流
2.DOM事件流的三个阶段
事件流之事件冒泡与事件捕获
在浏览器发展的过程中,开发团队遇到了一个问题。那就是页面中的哪一部分拥有特定的事件?
可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上所有的圆。放到实际页面中就是,你点击一个按钮,事实上你还同时点击了按钮所
有的父元素。
开发团队的问题就在于,当点击按钮时,是按钮最外层的父元素先收到事件并执行,还是具体元素先收到事件并执行?所以这儿引入了事件流的概念。
事件冒泡
事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。
举个栗子,就很容易明白了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Bubbling</title>
</head>
<body>
<button id="clickMe">Click Me</button>
</body>
</html>
然后,我们给button和它的父元素,加入点击事件。
<script type="text/javascript">
var button = document.getElementById('clickMe');
button.onclick = function() {
console.log('1. You click Button');
};
document.body.onclick = function() {
console.log('2. You click body');
};
document.onclick = function() {
console.log('3. You click document');
};
window.onclick = function() {
console.log('4. You click window');
};
</script>
效果如图:

在代码所示的页面中,如果点击了button,那么这个点击事件会按如下的顺序传播(Chrome浏览器):
- button
- body
- document
- window
也就是说,click事件首先在<button>元素上发生,然后逐级向上传播。这就是事件冒泡。
事件捕获
事件捕获的概念,与事件冒泡正好相反。它认为当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。比如说刚才的demo,如果是事件捕获的话,事件发生顺序会是这样的:
- window
- document
- body
- button

当然,由于时代更迭,事件冒泡方式更胜一筹。所以放心的使用事件冒泡,有特殊需要再使用事件捕获即可。
DOM事件流
DOM事件流包括三个阶段。
1.事件捕获阶段
2.处于目标阶段
3.事件冒泡阶段
如图所示(图片源于网络,若侵权请告知):
1. 事件捕获阶段
也就是说,当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
例如,我把上面的Demo中,window点击事件更改为使用事件捕获模式。(addEventListener最后一个参数,为true则代表使用事件捕获模式,false则表示使用事件冒泡模式。不理解的可以去学习一下addEventListener函数的使用)
window.addEventListener("click",function(){
console.log('4. You click window');
},true)
此时,点击button的效果是这样的。
可以看到,点击事件先被父元素截获了,且该函数只在事件捕获阶段起作用。
2.处于目标与事件冒泡阶段
事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。
随后,冒泡阶段发生,事件开始冒泡。
3.阻止事件冒泡
事件冒泡过程,是可以被阻止的。防止事件冒泡而带来不必要的错误和困扰。
这个方法就是:stopPropagation()
stopPropagation() 方法
终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。
我们对button的click事件做一些改造。
<script type="text/javascript">
var button = document.getElementById('clickMe');
button.addEventListener('click', function(event) {
console.log('1. You click Button');
event.stopPropagation();
console.log('Stop Propagation!');
}, false);
document.body.onclick = function() {
console.log('2. You click body');
};
document.onclick = function() {
console.log('3. You click document');
};
window.addEventListener("click",function(){
console.log('4. You click window');
},true)
</script>

不难看出,事件在到达具体元素后,停止了冒泡。但不影响父元素的事件捕获。
总结与感想
事件流:描述的就是从页面中接受事件的顺序。分有事件冒泡与事件捕获两种。
DOM事件流的三个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
原文链接: 寒假前端学习(10)——理解DOM事件流的三个阶段
理解DOM事件流的三个阶段的更多相关文章
- DOM事件流的三个阶段
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流. DOM事件流分为三个阶段,分别为: 捕获阶段:事件从Document节点自上而下向目标节点传播的阶段: 目标阶段:真正的目标 ...
- 从click事件理解DOM事件流
事件流是用来解释页面上的不同元素接受一个事件的顺序,首先要明确两点: 1.一个事件的影响元素可能不止一个(同心圆理论),但目标元素只有一个. 2.如果这些元素都绑定了相同名称的事件函数,我们怎么知道这 ...
- 漫谈DOM 事件流的三个阶段
一丶 流 什么是流? 比如 react 中的单项数据流,Node.js 中的流,或者本文中的 DOM 事件流,都是流的具体体现.专业地讲,流是程序输入或输出的一个连续的字节序列:通俗地讲,流是有方向的 ...
- 关于DOM事件流、DOM0级事件与DOM2级事件
一.DOM 事件模型 DOM 事件模型包括捕获和冒泡,捕获是从上往下到达目标元素,冒泡是从当前元素,也就是目标元素往上到 window 二.流 流的概念,在现今的 JavaScript 中随处可见.比 ...
- 深入理解DOM事件机制系列第一篇——事件流
× 目录 [1]历史 [2]事件冒泡 [3]事件捕获[4]事件流 前面的话 javascript操作CSS称为脚本化CSS,而javascript与HTML的交互是通过事件实现的.事件就是文档或浏览器 ...
- 深入理解javascript事件流
摘要:事件流这个东西是比较重要的,为了让自己更加理解js中的事件流,必须整理整理,梳理一下事件流的各种东西啊.本文大部分内容参考<javascript高级程序设计第三版> 先来一段书里的原 ...
- 【前端盲点】DOM事件流论证CSS盒模型是否具有厚度
前言 很久没有扯淡了,我们今天来扯淡吧. 我今天思考了一个问题,我们页面的dom树到底是如何渲染的,而CSS盒模型与javascript是否有联系,于是便想到一个问题: CSS的盒模型具有厚度么??? ...
- js事件捕获,事件冒泡,事件委托以及DOM事件流
一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body ...
- DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件
前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...
随机推荐
- WP8解析JSON格式(使用DataContractJsonSerializer类)(推荐)
DataContractJsonSerializer是.NET自带的类,在解析JSON格式的时候使用起来方便快捷,至于生成方面由于暂时没用到就没去看了.使用需要引用System.Runtime.Ser ...
- JAVA多线程售票问题
//定义一个类实现Runnable接口,定义一个需要同步的售票方法,然后重写run方法调用售票的sale方法 class SaleTicket implements Runnable{ private ...
- java 的各种实用类库(jar包)
总列表:# dom4j # org.json # pinyin4j # sqlite-jdbc # JavaMail # JLayer # dom4j 介绍:处理 xml 的类库.采用了 Java 集 ...
- HTML 上传图片实用小技巧
最近写的项目需要用的上传图片的功能但是浏览器自带的按钮样式实在是不忍直视,肯定要进行修改,网上也有很多方法(自己查....),我这里用了个取巧的方法:就是函数的间接调用 在点击btn的时候让它执行了图 ...
- Java 集合类的特性
ArrayList: 元素单个,效率高,多用于查询 Vector: 元素单个,线程安全,多用于查询 LinkedList: 元素单个,多用于插入和删除 HashMap: 元素成对,元素可为空 H ...
- 快速安装Percona pt工具
yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-Time-HiRes perl-IO-Socket-SSLwget http://pk ...
- Daily Scrum02 12.11
今天的会议的主要内容基本是解决界面组的问题,原本开始进行人员分配的时候没有考虑到要花特别长的时间为美化界面整理素材,且由于进行素材PS的同学的时间安排问题,和不熟练,很久没有将素材准备这项任务完成.因 ...
- 带额外toggle()功能的jquery库
<html><head><meta http-equiv="Content-Type" content="text/html;charset ...
- PHPCMS与UCenter整合要点
要点一: PHPCMS不能直接与UCenter整合,而是要经过 PHPSSO 适配,因此应用主URL应是 http://phpcms_url/phpsso_server 这种模式的. 要点二: 因为 ...
- .NET短距离领域通信-32feet.NET
32feet.NET[http://32feet.codeplex.com/]是shared-source的项目,支持CF.net 2.0以及桌面版本.NET framework,提供短距离领域(pe ...