2

这可能有点令人困惑。我正在尝试从我的自定义元素访问 innerHTML 或 childNodes。是否可以从 Web 组件导入文件中访问原始 DOM 结构?在附加阴影之前?

在下面的示例中,我试图从我的 jookah-gallery 导入文件中访问两个 jookah-images 的 src。

免责声明:当谈到影子 DOM 和 Web 组件时,我完全是个菜鸟,所以如果有任何重大错误,我很想了解原因。谢谢你的帮助!

索引.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-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);
4

1 回答 1

1

根据规范,您不应该在 Web 组件的构造函数中检查、更改、添加和子项。

https://w3c.github.io/webcomponents/spec/custom/#custom-element-conformance

相反,您需要将孩子的阅读移动到您的连接回调中:

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,它不是简单的 polyfill。所以如果你只在 Chrome 和 Safari 上工作,那就去吧。如果您计划支持更广泛的浏览器,那么您可能还不想使用 ShadowDOM。

https://alligator.io/web-components/composing-slots-named-slots/

还可以在这里阅读更多内容:如何在 Web 组件中使用子元素

于 2018-04-12T14:34:18.277 回答