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

哪些场景要把监听器放在捕获阶段?

给 addEventListener 传 { capture: true },监听器会在事件到达目标前的捕获阶段运行。需要父层先观察事件,或处理某些不冒泡事件时有用;一般按钮交互仍用默认冒泡。

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

事件路径有三个阶段

  1. 捕获阶段从外层祖先朝目标前进
  2. 目标阶段事件到达实际派发目标
  3. 冒泡阶段从目标向外层祖先返回

捕获监听能在子节点的冒泡监听前运行,但若更外层在捕获阶段先停止传播,也可能到不了当前节点。

核心回答

先记住这个答案

通常把监听器注册在冒泡阶段更符合常见的事件委托和组件处理。若父容器必须在子按钮处理之前观察事件,可传 { capture: true },让回调在事件沿祖先链向目标前进时执行。捕获也能用于监听某些不冒泡事件,例如祖先上捕获子输入框的 focus。但它不是绕过所有传播控制的特权通道。

  • 捕获沿祖先到目标传播
  • capture: true 让父层先接收
  • 可用于观察部分不冒泡事件
  • 不能穿过更早的传播阻断

表单容器先观察焦点

表单想统计用户首次进入哪个输入框,普通 focus 不冒泡,直接在表单上加默认监听不会像 click 那样收到子字段的焦点事件。捕获监听可沿传播路径观察到它。

在祖先捕获 focusJavaScript
const form = document.querySelector('#profile')
form.addEventListener('focus', event => {
  const field = event.target
  console.log('聚焦字段:', field.name) // 焦点到达字段前经过表单
}, { capture: true })

这里读取的是实际触发焦点的字段。若业务只需要会冒泡的焦点进入事件,也可改用 focusin,不必依赖捕获。 捕获监听运行较早,适合观察或少量前置控制;若在这里随意调用 stopPropagation(),可能让子组件监听不到它期待的事件。

捕获不是万能保险

事件从更外层开始进入。如果外层捕获监听先停止传播,内层捕获监听也不会得到这次事件。闭合 Shadow DOM 等封装边界还可能改变可见目标和路径。

排查“为什么没有触发”时,先画出目标与祖先链,检查事件是否经过该节点、是否冒泡或跨边界,再看哪个监听器在何阶段阻断传播。不要只把 capture 改成 true 试运气。

同一个元素上同时注册捕获和非捕获监听,事件到达目标时会先处理捕获监听,再处理普通监听;同阶段的多个监听按注册顺序执行。若业务要求一个操作严格先于另一个,优先在自己的处理流程里明确调用次序,少靠分散监听器之间的隐含约定。

移除捕获监听时还必须把捕获标志传对:注册用 { capture: true },清理却省略第三个参数,浏览器不会把它当作同一条监听器。组件反复挂载后若出现同一事件被记录多次,可以先检查这里。

回答前,多想一步

容易答错的地方

认为捕获能监听任何页面事件
目标与监听元素之间必须有传播路径关系,且可能被更早的监听器阻断。
把捕获等同于取消默认行为
捕获只决定回调运行阶段;是否取消默认行为还要看事件是否可取消并调用 preventDefault()。
试着用自己的话回答

面试官还会怎么问?

focus 不冒泡,怎样做表单级监听?

可以在表单祖先捕获 focus,也可使用会冒泡的 focusin。

捕获和冒泡都注册同一事件会怎样?

两个监听器在各自阶段执行,调用顺序取决于传播路径与目标位置。

子元素 stopPropagation() 能挡住祖先捕获吗?

子元素回调发生前,祖先捕获监听通常已经运行;它不能回头撤销已执行的回调。

从一道题,走向一组知识

把知识连起来

事件系统

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

完整传播顺序还包括目标阶段与冒泡阶段。

事件系统

哪些事件不能直接靠冒泡委托?

focus 不冒泡,可捕获或使用会冒泡的 focusin 做委托。

参考资料

  • MDN 参考文档

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

本题目录
  1. 先记住这个答案
  2. 表单容器先观察焦点
  3. 捕获不是万能保险
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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