Shadow DOM 中事件能否冒泡出边界仅取决于事件的 composed 属性,与 open/closed 模式无关;原生事件默认 composed: false 被截断,自定义事件需显式设置 composed: true 才能穿透。

事件冒泡在 Shadow DOM 中的路径行为,**不取决于 open/closed 模式**,而取决于事件本身的 composed 属性。open 和 closed 模式只影响外部 JS 是否能访问 shadowRoot 对象,对事件传播路径没有实质影响。
open 与 closed 模式的真实差异
两者都遵循相同的事件传播规则:
-
open 模式:外部可通过
el.shadowRoot访问影子树,能读取结构、样式、绑定事件,但不影响事件是否穿透边界 -
closed 模式:
el.shadowRoot返回null,外部无法直接操作影子树,但事件仍按相同规则传播——原生事件不穿透,自定义事件需显式设置composed: true
事件能否“冒泡出”Shadow DOM,只看 composed 属性
无论 open 还是 closed,以下行为一致:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 原生事件(如
click、input)默认composed: false,永远被 Shadow boundary 截断,外部监听不到 - 自定义事件必须手动指定
{ bubbles: true, composed: true }才能穿透到 light DOM - 漏掉
composed: true,事件就停在 shadow boundary 内,外部完全收不到——这是最常见错误
event.target 总是指向宿主元素的原因
这不是模式导致的,而是 Shadow DOM 的封装设计:
立即学习“Java免费学习笔记(深入)”;
- 内部按钮被点击,
event.target显示为<my-button>(宿主),而非内部<button> - 这是浏览器自动重定向的结果,目的是防止外部逻辑依赖影子树实现细节
- 要获取真实点击目标,请用
event.composedPath()[0],它在 Shadow 内外都返回原始触发元素
slot 投影内容的事件行为
通过 <slot> 插入的外部节点,其事件同样受 Shadow boundary 约束:
- 即使视觉上显示在组件内部,事件的
target仍被重定向为宿主元素 - 原生事件不会“逃逸”到 slot 外部父级;想让外部响应,仍需在 Shadow 内派发
composed: true自定义事件 - slot 内容自身绑定的事件监听器照常执行,但冒泡路径止于 slot 容器(即 shadow boundary)

















