前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库DOM 事件传播 捕获 冒泡 阶段
浏览浏览器事件系统

DOM 事件传播的三个阶段(捕获、目标、冒泡)分别是什么,监听器在哪个阶段触发?

事件传播分捕获、目标、冒泡三阶段:捕获自 Window 向下到目标父级,冒泡反向回到 Window。捕获监听器在阶段1触发,冒泡监听器在阶段3触发;目标元素上两类监听器都会触发。

前端进阶之旅 · 一题精讲更新于 2026.09.05
浏览器#事件系统
先看核心答案
理解线索

三阶段速记

  1. 捕获阶段1Window 向下至目标父级,触发 capture 监听器
  2. 目标阶段2到达目标,两类监听器均触发按注册序
  3. 冒泡阶段3从父级向上回 Window,仅 bubbles 为真

bubbles 为 false 的事件(如 focus)走不到冒泡阶段。

核心回答

先记住这个答案

DOM 事件先捕获:从 Window 经 Document、html 一路向下到目标父元素,期间触发 capture 监听器;然后到达目标,进入目标阶段,目标上注册的捕获与冒泡监听器都会触发,顺序按注册先后;最后若 bubbles 为 true 则冒泡,从目标父级向上回到 Window,触发冒泡监听器。用 addEventListener 第三个参数控制:true 为捕获,false 或不传为冒泡。event.eventPhase 可读出当前处于 1、2、3 哪个阶段。

  • 顺序:捕获向下、目标、冒泡向上
  • capture:true 在阶段1触发,默认在阶段3
  • 目标上两类监听器都触发,按注册顺序

三阶段的传播路径与监听器归属

浏览器派发事件时构造一条从 Window 到目标的传播路径。捕获阶段沿路径向下,依次经过 Document、html、body 直到目标的父元素,此阶段只触发用 addEventListener(type, fn, true) 注册的监听器。eventPhase 此时为 1,可通过 Event.CAPTURING_PHASE 常量比对。

到达目标后进入目标阶段,eventPhase 为 2。关键细节是:在目标元素自身上,捕获监听器和冒泡监听器都会触发,不再区分阶段方向,而是按照各自注册的先后顺序依次执行。之后若事件 bubbles 为 true,进入冒泡阶段(eventPhase 为 3),默认注册的监听器(第三个参数 false 或省略)在从目标父级回到 Window 的过程中逐个触发。

嵌套点击时确认父级拦截先于子级处理

一个弹层组件中,结构为 overlay > panel > button。需求是点击 button 前先让 overlay 检查登录态,未登录则不再向下分发。输入是一次真实 click,约束是 overlay 的检查必须先于 button 的业务逻辑执行。决策:overlay 用 addEventListener('click', check, true) 注册在捕获阶段。

结果:事件沿 overlay→panel→button 捕获时,check 最先运行,eventPhase 为 1 且 currentTarget 是 overlay;通过校验后 button 的默认冒泡监听器在其目标阶段执行。若误把 overlay 监听器注册成冒泡,执行顺序会反过来,button 先触发,拦截失效。这验证了监听器触发阶段由注册时的 capture 标志决定,而非元素层级。

该模型失效或需注意的条件

并非所有事件都有冒泡阶段:focus、blur、mouseenter 等 bubbles 为 false,事件在目标阶段结束后即终止,冒泡监听器永远不会触发。若依赖冒泡在祖先上统一处理这类事件,代码静默失效,须改用捕获注册或换成 focusin 等可冒泡变体。

另一个边界是监听器调用 stopPropagation 后传播路径被截断,后续路径上的节点(如尚未经过的捕获或冒泡节点)监听器不会触发,但同一元素上尚未执行的监听器仍可能运行。目标阶段的细节也仅对同一元素成立。排查时应先读 event.eventPhase 与 event.bubbles 确认事件实际走到了哪一步,再推断监听器为何未触发,而不是假设三阶段一定完整走完。

回答前,多想一步

容易答错的地方

认为捕获监听器在目标上不触发
捕获与冒泡的区分只在祖先路径上;事件到达目标进入 AT_TARGET 阶段后,目标上注册的捕获和冒泡监听器都会执行,顺序由注册先后决定,这是面试最易答错的点。
认为所有事件都完整走完三阶段
只有 bubbles 为 true 的事件才有冒泡阶段。focus、blur、load 等事件到目标阶段就结束,祖先上的冒泡监听器收不到。判断时应查事件类型的 bubbles 属性而非默认假设。
试着用自己的话回答

面试官还会怎么问?

如何知道监听器当前处于哪个阶段?

读回调参数 event.eventPhase:1 表示捕获,2 表示目标,3 表示冒泡,0 表示未在派发中。可与 Event.CAPTURING_PHASE 等常量比较,常用于调试传播顺序问题。

目标元素上两个监听器谁先执行?

目标阶段不区分捕获或冒泡,两者都触发,执行顺序按 addEventListener 调用先后。只有离开目标元素后,capture 标志才重新决定监听器属于哪个传播阶段。

window 上的监听器什么时候触发?

window 作为顶层祖先,在捕获阶段最先触发监听器(若注册为捕获),在冒泡阶段最后触发(若注册为冒泡)。因此 window 上注册的捕获监听器总是先于页面内其它元素执行,但若要阻止事件继续传播,仍需在回调内调用 stopPropagation()。

从一道题,走向一组知识

把知识连起来

事件系统

什么时候你会主动在捕获阶段注册事件监听器而不是默认的冒泡阶段?

在理解捕获阶段后,进一步说明何时应主动用捕获注册监听器及典型场景。

事件系统

事件回调中 event.target 与 event.currentTarget 有何区别?在事件委托中应使用哪个?

传播经过不同元素时 target 与 currentTarget 的取值不同,是理解三阶段回调行为的关键。

参考资料

  • Event: eventPhase property

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 三阶段的传播路径与监听器归属
  3. 嵌套点击时确认父级拦截先于子级处理
  4. 该模型失效或需注意的条件
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑