Wie macht man es besser?
bearbeitet von ( HAL )Hallo TS
> Ich habe zwar auch [von molily eine ausführlichere Erläuterung ](http://molily.de/js/event-handling-effizient.html#capturing) gefunden, aber verstanden habe ich nun selber trotzdem noch nichts. Was bewirkt das dritte Funktionsargument (Capturing)?
Molily hat es doch recht gut beschrieben, da wüsste ich ehrlich nicht, was ich da noch groß hinzufügen sollte. ;-)
Stell es dir einfach so vor:
Jedes Event hat _wenigstens_ zwei und _meistens_ drei Phasen:
| Capturing-Phase | Target-Phase | Bubbling-Phase |
----------------> -------------> -------------->
Beim _Capturing_ durchläuft das Event, ausgehend von _Window_ die ganze DOM-Hierarchie, bis es beim Zielelement angekommen ist, und innerhalb dieser Phase werden auf dem Weg alle für den entsprechenden Event-Typ hinzugefügten Handler ausgelöst, für die `Capture = true` gesetzt ist.
Da Capturing aber per Default auf _false_ gesetzt ist, passiert in dieser Phase normalerweise nichts.
Wenn dann die _Target-Phase_ erreicht ist, wird der für das Zielelement angelegte Handler ausgelöst, und wie es dann weitergeht, dass hängt davon ab. ;-)
Entweder es handelt sich um ein Event, dass über _keine_ Bubbling-Phase verfügt, weil es semantisch an das Zielelement gebunden ist, wie etwa 'load', 'focus', 'blur' usw., dann ist hier Schluss.
Ebenso ist die Geschichte zu Ende, wenn das Event-Bubbling durch `event.stopPropagation( );`{: .language-javascript} _unterbunden_ wurde.
Gibt es hingegen bei dem Event-Typ eine Bubbling-Phase und wurde diese auch nicht händisch unterbunden, dann beginnt hier der gleiche Prozess wie in der Capturing-Phase von vorne, nur umgekehrt.
Das heißt, das Event durchläuft - diesmal _ausgehend_ - vom Zielelement den DOM-Baum bis hoch zu Window, und löst dabei alle Event Handler aus, die auf dem Weg dorthin für diesen Event-Typ gesetzt wurden.
> Wie könnte man das vereinfachen? Wie meinst Du das mit dem "Bubbeling"?`
Mit Vereinfachen meinte ich, dass du dir das Event-Bubbling insofern zu Nutze machen kannst, als dass du statt für jedes einzelne Element einen Event Listener anzumelden, du den Listener auch an ein Element knüpfen kannst, welches _höher_ in der Hierarchie ist, wie bspw. `body`, oder eben das nächste Vorfahrenelement, für das es im Gesamtkontext sinnvoll ist.
Beispiel:
~~~ javascript
var body = document.getElementsByTagName('body')[0];
body.addEventListener('click', function (e) {
if (e.target.tagName === 'button' && e.target.innerHTML === 'frei') {
// etc...
}
});
~~~
An die Callback-Funktion wird als Argument immer das Event-Objekt übergeben, also das Zielelement, welches du innerhalb der Funktion mit `e.target` ansprechen kannst.
Auf die Art setzt du den Event Listener also beispielsweise nur _einmal_, statt für jedes Element einzeln, und selektierst dann wie gewohnt innerhalb der Callback-Funktion. - Was einem eben einiges an Schreibarbeit sparen kann. ;-)
Gruß,
HAL
Wie macht man es besser?
bearbeitet von ( HAL )Hallo TS
> Ich habe zwar auch [von molily eine ausführlichere Erläuterung ](http://molily.de/js/event-handling-effizient.html#capturing) gefunden, aber verstanden habe ich nun selber trotzdem noch nichts. Was bewirkt das dritte Funktionsargument (Capturing)?
Molily hat es doch recht gut beschrieben, da wüsste ich ehrlich nicht, was ich da noch groß hinzufügen sollte. ;-)
Stell es dir einfach so vor:
Jedes Event hat _wenigstens_ zwei und _meistens_ drei Phasen:
| Capturing-Phase | Target-Phase | Bubbling-Phase |
----------------> -------------> -------------->
Beim _Capturing_ durchläuft das Event, ausgehend von _Window_ die ganze DOM-Hierarchie, bis es beim Zielelement angekommen ist, und innerhalb dieser Phase werden auf dem Weg alle für den entsprechenden Event-Typ hinzugefügten Handler ausgelöst, für die `Capture = true` gesetzt ist.
Da Capturing aber per Default auf _false_ gesetzt ist, passiert in dieser Phase normalerweise nichts.
Wenn dann die _Target-Phase_ erreicht ist, wird der für das Zielelement angelegte Handler ausgelöst, und wie es dann weitergeht, dass hängt davon ab. ;-)
Entweder es handelt sich um ein Event, dass über _keine_ Bubbling-Phase verfügt, weil es semantisch an das Zielelement gebunden ist, wie etwa 'load', 'focus', 'blur' usw., dann ist hier Schluss.
Ebenso ist die Geschichte zu Ende, wenn das Event-Bubbling durch `event.stopPropagation( );`{: .language-javascript} _unterbunden_ wurde.
Gibt es hingegen bei dem Event-Typ eine Bubbling-Phase und wurde diese auch nicht händisch unterbunden, dann beginnt hier der gleiche Prozess wie in der Capturing-Phase von vorne, nur umgekehrt.
Das heißt, das Event durchläuft - diesmal _ausgehend_ - vom Zielelement den DOM-Baum bis hoch zu Window, und löst dabei alle Event Handler aus, die auf dem Weg dorthin für diesen Event-Typ gesetzt wurden.
> Wie könnte man das vereinfachen? Wie meinst Du das mit dem "Bubbeling"?`
Mit Vereinfachen meinte ich, dass du dir das Event-Bubbling insofern zu Nutze machen kannst, als dass du statt für jedes einzelne Element einen Event Listener anzumelden, du den Listener auch an ein Element knüpfen kannst, welches _höher_ in der Hierarchie ist, wie bspw. `body`, oder eben das nächste Vorfahrenelement, für das es im Gesamtkontext sinnvoll ist.
Beispiel:
~~~ javascript
var body = document.getElementsByTagName('body')[0];
body.addEventListener('click', function (e) {
if (e.target.tagName === 'button' && e.target.innerHTML === 'frei') {
// etc...
}
});
~~~
An die Callback-Funktion wird als Argument immer das Event-Objekt übergeben, also das Zielelement, welches du innerhalb der Funktion mit `e.target` ansprechen kannst.
Auf die Art setzt du den Event Listener also beispielsweise nur _einmal_, statt für jedes Element einzeln, und selektierst dann wie gewohnt innerhalb der Callback-Funktion, was einem eben einiges an Schreibarbeit sparen kann. ;-)
Gruß,
HAL