In diesem Beitrag beschäftigen wir uns mit dem Thema EventListener. Dabei geht es darum Events via. EventListener abzufangen und bestimmte Aktionen auszuführen.
Das ist gerade für die dynamische Programmierung im Browser zwingend notwendig um Aktionen ohne ein Neuladen der Seite ausführen zu können.
Ein Event ist eine Aktion, das kann ein Klick, ein Tastaturanschlag, ein Touch oder auch das Scrollen auf einer Webseite sein. Diese Events lösen bestimmte Aktionen aus wie zum Beispiel das Scrollen. Zusätzlich kann man auf diese JavaScript Events hören, um weitere Aktionen auszuführen.
Ein EventListener ist eine Methode in JavaScript, um auf Events zu hören. Sobald ein Event ausgelöst wird, hört ein Listener zu, an diesen werden die Event-Eigenschaften übergeben, als “Event” Objekt. Mit diesem Event Objekt kann man verschiedenste Aktionen und Handlungen ausführen für eine dynamische Webseite
Um ein EventListener zu verwenden, brauchen wir drei verschiedene Komponenten. Wir brauchen ein Event auf das wir hören wollen. Wir brauchen ein Element an diesem das Event ausgeführt werden soll und zu guter Letzt brauchen wir eine Funktion, die nun ausgeführt werden soll.
Als erstes kleines Beispiel fügen wir einem div
ein Listener zum Klicken hinzu und ändern dann die Farbe des Elements bei jedem Klick.
Als Erstes selektieren wir unser Element, in dem Fall mittels QuerySelector. Anschließend prüfen wir, ob unser Element vorhanden ist, falls nicht, wird der Listener nicht registriert, da das zu Fehlern führen würde. Anschließend rufen wir die Methode addEventListener
auf und registrieren das Event Click. Nun folgt eine Arrow Function (ES6 Syntax) dort definieren wir die Funktionalität, die bei einem Klick ausgeführt werden soll.
Du kannst die Funktion auch auslagern und diese dort nur als Parameter übergeben, das ist gerade dann sinnvoll, wenn du die Funktion an mehreren Stellen benötigst wird oder das Event wieder entfernen willst bei bestimmten Situationen.
Die Variable e ist immer das Event Objekt, dieses hat verschiedene Eigenschaften. Diese Variable mit dem Namen e zu bezeichnen kann man inzwischen schon als Standard ansehen. Die Eigenschaft target
enthält immer das aktuelle Element, das angeklickt wurde. Vorsicht wenn das Element noch ein Kind-Elemente hat, ist das Target je nach Situation auch mal das Kind-Element, weshalb du dort noch anders vorgehen solltest. Mehr dazu später unter Event Bubbeling und Event Capture.
let div = document.querySelector('#clickListener');
if(div){
div.addEventListener('click',e => {
let target = e.target;
if(target.style.backgroundColor == "rgb(27, 31, 33)"){
target.style.backgroundColor = "rgb(239, 65, 54)";
}else{
target.style.backgroundColor = "rgb(27, 31, 33)";
}
});
}
Um Events nur einmalig auszuführen, kannst du die once
Option verwenden. Dann wird die Funktion nur einmal aufgerufen.
div.addEventListener('click', e => {
/* ... */
},{once: true});
Manchmal willst du das Event nicht nur auf eine einmalige Ausführung begrenzen, sondern auch auf eine bestimmte Anzahl an Verwendungen oder es an einem bestimmten Punkt wieder zu deaktivieren. Die Methode removeEventListener
kann dir dabei helfen. Wichtig ist, du musst hier die Funktion auslagern und auch die Option Parameter wie once
oder capture
exakt gleich setzen, sonst kann das zu Schwierigkeiten beim Entfernen des Events führen. Beachte, dass die Browser hier unterschiedlich in der Interpretation sein können deshalb ist es am besten die gleichen Eigenschaften wie beim Hinzufügen des Events zu verwenden.
Einmal eine Version des ersten Beispiels angepasst, für den neuen Use Case zeigt, dass auch ein removeEventListener möglich ist. Dabei ist zu beachten, es verhält sich jetzt so als wäre die Option once
gesetzt. Da der clickHandler ausgeführt wird, wird am Ende der Listener wieder entfernt.
let div = document.querySelector('#clickListener');
if (div) {
div.addEventListener('click',_clickHandler);
}
function _clickHandler(e){
let target = e.target;
if (target.style.backgroundColor == "rgb(27, 31, 33)") {
target.style.backgroundColor = "rgb(239, 65, 54)";
} else {
target.style.backgroundColor = "rgb(27, 31, 33)";
}
target.removeEventListener('click',_clickHandler);
}
Ein weiterer Vorteil, dadurch das du die Funktion nun ausgelagert hast, ist, dass du die Funktion für andere Aktionen erneut verwenden kannst.
Der Unterschied zwischen der Capture und der Bubbel Methode ist, dass bei der Bubbel Methode erst das Event des geklickten Elements ausgelöst wird. Bei der Capture Methode wird als erstes Event das äußerste Event ausgelöst und dann zum innersten vorgearbeitet.
In der Beispielgrafik wurde das grüne Element angeklickt und es wurde für jedes der Elemente sowohl Capture als auch das Standard “Bubbel” Event registriert. Wodurch du nun erkennen kannst, in welcher Rangfolge die Elemente ausgelöst werden.
Für eine Capture Event muss zusätzlich dieses als Option angegeben werden, diese kann so aussehen:
zero.addEventListener('click',e => {
appendText('1. ebene 0 - red - capture');
},{capture: true});
Das besondere ist e.target
, das zeigt immer auf das direktangeklickte Element, auch wenn ein äußeres Event ausgelöst wird. Dadurch ist bei allen sechs Events das gleiche Element das Target. Deshalb muss du immer darauf achten, wann du welches Event auslösen willst.
Das bedeutet, selbst wenn das grüne Element kein Event hat, aber das rote und orange, dann wird 1. , 2. , 5. und 6. ausgelöst. Aber das Target bleibt das grüne Element. Dadurch solltest du, wenn du mit dem Target Attribute Arbeiten willst, immer prüfen welches Element genau angeklickt wurde.
Wenn du zum Beispiel den Fall hast, dass du nur bis zum grünen Capture Event die Events ablaufen willst, dann kannst du die Methode e.stopPropagation();
verwenden. Damit werden keine nachfolgende Events, seien es Capture oder Bubbel Events, ausgeführt.
Ein interaktives Beispiel wo du auch selber einmal am Code ausprobieren kannst, was stopPropagation so bewirkt, findest du auf CodePen.
Meine Variante um immer das richtige Element zu bekommen, wenn ich als Target das Element des Events benötige und nicht das angeklickte Element, so prüfe ich im ersten Schritt, ob Target dem Element des Events entspricht und falls nicht, nutze ich die closest
Methode, da ich in 99 % der Fälle mit Bubbel Events arbeite.
In diesem Fall haben wir eine Abfrage, ob das Target ein a
Tag ist, falls nicht, soll bitte das nächste a
, was außerhalb liegt, gefunden werden und als Target definiert werden, anderenfalls wird das e.target als Element genommen. Das trifft beispielsweise ein, wenn im a
noch ein
span
für einen zusätzlichen Hinweis vorhanden ist und dieses angeklickt wird.
let a = document.querySelector('a');
if(a){
a.addEventListener('click',(e) => {
e.preventDefault();
if(e.target.tagName != "A"){
target = e.target.closest('a');
}else{
target = e.target;
}
target // Element a
})
}
Neben den Events die über EventListener registriert werden können gibt es noch Standard Events wie zum Beispiel das Form Submit oder das Anklicken von einem Link.
Manchmal ist es notwendig, dass man diese Events nicht verwenden will bzw. ein eigenes Event zum Beispiel auf einen Link legen. Um die Standardevents des Browsers nun zu verhindern, kannst du e.preventDefault()
verwenden.
Noch einmal ein Beispiel wo der selektierte Link nicht geöffnet wird, durch die Verwendung von preventDefault
.
let a = document.querySelector('a');
if(a){
a.addEventListener('click',e => {
e.preventDefault();
alert('Der Link wird nicht geöffnet');
});
}
Ich persönlich habe diesen Fall zum Beispiel auch häufig bei Formularen um das Versenden zu verhindern und erst einmal eine Validierung mittels JavaScript vorher auszuführen.
Es gibt einige Events in JavaScript, die du verwenden kannst, hier eine kleine Übersicht von Events, die ich regelmäßig benötige.
Event Name | Event Beschreibung |
---|---|
click | Das Click Event wird wie der Name schon sagt immer bei Klick ausgelöst und kann an alle Elemente gebunden werden. |
contextmenu | Mit dem Contextmenu Event kannst du den Rechtskick abfangen und zum Beispiel ein eigenes Contextmenu bauen. |
focus | Wenn ein Element fokussiert wird, löst du automatisch das Focus Event aus. |
keydown | Das Keydown Event registriert Tastenanschläge. Sehr nützlich zum Beispiel für Custom Input Felder oder wenn die Suche dynamisch sich updaten soll, noch währende des Tippens. |
keyup | Ähnlich wie Keydown nur das Keyup eben beim Verlassen der Taste erst ausgelöst wird. |
scroll | Das Scroll Event registriert das Scrollen auf der Seite, wurde früher zum Beispiel auch für das LazyLoading verwendet, wobei das inzwischen mit dem Mutation Observer besser funktioniert. |
touchstart | Mit touchstart kannst du erkennen, wenn der Nutzer ein Element gebucht hat, diese wird vom Mausklick noch einmal differenziert. Wobei das Click Event auch das Touchen grundsätzlich erkennt. |
submit | Das Submit Event gibt es nur bei Formularen, damit kannst du entsprechend erkennen, ob das Formular versendet werden soll. |
play | Das Play Event wird bei Multimedia Elementen wie Video und Audio ausgelöst, sobald das Element abspielen gestartet wurde. Über die Multimedia API kannst du so zum Beispiel auch ein Custom Element für einen Audioplayer bauen. |
Alle Events hier aufzulisten hätte den Rahmen etwas gesprengt. Eine komplette und aktuelle Auflistung findest du in der Dokumentation von Mozzila.
Es gibt noch viele weitere interessante Events, die du verwenden kannst, um deine Webseite interaktiver zu gestalten. Hier habe ich dir Einblicke gegeben, wie du die verschiedenen Funktionalitäten der Methode addEventListener verwenden kannst, um eine besondere Webseite zu erstellen.
Hinterlasse mir gerne einen Kommentar zum Artikel und wie er dir weitergeholfen hat beziehungsweise, was dir helfen würde das Thema besser zu verstehen. Oder hast du einen Fehler entdeckt, den ich korrigieren sollte? Schreibe mir auch dazu gerne ein Feedback!
Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "JavaScript Basis: addEventListener Richtig Verwenden!"!