我想用<select>
元素制作一个Web组件。我正在尝试让用户提供的<option>
标签出现在Shadow DOM中。
我的组件
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<select placeholder="text">
<slot name="option"></slot>
</select>
`;
class SelectBox extends HTMLElement {
constructor() {
super();
if (!this.shadowRoot) {
this.root = this.attachShadow({mode: 'open'});
this.root.appendChild(tmpl.content.cloneNode(true));
}
}
}
customElements.define('select-box', SelectBox);
HTML:
<select-box>
<option slot="option" value="text">text</option>
</select-box>
这使我相信我还没有掌握将用户元素插入影子DOM的过程。
答案 0 :(得分:4)
问题似乎出在option
元素上,无法分配为广告位。
但是,由于您的模板只是一个选择,我想知道为什么您不只是简单地扩展选择而是将其命名为一天。
class SelectBox extends HTMLSelectElement {
connectedCallback() {
// in case is not fully parsed yet ...
if (this.selectedIndex < 0)
return setTimeout(() => this.connectedCallback());
this.addEventListener('change', this);
this.parentNode.insertBefore(
document.createElement('p'),
this.nextSibling
);
this.handleEvent();
}
handleEvent() {
this.nextSibling.textContent =
`${this.selectedIndex}: ${this.value}`;
}
}
customElements.define('select-box', SelectBox, {extends: 'select'});
在上述类中,您所需要的只是带有选项的DOM,并且您将选项放置在不属于这些选项的地方,只需进行完整的内置扩展即可。
<select is="select-box">
<option value="first">first</option>
<option value="second">second</option>
</select>
您可以看到它在live in this code pen下工作。
少于1k的polyfill,其余为described in this medium post。
我知道这并不能完全解决您的问题,但是除非您要等待所有浏览器修复该问题,否则至少您知道有一种扩展内置插件的标准/更好方法。