Zusammenfassung:
En DOM
Spezifikation beschrieben in:
https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
funktioniert auf folgende Weise:
Ein Ereignis wird auf einem Pfad von der Wurzel ( document
) des Baumes zum Zielknoten . Der Zielknoten ist der am tiefsten liegende HTML
Element, d.h. das event.target. Die Ereignisauslösung (auch Ereignisfortpflanzung genannt) erfolgt in drei Phasen und in der folgenden Reihenfolge:
- Die Erfassungsphase: wird das Ereignis an die Vorfahren des Ziels von der Wurzel des Baums aus weitergeleitet (
document
) auf den direkten Elternteil des Zielknotens.
- Die Zielphase: wird das Ereignis an den Zielknoten weitergeleitet. Die Zielphase liegt immer auf dem tiefsten
html
Element, bei dem das Ereignis ausgelöst wurde.
- Die Blasenbildungsphase: wird das Ereignis an die Vorfahren des Zielknotens vom direkten Elternteil des Zielknotens bis zur Wurzel des Baums weitergeleitet.
Beispiel:
// bubbling handlers, third argument (useCapture) false (default)
document.getElementById('outerBubble').addEventListener('click', () => {
console.log('outerBubble');
}, false)
document.getElementById('innerBubble').addEventListener('click', () => {
console.log('innerBubble');
}, false)
// capturing handlers, third argument (useCapture) true
document.getElementById('outerCapture').addEventListener('click', () => {
console.log('outerCapture');
}, true)
document.getElementById('innerCapture').addEventListener('click', () => {
console.log('innerCapture');
}, true)
div:hover{
color: red;
cursor: pointer;
}
<!-- event bubbling -->
<div id="outerBubble">
<div id="innerBubble">click me to see Bubbling</div>
</div>
<!-- event capturing -->
<div id="outerCapture">
<div id="innerCapture">click me to see Capturing</div>
</div>
Das obige Beispiel verdeutlicht den Unterschied zwischen Event Bubbling und Event Capturing. Beim Hinzufügen der Ereignis-Listener mit addEventListener
gibt es ein drittes Element namens useCapture. Dieses a boolean
die bei Einstellung auf true
ermöglicht es dem Ereignis-Listener, anstelle von Event-Bubbling Event-Capturing zu verwenden.
Wenn wir in unserem Beispiel das Argument useCapture auf false
sehen wir, dass das Event Bubbling stattfindet. Zunächst wird das Ereignis in der Zielphase ausgelöst (logs innerBubble), und dann wird über Event Bubbling das Ereignis im übergeordneten Element ausgelöst (logs outerBubble).
Wenn wir das Argument useCapture auf true
sehen wir, dass das Ereignis in der äußeren <div>
wird zuerst abgefeuert. Dies liegt daran, dass das Ereignis jetzt in der Erfassungsphase und nicht in der Blasenbildungsphase ausgelöst wird.