Den gråskæggede mand her er lidt træt af Javascript-frameworks såsom React, som jeg synes "vil for meget", så jeg er gået tilbage til W3Cs WebComponents. API'en er lidt bøvlet, men så kan man føle sig som en l33t haX0r, når ens plugin virker ;) Webstandardiseringsorganet W3C er desværre ikke så kendt for at lave simple API'er, så det er på mange måder mere usexet end React. Kan du ikke undvære React, så er der også Vue og Preact, der er en slags "Light-udgave" af React.
Men altså, Web Components fjerner eksterne afhængigheder helt. Jo færre eksterne moduler, dit script er afhængig af, jo større er sandsynligheden for, at det også virker om 5 år.
Nedenfor er et starter-eksempel på, hvordan man kan have et eksternt stylesheet ved siden af sin WebComponent. Du kan sagtens definere mere af nedenstående direkte i dit HTML-dokument, men jeg kan godt lide at have mest muligt samlet, for det gør det nemmere at genbruge og distribuere komponenten
Prop dette i en .js-fil - kald den imgcard.js (beklager formateringen - eller mangel på samme, Bludits theme overskriver Rich text editor'ens stylesheet)
import stylesheet from "./imgcard.css" with { type: "css" }
class SJImageCard extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.adoptedStyleSheets = [stylesheet];
const wrapper = document.createElement("div");
wrapper.setAttribute("class", "card shadow");
wrapper.textContent = this.textContent;
shadow.appendChild(wrapper);
}
disconnectedCallback() {
console.log("Elementet blev fjernet");
}
}
customElements.define("sj-imagecard", SJImageCard);
Lidt om koden:
Det er ren boilerplatekode. Jeg starter lige i bunden på sidste linje, og hopper så tilbage: customElements.define-linjen registrerer dit element med browserens CustomElementRegistry. Den første parameter afgør, hvordan man kalder sit custom element i ens HTML-dokument. Så placer tagget <sj-imagecard></sj-imagecard> i dit HTML-dokument, næste parameter er navnet på klassen, hvor din komponentlogik lever.
Tilbage på linje 1 importerer jeg stylesheetet, bemærk den nye syntaks. Tidligere kunne du skrive assert istedet for with, men den notation er deprecated.
Så opretter jeg en klasse SJImageCard, der danner grundlag for min komponent. Klassen skal nedarve fra HTMLElement for at få de rigtige egenskaber. I constructor'en skal du huske at kalde super()-metoden, for ellers bliver constructor'en i HTMLElement ikke kaldt på rette tidspunkt.
ConnectedCallback-metoden kaldes så snart ens komponent indlæses af browseren, så det er der, du placerer hoveddelen af din kode. attachShadow-metoden laver en ShadowDOM for din komponent, der er separat fra browserens "hoved"-DOM, og det er her, du så laver din komponents indre logik. Jeg tror umiddelbart resten af koden er selvforklarende. Ellers imødeser jeg en sur besked på Mastodon ;)