JavaScript – M+T Pocket . Das Programmier-Handbuch (Office Einzeltitel) [Taschenbuch]

7.3
Globale Ereignisbehandlung und das event-Objekt

In JavaScript kann man auf Ereignisse nicht nur über
Event-Handler reagieren. Es gibt im Reaktionskonzept der Ereignisbehandlung ein
spezielles Objekt, dass dafür eigens bereitsteht. Obwohl die Grundlagen von
Objekten erst auf Seite 195 behandelt werden, wollen wir das Thema hier im
Zusammenhang mit den Event-Handlern angehen.

Wenn man das Verfahren verwendet, hat das einige
weitreichende Konsequenzen. Die Ereignisüberwachung wird beispielsweise direkt
in JavaScript verlagert und findet nicht mehr auf HTML-Seite statt. Statt
dessen wird von speziellen JavaScript-Routinen das Auftreten eines
Ereignisobjekts überwacht. Je nach Art des Ereignisses kann der
JavaScript-Interpreter darauf reagieren.

7.3.1 Das event-Objekt
in JavaScript

Wenn in einer Webseite ein Ereignis auftritt, wird dabei
seit JavaScript 1.1 ein eignes Objekt generiert – das event-Objekt, welches ein Unterobjekt von window ist. Das event-Objekt
beinhaltet verschiedenste Informationen über ein aufgetretenes Ereignis in
einer Webseite samt der Randbedingungen, welche dabei eine Rolle gespielt
haben.

Sie müssen sich vergegenwärtigen, dass solche event-Objekte
während der Anzeige einer Webseite im Browser permanent im Hintergrund erzeugt
werden. Unabhängig davon, ob Sie diese in Ihrem Script zur Kenntnis nehmen oder
nicht. Sie sind einfach da. In einer Webseite ist eine Situation, welche ein
solches event-Objekt
erzeugt, beispielsweise der Klick mit der Maus auf irgendeinen Bestandteil der
Webseite. Ein Mausklick erzeugt ein event-Objekt, welches folgende
Informationen enthält:

Die verwendete Taste

Eventuell gedrückte Zusatztasten

Die Koordinaten, wo der Klick erfolgte

Andere event-Objekte,
die bei anderen Ereignissen erzeugt werden, beinhalten natürlich andere
Informationen, welche dem Ereignis angepasst sind.

Nun ist es sicher nicht Sinn und Zweck eines
Ereignismodells, dass permanent Ereignisse abgefeuert und diese nie beachtet
werden (sprich darauf reagiert wird). Bei bestimmten Situationen will man ja
explizit eine Reaktion haben, d.h. es soll ein Script aufgerufen werden. Ein event-Objekt wird,
wenn man unter JavaScript darauf reagieren will, an einen Mechanismus zum
Behandeln von event-Objekten
in Form einer Message (Botschaft) weitergereicht (dazu finden Sie bei der
Behandlung von Objekten und objektorienter Programmierung mehr).

Auf welche Art und Weise auf welches erzeugte Ereignisobjekt
dann reagiert werden soll, wird durch ein abstraktes Modell geregelt – dem
Ereignismodell. Darin sind sowohl die Verhaltensweisen auf Ereignisse
festgelegt, die konkrete Syntax zur Umsetzung, aber auch erst recht diejenigen
Ereignisse, welche überhaupt zu Kenntnis genommen werden.

Die Konzepte zur Behandlung des event-Objekt werden von
Microsoft und Netscape vollkommen inkompatibel umgesetzt.

Da Ereignisobjekte während der Lebenszeit einer Webseite
permanent im Hintergrund entstehen, stehen sie auch überall im Code zur
Verfügung. Es gibt verschiedene Konzepte, auf welche Weise so ein event-Objekt
angesprochen werden kann. Sie können es einfach über seinen Namen (event) ansprechen.
Dabei müssen Sie noch angeben, von welchem Objekt aus das event-Objekt
erzeugt wurde. Die Syntax dazu ist die in der objektorientierten Programmierung
übliche Punktnotation:

[Objekt].event

Beispiel (Webseite):

document.event

Sie wollen bei einer Auswertung in der Regel dann natürlich
eine ganz bestimmte Information eines Ereignisses verwenden. Dies sind bei
einer objektorientierten Betrachtungsweise einfach die Eigenschaften des
Objektes. So können Sie etwa einen Mausklick wie folgt ansprechen:

document.event.CLICK

Dies verstehen vom Prinzip her sowohl der Internet Explorer
als auch der Netscape Navigator. Dummerweise setzen sie aber die konkrete
Implementierung völlig unterschiedlich um. Auch in der Syntax zur Überwachung
von Ereignissen (wie schon bei der Unterstützung der Event-Handler)
unterscheiden sich beide Browser.

7.3.2
Globales Auffangen der Ereignisse

Sowohl das Netscape-Objektmodell als auch das
Microsoft-Objektmodell erlauben das globale Auffangen von event-Objekten.
Sie können damit an zentraler Stelle in einer Webseite oder gar einem
ausgelagerten Script behandelt werden. Dies ist sehr sinnvoll, wenn eine
konsequente strukturelle Trennung einer Seite erreicht werden soll. Globales
Eventhandling ist damit eine logische Konsequenz der Bemühungen, Layout, Inhalt
und Scriptfunktionalitäten in einer Webseite zu entflechten.

Leider sind jedoch – wie mehrfach erwähnt – die von den
beiden großen Internet-Protagonisten angewandten Techniken nicht kompatibel .
Der Internet Explorer wird beim Laden vom Javascipt-Code, der dem
Netscape-Objektmodell entsprechend programmiert wurde, in der Regel eine
Fehlermeldung bringen oder es ignorieren. Analog ist die Situation im Navigator
beim Laden von JavaScriptcode nach der Microsoft-Variante – Ignoranz oder
Fehler. Aus diesem Grund soll auch ausdrücklich von der Verwendung einer
globalen Ereignisbehandlung abgeraten werden, wenn nicht zwingende Gründe dafür
sprechen. Dann aber muss (!!) nach Browsern getrennt werden. Und das nicht nur
einfach, indem zwischen dem Netscape Navigator und dem Internet Explorer
unterschieden wird. Eine explizite Behandlung verschiedener Versionen eines
Browsers und natürlich aller wichtigen Plattformen und der sonst noch wichtigen
Browsern ist unumgänglich. Insbesondere muss für jede irgendwie relevante Browser-Konstellation
die unterstützte Variante des globalen Ereignissystems bekannt sein oder
nachgeschaut werden. In diesem Buch werden die Ereignismodelle nur schematisch
erklärt (ohne konkrete Beispielen).

Das Netscape-Ereignismodell

Unter dem (alten) Netscape-Modell können Sie über eine zum window-Objekt
gehörende Methode bewirken, dass alle dort als Parameter spezifizierten
Ereignisse eines spezifizierten Typs innerhalb eines bestimmten Objektes (etwa
einer ganzen Webseite) zentral behandelt werden. Dies ist die Methode captureEvents(), die wie folgt angewandt wird:

[Objekt].captureEvents([Ereignistyp])

Wenn so eine Zeile im JavaScript-Code notiert wird, werden
alle spezifizierten Ereignisse, die bei dem vorangestellten Objekt auftreten,
aufgefangen und an eine zentrale Stelle weitergeleitet – der zentralen
Ereignisbehandlungsroutine. Dies ist in diesem Fall einfach eine Funktion,
welche als Argument das erzeugte event-Objekt mit der gewünschten Eigenschaft verwendet.
Als Ereignistyp können die bei einem Objekt von Netscape unterstützen
Event-Handler verwendet werden. Das Netscape-Ereignismodell unterstützt die
folgenden Events bzw. Event-Handler in den beschriebenen Situationen:

Ereignis

Zugehörige Elemente

Abgefeuert bei

Event-Handler

Abort

Images

Abbruch des Ladens eines Bilds.

onAbort

Blur

Browserfenster und alle Formularelemente

Entfernen des Eingabefokus durch den User.

onBlur

Change

Textfelder, Textareas, Select-Listen

Wertveränderung des Elements durch den User.

onChange

Click

Buttons, Radiobutton, Checkboxen,
Submit-Button, Reset-Button, Links

User-Klick auf ein Element oder Link.

onClick

DragDrop

Das Browserfenster

Der User zieht ein Objekt in das Browserfenster und
lässt es los.

onDragDrop

Error

Images und Browserfenster

Fehler beim Laden eines Dokuments oder Bilds.

onError

Focus

Browserfenster und alle Formularelemente

Setzen des Eingabefokus durch den User auf ein Element.

onFocus

KeyDown

Dokumente, Bilder, Links, Textbereiche

Der User drückt eine Taste herunter.

onKeyDown

KeyPress

Dokumente, Bilder, Links, Textbereiche

Der User hält eine Taste gedrückt.

onKeyPress

KeyUp

Dokumente, Bilder, Links, Textbereiche

Der User lässt eine Taste los.

onKeyUp

Load

Dokumentenbody

Laden einer Seite.

onLoad

MouseDown

Dokumente, Button, Links

Drücken einer Maustaste

onMouseDown

MouseMove

Keine Defaultsituation

Mausbewegung

onMouseMove

MouseOut

Areas, Links

Mauszeiger bewegt sich aus dem Bereich des
client-side-Imagemap oder dem Link.

onMouseOut

MouseOver

Links

Bewegung des Mauszeigers auf dem Link.

onMouseOver

MouseUp

Dokumente, Button, Links

Loslassen einer Maustaste

onMouseUp

Move

Browserfenster

Der User oder ein Script bewegt ein Fenster.

onMove

Reset

Formulare

Der User klickt auf einen Resetbutton.

onReset

Resize

Browserfenster

Der User oder ein Script verändert eine Fenstergröße.

onResize

Select

Textfelder oder Textbereiche

Der User selektiert in einem Formular ein Eingabefeld.

onSelect

Submit

Formulare

Der User schickt ein Formular ab.

onSubmit

Unload

Dokumentenbody

Der User verlässt eine Seite.

onUnload

Tabelle 7.1: Globale Ereignisse im (alten)
Netscape-Ereignissmodell

Das Verfahren zum Auffangen und Behandeln von
Ereignisobjekten beinhaltet im wesentlichen vier Grundmethoden, die (bis auf
eine Ausnahme) beim window-,
document-,
und layer-Objekt
spezifiziert sind. Es sind einmal die bereits angesprochene Methode captureEvents()
sowie releaseEvents() (womit das
Ignorieren eines aufgefangenen Ereignisobjekts vom angegebenen Typ definiert
werden kann), routeEvent() (zum Weiter bzw. Umleiten eines aufgefangenen Ereignisobjekts zu einem angegebenen Zielobjekt) und handleEvent()
(womit das aufgefangene Ereignisobjekt explizit behandelt werden kann – diese
Methode ist beim layer-Objekt
nicht vorhanden).

Grundsätzliche Vorgehensweise bei dieser Form der
Ereignisbehandlung ist folgende:

1.
Das Auffangen eines Events wird ermöglicht.

2.
Die Definition des Event-Handlers erfolgt.

3.
Die Registrierung des Event-Handlers erfolgt.

Um das Auffangen eines Events zu ermöglichen, wird bei dem
entsprechenden Objekt (etwa window)
eine Anweisung der Art notiert:

window.captureEvents(Event.CLICK);

Das Argument der Methode captureEvents() ist eine Eigenschaft von
dem event-Objekt,
die den Typ des Ereignisses spezifiziert. Der Aufbau ist einfach das
vollständig groß geschriebene Ereignis, das per Punktnotation Event nachgestellt
wird.

Um mehrere Ereignisse aufzufangen, kann als Argument eine
Liste von solchen Eigenschaften angegeben werden. Die Eigenschaften werden mit
dem Zeichen | separiert. Um beispielsweise die Ereignisse Click, MouseDown und MouseUp
aufzufangen, muss folgendes notiert werden:

window.captureEvents(

Event.CLICK | Event.MOUSEDOWN |
Event.MOUSEUP)

Es können durchaus mehr wie eine Behandlungsfunktion
definiert werden, wenn entsprechend in der captureEvents()-Methode zugehörige
Ereignisse aufgefangen werden.

Die Definition der Event-Handler bedeutet, man definiert
eine Funktion, die das Ereignis behandelt. Das Argument e ist das Ereignisobjekt für das
Ereignis. Beispielsweise so:

function BehandleEreignis(e) {

}

Sinnvollerweise sollte die Funktion eine booleschen
Rückgabewert liefern, damit auf eine erfolgreiche Behandlung oder aber auch
einen Fehler bei der Behandlung reagiert werden kann. Ansonsten kann man hier
sehr differenzierte Vorgänge angeben, worauf wir aber verzichten wollen.

Das abschließende Registrieren des Event-Handlers läuft so
ab:

window.onClick = BehandleEreignis;

Das Ereignis, für das eine bestimmte Funktion als
Event-Handler agieren soll, wird – dem zugehörigen nachgestellt notiert – auf
der rechten Seite der Bezeichner der Event-Handler-Funktion zugewiesen. Dabei
sollte wieder beachtet werden, dass dort keine Klammern auftauchen.
Event-Handler sind Funktionsreferenzen. Deshalb dürfen bei der Zuordnung keine
(!) Klammern angegeben werden. Ansonsten würde die Funktion unmittelbar bei der
Zuordnung ausgeführt und das Ergebnis undefined zugewiesen.

Das Microsoft -Ereignismodell

Das Microsoft-Objektmodell erlaubt die zentrale Behandlung
von Ereignissen mittels der folgenden Syntax:

<SCRIPT FOR=[Objekt] EVENT=[Ereignis]

language="JavaScript">

…[Konkrete
Anweisungen]…

</SCRIPT>

Als [Ereignis]
geben Sie einfach die im vorherigen Abschnitt erklären Event-Handler an
(allerdings auf jeden Fall vollkommen klein geschrieben!). Mehr ist nicht
notwendig, um alle Ereignisse des spezifizierten Typs von dem angegebenen
Objekt zentral zu verarbeiten.

Beispiel:

<SCRIPT FOR=document EVENT=onclick

language="JavaScript">

</SCRIPT>

Innerhalb des Scripts können Sie dann auf alle Eigenschaften
des event-Objekts
zugreifen, die der Internet Explorer kennt.