一、什么是事件流

当用户与网页交互时(如点击按钮),事件并不是只在触发元素上发生,而是会经历一个完整的传播过程,这个过程称为事件流

二、事件流的三个阶段

(1)捕获阶段:从最外层的 window 对象向内传播到目标元素

(2)目标阶段:事件到达目标元素本身

(3)冒泡阶段:从目标元素向外传播回 window 对象

三、事件捕获(Event Capturing)

事件捕获是从外向内的传播过程,现代浏览器支持通过 addEventListener 的第三个参数来监听捕获阶段的事件。

document.getElementById('outer').addEventListener(
  'click',
  () => console.log('Outer - Capture'),
  true // true 表示在捕获阶段触发
);

四、事件冒泡(Event Bubbling)

事件冒泡是从内向外的传播过程,这是默认的事件传播方式。

document.getElementById('inner').addEventListener(
  'click',
  () => console.log('Inner - Bubble')
  // 第三个参数默认是 false,表示在冒泡阶段触发
);

五、完整示例

<div id="outer">
  <div id="middle">
    <div id="inner">Click me</div>
  </div>
</div>

<script>
// 捕获阶段
document.getElementById('outer').addEventListener('click', () => 
  console.log('Outer - Capture'), true);
document.getElementById('middle').addEventListener('click', () => 
  console.log('Middle - Capture'), true);
document.getElementById('inner').addEventListener('click', () => 
  console.log('Inner - Capture'), true);

// 冒泡阶段
document.getElementById('outer').addEventListener('click', () => 
  console.log('Outer - Bubble'));
document.getElementById('middle').addEventListener('click', () => 
  console.log('Middle - Bubble'));
document.getElementById('inner').addEventListener('click', () => 
  console.log('Inner - Bubble'));
</script>

点击 inner 元素时的输出顺序:Outer - Capture

Middle - Capture
Inner - Capture
Inner - Bubble
Middle - Bubble
Outer - Bubble

六、阻止事件传播

使用 event.stopPropagation() 可以阻止事件继续传播:

document.getElementById('middle').addEventListener('click', (e) => {
  console.log('Middle - Bubble');
  e.stopPropagation(); // 阻止事件继续冒泡
});

七、实际应用场景

(1)事件委托:利用冒泡特性,将事件监听器添加到父元素而非每个子元素

(2)事件节流与防抖:在捕获或冒泡阶段处理高频触发事件

(3)组件封装:在框架中利用事件流实现父子组件通信

八、注意事项

(1)IE8 及以下只支持事件冒泡

(2)某些事件(如 focus、blur)不支持冒泡

(3)使用 event.target 获取实际触发事件的元素

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐