事件流严格按捕获→目标→冒泡三阶段单向执行:捕获阶段由外向内触发useCapture:true监听器,不进入目标元素;目标阶段触发目标元素上所有监听器,true优先于false;冒泡阶段由内向外触发useCapture:false监听器。

事件捕获阶段一定先于冒泡阶段执行,中间夹着目标阶段。整个事件流是严格单向、不可跳过、不可逆序的三段式流程:捕获 → 目标 → 冒泡。
捕获阶段:从外到内,只响应 useCapture: true 的监听器
事件从 window 开始,依次经过 document、<html>、<body>、父容器,直到目标元素的**直接父级**为止,不会进入目标元素自身。这个阶段只会触发显式设置第三个参数为 true(或 {capture: true})的监听器。
- 比如点击
<div id="A"><div id="B"><button id="C">点我</button></div></div>,捕获路径是:window → document → html → body → #A → #B,#C不参与捕获阶段 - 即使给
#C绑定了useCapture: true的监听器,它也不会在捕获阶段运行——而是在目标阶段执行
目标阶段:只发生在目标元素上,所有监听器都可触发
事件抵达被点击/触发的那个具体元素(如 #C)时,进入目标阶段。此时不管监听器是 true 还是 false,只要绑定在该元素上,都会在此刻执行;但执行顺序有规则:
- 同一元素上,
useCapture: true的监听器先于useCapture: false(或省略)的监听器执行 - 同为
true或同为false,则按代码中addEventListener的注册顺序执行
冒泡阶段:从内到外,只响应 useCapture: false 的监听器
事件从目标元素开始,沿 DOM 树逐层向上,经过父级、祖父级,最终到达 window。这个阶段只触发第三个参数为 false 或未传参(默认就是 false)的监听器。
立即学习“Java免费学习笔记(深入)”;
- 继续上面的例子,冒泡路径是:
#C → #B → #A → body → html → document → window - 如果
#B上同时绑了true和false的点击监听器,true的已在捕获阶段执行过了,冒泡阶段只执行false的那个
完整执行优先级总结
对任意一次用户触发(如点击),事件处理的全局顺序固定为:
- 所有祖先元素(含
document、window)上标记为useCapture: true的监听器,按由外向内的顺序执行 - 目标元素自身上所有监听器,
true类型先于false类型执行 - 所有祖先元素上标记为
useCapture: false的监听器,按由内向外的顺序执行
这个顺序不是“谁先绑定谁先执行”,而是由事件流阶段 + 监听器注册参数共同决定的刚性规则。


















