Start · Sprachen · JavaScript · Referenz · Event.composed

Event.composed

Eigenschaft

Schreibgeschützter boolescher Wert, der angibt, ob ein Ereignis die Shadow-DOM-Grenze überschreitet und bis ins reguläre DOM weitergereicht wird.

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

Signatur

Event.composed

Beschreibung

Die Eigenschaft composed zeigt an, ob ein Ereignis beim Propagieren die Grenze eines Shadow-DOM überschreiten darf. Ist der Wert true, läuft das Ereignis aus der Shadow-Root heraus weiter zum Host-Element und durch das umgebende Dokument. Ist er false, endet die Propagation an der Shadow-Root.

Die meisten vom Browser ausgelösten UI-Ereignisse wie click, input, keydown, focus oder pointerdown haben composed: true. Andere Ereignisse, etwa load, change, scroll, slotchange oder toggle, sind composed: false. Selbst erzeugte Ereignisse (new Event(), new CustomEvent()) sind standardmäßig nicht composed. Bei ihnen muss man die Option composed: true im Konstruktor ausdrücklich setzen.

Wenn ein composed-Ereignis die Shadow-Grenze überschreitet, wird es retargetiert: Für Listener außerhalb der Komponente zeigt event.target auf das Host-Element und nicht auf das innere Element. Den vollständigen Pfad samt innerer Knoten liefert event.composedPath(), allerdings nur bei offenen Shadow-Roots (mode: "open").

Man braucht die Eigenschaft vor allem bei der Entwicklung von Web Components. Damit legt man fest, ob eigene Ereignisse zur öffentlichen Schnittstelle der Komponente gehören (composed: true) oder nur intern gelten.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn das Ereignis die Shadow-DOM-Grenze überschreitet, sonst false. Der Wert wird bei der Erzeugung festgelegt und ist schreibgeschützt.

Beispiele

composed bei nativen Ereignissen prüfen

document.addEventListener('click', (e) => {
  console.log('click composed:', e.composed);
});

window.addEventListener('load', (e) => {
  console.log('load composed:', e.composed);
});
load composed: false click composed: true // nach einem Klick

Eigenes Ereignis aus einer Web Component nach außen senden

class LikeButton extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = '<button>Gefällt mir</button>';
    root.querySelector('button').addEventListener('click', () => {
      // bubbles + composed: Ereignis verlässt die Shadow-Root
      this.shadowRoot.querySelector('button').dispatchEvent(
        new CustomEvent('like', { bubbles: true, composed: true, detail: { id: 42 } })
      );
    });
  }
}
customElements.define('like-button', LikeButton);

document.body.append(document.createElement('like-button'));

document.addEventListener('like', (e) => {
  console.log(e.composed, e.target.tagName, e.detail.id);
});
true LIKE-BUTTON 42 // nach Klick; target wurde auf den Host retargetiert

Unterschied composed: true vs. false

const host = document.createElement('div');
document.body.append(host);
const root = host.attachShadow({ mode: 'open' });
const inner = document.createElement('span');
root.append(inner);

document.body.addEventListener('ping', (e) => {
  console.log('Body empfängt ping, composed =', e.composed);
});

inner.dispatchEvent(new Event('ping', { bubbles: true }));                 // bleibt in der Shadow-Root
inner.dispatchEvent(new Event('ping', { bubbles: true, composed: true }));  // erreicht body
Body empfängt ping, composed = true

// Wichtig · Fallstricke

  • Standardwert false: Selbst erzeugte Ereignisse verlassen eine Shadow-Root nur mit composed: true. Das wird häufig vergessen, und dann erreicht das Ereignis Listener außerhalb der Komponente nicht.
  • composed ersetzt nicht bubbles: Ohne bubbles: true erreicht ein composed-Ereignis nur den Host selbst, aber nicht dessen Vorfahren.
  • Retargeting: Außerhalb der Komponente zeigt event.target auf das Host-Element. Das innere Ziel findet man über event.composedPath(). Bei geschlossenen Shadow-Roots (mode: "closed") fehlen die inneren Knoten im Pfad.
  • Schreibgeschützt: Eine Zuweisung wie e.composed = true wird stillschweigend ignoriert und löst im strikten Modus einen TypeError aus.
  • Kapselung: Setze composed: true nur bei Ereignissen, die zur öffentlichen Schnittstelle der Komponente gehören. Sonst gelangen interne Implementierungsdetails nach außen.
  • Kompatibilität: Unterstützt in allen modernen Browsern (Chrome 53+, Firefox 52+, Safari 10+, Edge 79+). Nicht verfügbar im Internet Explorer.