为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星coding 2024-01-03 14:03:48
我正在尝试获取所选选项的值,因此当有人使用我的 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>
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞


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

slotchange2. 对于在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/


查看完整回答
反对 回复 2024-01-03
  • 1 回答
  • 0 关注
  • 79 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信