Start · Sprachen · JavaScript · Referenz · Event.bubbles

Event.bubbles

Eigenschaft

Schreibgeschützter Boolean, der angibt, ob ein Ereignis nach der Zielphase im DOM-Baum nach oben zu den Vorfahren-Elementen weitergereicht wird.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

Event.bubbles

Beschreibung

Die schreibgeschützte Eigenschaft bubbles der Event-Schnittstelle gibt an, ob ein Ereignis die Bubbling-Phase durchläuft. Ist der Wert true, wird das Ereignis nach dem Auslösen am Zielelement nacheinander an alle Vorfahren bis zu document und window weitergereicht. Ist er false, endet die Weiterleitung nach der Zielphase. Die Capturing-Phase (von oben nach unten) findet jedoch in beiden Fällen statt.

Die meisten Benutzerereignisse wie click, input, keydown oder submit steigen im Baum auf. Einige wichtige Ereignisse tun das nicht, zum Beispiel focus, blur, mouseenter, mouseleave, load (auf Elementen) und scroll (auf Elementen). Dafür gibt es oft aufsteigende Gegenstücke wie focusin/focusout oder mouseover/mouseout.

Die Eigenschaft ist vor allem dann wichtig, wenn man Event-Delegation verwendet, also einen einzigen Listener auf ein Elternelement setzt, statt viele Listener auf einzelne Kindelemente. Das funktioniert nur mit Ereignissen, die aufsteigen. Bei eigenen Ereignissen, die mit new Event() oder new CustomEvent() erzeugt werden, ist bubbles standardmäßig false und muss über das Options-Objekt { bubbles: true } ausdrücklich eingeschaltet werden.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn das Ereignis im DOM-Baum aufsteigt, sonst false.

Beispiele

Prüfen, ob ein Klick-Ereignis aufsteigt

document.addEventListener('click', (event) => {
  console.log(`${event.type} bubbles:`, event.bubbles);
});

document.body.click();
click bubbles: true

Unterschied zwischen focus und focusin

const input = document.createElement('input');
document.body.append(input);

const log = (event) => console.log(event.type, event.bubbles);
input.addEventListener('focus', log);
input.addEventListener('focusin', log);

input.focus();
focus false focusin true

Eigenes Ereignis mit Bubbling für Event-Delegation

const list = document.createElement('ul');
const item = document.createElement('li');
item.textContent = 'Eintrag 1';
list.append(item);
document.body.append(list);

// Ein Listener am Elternelement fängt Ereignisse aller Kinder ab
list.addEventListener('item-selected', (event) => {
  console.log('Ausgewählt:', event.target.textContent, '| bubbles:', event.bubbles);
});

// Ohne bubbles: true würde der Listener an <ul> nie ausgelöst
const noBubble = new CustomEvent('item-selected');
item.dispatchEvent(noBubble);
console.log('Ohne Bubbling:', noBubble.bubbles);

item.dispatchEvent(new CustomEvent('item-selected', { bubbles: true }));
Ohne Bubbling: false Ausgewählt: Eintrag 1 | bubbles: true

Generischer Handler, der nicht aufsteigende Ereignisse per Capturing abfängt

const form = document.querySelector('form') ?? document.body;

const handler = (event) => {
  // Nicht aufsteigende Ereignisse erreichen das Formular nur in der Capturing-Phase
  const phase = event.bubbles ? 'Bubbling/Capturing' : 'nur Capturing';
  console.log(`${event.type} an <${event.target.tagName.toLowerCase()}> (${phase})`);
};

// capture: true sorgt dafür, dass auch 'blur' ankommt
form.addEventListener('blur', handler, { capture: true });

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung wie event.bubbles = true wird still ignoriert (im Strict Mode gibt es einen TypeError). Der Wert lässt sich nur beim Erzeugen über new Event(type, { bubbles: true }) festlegen.
  • Standardwert bei eigenen Ereignissen: new Event() und new CustomEvent() steigen standardmäßig nicht auf. Das ist ein häufiger Grund, warum delegierte Listener nicht ausgelöst werden.
  • Nicht mit stopPropagation() verwechseln: bubbles bleibt auch nach event.stopPropagation() auf true. Ob die Weiterleitung tatsächlich abgebrochen wurde, verrät die Eigenschaft nicht.
  • Shadow DOM: Damit ein aufsteigendes Ereignis die Grenze eines Shadow Root überschreitet, ist zusätzlich composed: true nötig.
  • Nicht aufsteigende Ereignisse lassen sich trotzdem an einem Vorfahren abfangen, wenn man den Listener mit { capture: true } registriert.
  • Die Eigenschaft wird von allen Browsern unterstützt. Das veraltete event.initEvent(type, bubbles, cancelable) sollte man nicht mehr verwenden, sondern den Konstruktor nutzen.