我想要一个接受 N 个孩子的 Web 组件,并以列表格式显示它们。我发现我可以声明 N 个具有相同名称的插槽,它们将被添加为彼此的兄弟,如下所示:
window.customElements.define('x-list', class extends HTMLElement {
constructor () {
super();
const template = document.querySelector('#x-list').content;
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.cloneNode(true));
}
});
<x-list>
<li slot="item">Item 1</li>
<li slot="item">Item 2</li>
<li slot="item">Item 3</li>
</x-list>
<template id="x-list">
<ul>
<slot name="item">Items go here</slot>
</ul>
</template>
效果很好。但我不想泄露实现细节,所以我一直在寻找其他方法。理想情况下,使用该组件的人只需要提供 N 个元素,并且包装成一个列表将发生在组件本身的内部。
更改代码以使模板中有一个
<li>
内部的<ul>
失败微不足道,因为所有可插槽都进入同一个<li>
元素。role="listitem"
在<slot>
内部设置<ul>
失败,因为在 上设置的属性<slot>
没有复制到可插槽中。为每个分配的节点添加
slotchange
事件侦听器<slot>
和设置role="listitem"
确实有效,但这意味着 Web 组件正在与提供的节点混淆,这似乎不合适。进入
slotchange
事件并试图弄乱分配的节点,以便我可以动态地将它们包装在新创建的<li>
元素周围,需要我将它们从它们在 DOM 中的位置中删除。因此,它不仅会与用户提供的标记混淆,而且还会触发新的slotchange
事件发生。
有没有其他方法可以在不泄露自定义元素的实现细节的情况下做到这一点?