事件冒泡是从目标元素逐级向上传播到document的机制;可用stopPropagation()阻止冒泡,preventDefault()阻止默认行为,stopImmediatePropagation()则同时阻止冒泡和同元素其他监听器执行。

事件冒泡是 JavaScript 中事件传播的一种默认行为:当某个元素上的事件被触发时,该事件会先在目标元素上执行,然后逐级向上传播到它的父元素、祖父元素,直到 document(或 window)。理解它,关键在于“从内向外”这个方向。
事件冒泡是怎么发生的?
比如你点击一个按钮,而这个按钮在 div 里,div 又在 body 里。点击瞬间,click 事件先在按钮上触发,接着“冒泡”到 div,再冒泡到 body,最后到 document。浏览器就是按这个顺序检查每个祖先元素是否绑定了同类型事件监听器。
这本身不是 bug,而是设计机制——它让委托事件(event delegation)成为可能,比如给 ul 绑一个 click 监听器来统一处理所有 li 的点击,不用每个 li 都单独加。
怎样阻止事件冒泡?
用 event.stopPropagation() 就可以中断冒泡过程,让事件停在当前目标元素,不再往上传。
立即学习“Java免费学习笔记(深入)”;
- 它只影响冒泡阶段,不影响当前元素上的其他监听器执行(同一阶段的多个监听器仍会依次运行)
- 它不阻止默认行为(比如点击链接跳转、表单提交),要阻止默认行为得用 event.preventDefault()
- 如果想彻底终止事件的所有后续行为(既不冒泡也不执行默认动作),两个方法可以一起用
有没有更彻底的阻止方式?
有。event.stopImmediatePropagation() 不仅阻止冒泡,还会立即停止当前元素上**其他同类型事件监听器**的执行。比如一个按钮绑了两个 click 回调,调用这个方法后,第二个监听器根本不会运行。
注意:它比 stopPropagation() 更“强硬”,但使用要谨慎,容易让协作代码失效,调试时也难追踪。
实际写法示例
假设 HTML 是:
JS:
document.getElementById('inner').addEventListener('click', function(e) {
console.log('按钮被点了');
e.stopPropagation(); // ✅ 阻止冒泡
});
document.getElementById('outer').addEventListener('click', function() {
console.log('外层 div 也被点了'); // ❌ 这行不会执行
});
基本上就这些。冒泡是基础机制,阻止它不复杂但容易忽略细节——关键是分清 stopPropagation 和 preventDefault 的分工。











