I am curretly adding some customm elements for an inhouse framework , however I noticed that we are getting all the elements on an index file to use them inside the html.
Do you know a better way to do this ? like a lazy instantiation.
current code :
customElements.define('element-a', ElementA);
customElements.define('element-b', ElementB);
customElements.define('element-c', ElementC);
customElements.define('element-d', ElementD);
customElements.define('element-f', ElementF);
....
You can find custom elements, hide them, load classes async and upgrade elements:
class CustomElement extends HTMLElement{
connectedCallback() {
const template = document.createElement("template")
template.innerHTML = /* html */ `
<style>
:host {
background-color: yellow;
}
</style>
<slot></slot>
`
const shadowRoot = this.attachShadow({ mode: "open" })
shadowRoot.appendChild(template.content.cloneNode(true))
}
}
const promises = {};
// you can also traverse DOM tree, could be faster
document.querySelectorAll('*').forEach(async el => {
if(el.tagName.includes('-')){
let display;
[{display}, el.style.display] = [el.style, 'none'];
const tag = el.tagName.toLowerCase();
const name = tag.replace(/^\w|-\w/gd, m => m.at(-1).toUpperCase());
// use something like import() to load a custom element class
let defined = true;
const factory = await (promises[name] ??= (
defined = false,
new Promise(r => setTimeout(() => r(eval(name)), 200))
));
defined || customElements.define(tag, factory),
el.style.display = display;
}
});
<custom-element>Custom Element</custom-element><br/>
<custom-element>Second Element</custom-element>