从 Web 组件中的选定选项中获取值

get value from selected option in web component

我正在尝试获取所选选项的值,以便当有人使用我的 Web 组件时他们可以访问它。我认为问题与影子根有关

__createOptions() {
    const SELECT = this.shadowRoot.querySelector('select');
    SELECT.addEventListener('change', event => {
        this.value= event.target.value;
    });
    this.shadowRoot.addEventListener('slotchange', () => {
        const OPTION = this.querySelector('option');
        if (OPTION) {
            SELECT.append(OPTION);
        }
    });
}

render() {
    return html`
    <div class="selectWrapper">
        <select id="typeDropdown"></select>
    </div>
    <slot></slot>
`;
}

  <wc-select value="">
   <option value="1">Option 1</option>
   <option value"2">Option 2</option>
   <option value="3">Option 3</option>
  </wc-select>

我的评论太快了。

<SLOTs> 无法像 'normal' DOM 元素那样定位

(like many) You are running into the trap of thinking slotted content
is MOVED to ShadowDOM <slots>

不是

slotted content is only REFLECTED in shadowDOM, it still remains invisible! in lightDOM

您可以使用.querySelector.children[]
访问反映的内容 ...因为它不在那里(在阴影中DOM)。它仍然在光中DOM。

出于同样的原因,您在 light 中设置了开槽内容的样式DOM:


将光追加到阴影中DOM <OPTIONs> DOM <SELECT`>

1.你要么将它们从 lightDOM 移动到 shadowDOM:

    let select = this.shadowRoot.querySelector('select');
    let host = this.shadowRoot.getRootNode().host;
    let options = host.querySelectorAll('option');
    select.append(...options);

#1 是最简单的,因为它不需要影子中的任何 <slots>DOM

2。您在 slotchange 事件
中走在了正确的轨道上 它需要一个 (named/unnamed) <slot></slot> 在 shadowDOM 模板中。
您在以下位置找到您的 lightDOM 节点:

注意,这会让你得到所有 nodeTypes 包括 text 个节点,因为 <my-element> innerHTML 中有换行符和空格!

    <my-element>
      <option>Grow up</option>
      <option>Learn React</option>
      <option>Learn Lit</option>
      <option>Forget W3C standard Custom Elements API</option>
      <H1 slot=title>My Never Todo List</hH>
    </my-element>

幸运的是 <SELECT> 不在乎,所以你可以直接将 assignedNodes 转储进去..

    this.shadowRoot.addEventListener('slotchange', (evt) => {
      if (!evt.target.name) { // only for unnamed slot
        this.shadowRoot.querySelector('select')
            .append(...evt.target.assignedNodes());
      }
    });

注意! <options> 反映 到未命名插槽,
<H1 slot=title>反映<slot name=title>

(他们应该将它们命名为 reflections 而不是 slots

单击显示代码片段以获取完整代码

customElements.define("my-element", class extends HTMLElement {
  connectedCallback() {
    let template = document.getElementById(this.nodeName);
    this.attachShadow({
      mode: 'open'
    }).append(template.content.cloneNode(true));

    this.shadowRoot.addEventListener('slotchange', (evt) => {
      if (!evt.target.name) { // only for unnamed slot
        let select = this.shadowRoot.querySelector('select');
        select.append(...evt.target.assignedNodes());
      }
    });

  }
})
<template id=MY-ELEMENT>
  <style>
    :host {
      display: block;
    }

    select{
      font-size:1.5em;
    }

  </style>
  <slot name=title></slot>
  <select multiple>
  </select>
  <slot></slot>
</template>

<my-element>
  <option>Grow up</option>
  <option>Learn React</option>
  <option>Learn Lit</option>
  <option>Forget W3C standard Custom Elements API</option>
  <h1 slot=title>My Never Todo List</h1>
</my-element>

JSFiddle 游乐场有两个选项: https://jsfiddle.net/CustomElementsExamples/v2f9zmu5/


更多与 SLOT 相关的答案可以通过 Whosebug 搜索找到:Custom Elements SLOTs