【发布时间】:2022-01-16 19:13:12
【问题描述】:
我创建了这个简单的示例(纯 JS,不在 Vue 或 React 等中):
<body>
<script>
(function () {
class MyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
const template = document.createElement('template');
template.innerHTML = `
<div>
<button>
<slot> <em>left</em> </slot>
</button>
</div>
`;
shadowRoot.append(template.content.cloneNode(true))
shadowRoot.addEventListener('click', (event) => {
// normal event delegation stuff,
const button = event.target.closest('button');
if (!button) return;
// do somthing with button
console.log(button);
});
}
}
customElements.define('my-component', MyComponent);
}());
</script>
<my-component id="myComponent"></my-component>
</body>
目前运行良好。
但是,在添加槽之后:
<my-component id="myComponent"> <span>previous</span> </my-component>
事件委托代码坏了,因为我点击的是Light DOM但Shadow DOM,所以,我用const button = event.target.closest('button');得到了null
有什么建议在槽内使用事件委托?
如果语法有问题,我是中国人:) 感谢您的阅读
【问题讨论】:
-
请创建一个 MCVE。 stackoverflow.com/help/mcve。另请注意,使用插槽时,插槽内容保留在 light DOM 中;它只是为了渲染目的而反映到shadow DOM。这不会改变它在文档中的位置,因此 light DOM 中的任何事件都不会看到 shadow DOM。
-
@connexo 谢谢,添加了 MCVE。您的评论帮助我确认了我的想法,我认为我必须以另一种方式实现相同的目标。
标签: web-component shadow-dom event-bubbling slot