Das traditionelle Event-Handling basiert darauf, dass ein Funktionsobjekt in einer Eigenschaft des Elementobjekts gespeichert wird. Wir erinnern uns an das Schema:
element.onevent = handlerfunktion;
Der Vorteil dieses Schemas ist seine Einfachheit. Will man ein Ereignis überwachen, schreibt man bloß die Handler-Funktion in eine entsprechende Element-Eigenschaft. Der größte Nachteile ist jedoch folgender: Es kann nur eine Handler-Funktion zugleich registriert werden. Denn in der Eigenschaft kann nur eine Funktion gespeichert werden. Weist man eine andere Funktion zu, überschreibt man die erste.
In manchen Fällen mag eine Handler-Funktion für ein Element und Ereignistyp ausreichen. Diese kann schließlich weitere Funktionen aufrufen, sodass nicht der gesamte auszuführende Code direkt in dieser einen Funktion stehen muss. Doch wenn verschiedene Scripte zusammenarbeiten, besteht die Gefahr, dass sie beim traditionellen Event-Handling einander in die Quere kommen.
Wenden wir uns den fortgeschrittenen Modellen für Event-Handling zu, die es problemlos erlauben, mehrere Handler-Funktionen zu registrieren.
Das bisher beschriebene traditionelle Schema stammt aus den Anfangstagen von JavaScript. Der Browserhersteller und JavaScript-Erfinder Netscape erfand das Schema einst und andere Browser übernahmen es im Zuge ihrer JavaScript-Unterstützung.
Die Entwicklung ging jedoch weiter: Bei der Standardisierung des Event-Handlings verwarf das World-Wide-Web-Konsortium das traditionelle Event-Handling. Der DOM-Standard sieht ein anderes Modell vor: Alle Elementobjekte und weitere zentrale Objekte besitzen die Methode addEventListener
(englisch für Ereignis-Überwacher hinzufügen). Will man dem Element einen Event-Handler zuweisen, so ruft man diese Methode auf.
addEventListener
Das standardisierte Schema enthält ebenfalls die drei Bestandteile Elementobjekt, Ereignistyp und Handler-Funktion. Es lautet folgendermaßen:
element.addEventListener('event', handlerfunktion, capturing);
Die Methode erwartet also drei Parameter:
'click'
, 'mouseover'
, 'load'
, 'submit'
und so weiter.Der dritte Parameter bestimmt, für welche Event-Phase der Handler registriert werden soll. Es handelt sich um einen Boolean-Parameter, d.h. sie können true
oder false
notieren.
false
steht für die Bubbling-Phase, true
für die weniger wichtige Capturing-Phase. Die genaue Bedeutung des dritten Parameters wird später erklärt werden. Standardmäßig sollten Sie hier false
notieren.
Das folgende Beispiel kennen wir bereits vom traditionellen Event-Handling. Dieses Mal nutzen wir die standardisierte Methode addEventListener
:
<!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Beispiel für addEventListener</title> </head> <body> <button id="interaktiv"> Dies ist ein Button ohne Bedeutung, aber mithilfe von JavaScript können wir ihn interaktiv gestalten. Klicken Sie diesen Button einfach mal mit der Maus an! </button> <script> function clickHandler() { window.alert('Button wurde geklickt!'); } document.getElementById('interaktiv').addEventListener('click', clickHandler, false); </script> </body> </html>
Folgendes hat sich geändert: Aus der Zuweisung
document.getElementById('interaktiv').onclick = clickHandler;
ist der Aufruf von addEventListener
geworden:
document.getElementById('interaktiv').addEventListener('click', clickHandler, false);
Das obige Beispiel funktioniert in allen modernen Browsern, jedoch nicht im Internet Explorer vor der Version 9. Die unterstützen den DOM-Standard noch nicht und die Methode addEventListener
ist ihnen unbekannt.
Der Internet Explorer unterstützt den DOM-Events-Standard erst ab Version 9. Älteren Internet-Explorer-Versionen ist die Methode addEventListener
unbekannt. Sie unterstützen stattdessen ein proprietäres Modell.
Der Hauptvorteil von addEventListener
ist, dass Sie für ein Element mehrere Handler-Funktionen für denselben Ereignistyp registrieren können. Passen wir das obige Beispiel so an, dass beim button
-Element zwei Handler statt einem registriert werden:
function meldung1() { window.alert('Erste Handler-Funktion ausgeführt!'); } function meldung2() { window.alert('Zweite Handler-Funktion ausgeführt!'); } var button = document.getElementById('interaktiv'); button.addEventListener('click', meldung1, false); button.addEventListener('click', meldung2, false);
Es werden zunächst zwei Handler-Funktionen namens meldung1
und meldung2
definiert.
Um die Wiederholung von document.getElementById('interaktiv')
zu vermeiden, suchen wir das Elementobjekt einmal heraus und speichern es in der Variablen button
. Dann werden die die Funktionen meldung1
und meldung2
als click
-Handler registriert. Wenn Sie auf den Button klicken, dann sollten nacheinander zwei Meldefenster erscheinen – und zwar in der Reihenfolge, in der die Handler mittels addEventListener
registriert wurden.
Sie können einmal mit addEventListener
registrierte Handler wieder entfernen. Dazu existiert die Schwestermethode removeEventListener
(englisch für Ereignis-Empfänger entfernen). Die Methode erwartet dieselben Parameter, die addEventListener
beim Registrieren bekommen hat: Einen String mit dem Ereignistyp, die zu löschende Handler-Funktion und schließlich einen Boolean-Wert für die Event-Phase.
Um beide im Beispiel definierten Handler für das button
-Element, meldung1
und meldung2
, wieder zu entfernen, notieren wir:
button.removeEventListener('click', meldung1, false); button.removeEventListener('click', meldung2, false);
Bevor der DOM-Standard verabschiedet wurde, erfand Microsoft eine eigene Alternative zum traditionellen Event-Handling. Diese hat sich nicht durchgesetzt und wurde nur vom Internet Explorer umgesetzt. Seit der Version 9 unterstützt der Internet Explorer den DOM-Standard. Daher ist das Microsoft-Modell noch für ältere Internet-Explorer-Versionen interessant.
Das Microsoft-Modell teilt einige Fähigkeiten mit addEventListener
und removeEventListener
, funktioniert im Detail jedoch anders und bringt einige Eigenheiten mit sich.
Das Microsoft-Modell definiert die Methode attachEvent
zum Registrieren von Event-Handlern. Elementobjekte sowie einige zentrale Objekte besitzen diese Methode. Das Schema lautet folgendermaßen:
element.attachEvent('onevent', handlerfunktion);
Die Methode erwartet zwei Parameter:
on
. Beispiele für den ersten Parameter sind 'onclick'
, 'onmouseover'
, 'onload'
, 'onsubmit'
und so weiter.Wir greifen das bekannte Beispiel auf und setzen es mit dem Microsoft-Modell um:
<!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Beispiel für attachEvent</title> </head> <body> <button id="interaktiv"> Dies ist ein Button ohne Bedeutung, aber mithilfe von JavaScript können wir ihn interaktiv gestalten. Klicken Sie diesen Button einfach mal mit der Maus an! </button> <script> function clickHandler() { window.alert('Button wurde geklickt!'); } document.getElementById('interaktiv').attachEvent('onclick', clickHandler); </script> </body> </html>
Das Beispiel hat sich gegenüber dem DOM-Standardmodell nur geringfügig geändert. Anstelle von document.getElementById('interaktiv').addEventListener(…)
wurde document.getElementById('interaktiv').attachEvent(…)
notiert.
Der Ereignistyp im ersten Parameter enthält nun den Präfix on
: Aus 'click'
wird 'onclick'
. Der dritte Parameter, der die Event-Phase angibt, fällt weg. Denn Microsofts Modell unterstützt nur das Registrieren in der Bubbling-Phase.
Auch mit attachEvent
können Sie verschiedene Handler für denselben Ereignistyp definieren. Das obige Beispiel wird entsprechend angepasst:
function meldung1() { window.alert('Erste Handler-Funktion ausgeführt!'); } function meldung2() { window.alert('Zweite Handler-Funktion ausgeführt!'); } var button = document.getElementById('interaktiv'); button.addEventListener('onclick', meldung1); button.addEventListener('onclick', meldung2);
Das Beispiel enthält nichts neues, die Aufrufe von addEventListener
wurden auf die besagte Weise durch attachEvent
ausgetauscht.
Auch das Microsoft-Modell bietet eine Methode, um registrierte Handler wieder zu entfernen. Sie nennt sich detachEvent
und erwartet dieselben Parameter wie sein Gegenstück attachEvent
.
Um die besagten click
-Handler meldung1
und meldung2
wieder zu entfernen, notieren wir:
button.detachEvent('onclick', meldung1); button.detachEvent('onclick', meldung2);
Das Microsoft-Modell bringt eine erfreuliche und eine unerfreuliche Besonderheit mit sich:
attachEvent
gestaltet sich der Zugriff auf das Event-Objekt einfacher, als wir es vom traditionellen Event-Handling gewöhnt sind. Dort war der Zugriff über window.event
nötig. Bei der Benutzung von attachEvent
wird das Event-Objekt der Handler-Funktion als Parameter übergeben, wie wir es aus anderen Browsern gewohnt sind und wie es auch beim im DOM-Standard vorgeschrieben ist.this
kennengelernt, um das Element anzusprechen, bei dem die gerade ausgeführte Handler-Funktion registriert wurde. Das ist im Zusammenhang mit attachEvent
nicht möglich, denn this
zeigt nicht auf das gewünschte Objekt, sondern stets auf das globale Objekt window
– und ist damit unbrauchbar.Wir haben drei Modelle und deren Detailunterschiede kennengelernt. Sie werden sich sicher fragen, welches Sie nun in der Praxis ohne Bedenken anwenden können.
Mittlerweile unterstützen alle relevanten Browser den DOM-Standard. Das heißt, Sie können problemlos addEventListener
und removeEventListener
sowie event.target
und event.currentTarget
(siehe Arbeiten mit dem Event-Objekt) verwenden.
Der Internet Explorer vor Version 9 unterstützt den DOM-Standard nicht. Diese Versionen sind allerdings nicht mehr stark verbreitet. Falls Sie diese Versionen dennoch unterstützen müssen, so sollten Sie eine Bibliothek verwenden, die das browserübergreifende Registrieren von Event-Handlern ermöglicht. Ein Beispiel ist jQuery 1.x.