事件
事件是某事发生的信号。所有的 DOM 节点都生成这样的信号(但事件不仅限于 DOM)。比如:当鼠标点击一个元素时,会触发 click 事件。以下代码就是在用户点击按钮后弹出「Click!」消息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<button id="button">Click Me</button>
<script>
button.onclick = () => {
alert("Click!");
};
</script>
</body>
</html>
|
捕获与冒泡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div onclick="alert('The handler!')">
<em
>If you click on <code>EM</code>, the handler on
<code>DIV</code> runs.</em
>
</div>
</body>
</html>
|
运行上面的代码,你会发现点击「EM」时仍然能触发对话框,这是因为点击 <em>
时会触发 <div>
上的事件。从内到外运行事件程序叫做「冒泡」(bubbling)。以下是冒泡的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
</body>
</html>
|
事件处理的另一个阶段叫「捕获」(capturing),它是从外到内执行事件处理程序,和冒泡相反。
DOM 事件标准规定了事件传播的顺序:
- 捕获阶段(Capturing phase)—— 事件(从 Window)向下走近元素。
- 目标阶段(Target phase)—— 事件到达目标元素。
- 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡。
同一事件,先捕获还是先冒泡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<button id="button">button</button>
</body>
<script>
button.addEventListener("click", () => console.log("bubbling"));
button.addEventListener("click", () => console.log("capturing"), true);
</script>
</html>
|
以上代码在 Firefox 允许会按代码顺序打印,先打印「bubbling」,再打印「capturing」。在 Chrome>89 则按先捕获的顺序,也就是先打印「capturing」,再打印「bubbling」。
参考资料
https://zh.javascript.info/bubbling-and-capturing
文章作者
叶寻 | Cyrus Yip
上次更新
2021-11-01
(8fa0f61)