I have a web component like this
<template id="component">
<link href="/static/css/main.cacbacc7.css" rel="stylesheet">
<script src="/static/js/vendor.js" type="text/javascript"></script>
<script src="/static/js/bundle.js" type="text/javascript"></script>
<span id="react-app"></span>
</template>
<script>
(function (window, document) {
const doc = (document._currentScript || document.currentScript).ownerDocument;
const proto = Object.create(HTMLElement.prototype, {
attachedCallback: {
value: function () {
const template = doc.querySelector('template#component').content;
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.cloneNode(true));
// executeThis() when all scripts have been loaded
}
},
});
document.registerElement('react-webcomponent', { prototype: proto });
})(window, document);
</script>
Can I know when all script
tags in my template
have been loaded?
Update
What I am currently doing is
const scripts = [...shadowRoot.querySelectorAll('script')];
let scriptsLoaded = 0;
scripts.forEach(function (script) {
script.addEventListener('load', function () {
if (++scriptsLoaded >= scripts.length) {
LoadReactAppIntoShadowDomContainer(shadowRoot.querySelector('#react-app'));
}
})
});
But I am hoping for a nicer way.
About the possible duplicate: Will it work for web components?
From what I understand, as of now,
you do not have event listeners for onload
of the dom in your shadow root
when you define a custom element, you can have a connectedCallback
which is called when you attach an element to your DOM
from what you are trying, it seems to me, that you are trying to ascertain, the exact time when your shadow DOM loads its internal scripts
from what I know, scripts are not scoped to your element, and are global.
So Instead of trying to do what you are doing at the moment which is,
you can simply slap an onload to the tags which work like they always have.
Further, you might be interested in mutation observers
if you may want to observe for changes to your shadow DOM, once it is attached
and beyond.
AFAIK, you can not observe DOM changes while you are constructing your element itself / before it is attached
Or, if you are defining your elements in a different file and prefer using HTML Imports
to import them onto the document,
you can use the webcomponentsready
listener from the document that imports, which fires when all the DOM is imported, parsed, and loaded
If there is indeed a way to observe the DOM or listen to template attachments to your element, I would also like to know.
Also, Since you are trying to embed your react app into the custom element, which is probably why you had this question of knowing when to call the loadreactapp
function, you may want to consider using slots
in your shadow DOM, which open up places where you may distribute content after your element has been registered on the browser
Just add your apps or other custom elements, by passing in the attribute slot=<slotname>