Search code examples
javascripthtmlweb-componenthtmlelementsnative-web-component

how to queryselector a template object from javascript


Basically, I want to querySelect a <template> from javascript and I keep getting null.

JavaScript file:

    class MyImportWebcomponent extends HTMLElement {
        constructor() {
            super();
        }
        connectedCallback() {
            const shadowRoot = this.attachShadow({ mode: "open" });
            const template = document.querySelector("my-import-webcomponent-template");
            const instance = template.content.cloneNode(true);
            shadowRoot.appendChild(instance);
        }
    }

customElements.define("my-import-webcomponent", MyImportWebcomponent);

Template object from my vanilla webcomponent

<template id="my-import-webcomponent-template">
  <div id="mydiv" name="mydiv">
    <p>Trying html importing another javascript file</p>
  </div>
</template>

<script src="/to-try/my-import-webcomponent.js"></script>

index.html

<my-import-webcomponent></my-import-webcomponent>
<link rel="import" href="./to-try/my-import-webcomponent.html" />

The main issue is that document.querySelector("my-import-webcomponent-template") returns undefinied.

IN case it adds something usefull, if I try keep both javascript and html in same file and instead of querySelector I create straight the element, I successfully can do it.

All in a single file

const templateString = `<div id="mydiv" name="mydiv"><p>Trying html plus javascript in same file</p></div>`;
const template = document.createElement("template");
template.innerHTML = templateString;

export class MyCompleteWebcomponent extends HTMLElement {
    constructor() {
        super();
        const shadowRoot = this.attachShadow({ mode: "open" });
        shadowRoot.appendChild(template.content.cloneNode(true));
    }
}
customElements.define("my-complete-webcomponent", MyCompleteWebcomponent);

My question would be exact the same as queryselector if it wasn't for two reasons: (1) they seemed to rely on Polifys which it isn't my case and (2) the answer accepted is based on document.currentScript.ownerDocument which demands an old library as far as I know.

*** edited after suggestion to use instead of

<!-- <link rel="import" href="./to-try/my-import-webcomponent.html" /> -->
<script type="module" src="./to-try/my-import-webcomponent.js"></script>
<my-import-webcomponent></my-import-webcomponent>

Nothing changed at all

*** edited after recommended to add "#". No changes at all

enter image description here


Solution

  • If you want to load HTML files with <link rel="import"> then you'll need to load the HTML Imports library before.

    <script src="https://raw.githubusercontent.com/webcomponents/html-imports/master/html-imports.min.js"></script>
    <link rel="import" href="./to-try/my-import-webcomponent.html">
    ...