问题
This might be a bit confusing. I am trying to access innerHTML or childNodes from my custom element. Is it possible to get access to the original DOM structure from the web component import file? BEFORE attachShadow?
In the below example I am trying to get access to the src of the two jookah-images from my jookah-gallery import file.
Disclaimer: Im a total noob when it comes to shadow DOM and web components so if there are any major mistakes I'd love to understand why. Thanks for any help!
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>
import file for jookah-gallery:
(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:
According to the Spec you are not supposed to inspect, change, add and children in the constructor of your Web Component.
https://w3c.github.io/webcomponents/spec/custom/#custom-element-conformance
Instead you need to move the reading of the children into your connected callback:
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);
You can also use <slot> to embed your children. But there are some CSS issues you need to be aware of when using slots.
Remember that shadowDOM is not supported in all browsers and is not a simple polyfill. So if you are only working on Chrome and Safari, go for it. If you are planning to support a broader range of browsers then you might not want to use ShadowDOM just yet.
https://alligator.io/web-components/composing-slots-named-slots/
Also read more here: How to use child elements in Web Components
来源:https://stackoverflow.com/questions/49786436/accessing-childnodes-of-custom-elments