Я был слишком быстр в своем комментарии.
<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