Beherrsche den Lebenszyklus von Custom Elements, die Kapselung durch Shadow DOM und die Inhaltsprojektion über Slots.
Diese Lektion in Kodokon öffnenCustom Elements erweitern das HTML-Vokabular: Jede Klasse, die von HTMLElement erbt, kann im CustomElementRegistry registriert werden, solange ihr Name einen Bindestrich enthält (user-badge, niemals userbadge). Feiner Punkt: Erscheint das Tag im Dokument, bevor customElements.define aufgerufen wird, wird es zunächst als unbekanntes Element erstellt und dann an Ort und Stelle aktualisiert (upgraded) - der Konstruktor wird also nachträglich auf einem Knoten aufgerufen, der bereits im Baum vorhanden ist.
class UserBadge extends HTMLElement {
static observedAttributes = ["name"];
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
this.textContent = this.getAttribute("name");
}
}
customElements.define("user-badge", UserBadge);Der Lebenszyklus hält einige Fallen bereit: attributeChangedCallback wird nur für die in observedAttributes aufgelisteten Attribute ausgelöst, und bei einem Upgrade wird es für jedes bereits vorhandene Attribut vor connectedCallback aufgerufen. Die Spezifikation verbietet dem Konstruktor, Attribute und Kinder zu untersuchen oder welche hinzuzufügen: In dem Moment, in dem er läuft (über createElement oder Klonen), kann das Element völlig leer sein.
<template id="card-tpl">
<style>
:host { display: block; padding: 1rem; }
::slotted(h2) { margin: 0; }
</style>
<slot name="title"></slot>
<slot></slot>
</template>attachShadow erstellt einen gekapselten Teilbaum: Styles dringen nicht nach außen, die Selektoren der Seite reichen nicht hinein - nur vererbte CSS-Eigenschaften (color, font) und Custom Properties überqueren die Grenze. Der Inhalt eines <template> liegt in einem DocumentFragment, das über .content zugänglich ist: Seine Skripte laufen nicht und seine Bilder laden nicht, bis du es in das Dokument klonst. Knoten, die im Light DOM platziert sind, werden in die <slot>-Elemente projiziert: Sie bleiben physisch im Light DOM, und das slotchange-Ereignis benachrichtigt dich über jede Änderung der Zuordnung.
class InfoCard extends HTMLElement {
constructor() {
super();
const tpl = document.getElementById("card-tpl");
this.attachShadow({ mode: "open" })
.appendChild(tpl.content.cloneNode(true));
}
}
customElements.define("info-card", InfoCard);Zwei Erweiterungen verdienen deine Aufmerksamkeit. Formularassoziierte Custom Elements: Mit static formAssociated = true und attachInternals() nimmt deine Komponente voll an Formularen teil (übermittelter Wert, native Validierung, :invalid-Zustände). Und Declarative Shadow DOM: <template shadowrootmode=open> hängt eine Shadow Root beim Parsen an, ohne JavaScript, was Web Components mit Server-Side Rendering kompatibel macht.
element.shadowRoot bei attachShadow({ mode: 'closed' }) von außen zurück?null: Nur die von attachShadow zurückgegebene Referenz gibt Zugriff auf die Shadow Root<slot> projizierten Knoten physisch?