Доступ к дочерним узлам пользовательских элементов?
Это может быть немного запутанным. Я пытаюсь получить доступ к innerHTML или childNodes из моего пользовательского элемента. Можно ли получить доступ к исходной структуре DOM из файла импорта веб-компонента? ДО прикрепить тень?
В приведенном ниже примере я пытаюсь получить доступ к src двух изображений jookah из моего файла импорта jookah-gallery.
Отказ от ответственности: я абсолютный нуб, когда дело доходит до теневого DOM и веб-компонентов, поэтому, если есть какие-то серьезные ошибки, я бы хотел понять, почему. Спасибо за любую помощь!
index.html
<jookah-gallery>
//here
<jookah-image class="gallery-image" src="http://merehead.com/blog/wp-content/uploads/gradient-design.jpeg">
<jookah-image class="gallery-image" src="https://webgradients.com/public/webgradients_png/035%20Itmeo%20Branding.png">
</jookah-gallery>
Импортировать файл для галереи Jookah:
(function(owner) {
class jookahGallery extends HTMLElement {
constructor() {
super();
//this returns false
if (this.hasChildNodes()) {
console.log('there are nodes')
}else{
console.log('NO nodes')
}
//shadow DOM attach
const shadowRoot = this.attachShadow({mode: 'open'});
const template = owner.querySelector('#jookah-gallery-template');
const instance = template.content.cloneNode(true);
shadowRoot.appendChild(instance);
}
// ---------------- object events -------------------------//
connectedCallback() {
}
render(){
}
disconnectedCallback(){
}
attributeChangedCallback(){
}
// ---------------- methods ------------------------//
}
customElements.define('jookah-gallery', jookahGallery);
})(document.currentScript.ownerDocument);
1 ответ
Согласно спецификации вы не должны проверять, изменять, добавлять и дочерние элементы в конструкторе вашего веб-компонента.
https://w3c.github.io/webcomponents/spec/custom/
Вместо этого вам нужно переместить чтение детей в ваш связанный обратный вызов:
class jookahGallery extends HTMLElement {
constructor() {
super();
this._childrenRead = false;
const shadowRoot = this.attachShadow({mode: 'open'});
const template = document.createElement('template');
template.innerHtml = `Place your template here`;
const instance = template.content.cloneNode(true);
shadowRoot.appendChild(instance);
}
connectedCallback() {
if (!this._childrenRead) {
this._childrenRead = true;
if (this.hasChildNodes()) {
console.log('there are nodes')
}else{
console.log('NO nodes')
}
}
}
}
customElements.define('jookah-gallery', jookahGallery);
Вы также можете использовать<slot>
встраивать своих детей. Но есть некоторые проблемы с CSS, которые необходимо учитывать при использовании слотов.
Помните, что shadowDOM поддерживается не во всех браузерах и не является простым полифилом. Так что, если вы работаете только с Chrome и Safari, сделайте это. Если вы планируете поддерживать более широкий диапазон браузеров, то вы, возможно, пока не захотите использовать ShadowDOM.
https://alligator.io/web-components/composing-slots-named-slots/
Также читайте больше здесь: Как использовать дочерние элементы в веб-компонентах