The snippet below spits out an error that CustomElementParent
is not defined when I try to extend from it in CustomElementChild
.
When I remove the ! customElements.get('custom-element-parent')
check, it works.
In my case, CustomElementParent
is in a third party script, so I can't actually remove the if statement.
I guess this is a problem of conditionally defining a class. Is there any way to extend this class if it is conditionally defined?
<script>
if (! customElements.get('custom-element-parent')) {
class CustomElementParent extends HTMLElement {
constructor() {
super();
}
}
customElements.define('custom-element-parent', CustomElementParent);
}
if (! customElements.get('custom-element-child')) {
class CustomElementChild extends CustomElementParent {
constructor() {
super();
alert('test');
}
}
customElements.define('custom-element-child', CustomElementChild);
}
</script>
<custom-element-child></custom-element-child>
Scope. Classes have scope, same as variables.
if (true) {
let x = 5;
}
// you can’t access `x` here
(We don’t talk about var
. Point is, class
works like let
/const
/function declarations in strict mode.)
If you can’t change how CustomElementParent
is scoped and you can’t put your code in its scope, you can’t access it that way. You can look it up in the custom element registry instead:
const CustomElementParent = customElements.get('custom-element-parent');
Full example:
{
class Hidden extends HTMLElement {
constructor() {
super();
console.log('parent');
}
}
customElements.define('custom-element-parent', Hidden);
}
const CustomElementParent = customElements.get('custom-element-parent');
class CustomElementChild extends CustomElementParent {
constructor() {
super();
console.log('child');
}
}
customElements.define('custom-element-child', CustomElementChild);
<custom-element-child></custom-element-child>