You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shadow DOM下两个自定义元素间事件传递问题及解决方法

Shadow DOM自定义元素事件监听踩坑&解决方法

场景还原

我做了两个带Shadow DOM的自定义组件:

  • <ce-button>:用来触发并派发自定义事件
  • <ce-modal>:负责监听这个自定义事件

结果折腾半天发现,<ce-modal>根本收不到<ce-button>发的事件,当时头都大了😂

问题根源

一开始我的HTML结构是这样的:

<ce-button></ce-button>
<ce-modal></ce-modal>

这俩是同级元素!而Shadow DOM本身是封装性很强的独立环境,自定义元素内部Shadow DOM派发的事件,默认是没法跨同级自定义元素冒泡传播的——相当于两个独立的“盒子”,事件出了自己的盒子就传不到隔壁盒子里了。

搞定方案

我直接把<ce-button>挪到了<ce-modal>的Shadow DOM里面,这样俩组件就处在同一个Shadow上下文里了。现在HTML只需要写一行:

<ce-modal></ce-modal>

然后在<ce-modal>的实现代码里,把按钮加到它的Shadow DOM中,同时监听事件:

class CeModal extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({ mode: 'open' });
    
    // 创建ce-button并加入到modal的shadow DOM
    const triggerBtn = document.createElement('ce-button');
    shadowRoot.appendChild(triggerBtn);
    
    // 在这里监听自定义事件
    shadowRoot.addEventListener('custom-button-click', (event) => {
      console.log('终于收到事件啦!', event.detail);
      // 这里写modal的弹窗逻辑
    });
  }
}
customElements.define('ce-modal', CeModal);

这样调整后,事件就能正常在同一个Shadow DOM环境里传播,<ce-modal>稳稳接收到<ce-button>派发的事件了!

内容的提问来源于stack exchange,提问作者DennisKo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:04:44