浅谈冒泡和捕获

了解冒泡和捕获之前,先要了解什么是事件和事件流

事件 :事件是可以被JS检测到的行为,当我们与页面交互时,事件就会产生

事件流 :触发事件会产生事件流,单个元素受到影响后会传播给其他元素,事件流描述的是页面中接受事件的顺序,分为冒泡捕获

冒泡

一个子元素触发事件后,事件会从该子元素起一层一层向上传播,从下往上

graph BT
div --> body --> html --> document

捕获

一个子元素触发事件后,事件会从最顶层父级一层一层向下传播,从下往上

graph TB
document --> html --> body --> div

三种事件监听函数下的事件流

1.直接在html中定义事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
#father{
margin: 20px auto;
width: 200px;
height: 200px;
background-color: blue;
}
#son{
width: 100px;
height: 100px;
background-color: red;
}
</style>

<div id="father" onclick="console.log('father')"> //点击#father而不点击#son 只会输出father
<div id="son" onclick="console.log('son')"> // 点击#son 依次输出son father,属于冒泡
</div>
</div>

结论:直接在html中定义事件只会冒泡

2.DOM0 级 事件

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
<style>
#father {
margin: 20px auto;
width: 200px;
height: 200px;
background-color: blue;
}
#son {
width: 100px;
height: 100px;
background-color: red;
}
</style>

<div id="father"> //点击#father而不点击#son 只会输出father
<div id="son"></div> // 点击#son 依次输出son father,属于冒泡
</div>

<script>

father.onclick = function () {
console.log("father");
};

son.onclick = function () {
console.log("son");
};

</script>

结论:dom0 只会冒泡

html行内绑定事件和dom0级别一样

3.DOM2级 事件

dom2 级格式为 el.addEventListener('click',fn,false) 其中 dom2 级第三个默认 false,改为 true 就变为事件捕获。

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
<style>
#father {
margin: 20px auto;
width: 200px;
height: 200px;
background-color: blue;
}
#son {
width: 100px;
height: 100px;
background-color: red;
}
</style>

<div id="father">
<div id="son"></div>
</div>

<script>
father.addEventListener(
"click",
() => {
console.log("father");
},
true
);

son.addEventListener(
"click",
() => {
console.log("son");
},
true
);

</script>
  • 都是 true 的时候,father 和 son 都是捕获,输出father son,点击father 只输出 father

  • 都是 false 的时候,father 和 son 都是冒泡,输出son father,点击father 只输出 father

  • father 事件监听函数参数为 true , son 事件监听函数参数为 false 时,father 为捕获,son 为冒泡,输出father son,点击father 只输出 father

  • father 事件监听函数参数为 false, son 事件监听函数参数为 true 时,son为捕获,father为冒泡,输出son father,点击father 只输出 father

总结:

事件流的模型是自上而下捕获,到达目标,然后再自下而上冒泡。就像小球从空中落地再弹起。
1.事件捕获阶段
2.处于目标阶段
3.事件冒泡阶段


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!