Reputation: 3802
I've created a little web component without any frameworks. This is my index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<script src="clock.js" async></script>
</head>
<body>
<clock-digital></clock-digital>
<script>
console.log(document.querySelector('clock-digital').cID);
document.querySelector('clock-digital').method();
</script>
</body>
</html>
and this is my clock.js
:
customElements.define('clock-digital', class extends HTMLElement {
get cID() {}
set cID(value) {}
constructor() {
super();
var shadowRoot = this.attachShadow({
mode: 'open'
});
var that = shadowRoot;
this.cID = setInterval(function () {
var currentdate = new Date();
that.innerHTML = `<div style="display: inline; background-color: whitesmoke; font-style: italic;">${currentdate.getHours()}:${currentdate.getMinutes()}:${currentdate.getSeconds()}</div>`;
}, 500);
}
method() {
console.log('method');
}
});
The browser console shows this error:
undefined (index):14 Uncaught TypeError: document.querySelector(...).method is not a function at (index):14
Why can't my inline script access cID
and method()
?
Upvotes: 1
Views: 585
Reputation: 56813
The web components API has you covered here. Simply use the customElements.whenDefined(tagName)
promise here:
customElements.whenDefined('clock-digital').then(() => {
console.log(document.querySelector('clock-digital').cID);
document.querySelector('clock-digital').method();
});
Upvotes: 0
Reputation: 31219
To keep the script asynchronous (async
), which is sometimes better, you can add an onload
event handler to the <script>
element, that will call your inline script:
<script>
function init() {
console.log(document.querySelector('clock-digital').cID);
document.querySelector('clock-digital').method();
}
</script>
<script src="clock.js" async onload="init()"></script>
Upvotes: 1
Reputation: 138696
Your inline script runs before clock.js
is imported (which is asynchronous because of the async
attribute you've added to the <script>
tag). Since the element is defined in clock.js
, <clock-digital>.method
and <clock-digital>.cID
don't yet exist when your inline script tries to access them.
A couple options:
async
tag so that the import happens synchronously before your inline script runs (demo). You'd lose the advantage of the asynchronous load, but that might not be an issue for you.clock.js
to finish importing)Upvotes: 1