事件冒泡和事件捕捉

113 阅读1分钟

1. 事件流概述

当你在网页上的一个元素上触发一个事件(比如点击按钮),这个事件不会仅仅停留在这个元素上,而是会在整个DOM树中传播。这种传播有两个方向:从上到下(事件捕捉)和从下到上(事件冒泡)。

2. 事件捕捉(从外到内)

<div id="outer">
  <div id="middle">
    <button id="inner">Click Me</button>
  </div>
</div>

当你点击按钮时,事件首先会从 document 开始,逐层往下传播到 div#outerdiv#middle,最后到达 button#inner。这个从外向内的过程就是事件捕捉

3. 目标阶段

当事件传播到目标元素(即你点击的按钮 button#inner)时,事件进入目标阶段。在这个阶段,事件会被目标元素处理。

4. 事件冒泡(从内到外) 在目标阶段之后,事件开始从目标元素向外传播,依次经过 div#middlediv#outer,最后回到 document。这个从内向外的过程就是事件冒泡

假设你在 div#outerdiv#middlebutton#inner 上都绑定了点击事件处理程序,事件处理的顺序会根据你使用的是事件捕捉还是事件冒泡而不同。

  • 事件捕捉(从外到内):如果你选择捕捉阶段处理事件,那么事件处理顺序是 div#outer -> div#middle -> button#inner
  • 事件冒泡(从内到外):如果你选择冒泡阶段处理事件,那么事件处理顺序是 button#inner -> div#middle -> div#outer

如何控制事件处理阶段

addEventListener 的第三个参数用来指定是使用事件捕捉还是事件冒泡:

document.getElementById('outer').addEventListener('click', () => {
  console.log('Outer div');
}, true);  // true表示使用事件捕捉阶段

document.getElementById('inner').addEventListener('click', () => {
  console.log('Inner button');
}, false); // false表示使用事件冒泡阶段,默认值