получить значение из выбранной опции в веб-компоненте - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь получить значение выбранного параметра, поэтому, когда кто-то использует мой веб-компонент, он может получить к нему доступ. Я думаю, что проблема связана с тенью root

__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>

1 Ответ

1 голос
/ 17 апреля 2020

Я был слишком быстр в своем комментарии.

<SLOTs> не может быть нацелен на «обычные» элементы DOM

(как и многие) Вы попали в ловушку мышления прорезано содержимое
is MOVED в ShadowDOM <slots>

Это НЕ .

слот контент только в ОТРАЖЕННЫЙ в shadowDOM, он все еще остается невидимым! в lightDOM

Вы можете не получить доступ к отраженному контент с .querySelector или .children[]
... потому что его там нет (в shadowDOM) .. он все еще находится в lightDOM.

По той же причине, по которой вы оформляете слот-контент в lightDOM :
Используйте CSS селекторы, такие как: первый ребенок внутри тени 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> в shadowDOM

2. Вы оказались на правильном пути с событием slotchange
, для которого требуется (именованный / безымянный) <slot></slot> в шаблоне shadowDOM.
Вы найдете ваши узлы lightDOM в:

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

note! * <options> были отражены в ячейку без имени,
<H1 slot=title> отражено до <slot name=title>

(они должны были назвать их отражения вместо слотов )

Нажмите Показать фрагмент кода для получения полного кода

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/

HTH

...