focus/blur 默认不冒泡,因其焦点状态具有元素专属性;应使用冒泡版 focusin/focusout 替代,或通过 event.target 判断实现委托。

事件冒泡是指事件从目标元素出发,逐级向上传播到父元素、document 甚至 window 的过程。但像 focus、blur、mouseenter、mouseleave 这类事件,**默认不冒泡**——它们只在触发的元素本身生效,不会“传染”给祖先节点。
为什么 focus/blur 不冒泡
焦点状态是元素专属的:一个输入框获得焦点,不意味着它的父容器也“获得焦点”。若允许冒泡,父级会频繁收到子元素的焦点变化通知,逻辑混乱且无实际用途。因此浏览器设计上就禁止了这类事件的冒泡行为。
- focus 和 blur 只在可聚焦元素(如
input、button、带tabindex的div)上触发 - 即使给父元素监听
focus,点击子input也不会触发它 - 想让父级响应子元素焦点变化,不能靠冒泡,得换思路
用 focusin/focusout 替代实现“冒泡式”监听
focusin 和 focusout 是 focus/blur 的冒泡版本,W3C 标准明确支持它们向上冒泡,是官方推荐的替代方案。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 它们与 focus/blur 触发时机一致(focusin ≈ focus,focusout ≈ blur)
- 可直接在父容器上监听,一次绑定覆盖所有子可聚焦元素
- 兼容性良好(IE9+、现代所有浏览器)
其他不冒泡事件的处理思路
类似地,mouseenter/mouseleave 也不冒泡(为避免重复触发),但可用 mouseover/mouseout 替代——后者会冒泡,只是需手动判断 event.relatedTarget 来过滤非进出边界的情况。
立即学习“Java免费学习笔记(深入)”;
-
load、unload(已废弃)、scroll等资源或窗口级事件通常也不冒泡,因其作用域天然限定在目标对象 - 遇到不冒泡事件时,优先查文档确认是否有对应冒泡版事件(如 focusin/focusout、beforeinput 等)
- 没有冒泡替代时,可考虑事件委托的变体:在父级监听 document 或 window 级事件,再通过
e.target判断来源
主动阻止冒泡不是问题,忽略“不支持”才是坑
开发者有时会下意识对所有事件调用 e.stopPropagation(),但对本就不冒泡的事件这么做毫无意义,还可能掩盖真实意图。关键不是“怎么拦”,而是先确认“它本来会不会传”。
- 检查 MDN 文档中事件的 Bubbles 字段(标为
No即不冒泡) - 调试时打印
e.bubbles属性,运行时验证行为 - 不要假设 click 的逻辑能套用到 focus 上——交互语义不同,传播规则自然不同

















