事件冒泡和捕获机制
理解 DOM 事件的冒泡和捕获阶段,以及 addEventListener 的第三个参数
问题
当嵌套元素都绑定了同一事件时,事件的触发顺序是怎样的?
<div id="outer">
<p id="inner">Click me!</p>
</div>
如果 div 和 p 都绑定了 click 事件,点击 p 时哪个处理函数会先执行?
解答
事件冒泡(Event Bubbling)
微软提出的事件流机制。事件从最内层元素开始触发,逐层向上传播到 document。
点击 p 元素的触发顺序:
p → div → body → html → document
事件捕获(Event Capturing)
网景提出的事件流机制。事件从最外层开始触发,逐层向下传播到目标元素。
点击 p 元素的触发顺序:
document → html → body → div → p
W3C 标准:先捕获后冒泡
W3C 采用折中方案,事件传播分为三个阶段:
- 捕获阶段:从
document到目标元素 - 目标阶段:到达目标元素
- 冒泡阶段:从目标元素到
document
addEventListener 的第三个参数
element.addEventListener(event, function, useCapture)
event:事件类型(如'click')function:事件处理函数useCapture:布尔值,默认falsefalse:在冒泡阶段调用处理函数true:在捕获阶段调用处理函数
示例:
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
// 冒泡阶段触发
outer.addEventListener('click', () => console.log('outer 冒泡'), false);
inner.addEventListener('click', () => console.log('inner 冒泡'), false);
// 捕获阶段触发
outer.addEventListener('click', () => console.log('outer 捕获'), true);
inner.addEventListener('click', () => console.log('inner 捕获'), true);
// 点击 inner 输出顺序:
// outer 捕获 → inner 捕获 → inner 冒泡 → outer 冒泡
关键点
- 冒泡:事件从内向外传播(p → div → body → document)
- 捕获:事件从外向内传播(document → body → div → p)
- W3C 标准:先捕获后冒泡,共三个阶段
addEventListener第三个参数控制在哪个阶段触发,默认false(冒泡阶段)- 可以用
event.stopPropagation()阻止事件继续传播
目录