Javascript EventListener: capture oder bubble?

Wenn sowohl ein Element als auch Vorfahren des Elements für ein Event registriert sind, erreicht das Event zuerst den Vorfahren und wandert dann zu den Nachkommen? Oder wird das Ereignis zuerst an das Element und dann an die Vorfahren gemeldet?

Javascript addEventListener Warten auf ein Event

Die Reise eine Events über die Elemente des DOM

Wenn ein Ereignis wie der Klick auf einen Button registriert wird, betrifft das Ereignis nicht nur den Button. Ein Klick auf einen Button triff nicht nur den Button, sondern implizit auch ein »darunter liegendes« Element wie ein div, unter dem das body-Element liegt und unter dem wiederum das documentElement und am Ende das Window sitzt.

JavaScript Event Listener bubble

Ein Äquivalent dazu: Wenn ich auf den Teppich trete, trete ich auch auf den Holzboden darunter, unter dem wiederum der Estrich ist.

<body>
	<main>
		<button id=button>Klick mich</button>
	</main>
…
</body>

Events reisen vom Root zum Element

Aus der Sicht des DOM reist ein Ereignis in der Capture-Phase vom ROOT des Dokuments zu seinem Ziel und benachrichtigt auf dem Weg nach unten jedes Element. Liegt für die betroffenen Elemente auf dem Weg zum getriggerten Element kein eventListener an, überhören die Elemente das Event.

Schema Event capturing und bubbling
Event capturing und bubbling
Ein Event beginnt nicht auf dem getriggerten Element,
sondern am ROOT,
und reist im DOM-Baum nach unten.

Wenn es die Art des Ereignisses erlaubt, steigt das Ereignis in einer Bubbling-Phase durch den Baum zurück nach oben und könnte in der Bubbling-Phase ebenfalls jedes Element auf dem Weg nach oben triggern.

                               capture  -----┐
                                             │
                                             ▼
button.addEventListener ("click", alertMe, true);
button.addEventListener ("click", alertMe, false);
                                             ▲
                                             │
                                bubble   ----┘
			

Der dritte Parameter von addEventListener – useCapture – legt fest, in welcher Phase ein Event einen Event Listener aktiviert.

Capture
true Zuerst die Event Handler von Vorfahren aufrufen, dann erst den Event Handler des Elements
Bubble
false (default) Zuerst den Event Handler des Elements aufrufen, erst dann die Event Handler von Vorfahren

Bubbling Phase

Wenn ein Skript Ereignisse auf verschachtelten HTML-/XML-Elementen registriert, die auf dasselbe Ereigniss warten, führt der Browser beim Bubbling die innerste Registrierung zuerst aus und arbeitet sich dann nach oben vor.

<div class="root">
	<div class="middle">
		<div class="inner">
			<button class="btn">inneres Element</button>
		</div>
	</div>
</div>
root
middle
inner

			

Event delegation ist eine elegante Methode und macht sich das Event Bubbling zunutze: Statt einen EventListener auf jedes Element zu setzen, bindet Event Delegation den Event Listener an das Parent Element.

Capturing Phase

Beim Capturing {useCapture: true} behandelt der Browser das Ereignis auf dem Weg »nach unten«. Das oberste Element mit einem eventListener meldet das das Event zuerst. Wenn das Event bei seinem Ziel, dem target, angekommen ist, reist das Event in der bubble-Phase zurück zum Element nach oben.

root
middle
inner




			
Wir ziehen heute fast immer bubble (false) vor.
Für moderne Skripte macht es selten Sinn, ein Event von mehreren Event Handlern behandeln zu lassen. Wenn wir auf ein Element klicken, erwarten wir eine Aktion auf diesem Element. Darum wird jedes Event in einem eigenen Skript behandelt.

Also können wir den dritten Parameter meist fallen lassen – bubble (false) ist der Default-Wert – und der dritte Parameter ist optional.

Nach oben

Wenn der Event Listener jedoch auch auf den Elementen über dem getriggerten Element liegt – so z.B. auf den Elemente dieser verschachtelten HTML-Liste –, ist capture angebracht, um das Ereignis an der korrekten Stelle zu empfangen.

bubble false
 
  • Element 1
  • Element 2
    • Element 3
    • Element 4
  • Element 5
    • Element 6
    • Element 7
      • Element 8
      • Element 9
  • Element 10
bubble true – capture
 
  • Element 1
  • Element 2
    • Element 3
    • Element 4
  • Element 5
    • Element 6
    • Element 7
      • Element 8
      • Element 9
  • Element 10

Bubble: Bei einem Klick auf einen Text der ersten Liste reagiert das Parent-Element,
Capture: Bei einem Klick auf ein Element der zweiten Liste nur das Element selber. Darum zeigt die dunkle Konsole über der Liste bei einem Klick auf Element 9 den Text Element 5, ein Klick auf die bubble:true-Liste den Text Element 9.

Suchen auf mediaevent.de