Start · Sprachen · JavaScript · Referenz · Event.eventPhase

Event.eventPhase

Eigenschaft

Schreibgeschützte Zahl, die angibt, in welcher Phase des Ereignisflusses (Capturing, Ziel, Bubbling) sich ein Event gerade befindet.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

Event.eventPhase

Beschreibung

Die schreibgeschützte Eigenschaft eventPhase des Event-Interfaces gibt an, in welcher Phase des DOM-Ereignisflusses der gerade aufgerufene Listener läuft. Der Wert ist eine Ganzzahl, die einer der Konstanten auf Event entspricht:

  • Event.NONE (0): Das Event wird gerade nicht verarbeitet, z. B. vor dispatchEvent() oder nach dem Ende der Weiterleitung.
  • Event.CAPTURING_PHASE (1): Das Event läuft vom window über die Vorfahren nach unten zum Ziel. Hier werden Listener mit { capture: true } aufgerufen.
  • Event.AT_TARGET (2): Das Event ist beim Zielelement (event.target) angekommen. Hier werden Capture- und Nicht-Capture-Listener aufgerufen.
  • Event.BUBBLING_PHASE (3): Das Event steigt vom Ziel wieder zu den Vorfahren auf. Das passiert nur, wenn event.bubbles den Wert true hat.

Nützlich ist eventPhase vor allem bei Event-Delegation und bei Listenern, die für Capturing und Bubbling gleichzeitig registriert sind. So findest du heraus, ob ein Klick direkt auf dem Element selbst oder auf einem Kindelement ausgelöst wurde. Auch zum Debuggen komplexer Ereignisketten hilft die Eigenschaft.

Vergleiche den Wert am besten mit den benannten Konstanten (Event.AT_TARGET usw.) statt mit festen Zahlen. Das ist besser lesbar und macht die Absicht klar.

Rückgabewert

Typ
number
Beschreibung
0 (NONE), 1 (CAPTURING_PHASE), 2 (AT_TARGET) oder 3 (BUBBLING_PHASE).

Beispiele

Phasen eines Klicks protokollieren

// HTML: <div id="outer"><button id="btn">Klick</button></div>
const phaseNames = ['NONE', 'CAPTURING', 'AT_TARGET', 'BUBBLING'];
const outer = document.getElementById('outer');
const btn = document.getElementById('btn');

const log = (label) => (event) => {
  console.log(`${label}: ${phaseNames[event.eventPhase]}`);
};

outer.addEventListener('click', log('outer (capture)'), { capture: true });
btn.addEventListener('click', log('btn'));
outer.addEventListener('click', log('outer (bubble)'));

btn.click();
outer (capture): CAPTURING btn: AT_TARGET outer (bubble): BUBBLING

Nur direkte Klicks auf ein Overlay behandeln

// Modal schließen, wenn der Hintergrund angeklickt wird, aber nicht der Inhalt
const overlay = document.querySelector('.modal-overlay');

overlay.addEventListener('click', (event) => {
  if (event.eventPhase === Event.AT_TARGET) {
    overlay.hidden = true;
    console.log('Modal geschlossen');
  }
});
Modal geschlossen // nur bei Klick direkt auf das Overlay

eventPhase außerhalb der Weiterleitung

const event = new CustomEvent('ping', { bubbles: true });
console.log('vorher:', event.eventPhase);

document.body.addEventListener('ping', (e) => {
  console.log('während:', e.eventPhase);
});

document.body.dispatchEvent(event);
console.log('nachher:', event.eventPhase);
vorher: 0 während: 2 nachher: 0

// Wichtig · Fallstricke

  • Nur im Listener aussagekräftig: Nach der Weiterleitung wird eventPhase wieder auf 0 gesetzt. Wenn du den Wert asynchron ausliest (z. B. in setTimeout oder nach await), bekommst du deshalb immer NONE. Lies ihn synchron aus oder speichere ihn vorher.
  • AT_TARGET und Capture-Listener: Auf dem Zielelement liefern auch Listener mit capture: true den Wert 2 und nicht 1. Moderne Browser rufen Capture-Listener am Ziel vor den Nicht-Capture-Listenern auf. Ältere Browser haben sie in Registrierungsreihenfolge aufgerufen.
  • Kein Bubbling bei manchen Events: Events wie focus, blur, mouseenter oder load haben bubbles === false. Die Phase 3 tritt bei ihnen nie auf.
  • Shadow DOM: Wenn ein Event aus einem Shadow Tree kommt, wird es neu zugeordnet (Retargeting). Am Host-Element meldet eventPhase dann AT_TARGET, obwohl das eigentliche Ziel tiefer im Shadow Tree liegt.
  • Die Eigenschaft ist schreibgeschützt. Zuweisungen werden stillschweigend ignoriert, im Strict Mode lösen sie einen TypeError aus.
  • Unterstützt von allen Browsern und in Node.js (EventTarget, ab Version 15). In Node.js gibt es keinen DOM-Baum, dort kommen daher nur 0 und 2 vor.