Start · Sprachen · JavaScript · Referenz · HTMLSlotElement

HTMLSlotElement

Schnittstelle

Steht für ein <code>&lt;slot&gt;</code>-Element im Shadow DOM und liefert dessen Namen sowie die ihm zugeordneten Light-DOM-Knoten und -Elemente.

seit JavaScript Baseline: alle modernen Browser (seit 2020); assig Kategorie: webapi

Signatur

interface HTMLSlotElement extends HTMLElement

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 das name-Attribut. Ein Slot ohne Namen ist der Standard-Slot und nimmt alle Kinder ohne slot-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 mit slotAssignment: "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

Typ
HTMLSlotElement
Beschreibung
Instanzen entstehen über 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));
title ["H2"] ["P"]

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);
Header vorhanden: true

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);
Tab 2

// Wichtig · Fallstricke

  • Kein Verschieben im DOM: Zugeordnete Knoten bleiben Kinder des Hosts. slot.children enthält nur den Fallback-Inhalt, nicht die eingesetzten Knoten. Die eingesetzten Knoten bekommst du über assignedNodes() bzw. assignedElements().
  • Textknoten: assignedNodes() liefert auch Leerraum-Textknoten, die durch Zeilenumbrüche im Markup entstehen. Für Elemente ist assignedElements() meist die bessere Wahl.
  • Fallback-Inhalt: Ohne flatten: true ist 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). Statt addEventListener kannst du auch slot.onslotchange = handler setzen.
  • 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.assignedSlot bzw. Text.assignedSlot: Sie geben den Slot zurück, dem ein Knoten zugeordnet ist.