js:深入理解事件流

前言

最近在学习一些js知识,遇到DOM事件流这个概念以及一些相关知识点,写个笔记做个记录也为加深自己的印象。

事件流

定义:

  1. 事件流 描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。
  2. 事件 就是用户或浏览器自身执行的某种动作。诸如click(点击)、load(加载)、mouseover(鼠标悬停)。
  3. 事件处理程序 响应某个事件的函数就叫事件处理程序(或事件侦听器)。

事件处理程序有两个方法:addEventListener()removeEventListener()分别用于处理监听某个指定事件和删除事件。所有DOM节点中都包含这两个方法,并且它们都接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。当这个布尔值为true时,表示在捕获阶段调用事件处理程序;若果是false,表示在冒泡阶段调用事件处理程序。

事件作用范围

元素自己所占页面空间部分加嵌套元素所占空间范围(若嵌套元素覆盖在容器元素上,则事件的作用范围为容器元素自身所占空间大小)

事件的执行顺序

事件执行有两种分别为事件冒泡和事件捕获,事件冒泡 为从最内层的div逐步到最外层div。即事件开始时由最具体的元素(文档中嵌套层次最深的节点)接收,然后逐级向上传播到较为不具体的节点。
而事件捕获则完全相反,事件捕获为从最外层的div逐步到最内层div。事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。

结论:

  1. 当容器元素及其嵌套元素都在冒泡阶段调用事件处理程序时:事件按事件冒泡的顺序执行事件处理程序。
  2. 当容器元素及其嵌套元素都在捕获阶段调用事件处理程序时:事件按事件捕获的顺序执行事件处理程序。
  3. 当容器元素及嵌套元素,即在捕获阶段又在冒泡阶段调用事件处理程序时:事件按DOM事件流的顺序执行事件处理程序,且当事件处于目标阶段时,事件调用顺序决定于绑定事件的书写顺序,按上面的例子为,先调用冒泡阶段的事件处理程序,再调用捕获阶段的事件处理程序。
    具体执行代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<html>
<head>
<style>
#wrap {
width: 200px;
height: 200px;
background: orange;
}
#outer {
position: relative;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background: #eeddff;
}
#inner {
position: relative;
top: 25px;
left:25px;
width: 50px;
height: 50px;
background: #44ddff;
}
</style>
</head>
<body>
<div id="wrap">
<div id="outer">
<div id="inner"></div>
</div>
</div>
</body>
<script>
var wrap = document.getElementById('wrap');
var outet = document.getElementById('outer');
var inner = document.getElementById('inner');

wrap.addEventListener('click',function(){
alert('789');
},false);
outer.addEventListener('click',function(){
alert('456');
},false);
inner.addEventListener('click',function(){
alert('123');
},false);
wrap.addEventListener('click',function(){
alert('wrap');
},true);
outer.addEventListener('click',function(){
alert('outer');
},true);
inner.addEventListener('click',function(){
alert('inner');
},true);
</script>
</html>

当点击页面中心浅蓝色部分的时候,先从最不具体的节点捕获事件,先弹出wrap,接着弹出outer。接着处于目标阶段,先弹出123,再弹出inner。紧接着,事件处于冒泡阶段,先弹出456,再弹出789。
当点击橙色部分时候,即从捕获阶段进入到了目标阶段,则按事件顺序执行,先弹出789,接着弹出wrap,整个事件捕获冒泡完毕。

参考博客:https://segmentfault.com/a/1190000003497939