Webdesign mit CSS, HTML und Javascript
Stil mit {stil}
![]() Besser fotografieren: Schärfe kommt vom Objektiv foto.5lux.de Online-Magazin für Fotografie und Bildbearbeitung |
Okt 2008
Javascript EventListener des W3C • Event Handler registrieren
Das DOM gibt uns eine zentrale Funktion, bei der wir Events und die dazugehörigen Aktionen registrieren: den Event Listener.
In IE gibt es anstelle des Event Listeners eine ähnliche Methode, die ein Element auf ein Event vorbereitet – attachEvent – mit ebenfalls ähnlichen Argumenten.
Event Listener des DOM
elem.addEventListener(eventType, <-- EventType (z.B. click o. mouseover) handler, <-- aufzurufende Funktion useCapture); <-- Phase der Aktivierung
attachEvent in IE
elem.attachEvent (event, <-- EventType (z.B. click o. mouseover) handler); <-- aufzurufende Funktion
In IE muss das Ereigniss mit "on" beginnen. Das dritte Argument useCapture entfällt, da IE nur Event-Bubbling implementiert.
Event Handler vom Ereigniss abkoppeln
Zu addEventListener / attachEvent gibt es ein Gegenstück removeEventListener bzw detachEvent, das den Event Handler wieder vom Event entbindet:
elem.removeEventListener(eventType,
handler,
useCapture);
elem.detachEvent(event,
handler);
Cross-Browser-Registrierung von Ereignissen
Die Konzepte des Event Listeners bzw. attachEvent sind sich ähnlich genug, um die Differenzen unter einer einfachen Funktion zu verstecken. Ein Script muss prüfen, welches der beiden Konzepte vom Browser unterstützt wird – addEventListener vom W3C oder attachEvent in IE.
/** * John Resig, erklärt auf Flexible Javascript Events */ function addEvent( obj, type, fn ) { if (obj.addEventListener) { obj.addEventListener( type, fn, false ); } else if (obj.attachEvent) { obj["e"+type+fn] = fn; obj[type+fn] = function() { obj["e"+type+fn]( window.event ); } obj.attachEvent( "on"+type, obj[type+fn] ); } } function removeEvent( obj, type, fn ) { if (obj.removeEventListener) { obj.removeEventListener( type, fn, false ); } else if (obj.detachEvent) { obj.detachEvent( "on"+type, obj[type+fn] ); obj[type+fn] = null; obj["e"+type+fn] = null; } }
Das onload-Problem
An einem generellen Problemfeld ändert auch der eventListener des W3C nichts: Sowohl mit addEventListener als auch mit attachEvent kann der Handler erst ausgeführt werden, wenn das Tag des Elements im Browser geladen wurde. Die Funktion muss innerhalb einer Funktion aufgerufen werden, die von einem window.onload-Event Handler angestossen wurde, nachdem alle Elemente des Dokuments (das gesamte Markup, Style Sheets, Bilder und Plugins) geladen wurden. Wird ein Ereignis-Handler registriert, bevor der Browser das HTML-Element geladen hat, kommt es zu einem JavaScript-Fehler: Das Objekt ist unbekannt.
Das Warten auf das Laden des Dokuments (mit sämtlichen Bilder, Plugins ... ) führt zu einer Verzögerung bis zum Skript-Aufruf.
Cross-Browser-Registrierung von Ereignissen mit jQuery
Dem Ärger mit verschiedenen Methoden zur Registrierung von Ereignissen und damit verbundenen Aktionen entgegnet die Javascript-Library jQuery mit einem Cross-Browser-Aufruf:
$(document).ready(function() {
// dieser Code wird ausgeführt, wenn das HTML-Dokument
// geladen – also das DOM fertig aufgebaut – ist.
$("h1").text("Das DOM ist geladen und kann durchquert werden");
});
$(document).ready(function() wartet nicht einmal, bis das gesamte Dokument im Browser geladen ist, sondern tritt bereits in Aktion, wenn das HTML-Dokument geladen ist und der DOM-Baum durchquert werden kann. Das ist kürzer als die Zeit bis zum vollständigen Laden aller Dokumente einer Webseite.
Dazu muss allerdings die jQuery-Library vor allen anderen Skripten in das Dokument geladen werden.
useCapture – der Weg des Ereignisses
Der dritte Parameter der Funktion – useCapture – legt fest, in welcher Phase ein Ereignis den Beobachter aktiviert.
Aus der Sicht des DOM 2 reist ein Ereignis in einer Capture-Phase von der Wurzel des Dokuments zu seinem Ziel. Wenn es die Art des Ereignisses erlaubt, steigt das Ereignis in einer Bubbling-Phase wie eine Wasserblase durch den Baum zurück nach oben. Dabei kann jeder Knoten auf dem Weg von der Wurzel des Dokuments zum Zielknoten – dem EventTarget-Objekt – ein Beobachter sein, den das Ereignis beim Passieren in einer der beiden Phasen aktiviert.

- Wenn ein Skript Ereignisse auf verschachtelten (X)HTML-/XML-Elementen registriert, die auf dasselbe Ereigniss warten, führt der Broswer beim Bubbling die innerste Registrierung zuerst aus und arbeitet sich dann nach oben vor. Beim Capturing behandelt der Browser das Ereignis auf dem Weg »nach unten«.
<div>
<p><a href="" … >Lorem Ipsum </a></p>
</div>
Capturing
Bubbling
Ein Klick auf eines der inneren Element zeigt, in welcher Reihenfolge das Klick-Ereignis aufgenommen wird: von oben nach unten oder von unten nach oben. Das Beispiel funktioniert nicht in IE 6 / IE 7 / IE 8, der das Konzept des Event Capturings nicht unterstützt.
Mozilla, Safari, Konquerer und Opera (ab 6) implementieren die Methode addEventListener des W3C seit 2001.
var d1 = document.getElementById( 'capture' );
d1.addEventListener( "click", showDiv, true );
d1.getElementsByTagName( 'p' )[0].addEventListener( "click", showP, true );
d1.getElementsByTagName( 'a' )[0].addEventListener( "click", showA, true );
var d2 = document.getElementById( 'bubble' );
d2.addEventListener( "click", showDiv, false );
d2.getElementsByTagName( 'p' )[0].addEventListener( "click", showP, false );
d2.getElementsByTagName( 'a' )[0].addEventListener( "click", showA, false );
function showDiv( evt ) {
evt.target.appendChild(document.createTextNode(' über das DIV '));
}
function showP( evt ) {
evt.target.appendChild(document.createTextNode(' über das P '));
}
function showA( evt ) {
evt.preventDefault();
evt.target.appendChild(document.createTextNode(' über das A '));
}
Den Weg des Events abschneiden
- DOM: stopPropagation()
- Stopt den Ereignis-Fluss. Kann entweder in der Capture- oder in der Bubble-Phase benutzt werden.
- IE: stopPropagation()
- ie: stopPropagation() ist keine Methode, sondern eine Boole'sche Eigenschaft, die auf true gesetzt wird, damit das Ereignis nicht aufsteigt (bubbling)
