Web 组件:插槽出现在 shadow DOM 之外

sus*_*sdu 2 html javascript web-component

我想从一个<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);
Run Code Online (Sandbox Code Playgroud)

HTML:

<select-box>
  <option slot="option" value="text">text</option>
</select-box>
Run Code Online (Sandbox Code Playgroud)

渲染的是一个空的选择框。我可以在控制台中看到该元素为空 在此处输入图片说明

这让我相信我还没有掌握将用户元素插入 shadow DOM 的过程。

And*_*chi 5

看起来问题是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'});
Run Code Online (Sandbox Code Playgroud)

有了上面的类,您只需要带有选项的 DOM,并且您将选项放在这些不属于的地方,只需完全内置扩展即可。

<select is="select-box">
  <option value="first">first</option>
  <option value="second">second</option>
</select>
Run Code Online (Sandbox Code Playgroud)

您可以在此代码笔中看到它实时运行

小于 1k 的 polyfill 和其余部分在这个中等帖子中描述

我知道这并没有完全解决您的问题,但是除非您想等待所有浏览器修复该问题,否则至少您知道有一种标准/更好的方法来扩展内置插件。