Nested element (web component) can’t get its template

document.currentScript contains a reference to the script that is currently parsed and executed. Therefore it is not valid anymore for your purpose when the constructor() function is called (from another script).

Instead you shoud save its value in a variable at the beginning of the script, and use this variable in the constructor:

<script>
    var currentScript = document.currentScript
    customElements.define( ... )
    ...
</script>

If you have multiple scripts, you should use distinct names.

Alternately, you can encapsulate the ephemeral value in a closure:

(function(owner) {
    customElements.define('app-container', class extends HTMLElement {
        constructor() {
           super();
           let shadowRoot = this.attachShadow({ mode: 'open' });
           const content = owner.querySelector('#app-container').content;
           shadowRoot.appendChild(content.cloneNode(true));
        }
    });
})(document.currentScript.ownerDocument);

Here the value document.currentScript.ownerDocument is assigned to the owner argument which is still defined correctly when constructor() is called.

owner is locally defined so you can use the same name in the other document.

Leave a Comment