猿问

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

我正在尝试获取所选选项的值,因此当有人使用我的 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>


繁星coding
浏览 99回答 1
1回答

杨__羊羊

<SLOTs>无法像“普通”DOM 元素一样定位(和许多人一样)您陷入了认为分槽内容已移动到 ShadowDOM 的陷阱<slots>它不是。开槽内容仅在 ShadowDOM 中反射,它仍然不可见!在 lightDOM 中您无法使用或...访问反射内容 ,因为它不在那里(在 ShadowDOM 中).. 它仍然在 lightDOM 中。.querySelector.children[]出于同样的原因,您可以在 lightDOM 中设置开槽内容的样式:使用 CSS 选择器,例如 :first-child inside Shadow dom将 lightDOM 追加<OPTIONs>到 ShadowDOM 中<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>ShadowDOMslotchange2. 对于在shadowDOM 模板中需要(命名/未命名)的事件,您的思路是正确的。 您可以在以下位置找到 lightDOM 节点:<slot></slot>MDN:分配的节点MDN:分配元素请注意,这会获取所有节点类型,包括text节点,因为innerHTML 中存在换行符和空格<my-element>!    <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/
随时随地看视频慕课网APP

相关分类

Html5
我要回答