简体   繁体   English

Web组件:插槽出现在阴影DOM外部

[英]Web Components: slot appears outside shadow DOM

I want to make a web component from a <select> Element. 我想从<select>元素制作一个Web组件。 I'm trying to get the <option> tags supplied by the user to appear in the Shadow DOM. 我试图让用户提供的<option>标记出现在Shadow DOM中。

My component: 我的组件:

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: HTML:

<select-box>
  <option slot="option" value="text">text</option>
</select-box>

What's being rendered is an empty select box. 正在呈现的是一个空的选择框。 I can see in the console that the element is empty 我可以在控制台中看到该元素为空 在此处输入图片说明

Which leads me to believe I haven't grasped the process of inserting user elements into the shadow DOM. 这使我相信我还没有掌握将用户元素插入影子DOM的过程。

It looks like the problem is the option element that cannot be assigned as slot. 看来问题是无法分配为插槽的option元素。

However, since your template is just a select, I wonder why you are not simply extending a select instead and call it a day. 但是,由于您的模板只是一个选择,所以我想知道为什么您不只是简单地扩展选择并将其命名为一天。

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'});

With above class all you need is just the DOM with your options, and you were putting options where these didn't belong anyway, just go full built-in extend. 在上面的类中,您所需要的只是带有选项的DOM,并且您将选项放置在这些都不属于的位置,只需进行完整的内置扩展即可。

<select is="select-box">
  <option value="first">first</option>
  <option value="second">second</option>
</select>

You can see it working live in this code pen . 您可以在此代码笔中看到它的实时运行

The less than 1k polyfill and the rest is described in this medium post . 少于1k的polyfill和其余的在此中等职位中描述

I know this didn't exactly solve your issue, but unless you want to wait for all browsers to fix that at least you know there is a standard/better way to extend built-ins. 我知道这并不能完全解决您的问题,但是除非您要等待所有浏览器修复该问题,至少您应该知道有一种扩展内置插件的标准/更好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM