I am making a component where I only wish to define the component after its CSS file has finished loading. This way I can use wl-button:not(:defined) { animation: loading 1s alternating }
in a smaller render blocking stylesheet and it will look clean until the components deferred full CSS and Script files are finished.
However, I am a little paranoid about an edge case where the customElements.define()
does not get called due to the timing of when the stylesheet loads. Initially my code was just:
const stylesheet = document.getElementById("stylesheet__wl_button");
stylesheet.addEventListener("load", () => {
customElements.define('wl-button', WL_Button); // where WL_Button is a class
});
I suppose this is what a sane person would do, but I am not sane, so I figured.. what if the stylesheet has already loaded before the onload event listener is attached? Will it still trigger?
Furthermore, as I expanded the code to check if the stylesheet had already loaded before attaching the event listener, I figured.. what if the stylesheet loads in the awkward tiny gap between the stylesheet.sheet
check and the addEventListner()
call is finished? This made me write all this logic and I can’t help but wonder if I am completely off my meds right now.
Is there a better way to do this?
const stylesheet = document.getElementById("stylesheet__wl_button");
const def = () => customElements.define('wl-button', WL_Button);
if (!stylesheet) {
console.warn("Stylesheet missing for '<wl-button>'.");
def();
}
else if (stylesheet.sheet) {
// if the style sheet has already loaded, define the component
def();
}
else {
// if the style sheet has not loaded, listen to the onload event
stylesheet.addEventListener("load", def);
// check if the sheet loaded before the eventlistener was attached
if (stylesheet.sheet) {
stylesheet.removeEventListener("load", def);
// check if the sheet actually loaded after the eventlister was attached but before the second stylesheet.sheet call was made to prevent defining twice
if (!customElements.get("wl-button")) {
def();
}
}
}