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.
addEventListenerDas 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.