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
相关产品推荐
相关产品推荐

