JavaScript事件流分捕获、目标、冒泡三阶段;addEventListener第三参数useCapture控制监听阶段(true为捕获,false或省略为冒泡);stopPropagation()仅阻止冒泡,stopImmediatePropagation()彻底中断事件流。

JavaScript 的事件冒泡与捕获是事件流的两个核心阶段,处理它们的关键在于理解传播方向、触发时机,并合理使用 addEventListener 的第三个参数和事件对象方法。
明确事件流的三个阶段
一个完整的点击等事件会依次经历:
-
捕获阶段:从
window→document→ 祖先元素 → 目标元素父级(不包括目标自身) - 目标阶段:事件到达绑定该事件的元素本身(此时捕获与冒泡监听器都可触发,但捕获监听器优先)
-
冒泡阶段:从目标元素 → 父元素 → 祖先元素 →
document→window
注意:目标阶段不是独立于捕获/冒泡之外的“第三种监听方式”,而是两者交汇点——在目标元素上同时设置捕获和冒泡监听器时,捕获版会先执行。
用第三个参数控制监听阶段
addEventListener(type, handler, useCapture) 中的 useCapture 决定监听时机:
立即学习“Java免费学习笔记(深入)”;
-
true:只在捕获阶段触发(从外向内) -
false或省略:只在冒泡阶段触发(从内向外,默认行为)
例如:el.addEventListener('click', fn, true) → 捕获阶段响应el.addEventListener('click', fn) → 冒泡阶段响应
阻止传播要分清目的
根据需求选择对应方法,避免误用:
-
只停冒泡,保留捕获和目标阶段:用
event.stopPropagation() -
彻底中断当前事件流(含捕获、目标、冒泡):用
event.stopImmediatePropagation()(还会阻止同一阶段其他同类型监听器) -
仅阻止默认行为(如表单提交、链接跳转):用
event.preventDefault(),不影响传播
比如在子按钮点击时不想让父容器响应,就在子元素的处理函数中调用 stopPropagation() 即可。
事件委托依赖冒泡机制
把事件监听器统一绑定在父级,利用冒泡让子元素触发时被父级捕获,再通过 event.target 判断真实点击源:
- 适合动态增删子项的列表、菜单等场景
- 节省内存,避免为每个子元素单独绑定
- 必须确保子元素事件能正常冒泡(未被中途
stopPropagation)
典型写法:parent.addEventListener('click', e => { if (e.target.matches('.item')) { /* 处理逻辑 */ } });


















