理解事件冒泡和事件捕获是掌握DOM事件流的关键。当页面上发生一个事件(比如点击)时,浏览器需要确定哪些元素应该接收这个事件,以及它们接收的顺序。这整个过程被称为事件流,它由三个主要阶段构成:捕获阶段、目标阶段和冒泡阶段。
![图片[1]-什么是事件冒泡和事件捕获?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/0d7a33c9e8d74c9f9ac75e4932b661aa_tplv-tb4s082cfz-aigc_resize_1080_1080-1-1024x683.webp)
事件捕获阶段
事件捕获是事件流的第一个阶段。事件从最外层的祖先元素(window)开始,沿着DOM树向下传播,直到到达事件的实际目标元素。
document.querySelector('#outer').addEventListener('click', () => {
console.log('捕获阶段:外层元素');
}, true); // 第三个参数为 true,表示在捕获阶段监听
在这个例子中,如果点击了#outer内部的某个元素,捕获阶段的监听器会先被触发。捕获阶段在实际开发中使用较少,但它在某些需要提前拦截事件的场景下很有用。
目标阶段
当事件传播到达实际触发事件的元素(event.target)时,就进入了目标阶段。在这个阶段,绑定在目标元素上的事件监听器(无论是否在捕获阶段注册)会按照它们的注册顺序被调用。这是你通常处理事件的地方。
事件冒泡阶段
紧接着目标阶段之后,事件会开始向上传播,从目标元素沿着DOM树回溯到根节点。这个过程就是事件冒泡,它是默认的行为。
document.querySelector('#inner').addEventListener('click', () => {
console.log('冒泡阶段:内层元素');
}); // 第三个参数默认为 false,表示在冒泡阶段监听
大多数情况下,我们的事件监听器都注册在冒泡阶段。这使得事件委托成为可能:你可以在父元素上设置一个监听器,来管理其所有子元素的事件。
事件流的完整过程与event.stopPropagation()
一次完整的事件流程是:捕获阶段(从window到target) -> 目标阶段(在target上) -> 冒泡阶段(从target到window)。
<div id="outer">
<button id="inner">点击我</button>
</div>
<script>
document.getElementById('outer').addEventListener('click', () => console.log('冒泡:outer'));
document.getElementById('inner').addEventListener('click', () => console.log('目标:inner'));
</script>
点击按钮后,控制台会依次输出“目标:inner”,然后是“冒泡:outer”。
你可以使用event.stopPropagation()来阻止事件进一步传播。如果在捕获阶段调用,它将阻止事件到达目标及后续的冒泡。如果在冒泡阶段调用,它将阻止事件继续向上冒泡。
inner.addEventListener('click', (event) => {
console.log('inner 被点击,阻止冒泡');
event.stopPropagation();
});
注意,event.stopImmediatePropagation()会阻止同一元素上后续所有监听器的执行。
理解冒泡和捕获机制,能让你更精准地控制事件响应。事件委托正是利用了冒泡的便利,而stopPropagation则提供了中断事件流的能力。合理运用它们,可以构建出更高效、更易维护的事件处理逻辑。






















暂无评论内容