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 template
is 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?
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
.