在 addEventListener 中启用捕获阶段需将第三个参数设为 true 或配置对象中 capture: true;事件自外向内传播,支持在到达目标前拦截,配合 stopPropagation() 可阻断后续流程。

在 addEventListener 中开启捕获阶段,只需将第三个参数设为 true 或传入一个配置对象并设置 capture: true。这样事件会从外层元素向目标元素传播(捕获阶段),让你有机会在事件到达目标前就拦截处理。
使用布尔值开启捕获
最简单的方式是把第三个参数设为 true:
element.addEventListener('click', handler, true);
这时 handler 会在捕获阶段触发,而不是默认的冒泡阶段。
使用 options 对象更灵活地控制
推荐用对象形式,语义更清晰,还能同时配置其他选项:
-
capture: true—— 启用捕获 -
once: true—— 只执行一次(可选) -
passive: true—— 告诉浏览器不调用preventDefault(常用于滚动优化)
示例:
element.addEventListener('click', handler, {
capture: true,
once: false,
passive: false
});
捕获阶段的实际拦截效果
假设 DOM 结构是:<div id="outer"><div id="inner">点我</div></div>,你在 outer 上用捕获监听 click:
document.getElementById('outer').addEventListener('click', e => {
console.log('outer 捕获');
e.stopPropagation(); // 阻止继续传播,inner 的监听器就不会触发了
}, true);
document.getElementById('inner').addEventListener('click', e => {
console.log('inner 冒泡'); // 这行不会执行
});
点击 inner 时,先触发 outer 的捕获回调,并可通过 stopPropagation() 切断后续流程。
注意捕获与冒泡共存时的顺序
同一个元素上同时注册捕获和冒泡监听器,捕获版总是先于冒泡版执行(即使添加顺序相反):
- 所有祖先元素的捕获监听器(由外向内)
- 目标元素自身的捕获监听器(如果设置了
capture: true) - 目标元素自身的冒泡监听器(即使先添加,也后执行)
- 祖先元素的冒泡监听器(由内向外)
所以“优先拦截”的关键就是:在父级元素上用捕获 + stopPropagation() 或 preventDefault()。

















