JavaScript事件机制包含捕获、目标、冒泡三阶段:捕获从window向下至目标父级,目标阶段执行目标元素监听器,冒泡从目标向上传至window;默认addEventListener在冒泡阶段执行,设third参数为true可启用捕获。
JavaScript事件机制是指事件在DOM树中传播的完整过程,它不是简单地在某个元素上触发一次就结束,而是会按特定路径经过多个节点。这个机制由三个阶段组成:捕获阶段、目标阶段和冒泡阶段。
捕获阶段从最外层的window对象开始,逐级向下传递到目标元素(比如你点击的按钮),但不会进入目标元素本身;
目标阶段是事件真正到达触发源的时刻,在这个阶段执行目标元素上绑定的事件处理函数;
冒泡阶段则从目标元素开始,逐级向上传递回window,途中会经过所有父级元素。
默认情况下,addEventListener绑定的事件监听器都在冒泡阶段执行(第三个参数省略或为false)。若想在捕获阶段响应,需显式传入true。
事件冒泡是日常开发中最常用的部分,尤其适合处理结构重复、动态添加的元素。
click、mousedown、keydown)都支持冒泡,但focus、blur、mouseenter/mouseleave等例外 常见用法示例:
event.target识别具体被点中的,避免给每个单独绑定事件 上拦截并验证,而不是在每个按钮上重复写逻辑 document.getElementById('list').addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
console.log('点击了列表项:', e.target.textContent);
}
});事件捕获发生在事件到达目标之前,适合做“预处理”——比如权限检查、日志记录、阻止非法操作等。
addEventListener中将第三个参数设为true 典型场景:
或上拦截 document.body.addEventListener('click', function(e) {
console.log('捕获阶段:body已收到点击');
}, true); // 注意这个 true
document.getElementById('button').addEventListener('click', function(e) {
console.log('目标阶段:按钮被点击');
});点击按钮时,控制台先输出捕获阶段:body已收到点击,再输出目标阶段:按钮被点击。
如何控制事件传播行为
有时你不希望事件继续走完全部流程,可以主动干预:
-
event.stopPropagation():阻止事件继续向当前方向传播(无论是捕获还是冒泡)
-
event.stopImmediatePropagation():不仅阻止传播,还阻止同一阶段其他监听器执行
-
event.cancelBubble = true:IE兼容写法,效果等同于stopPropagation()
注意:
-
stopPropagation() 不影响当前监听器内后续代码执行
- 它只对当前事件流生效,不影响其他独立事件
- 若需要彻底禁用默认行为(如表单提交、链接跳转),还需配合
event.preventDefault()
button.addEventListener('click', function(e) {
e.stopPropagation(); // 父级不会收到这次点击
console.log('按钮处理完成');
});