Signatur
Beschreibung
HTMLSlotElement ist die DOM-Schnittstelle des <slot>-Elements. Slots sind Platzhalter im Shadow Tree einer Web Component. Die Kind-Knoten des Host-Elements (das sogenannte Light DOM) werden an diesen Stellen angezeigt, bleiben aber im DOM weiterhin Kinder des Hosts. Diesen Vorgang nennt man Distribution bzw. Slotting.
Die wichtigsten Mitglieder:
name: spiegelt dasname-Attribut. Ein Slot ohne Namen ist der Standard-Slot und nimmt alle Kinder ohneslot-Attribut auf.assignedNodes(options): gibt die zugeordneten Knoten zurück, Textknoten eingeschlossen.assignedElements(options): gibt nur die zugeordneten Elemente zurück.assign(...nodes): ordnet Knoten von Hand zu, wenn der Shadow Root mitslotAssignment: "manual"erzeugt wurde.- Event
slotchange: wird ausgelöst, sobald sich die Menge der zugeordneten Knoten ändert.
Du brauchst HTMLSlotElement immer dann, wenn eine Komponente auf ihren eingesetzten Inhalt reagieren soll. Beispiele: Tabs aus den Kindern erzeugen, einen leeren Slot ausblenden oder Fallback-Inhalt steuern. Mit der Option { flatten: true } werden verschachtelte Slots (ein Slot, der selbst in einen Slot eingesetzt wird) rekursiv aufgelöst. Ist dem Slot nichts zugeordnet, liefert die Option außerdem den Fallback-Inhalt des Slots.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options.flatten | boolean | false | Gilt für assignedNodes() und assignedElements(). Bei true werden verschachtelte Slots rekursiv aufgelöst. Ist dem Slot nichts zugeordnet, wird sein Fallback-Inhalt zurückgegeben. |
| $...nodes | Element | Text | Gilt für assign(): Die Knoten, die dem Slot von Hand zugeordnet werden. Sie müssen Kinder des Host-Elements sein. Nur wirksam bei slotAssignment: "manual". |
Rückgabewert
document.createElement('slot') oder über das Markup im Shadow Root. assignedNodes() gibt ein Node[] zurück, assignedElements() ein Element[] und assign() undefined.Beispiele
Slot erzeugen und zugeordnete Elemente auslesen
class UserCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const titleSlot = document.createElement('slot');
titleSlot.name = 'title';
const defaultSlot = document.createElement('slot');
shadow.append(titleSlot, defaultSlot);
}
}
customElements.define('user-card', UserCard);
const card = document.createElement('user-card');
card.innerHTML = '<h2 slot="title">Anna</h2><p>Entwicklerin</p>';
document.body.append(card);
const [titleSlot, defaultSlot] = card.shadowRoot.querySelectorAll('slot');
console.log(titleSlot.name);
console.log(titleSlot.assignedElements().map(el => el.tagName));
console.log(defaultSlot.assignedElements().map(el => el.tagName));
Auf slotchange reagieren und leeren Slot ausblenden
class InfoBox extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' }).innerHTML = `
<header part="header"><slot name="header"></slot></header>
<slot></slot>`;
const slot = this.shadowRoot.querySelector('slot[name="header"]');
slot.addEventListener('slotchange', () => {
const hasContent = slot.assignedNodes({ flatten: true }).length > 0;
slot.parentElement.hidden = !hasContent;
console.log('Header vorhanden:', hasContent);
});
}
}
customElements.define('info-box', InfoBox);
const box = document.createElement('info-box');
box.innerHTML = '<strong slot="header">Hinweis</strong> Text';
document.body.append(box);
Zuordnung von Hand mit assign()
class TabView extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open', slotAssignment: 'manual' });
shadow.innerHTML = '<slot></slot>';
this.slotEl = shadow.querySelector('slot');
}
show(index) {
const panel = this.children[index];
if (panel) this.slotEl.assign(panel); // nur dieses Kind anzeigen
}
}
customElements.define('tab-view', TabView);
const tabs = document.createElement('tab-view');
tabs.innerHTML = '<div>Tab 1</div><div>Tab 2</div>';
document.body.append(tabs);
tabs.show(1);
console.log(tabs.slotEl.assignedElements()[0].textContent);
// Wichtig · Fallstricke
- Kein Verschieben im DOM: Zugeordnete Knoten bleiben Kinder des Hosts.
slot.childrenenthält nur den Fallback-Inhalt, nicht die eingesetzten Knoten. Die eingesetzten Knoten bekommst du überassignedNodes()bzw.assignedElements(). - Textknoten:
assignedNodes()liefert auch Leerraum-Textknoten, die durch Zeilenumbrüche im Markup entstehen. Für Elemente istassignedElements()meist die bessere Wahl. - Fallback-Inhalt: Ohne
flatten: trueist der Fallback-Inhalt nicht enthalten. Das Ergebnis ist dann ein leeres Array, obwohl etwas angezeigt wird. - slotchange: Das Event löst nicht aus, wenn sich nur der Inhalt eines bereits zugeordneten Knotens ändert (z. B. sein Text). Dafür brauchst du einen
MutationObserver. Das Event steigt im Shadow Tree auf (bubbles), überschreitet die Shadow-Grenze aber nicht (composed: false). StattaddEventListenerkannst du auchslot.onslotchange = handlersetzen. - assign(): Wirkt nur bei
slotAssignment: "manual". Knoten, die keine Kinder des Hosts sind, werden ignoriert.assign()ist seit Chrome 86, Firefox 92 und Safari 16.4 verfügbar. - Styling: Eingesetzte Elemente lassen sich im Shadow-CSS mit
::slotted()gestalten. Das funktioniert nur für Elemente der obersten Ebene, nicht für deren Nachfahren. - Die Gegenrichtung liefern
Element.assignedSlotbzw.Text.assignedSlot: Sie geben den Slot zurück, dem ein Knoten zugeordnet ist.