1

I have a basic CustomElement but I'm having the following problem:

<template id="custom-element">
  <h1>Example 1</h1>
</template>

<script>

  class CustomElement extends HTMLElement {

    constructor() {
      super(); // always call super() first in the ctor.
      let shadowRoot = this.attachShadow({mode: 'open'});
      const template = document.querySelector('#custom-element');
      const instance = template.content.cloneNode(true);
      shadowRoot.appendChild(instance);
    }
    connectedCallback() {
      console.log("Connected");
    }

    disconnectedCallback() {

    }

    attributeChangedCallback(attrName, oldVal, newVal) {

    }
  }

  window.customElements.define('custom-element', CustomElement);

</script>

I'm getting this error in console:

Uncaught TypeError: Cannot read property 'content' of null

And it is because the const templateis always null. This was working before but I don't know if anything has changed that now it doesn't works. I'm using Chrome Version 62.0.3202.94 (Official Build) (64-bit) Any help on this please?

Jose Raul Perera
  • 778
  • 1
  • 7
  • 35

1 Answers1

0

Try this:

<template id="custom-element">
  <style>
  h1 {
    color: red;
    font: bold 24px Tahoma;
  }
  </style>
  <h1>Example 1</h1>
</template>
<script>
  const template = (document.currentScript||document._currentScript).ownerDocument.querySelector('#custom-element').content;

  class CustomElement extends HTMLElement {
    constructor() {
      super(); // always call super() first in the ctor.
      let shadowRoot = this.attachShadow({mode: 'open'});
      let instance = template.cloneNode(true);
      shadowRoot.appendChild(instance);
    }
    connectedCallback() {
      console.log("Connected");
    }

    disconnectedCallback() {
    }

    attributeChangedCallback(attrName, oldVal, newVal) {
    }
  }

  window.customElements.define('custom-element', CustomElement);
</script>

You need to get at document.currentScript||document._currentScript before the constructor. It must be accessed in the global space of the imported HTML file.

I always use both together to work with all of the web-component polyfills. If you don't need the polyfill, by limiting the browsers you support, then you can just use document.currentScript.

Intervalia
  • 10,248
  • 2
  • 30
  • 60