vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Tag 10

Mit JavaScript auf HTML-Elemente zugreifen

Heute werden wir uns anschauen, wie man aus einem JavaScript-Skript heraus auf die HTML-Elemente einer Webseite zugreift. Nebenbei werden wir uns etwas ausführlicher mit der Ereignisbehandlung unter JavaScript beschäftigen, das DOM-Modell zur Repräsentation von Webseiten kennen lernen und uns einige Lösungen für browserunabhängige Webseiten anschauen.

Die Themen im Einzelnen:

10.1 Ereignisse

Wie man Funktionen zur Bearbeitung von HTML-Ereignissen einrichtet, haben wir bereits in Kapitel 8 gesehen. Rekapitulieren wir noch einmal die wichtigsten Schritte.

Das Grundmodell der Ereignisbehandlung

Nehmen wir an, Sie wollen das Anklicken eines Bildes mit dem Aufruf eines Meldungsfensters verbinden. Im Meldungsfenster weisen Sie den Websurfer daraufhin, dass er das Bild nicht weiter anzuklicken braucht, da es nicht mit einem Hyperlink verbunden ist.

  1. Sie setzen im Header-Bereich die Funktion zur Bearbeitung des Ereignisses auf.
    <script type="text/javascript">
    function hinweis()
    {
    alert("Dieses Bild ist nicht mit einem Hyperlink verbunden!","");
    }
    </script>
  2. Sie erweitern das <img>-Tag um das Ereignis-Attribut onclick und weisen diesem die im ersten Schritt aufgesetzte Funktion als »Wert« zu.
    <body>
    ...
    <img src="mars.gif" onclick="hinweis();" />
    ...
    </body>

Besteht der Code zur Behandlung eines Ereignisses nur aus ein oder zwei Anweisungen (wie im obigen Beispiel) lohnt sich die Definition einer Ereignisbehandlungsfunktion im Grunde nicht. In so einem Fall kann man sich überlegen, ob man den Code nicht einfach direkt als Wert des Ereignis-Attributs angibt.

Wenn Sie obiges Beispiel nachprogrammieren und austesten, werden Sie feststellen, dass der Code im Internet Explorer und Netscape 6-Browser wie gewünscht funktioniert, nicht aber im Netscape Navigator 4. Der Grund hierfür ist, dass der Netscape Navigator 4 das onclick-Ereignis nicht in Kombination mit <img>-Elementen unterstützt.

Dies führt uns zu der Frage, welche Ereignisse es überhaupt gibt, für welche HTML- Elemente sie definiert sind und inwieweit sie von den verschiedenen Browsern unterstützt werden.

Die verschiedenen HTML-Ereignisse

In der HTML 4-Spezifikation sind folgende Ereignisse definiert:

Attribut

Ereignis

HTML-Elemente

onblur

Tritt ein, wenn das Element den Fokus verliert.

(Ein Element verliert den Fokus, wenn ein anderes Element den Fokus erhält, siehe onfocus)

a, area, label, input, select, textarea, button

onchange

Tritt ein, wenn das Element den Fokus verliert und sich sein Inhalt seit dem Erhalt des Fokus verändert hat.

input, select, textarea

onclick

Tritt ein, wenn der Besucher auf das Element klickt.

Gilt für die meisten Elemente

ondblclick

Tritt ein, wenn der Besucher doppelt auf das Element klickt.

Gilt für die meisten Elemente

onfocus

Tritt ein, wenn das Element den Fokus erhält (aktiviert wird).

(Ein Element erhält den Fokus, wenn es angeklickt wird oder der Fokus mit der (Tab)-Taste weitergereicht wird.)

a, area, label, input, select, textarea, button

onkeydown

Tritt ein, wenn das Element aktiviert (angeklickt) ist und der Besucher eine Taste drückt.

Gilt für die meisten Elemente

onkeypress

Tritt ein, wenn das Element aktiviert (angeklickt) ist und der Besucher eine Taste drückt und loslässt.

Gilt für die meisten Elemente

onkeyup

Tritt ein, wenn das Element aktiviert (angeklickt) ist und der Besucher eine Taste loslässt.

Gilt für die meisten Elemente

onload

Tritt ein, nachdem eine Webseite (Fenster) oder alle Frames einer Frameseite geladen wurden

body, frameset

onmousedown

Tritt ein, wenn der Besucher über dem Element eine Maustaste drückt.

Gilt für die meisten Elemente

onmousemove

Tritt ein, wenn der Besucher die Maus über dem Element bewegt.

Gilt für die meisten Elemente

onmouseout

Tritt ein, wenn die Maus aus dem Bereich des Elements herausbewegt wird.

Gilt für die meisten Elemente

onmouseover

Tritt ein, wenn die Maus über einem Element steht.

Gilt für die meisten Elemente

onmouseup

Tritt ein, wenn der Besucher über dem Element eine Maustaste loslässt.

Gilt für die meisten Elemente

onreset

Tritt ein, wenn das Formular zurückgesetzt wurde

form

onselect

Tritt ein, wenn der Besucher in einem Textfeld eine Textpassage markiert

input, textarea

onsubmit

Tritt ein, wenn das Formular abgeschickt wurde

form

onunload

Tritt ein, wenn eine Webseite aus einem Fenster oder einem Frame entfernt wird

body, frameset

Tabelle 10.1: Die HTML/Javascript-Ereignisse

Obige Liste darf man aber bestenfalls als Orientierungshilfe und Richtlinie ansehen. Mehr noch als beim Aufsetzen von HTML-Code gilt bei der JavaScript-Programmierung, dass für den Webautor letzten Endes nicht die Spezifikation, sondern die reale Unterstützung durch die Browser entscheidend ist - und hier gibt es bezüglich der unterstützten Ereignisse erhebliche Abweichungen.

Eine gute Übersicht über die verschiedenen Ereignisse und deren Unterstützung durch Internet Explorer und Netscape Navigator finden Sie auf der Webseite http://www.teamone.de/selfhtml unter »JavaScript«, »JavaScript Sprach- elemente«, »Event-Handler«. Dort finden Sie auch Beispiele zu den einzelnen Ereignissen.

Wenn Sie selbst austesten wollen, ob ein bestimmter Browser ein bestimmtes Ereignis für ein bestimmtes HTML-Element unterstützt, setzen Sie einfach eine Webseite auf, die das betreffende HTML-Element enthält und verbinden Sie das Ereignis mit dem Aufruf eines Meldungsfensters (nicht in Zusammenhang mit onfocus oder onblur).

Listing 10.1: test.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Testseite</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>

<body>
<h1>Testseite für JavaScript-Ereignisse</h1>

<p onclick="alert('Hallo');">Dies ist ein Absatz, für den das onclick-Ereignis definiert wurde. Klicken Sie auf den Absatz, um die Ereignisverarbeitung zu testen.</p>

</body>
</html>

Abbildung 10.1:  onclick-Ereignis für <p>-Tag

Rufen Sie nie im onblur-Ereignis einer Webseite (<body>-Tag) ein anderes Fenster (inklusive Meldungsfenster, Eingabeaufforderung, etc.) auf. Beim Aufrufen des neuen Fensters verliert das ursprüngliche Fenster den Fokus. Kehrt der Webbesucher zu dem ursprünglichen Fenster zurück, erhält dieses wieder den Fokus und das onblur-Ereignis wird wieder ausgeführt (mit dem Resultat, dass das andere Fenster erneut aufgerufen wird). So entsteht eine Endlosschleife, aus der der Websurfer nicht mehr ausbrechen kann.

Das onclick-Ereignis für Bilder

Die folgende Webseite zeigt dem Besucher eine Auswahl von vier Landesflaggen und fordert ihn auf, die Flagge Sri Lankas herauszufinden und anzuklicken.

Abbildung 10.2:  Webseite zu Listing 10.2

Der HTML- und JavaScript-Code dieser Webseite sieht wie folgt aus.

Listing 10.2: flaggen1.html - onclick-Ereignis für Bilder (IE und Net 6)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>

<body style="background-color: #F0F0F0">

<h1>Welche der folgenden Flaggen ist die Flagge von Sri Lanka?</h1>

<table>
<tr>
<td><img src="flag1.gif"
onclick="alert('Dies ist die Flagge des Senegal');" /></td>
<td><img src="flag2.gif"
onclick="alert('Dies ist die Flagge Japans');" /></td>
<td><img src="flag3.gif"
onclick="alert('Richtig!');" /></td>
<td><img src="flag4.gif"
onclick="alert('Dies ist die Flagge Finnlands');" /></td>
</tr>
</table>

<br />
<p>Klicken Sie einfach auf die Flagge.</p>

</body>
</html>

Im Internet Explorer 5 oder im Netscape 6-Browser funktioniert diese Webseite ganz wie geplant. Websurfer, die mit dem Navigator unterwegs sind, werden von dieser Webseite aber herbe enttäuscht, denn da der Navigator das onclick-Ereignis nicht für <img>-Tags unterstützt, werden Navigator-Nutzer vergeblich auf die einzelnen Flaggen klicken.

Will man die Navigator-Nutzer nicht ausgrenzen, gibt es zwei Möglichkeiten:

Letzteres geht nur mit einem Trick. Man muss das Bild in ein Anker-Element mit href- Attribut einschließen. Für Anker-Elemente unterstützt nämlich auch der Navigator das onclick-Ereignis.

Listing 10.3: Auszug aus flaggen1b.html - onclick-Ereignis für Bilder (IE, Nav4, Net6)

<table>
<tr>
<td><a href="#" onclick="alert('Dies ist die Flagge des Senegal');">
<img src="flag1.gif" /></></td>
<td><a href="#" onclick="alert('Dies ist die Flagge Japans');">
<img src="flag2.gif" /></></td>
<td><a href="#" onclick="alert('Richtig!');">
<img src="flag3.gif" /></></td>
<td><a href="#" onclick="alert('Dies ist die Flagge Finnlands');">
<img src="flag4.gif" /></></td>
</tr>
</table>

Beachten Sie, dass das href-Attribut in dem Anker-Element gesetzt sein muss. Damit der Browser aber nicht beim Anklicken des Bildes zu einer anderen Webseite oder Teststelle wechselt, geben wir als Wert zu href eine leere Textmarke "#" an.

Wenn Sie ein Bild in ein Anker-Element einschließen, legen die meisten Browser einen Rahmen um das Bild. Wenn Sie dies für alle gängigen Browser verhindern wollen, setzen Sie das deprecated-Attribut border auf 0: <img border="0" src=... />.

In Abschnitt 10.5 werden wir uns ausführlicher mit der Erstellung browserunabhängiger Webseiten befassen.

Argumente an Ereignisbehandlungsfunktionen übergeben

Wie jeder JavaScript-Funktion kann man auch einer Ereignisbehandlungsfunktion ein oder mehrere Argumente übergeben.

Ein speziell für die Ereignisbehandlung recht interessantes Argument ist das Schlüsselwort this. Wie Sie aus Kapitel 9.5.2 wissen, repräsentiert das Schlüsselwort this in JavaScript- Methoden das jeweils aktuelle Objekt. In der Ereignisbehandlung repräsentiert es das HTML-Element, für das das Ereignis ausgelöst wurde.

Listing 10.4: flaggen2.html - this-Argument in Ereignisfunktionen

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function falsch(elem)
{
elem.src = "falsch.gif";
}

function richtig(elem)
{
elem.src = "richtig.gif";
}

</script>
</head>

<body style="background-color: #F0F0F0">

<h1>Welche der folgenden Flaggen ist die Flagge von Sri Lanka?</h1>

<table>
<tr>
<td><img src="flag1.gif" onclick="falsch(this)" /></td>
<td><img src="flag2.gif" onclick="falsch(this)" /></td>
<td><img src="flag3.gif" onclick="richtig(this)" /></td>
<td><img src="flag4.gif" onclick="falsch(this)" /></td>
</tr>
</table>

<br />
<p>Klicken Sie einfach auf die Flagge.</p>

</body>
</html>

In diesem Beispiel werden zwei Ereignisbehandlungsfunktionen verwender - je nachdem, ob die richtige oder die falsche Flagge angeklickt wurde. Beiden Funktionen wird jeweils das auslösende HTML-Element als Argument übergeben (this) und beide Funktionen speichern dieses Element in ihrem Parameter elem. Da elem in den JavaScript-Funktionen ein <img>-Element repräsentiert, verfügt elem über eine src-Eigenschaft. Indem wir dieser Eigenschaft den URL eines anderen Bildes zuweisen, wechseln wir das Bild des <img>- Elements.

Abbildung 10.3:  Bildwechsel durch Ereignisbehandlung

Beachten Sie, dass dieses Beispiel so nicht im Navigator funktioniert (wohl aber in IE 5 und Netscape 6). Wenn Sie die Bilder in Anker-Elemente fassen und deren onclick-Ereignisse mit den Funktionen falsch() und richtig() verbinden, bezieht sich das this-Argument auf den Anker und nicht auf das darin enthaltene Bild. Man kann also nicht über den Parameter auf das Bild zugreifen, sondern muss einen ganz anderen Weg wählen, beispielsweise: document.images[0].src = "falsch.gif";. Mehr hierzu erfahren Sie in Abschnitt 10.4.

10.2 Das event-Objekt

Wenn wir eine Ereignisbehandlungsfunktion aufsetzen, wissen wir für welche Objekte und welche Ereignisse diese Funktion aufgerufen wird (wobei ein und dieselbe Funktion mit mehreren Objekte und gegebenenfalls sogar mit mehreren Ereignisse verbunden werden kann). Doch manchmal reicht diese Information nicht, um den Code der Funktion aufzusetzen. Vielleicht soll die Funktion Mausklicks in Bildern abfangen und, je nachdem in welche Bildbereiche geklickt wurde, unterschiedlich reagieren. Dann benötigen wir Informationen darüber, auf welchen Koordinaten der Mausklick erfolgte. Oder wir wollen unterscheiden, ob der Webbesucher beim Auslösen des Ereignisses die (Shift)-Taste gedrückt hat oder nicht. Zum Abfragen solcher Informationen muss man auf das event- Objekt zugreifen.

Wie man auf das Objekt zugreift, hängt davon ab, in welchem Browser die Webseite angezeigt wird. Zwar kennen sowohl der Internet Explorer als auch die Netscape-Browser ein event-Objekt, doch werden diese auf unterschiedliche Weise zur Verfügung gestellt und weisen auch uneinheitlich benannte Eigenschaften auf.

Wir werden uns im Folgenden zuerst die event-Objekt der beiden Browser-Typen anschauen und dann eine Lösung vorstellen, wie man beiden Browsern gerecht werden kann.

Das event-Objekt im Internet Explorer

Im Internet Explorer wird das event-Objekt als Eigenschaft des globalen window-Objekts zur Verfügung gestellt und ist dabei stets verfügbar.

Tritt ein Ereignis ein, aktualisiert der Browser die Eigenschaften des event-Objekts mit den Daten aus dem aktuellen Ereignis. Wir brauchen diese nur noch abzufragen:

<img src="bild.gif" onclick="demo()" 
...
function demo()
{
var xpos = window.event.offsetX;
var ypos = window.event.offsetY;
...
}

Welche Informationen uns das event-Objekt im Einzelnen zur Verfügung stellt, können Sie entnehmen.

Eigenschaft

Beschreibung

altKey

Gibt an, ob die (Alt)-Taste gedrückt war.

button

Gibt an, welche Maustaste gedrückt war.

cancelBubble

Legt fest, ob das Ereignis an übergeordnete HTML-Elemente weitergegeben werden soll.

clientX

x-Koordinate von Mausereignissen relativ zum Browserfenster

clientY

y-Koordinate von Mausereignissen relativ zum Browserfenster

ctrlKey

Gibt an, ob die (Strg)-Taste gedrückt war.

fromElement

Gibt bei mouseover- und mouseout-Ereignissen an, von welchem HTML-Element die Maus kam.

keyCode

Gibt bei gedrückter Taste den Unicode der Taste an.

offsetX

x-Koordinate von Mausereignissen relativ zum auslösenden Element

offsetY

y-Koordinate von Mausereignissen relativ zum auslösenden Element

shiftKey

Gibt an, ob die (Shift)-Taste gedrückt war.

srcElement

Das HTML-Element, für das das Ereignis ausgelöst wurde.

toElement

Gibt bei mouseover- und mouseout-Ereignissen an, zu welchem HTML-Element sich die Maus bewegt hat.

type

Typ des Ereignisses (interessant, wenn man mehrere verschiedene Ereignisse mit einer JavaScript-Funktion verbindet).

x

x-Koordinate von Mausereignissen relativ zum übergeordneten Element

y

y-Koordinate von Mausereignissen relativ zum übergeordneten Element

Tabelle 10.2: Die wichtigsten Eigenschaften des event-Objekts im Internet Explorer

Das event-Objekt in den Netscape-Browsern

In den Netscape-Browsern muss das event-Objekt als Argument an die Ereignisbehandlungsfunktionen übergeben werden.

<img src="bild.gif" onclick="demo(event)" 
...
function demo(e)
{
var xpos = e.x;
var ypos = e.y;
...
}

Welche Informationen uns das event-Objekt im Einzelnen zur Verfügung stellt, können Sie entnehmen.

Eigenschaft

Beschreibung

height

Höhe des Fensters oder Frames.

modifiers

Gibt an, welche Steuertasten während des Ereignisses gedrückt waren. (Event.SHIFT_MASK, Event.CONTROL_MASK, Event.ALT_MASK, Event.META_MASK)

layerX

x-Koordinate von Mausereignissen relativ zum übergeordneten Layer-Element1

layerY

y-Koordinate von Mausereignissen relativ zum übergeordneten Layer-Element.

pageX

x-Koordinate von Mausereignissen relativ zur Webseite.

pageY

y-Koordinate von Mausereignissen relativ zur Webseite.

screenX

x-Koordinate von Mausereignissen relativ zum Bildschirm.

screenY

y-Koordinate von Mausereignissen relativ zum Bildschirm.

target

Das HTML-Element, für das das Ereignis ausgelöst wurde.

ctrlKey

Gibt an, ob die (Strg)-Taste gedrückt war.

type

Typ des Ereignisses (interessant, wenn man mehrere verschiedene Ereignisse mit einer JavaScript-Funktion verbindet).

which

Gibt an, welche Maustaste während des Ereignisses gedrückt war.

width

Breite des Fensters oder Frames.

Tabelle 10.3: Die wichtigsten Eigenschaften des event-Objekts der Netscape-Browser

1

    Das LAYER-Element ist eine Erfindung des Netscape Navigators, mit der man Webseiten in Schichten aufbauen konnte (sozusagen als übereinanderliegende transparente Folien). Allerdings wurde es nie in den offiziellen HTML-Standard aufgenommen (dort favorisierte man die Positionierung mit Stylesheets). Im Net- scape 6-Browser wird es nicht mehr unterstützt.

Beispiel

Listing 10.5: flaggen3.html - Zugriff auf das event-Objekt

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function falsch(e)
{
if (navigator.appName.indexOf("Microsoft") != -1)
{
var elem = window.event.srcElement;
elem.src = "falsch.gif";
}
else if (navigator.appName.indexOf("Netscape") != -1
&& parseInt(navigator.appVersion) > 4)
{
var elem = e.target;
elem.src = "falsch.gif";
}
}

function richtig(e)
{
if (navigator.appName.indexOf("Microsoft") != -1)
{
var elem = window.event.srcElement;
elem.src = "richtig.gif";
}
else if (navigator.appName.indexOf("Netscape") != -1
&& parseInt(navigator.appVersion) > 4)
{
var elem = e.target;
elem.src = "richtig.gif";
}
}

</script>
</head>

<body style="background-color: #F0F0F0">

<h1>Welche der folgenden Flaggen ist die Flagge von Sri Lanka?</h1>

<table>
<tr>
<td><img src="flag1.gif" onclick="falsch(event)" /></td>
<td><img src="flag2.gif" onclick="falsch(event)" /></td>
<td><img src="flag3.gif" onclick="richtig(event)" /></td>
<td><img src="flag4.gif" onclick="falsch(event)" /></td>
</tr>
</table>

<br />
<p>Klicken Sie einfach auf die Flagge.</p>

</body>
</html>

10.3 Erweiterte Möglichkeiten zum Abfangen von Ereignissen

Bisher hatten wir stets eine feste Verbindung zwischen HTML-Element und Ereignis. Daneben gibt es aber auch die Möglichkeit, Ereignisse aus JavaScript-Code heraus auszulösen oder an übergeordnete HTML-Elemente weiterzureichen.

Ereignisse simulieren

In den meisten Fällen legen Sie als Autor einer Webseite fest, für welche HTML-Elemente welche Ereignisse bearbeitet werden, und der Besucher der Webseite löst die Ereignisse mit seiner Maus oder seiner Tastatur aus.

Es werden sich aber unter Umständen auch einmal Situationen ergeben, in denen Sie ein Ereignis selbst, über Ihren JavaScript-Code, auslösen möchten.

Im Grunde ist dies ganz einfach. Sie müssen lediglich die passende Methode des HTML- Elements aufrufen. Die Methoden zum Auslösen der Ereignisse heißen ebenso wie die Ereignisattribute allerdings ohne das »on«-Präfix. Die einzige Schwierigkeit dabei ist, einen Weg zu finden, wie Sie auf das HTML-Element, dessen Ereignis simuliert werden soll, zugreifen können.

Globale Ereignisbearbeitung im Internet Explorer

HTML-Elemente können nacheinander definiert werden, sie können aber auch ineinander verschachtelt werden (wobei das äußere Element das innere Element stets ganz einschließt). Betrachten wir zum Beispiel folgenden Code:

<body>
<p>Ereignisse können - <b>in Abhängigkeit vom Browser</b> - auf verschiedene Weise in der HTML-Elementhierarchie weitergereicht werden.</p>
</body>

Hier ist das innerste Element die fett formatierte Textpassage in den <b>-Tags. Um dieses Element liegt das <p>-Element, das selbst wieder in das <body>-Element eingeschlossen ist.

 <b>
|
<p>
|
<body>

Was bedeutet dies für die Ereignisbearbeitung?

Wenn Sie in den Text des <b>-Elements klicken, klicken Sie automatisch auch in das <p>- Element und selbstredend auch in das <body>-Element. Die Frage ist nun, welche Ereignisse beim Klick in ein inneres Element ausgelöst werden?

Der Internet Explorer benutzt das sogenannte Bubbling-Up, bei dem das Ereignis - wie eine Luftblase im Wasser - vom innersten Element zum äußersten Element hochsteigt. Wenn Sie also in obigem Beispiel in das <b>-Element klicken, prüft der IE-Browser zuerst, ob für das <b>-Element eine onclick-Bearbeitungsfunktion definiert ist. Wenn ja, ruft er diese auf. Danach prüft er, ob für das <p>-Element eine onclick-Bearbeitungsfunktion. Wenn ja, führt er auch diese aus. So geht er von innen nach außen weiter, bis er schließlich beim <body>-Element angelangt.

Damit Sie selbst ein wenig mit dem Bubbling-Up herumexperimentieren können, finden Sie auf der Buch-CD die Webseite globEvent_IE.html.

Listing 10.6: globEvent_IE.html - Ereignisverarbeitung im Internet Explorer

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Ereignisse</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function fkt_w()
{
alert("Grüsse von der Webseite!");
}
function fkt_p()
{
alert("Grüsse vom Absatz!");
}
function fkt_b()
{
alert("Grüsse vom fetten Einschub!");
}


</script>
</head>

<body onclick="fkt_w()">

<p onclick="fkt_p()">Ereignisse können - <b onclick="fkt_b()">in Abhängigkeit vom Browser</b> - auf verschiedene Weise in der HTML-Elementhierarchie weitergereicht werden.</p>

</body>
</html>

Wenn Sie verhindern wollen, dass ein Ereignis an das umliegende HTML-Element weitergereicht wird, setzen Sie in der Ereignisfunktion des letzten HTML-Elements die event-Eigenschaft cancelBubble auf true: event.cancelBubble = true;

Globale Ereignisbearbeitung im Netscape Navigator

Die Ereignisbearbeitung im Netscape Navigator ist nahezu das glatte Gegenteil zur Ereignisbearbeitung im Internet Explorer.

Hinzukommen noch einige weitere Besonderheiten.

An der Spitze der Ereignisbearbeitung stehen das window- (Browserfenster), das document- (Webseite in Browserfenster) und das layer-Objekt (Layer-Ebene in Webseite).

Um für diese Objekte Ereignisse abzufangen, muss man einen besonderen Weg einschlagen:

  1. Man weist die Ereignisbehandlungsfunktion der Ereignis-Eigenschaft der Objekte zu.
    window.onclick = fkt_w;
    document.onclick = fkt_d;
  1. Man muss den Browser explizit anweisen, die betreffenden Ereignisse für das window- bzw. document-Objekt abzufangen.

Die Webseite globEvent_Nav.html verdeutlicht, wie man im Netscape Navigator Ereignisse global abfangen kann. Sie können die Webseite auch von der Buch-CD laden und ein wenig mit der Ereignisbearbeitung im Navigator herumexperimentieren.

Listing 10.7: globEvent_Nav.html - Ereignisverarbeitung im Netscape Navigator

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Ereignisse</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function init()
{
window.captureEvents(Event.CLICK);
document.captureEvents(Event.CLICK);
window.onclick = fkt_w;
document.onclick = fkt_d;
}

function fkt_w(e)
{
alert("Grüsse vom Browserfenster!");
e.routeHandler(); // Ereignis weiterleiten
}
function fkt_d(e)
{
alert("Grüsse von der Webseite!");
e.routeHandler(); // Ereignis weiterleiten
}
function fkt_a()
{
alert("Grüsse vom Link!");
}


</script>
</head>

<body onload="init()">

<a href="#" onclick="fkt_a()"><img src="flag1.gif" /></a>

</body>
</html>

Globale Ereignisbearbeitung im Netscape 6-Browser

Der Netscape 6-Browser verwendet eine Kombination aus den Ereignisbearbeitungsmodellen des Internet Explorers und des Netscape 6-Browsers - und zwar auf zwei verschiedene Weisen.

Unterstützung der Ereignismodelle der anderen Browser

Der Netscape 6-Browser kann sowohl den IE-kompatiblen Code zum Abfangen der aufsteigenden Ereignisse als auch den Navigator-kompatiblen Code verarbeiten.

Der Netscape 6-Browser verwendet als Standardmodell der Ereignisbearbeitung das Bubbling-Modell. das heißt, die Ereignisse werden von den eingeschlossenen an die umliegenden HTML-Elemente weitergereicht. Dies gilt auch für Navigator-kompatiblen Code, dessen Ereignisse im Navigator in umgekehrter Richtung - von den umliegenden zu den eingeschlossenen Elementen - weitergereicht würden.

Eigenes Ereignismodell mit Abfangen von Ereignissen beim Ab- und Aufsteigen

Darüber hinaus definiert der Netscape-Browser ein eigenes Modell, das zwei Erweiterungen bietet:

Dieses Modell basiert darauf, dass Sie die Ereignisfunktionen mit Hilfe der HTML- Objektmethode addEventListener() einrichten.

  1. Den Code zur Verknüpfung der Ereignisfunktionen mit den Ereignissen setzt man am besten in einer eigenen Funktion auf, die beim Laden der Webseite ausgeführt wird.
    <head>
    ...
    <script type="text/javascript">
    function init()
    {
    ...

    </script>
    </head>
    <body onload="init()">
  2. Dann beschaffen Sie sich ein Objekt, dass das HTML-Element repräsentiert, dessen Ereignis Sie abfangen wollen.
  1. Für dieses Objekt ruft man dann die Methode addEventListener() auf und übergibt dieser

Wenn Sie die Ereignisse wie im Internet Explorer aufsteigend (von innen nach außen) abfangen wollen, übergeben Sie als Argument für den letzten Parameter false. Wenn Sie mit true Ereignisse beim Absteigen abfangen wollen, müssen Sie beachten, dass dies nicht mit allen Ereignissen geht, sondern nur mit den Ereignissen, die auch der Navigator unterstützt.

In Listing 10.8 sehen Sie die Adaption der Webseite globEvent_IE.html (Listing 10.6) für das Ereignismodell des Netscape-Browsers. (Beachten Sie, dass Sie die Webseite aus Listing 10.6 aber auch unverändert im Netscape-Browser ausführen können.) Listing 10.9 ist eine Adaption der Webseite globEvent_Nav.html (Listing 10.7) und demonstriert auch das Einrichten mehrerer Ereignisfunktionen für ein Ereignis sowie das Abfangen beim Ab- und Aufsteigen.

Listing 10.8: globEvent_Net6a.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Ereignisse</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function init()
{
obj = document.getElementById("body");
obj.addEventListener("click", fkt_w, false);
obj = document.getElementById("absatz");
obj.addEventListener("click", fkt_p, false);
obj = document.getElementById("fett");
obj.addEventListener("click", fkt_b, false);
}

function fkt_w()
{
alert("Grüsse von der Webseite!");
}
function fkt_p()
{
alert("Grüsse vom Absatz!");
}
function fkt_b()
{
alert("Grüsse vom fetten Einschub!");
}


</script>
</head>

<body id="body" onload="init()">

<p id="absatz">Ereignisse können - <b id="fett">in Abhängigkeit vom Browser</b> - auf verschiedene Weise in der HTML-Elementhierarchie weitergereicht werden.</p>

</body>
</html>

Listing 10.9: globEvent_Net6b.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Ereignisse</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function init()
{
obj = document.getElementById("body");
obj.addEventListener("click", fkt_w, true);
obj.addEventListener("click", fkt_w, false);
obj = document.getElementById("a");
obj.addEventListener("click", fkt_a, true);
obj.addEventListener("click", fkt_a, false);
}

function fkt_w(e)
{
alert("Grüsse von der Webseite!");
}
function fkt_a()
{
alert("Grüsse vom Link!");
}


</script>
</head>

<body onload="init()" id="body">

<a href="#" id="a"><img src="flag1.gif" /></a>

</body>
</html>

Allgemeine globale Ereignisbearbeitung

Wie soll man angesichts dieses Wirrwarrs an browserspezfischen Ereignismodellen seine Webseiten aufsetzen?

Nun, so schlimm ist es gar nicht. Betrachtet man die Modelle, kann man feststellen,

Ausgehend von diesen Prämissen, kann man zwei Wege zur Planung einer Webseite einschlagen.

Sie wollen unbedingt auch den Navigator unterstützen

In diesem Falle sollten Sie auf alle Ereignisse verzichten, die der Navigator nicht unterstützt. Klicks auf Bilder können Sie simulieren, indem Sie die Bilder in Anker- Elemente einschließen (siehe Listing 10.3).

Wenn Sie von der globalen Ereignisbearbeitung Gebrauch machen wollen, müssen Sie separaten Code für den Navigator und den Internet Explorer aufsetzen (siehe Abschnitt 10.5).

Sie wollen den Navigator nicht unbedingt unterstützen

Setzen Sie Ihre Webseite so auf, dass sie im Internet Explorer korrekt funktioniert. Testen Sie die Webseite dann im Netscape-6-Browser. Bezüglich der Ereignisbearbeitung sollte es dabei keine Schwierigkeiten geben.

Eventuell enthalten Ihre Ereignisfunktionen jedoch Anweisungen, die nur vom Internet Explorer verstanden werden (beispielsweise wenn Sie über document.all auf einzelne HTML-Elemente zugreifen, siehe nachfolgender Abschnitt). Dann müssen Sie in den Ereignisfunktionen separaten Code für den Internet Explorer und den Netscape 6-Browser aufsetzen.

Testen Sie die Webseite im Navigator. Richten Sie für den Navigator alternativen Code ein, damit die Webseite im Navigator einigermaßen adäquat angezeigt wird, oder verweisen Sie darauf, dass die Leser den Netscape 6-Browser herunterladen sollten (siehe Abschnitt 10.5).

10.4 Das DOM-Modell

JavaScript wäre als Websprache bei weitem nicht so interessant und weit verbreitet, wenn es keine Möglichkeit gäbe, mit JavaScript auf die verschiedenen HTML-Elemente einer Webseite zuzugreifen. Viele interessante Einsatzgebiete für JavaScript ergeben sich erst daraus, dass man mit JavaScript in eine Webseite schreiben kann, dass man die Werte von Eingabe- oder Optionsfeldern abfragen kann oder dass man ein Bild wechselt oder verschiebt. Wie dies geht und welche Möglichkeiten es hierfür gibt, wird aber weniger von der JavaScript-Sprachspezifikation als vielmehr von den Browsern und der DOM1- Spezifikation festgelegt.

Die Browser und die DOM-Spezifikation

Wie bereits erwähnt, ging die Initiative bei der Entwicklung von JavaScript bislang vornehmlich von den Browsern aus. Diese definierten auch das document-Objekt, über das wir auf die Eigenschaften und untergeordneten HTML-Elemente einer Webseite zugreifen können.

Schauen wir uns ein wenig genauer an, wie man über das document-Objekt auf die HTML- Elemente einer Webseite zugreifen kann.

Webseiten bestehen aus Absätzen, Überschriften, Bildern, Anker und Hyperlinks, Formularen, Tabellen, etc. Unter diesen verschiedenen HTML-Elementypen erachtete man die Anker, Applets, Formulare, Bilder und Hyperlinks als besonders interessant für den Zugriff aus JavaScript-Code. Daher boten die großen Browser bald Array- Eigenschaften an, über die man auf diese Elemente zugreifen konnte:

document.anchors[]
document.applets[]
document.forms[]
document.images[]
document.links[]

Bis dahin sah die Entwicklung im Wesentlichen so aus, dass Netscape sein JavaScript- DHTML-Modell ständig ausbaute und mit neuen Ideen immer weiter vorantrieb, während Microsoft atemlos hinterher rannte und bemüht war, die neuen Konzepte auch in seinem Internet Explorer zu unterstützen.

Zwischen Ende 96 und Anfang 98 spaltete sich die Entwicklung aber plötzlich in drei Äste auf - mit fatalen Folgen für den Netscape Navigator.

Das <layer>-Tag des Navigators 4

Netscape entwickelte das Layer-Konzept zum schichtweisen Aufbau von Webseiten. Dieses Konzept brachte zwei Neuerungen:

Frei positionierte Elemente (Stileigenschaft position: absolute), die über eine id-Kennung verfügen, können im Navigator auch über ihren id-Wert angesprochen werden: document.idWert.src = ... Wir werden darauf noch einmal im Kapitel 16.3 eingehen, ansonsten werden wir uns mit dem <layer>-Tag und den daran geknüpften Techniken nicht weiter befassen, da diese mit zunehmender Verbreitung des Internet Explorers und des Netscape 6-Browser wohl schon bald der Vergangenheit angehören werden.

Das all-Objekt des Internet Explorers 4

Der Internet Explorer führte das document.all-Objekt ein. Über dieses Objekt konnte (und kann) man auf alle (!) HTML-Elemente einer Webseite zugreifen. Der Zugriff erfolgt entweder über die Eigenschaft tags, Angabe des Tag-Typs (beispielsweise "h1") und einen Index:

document.all.tags("h1")[0].style.fontSize = "60px";

oder über den id-Wert des Elements:

document.all.idWert.style.fontSize = "60px";

In letzterem Fall kann man sogar auf das Präfix document.all verzichten:

idWert.style.fontSize = "60px";

Bei allem Komfort, den das all-Objekt bietet, werden wir nicht näher auf es eingehen, da es nicht W3C-konform ist und der Internet Explorer seit der Version 5 als Alternative auch die offiziellen DOM-Methoden, beispielsweise document.getElementById(), unterstützt (siehe nachfolgenden Abschnitte).

ECMA, CSS und DOM

Im gleichen Zeitraum wurde eine Reihe von HTML- und JavaScript-relevanten Webstandards ausgearbeitet und vorgestellt.

Plötzlich war der Internet Explorer ein gutes Stück näher an den offiziellen Webstandards als der Netscape Navigator. Der Internet Explorer 4/5 unterstützte - wie vom HTML-4- Standard gefordert - weit mehr Ereignisse als der in dieser Beziehung sehr restriktive Navigator 4 (obwohl auch in diesem neue Ereignisse hinzugekommen waren). Er setzte weite Teile der CSS1- und CSS2-Spezifikation um und machte die Stilinformationen für JavaScript-Code zugänglich, während der Navigator auch hier nur zögerlich reagierte und die freie Positionierung mit seinem Layer-Konzept verwob, das aber - wie man im Nachhinein feststellen kann - mit der offiziellen Bevorzugung des CSS2-Standards zum Scheitern verurteilt war. Schließlich lag der Internet Explorer auch näher am DOM- Standard, denn er implementierte neben seinem nicht DOM-kompatiblen all-Objekt auch schon die ersten DOM-Methoden.

Der Netscape 6-Browser

Die folgenden Jahre wurden zu einem Machtkampf zwischen dem Internet Explorer und dem Navigator, den der Internet Explorer mittlerweile klar gewonnen hat. Er bot mehr Funktionalität und war näher an den offiziellen Standards2.

Nun hat Netscape mit seinem neuen Netscape 6-Browser dem alten Layer-Konzept und der Politik der zögerlichen Unterstützung der offiziellen Standards den Rücken gekehrt. Vom Saulus zum Paulus gewandelt, bemüht sich der Netscape-Browser jetzt um vorbildliche Umsetzung der offiziellen Standards. Eine neue Runde ist eingeläutet, wir dürfen gespannt sein, wie es weiter geht.

Das document-Objekt

Das document-Objekt wird vom Browser erzeugt und repräsentiert die aktuell im Browserfenster angezeigte Webseite. Es enthält eine Reihe von interessanten Eigenschaften und Methoden.

Die Eigenschaften

Eigenschaft

Beschreibung

alinkColor

Farbe aktivierter Links

anchors[]

Array, über das man auf die Anker-Elemente der Webseite zugreifen kann

applets[]

Array, über das man auf die Applet-Elemente der Webseite zugreifen kann

body

Das <body>-Element der Webseite

bgColor

Hintergrundfarbe

cookie

Von der Webseite gesetzte Cookies

domain

Domänenname des Webservers, von dem die Webseite stammt

fgColor

Vordergrundfarbe

forms[]

Array, über das man auf die Formulare der Webseite zugreifen kann

images[]

Array, über das man auf die <img>-Elemente der Webseite zugreifen kann

linkColor

Farbe von Hyperlinks

links[]

Array, über das man auf die Hyperlinks der Webseite zugreifen kann

referrer

URL, von dem der Besucher zu dieser Seite gekommen ist

title

Titel der Webseite

URL

URL der Webseite

vlinkColor

Farbe besuchter Hyperlinks

Tabelle 10.4: document-Eigenschaften

Je nach Browser verfügt das document-Objekt noch über einige weitere Eigenschaften, aber die oben aufgeführten haben Eingang in den offiziellen DOM-Standard gefunden und werden weitestgehend unterstützt.

Die Attribute alinkColor, bgColor, fgColor, linkColor und vlinkColor sind in der DOM-Spezifikation allerdings nicht als Eigenschaften des document-Objekts, sondern als Eigenschaften des body-Objekts definiert. (IE 5 und Netscape 6 unterstützen den Zugriff über die body-Eigenschaft.)

Der Zugriff auf die Eigenschaften des document-Objekts ist die Einfachheit selbst:

var str = document.title;     // Wert der Eigenschaft abfragen
document.bgColor = "green"; // Wert der Eigenschaft neu setzen

Während es jedoch immer möglich ist, den Wert einer Eigenschaft abzufragen, kann man nicht jede Eigenschaft beliebig verändern. Beispielsweise können Sie zwar die Hintergrundfarbe einer geladenen Webseite ändern, nicht aber die Vordergrundfarbe oder den Titel.

Interessant sind auch die Array-Eigenschaften des document-Objekts. Während der Browser eine Webseite lädt und aufbaut, registriert er alle in der Webseite definierten Anker, Applets, Formulare, Bilder und Hyperlinks. Für jedes Vorkommen dieser HTML- Elemente erzeugt er ein eigenes Objekt und trägt es in das zugehörige Array ein. Nach dem Laden der Webseite können wir in unserem JavaScript-Code auf die betreffenden HTML-Elemente über die Arrays zugreifen.

str = document.links[0].href;  // liefert den URL des ersten Links der 
// Webseite zurück
document.images[3].src = "bld_a.gif" // weist dem 4. <img>-Tag ein
// neues Bild zu

Diese Eigenschaften wurden übrigens nur deshalb in den DOM-Standard aufgenommen, weil sie zu der Zeit, da der DOM-Standard erarbeitet wurde, bereits seit längerem von den wichtigen Browsern unterstützt und von Webautoren weidlich genutzt wurden. Um nicht zu sehr gegen den Strom zu schwimmen, legalisierte man den vorhandenen Code nachträglich und nahm die Eigenschaften in den Standard auf, obwohl der DOM- Standard an sich alternative und leistungsfähigere Möglichkeiten zum Zugriff auf die einzelnen HTML-Elemente vorsieht.

Die Methoden

Methode

Beschreibung

close()

Dokument abschließen

open()

Dokument öffnen

write()

In Dokument schreiben

writeln()

In Dokument schreiben (inklusive abschließendem Zeilenumbruch)

getElementById()

HTML-Element der angegebenen ID zurückliefern

getElementsByName()

HTML-Element des angegebenen Namens zurückliefern

Tabelle 10.5: document-Methoden

Die ersten vier Methoden kennen Sie bereits aus Kapitel 8. Neu sind dagegen die Methoden mit den viel versprechenden Namen getElementById() und getElementsByName(). Diese Methoden sind aber nicht nur für uns neu, sie sind auch insofern neu, als sie nicht von den Browser-Herstellern, sondern vom DOM 1-Standard definiert wurden. Daher werden Sie derzeit auch nur in den neuesten Browserversionen (Internet Explorer 5 und Netscape 6-Browser) unterstützt.

Mit document.getElementById() können Sie auf ein beliebiges HTML-Element zugreifen. Voraussetzung ist allerdings, dass das Element über eine eindeutige id-Kennung verfügt.

Nehmen wir beispielsweise an, Sie hätten eine Webseite mit einem <img>-Tag, dem Sie die id-Kennung "meinBild" zugewiesen haben.

<body>
...
<img id="meinBild" src="bd1.gif" />
...
</body>

Dann können Sie sich wie folgt ein JavaScript-Objekt zurückliefern, das das <img>-Element repräsentiert:

var obj = document.getElementById("meinBild");

Danach kann man wie gewohnt auf die Eigenschaften des Objekts (entsprechen den HTML-Attributen des HTML-Elements) zugreifen.

alert(obj.src);

id-Werte sollten immer eindeutig sein, das heißt, es sollte in einer Webseite keine zwei HTML-Elemente mit gleichen id-Kennungen geben. Ansonsten liefert die Methode getElementById() unvorhersehbare Ergebnisse.

Wenn Sie für das <img>-Element auch ein name-Attribut spezifiziert haben:

<body>
...
<img id="meinBild" name="bild1" src="bd1.gif" />
...
</body>

können Sie sich auch mit Hilfe der Methode getElementsByName() ein JavaScript-Objekt für das HTML-Element zurückliefern lassen:

var obj = document.getElementsByName("bild1");

Beachten Sie aber, dass die Methode getElementsByName() ein Array aller HTML- Elemente mit dem übergegebenen Namen zurückliefert. Wir müssen das gewünschte Objekt also über einen Index ansprechen:

alert(obj[0].src);

Beachten Sie, dass die Verwendung des name-Attributs nicht für alle HTML-Elemente gestattet ist und auch dort wo sie erlaubt ist, meist nur noch der Abwärtskompatibilität dient. Verwenden Sie daher bevorzugt das id-Attribut und die Methode getElementById().

Das DOM-Modell

Die DOM-Spezifikation des W3C-Konsortiums regelt wie die Elemente einer XML/ HTML-Seite in einer hierarchisch angeordneten Struktur repräsentiert und von Websprachen wie Java oder JavaScript aus bearbeitet werden können. Die DOM- Spezifikation ist bei weitem nicht auf das document-Objekt beschränkt, das wir im vorangehenden Abschnitt näher kennen gelernt haben, und es hat ziemlich wenig mit den traditionell von den Browsern unterstützten Array-Eigenschaften document.links[], document.images[], etc. zu tun.

Das DOM-Modell3 ist viel weiter gefasst als die traditionellen, schrittweise gewachsenen DHTML-Möglichkeiten der einzelnen Browser. Ziel der DOM-Spezifikation ist es, eine Schnittstelle zu schaffen, die es Programmierern erlaubt XML- und HTML-Dokumente dynamisch zu erstellen, ihre Struktur zu durchforsten und Elemente zu verändern, zu löschen oder hinzuzufügen. Bis auf wenige Ausnahmen soll alles, was in einem XML- oder HTML-Dokument zu finden ist, über die DOM-Schnittstelle verfügbar sein.

Die Dokumenthierarchie

Das DOM-Spezifikation beruht darauf, dass man jedes Dokument als eine hierarchische Struktur von Knoten interpretiert. Die einzelnen Knoten sind dabei die HTML- und Textelemente des Dokuments. Ganz oben in der Hierarchie steht der Knoten, der das <body>-Element repräsentiert. Unter dem <body>-Knoten folgen seine Kindknoten. Dies sind alle HTML-Elemente und jegliche Textelemente (die nicht in Tags eingeschlossen ist), die direkt unter dem <body>-Element definiert sind.

Allgemein gilt: Wenn ein HTML-Element andere HTML-Elemente einschließt, werden diese als Kindknoten des übergeordneten HTML-Elements interpretiert. Textelemente und HTML-Elemente ohne Inhalt (beispielsweise <img /> oder <hr /> können keine Kindknoten haben.

Gemäß diesen Regeln ist es keine große Schwierigkeit die DOM-Präsentation einer Webseite zu finden. Tatsächlich spiegelt diese einfach die Verschachtelung der HTML- Elemente im Code der Webseite wider.

Abbildung 10.4 zeigt das DOM-Modell der Webseite dom.html aus Listing 10.10.

Listing 10.10: dom.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Das DOM-Modell</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>

<body>

<h1>Das DOM-Modell</h1>

<p id="absatz1">Dies ist ein <a href="seite1.html">Hyperlink</a> in einem Textabsatz.</p>

<p>Dies ist ein zweiter Textabsatz.</p>

</body>
</html>

Abbildung 10.4:  DOM-Modell zur Webseite aus dom.html

Das Navigieren in der Dokumenthierarchie

Wie bekommt man Zugriff auf ein bestimmtes HTML-Element einer Webseite?

Hierfür gibt es zwei Möglichkeiten:

Jeder Knoten verfügt nämlich über Eigenschaften, mit denen man auf seine Kinder, seine Geschwister (Knoten, die das gleiche übergeordnete Elter-Tag haben) oder sein Elter-Tag zugreifen kann.

Eigenschaft

Beschreibung

firstChild

Liefert den ersten Kindknoten des aktuellen Knoten. Liefert null, wenn es keinen Kindknoten gibt.

lastChild

Liefert den letzten Kindknoten des aktuellen Knoten. Liefert null, wenn es keinen Kindknoten gibt.

childNodes

Liefert eine Liste der Kindknoten des aktuellen Knoten.

Die einzelnen Knoten in der Liste können über einen 0-basierten Index angesprochen werden. Die Anzahl der Knoten in der Liste kann über die Eigenschaft length der zurückgelieferten Liste abgefragt werden.

previousSibling

Liefert den vorangehenden Geschwisterknoten des aktuellen Knoten. Liefert null, wenn es keinen solchen Knoten gibt.

nextSibling

Liefert den nachfolgenden Geschwisterknoten des aktuellen Knoten. Liefert null, wenn es keinen solchen Knoten gibt.

parentNode

Liefert den übergeordneten (Elter)-Knoten des aktuellen Knoten. Liefert null, wenn es keinen solchen Knoten gibt (etwa weil dieser Knoten dynamisch entfernt wurde).

ownerDocument

Liefert das document-Objekt des Knotens.

Tabelle 10.6: Knoten-Eigenschaften für die Navigation in der Dokumentstruktur

In Listing 10.11 verwenden wir den direkten Zugriff über die id, um die Textfarbe für den ersten <p>-Absatz auf Rot zu setzen.

Von dem Objekt, das den Knoten des ersten <p>-Absatzes repräsentiert, springen wir dann mit Hilfe der Knoteneigenschaften zu dem Hyperlink (erster Kindknoten des <p>-Absatzes) und dem zweiten Absatz (nachfolgendes Geschwister des ersten <p>-Absatzes).

Listing 10.11: dom.html - erweitert um Skriptcode

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Das DOM-Modell</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>

<body>

<h1>Das DOM-Modell</h1>

<p id="absatz1">Dies ist ein <a href="seite1.html">Hyperlink</a> in einem Textabsatz.</p>

<p>Dies ist ein zweiter Textabsatz.</p>

<script type="text/javascript">

var p1 = document.getElementById("absatz1");
p1.style.color = "red";

var p1Kinder = p1.childNodes;
p1Kinder[1].style.backgroundColor = "red";

var ueber1 = p1Kinder[1].parentNode.previousSibling;
ueber1.style.color = "green";

</script>

</body>
</html>

Abbildung 10.5:  Sorry - die Farben sind leider verloren gegangen

Knoten/HTML-Elemente bearbeiten

Angenommen wir haben uns ein Objekt zu einem Knoten in der Dokumentstruktur zurückliefern lassen. Was können wir dann mit diesem Objekt anfangen?

Nun, das hängt zuerst einmal davon ab, um was für einen Knoten es sich handelt.

Text von Textelementen verändern

Handelt es sich um ein Textelement, können Sie über die Eigenschaft nodeValue einen neuen Text zuweisen.

Um beispielsweise den Text des zweiten Absatzes vom dom.html zu verändern, könnten Sie schreiben:

var p1 = document.getElementById("absatz1");
var p2 = p1.nextSibling;
p2.firstChild.nodeValue = "Dies ist ein neuer Text.";

innerHTML

Der Internet Explorer kennt noch eine weitere Möglichkeit, den Text in einem HTML-Element zu verändern. Voraussetzung ist, dass Sie die id-Kennung eines HTML-Elements wissen oder anderweitig Zugriff auf das Element haben (im nachfolgenden Beispiel übergeben wir das Objekt in Form des Schlüsselworts an die Funktion). Ist das Objekt verfügbar, können Sie dem Element über die Eigenschaft innerHTML einen neuen Text zuweisen.

<script type="text/javascript">
function aendern(elem)
{
elem.innerHTML = "Dies ist ein <b>neuer</b> Textabsatz."
}
</script>
...
<p onclick="aendern(this)">Dies ist ein Textabsatz.</p>

Die Eigenschaft ist etwas einfacher zu verwenden, als der Zugriff über die DOM-Eigenschaft nodeValue, da man nicht bis auf die Ebene des Textelements hinabsteigen muss, sondern direkt das HTML-Element manipuliert. Beachten Sie aber, dass die Eigenschaft innerHTML proprietär ist, sie wird derzeit sowohl vom Internet Explorer als auch vom Netscape 6-Browser unterstützt.

HTML-Attribute verändern

Handelt es sich um ein HTML-Element, können Sie sich mit getAttribute(name) den Wert eines Attributs zurückliefern lassen, mit setAttribute(name, wert) den Wert eines Attributs verändern oder ein neues Attribut zuweisen, mit removeAttribute(name) ein Attribut löschen.

Um beispielsweise den Hyperlink aus dom.html auf seite2.html umzulenken, könnten Sie schreiben:

var p1 = document.getElementById("absatz1");
var p1Kinder = p1.childNodes;
p1Kinder[1].setAttribute("href", "seite2.html");

Stileigenschaften verändern

Wenn Sie die Stileigenschaften eines HTML-Elements verändern wollen, gehen Sie nicht über die Methode setAttribute(), sondern verwenden die style-Eigenschaft des Elements:

var p1 = document.getElementById("absatz1");
p1.style.color = "red";
p1.style.fontSize = "20px";

Hierbei ist die Schreibweise der Stileigenschaften zu beachten:

So wird aus font-size die Eigenschaft fontsize oder aus background-color die Eigenschaft backgroundColor.

Die obigen Regeln zur Schreibweise von Stileigenschaften gelten in der DOM-Spezifikation übrigens ganz allgemein. Wenn Sie sich obige Beispiele anschauen, werden Sie leicht feststellen, dass die DOM-Methoden nach den gleichen Regeln benannt sind.

Noch einmal - das Flaggenbeispiel

Zum Abschluss dieses Themas wollen wir noch einmal das Flaggen-Beispiel vom Anfang dieses Tages aufgreifen und mit Hilfe der DOM-Methoden so implementieren, dass es im Internet Explorer 4/5 und im Netscape 6-Browser korrekt angezeigt wird.

Listing 10.12: flaggen1.html - onclick-Ereignis für Bilder (IE und Net 6)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

function loesen(str)
{
if (str == "bld3")
document.getElementById(str).src = "richtig.gif";
else
document.getElementById(str).src = "falsch.gif";
}

</script>
</head>

<body style="background-color: #F0F0F0">

<h1>Welche der folgenden Flaggen ist die Flagge von Sri Lanka?</h1>

<table>
<tr>
<td><img src="flag1.gif" id="bld1" onclick="loesen('bld1')" /></td>
<td><img src="flag2.gif" id="bld2" onclick="loesen('bld2')" /></td>
<td><img src="flag3.gif" id="bld3" onclick="loesen('bld3')" /></td>
<td><img src="flag4.gif" id="bld4" onclick="loesen('bld4')" /></td>
</tr>
</table>

<br />
<p>Klicken Sie einfach auf die Flagge.</p>

</body>
</html>

In dieser Version haben wir nur noch eine Funktion zum Bilderwechseln. Das bedeutet, dass wir in der Funktion entscheiden müssen, ob das Bild richtig.gif oder das Bild falsch.gif einzublenden ist. Und wir müssen natürlich auch sicherstellen, dass die Funktion das Bild wechselt, das angeklickt wurde. Dazu versehen wir jedes <img>-Tag mit einer id-Kennung und übergeben den Wert dieser Kennung als Argument an die JavaScript-Funktion.

<img src="flag1.gif" id="bld1" onclick="loesen('bld1')" />

In der Funktion können wir anhand des übergebenen id-Wert feststellen, ob die richtige oder eine falsche Flagge angeklickt wurde:

  function loesen(str)
{
if (str == "bld3")
// richtige Flagge wurde angeklickt
else
// falsche Flagge wurde angeklickt
}

Und wir können den id-Wert nutzen, um mittels getElementById() auf das zu wechselnde <img>-Tag zuzugreifen.

  function loesen(str)
{
if (str == "bld3")
document.getElementById(str).src = "richtig.gif";
else
document.getElementById(str).src = "falsch.gif";
}

Abbildung 10.6:  Dynamische Bilder mit DOM

10.5 Browserunabhängige Lösungen

In diesem Kapitel haben Sie mehr als einmal Hinweise der Art »Dies geht nur in diesem oder jenem Browser«, »Diese Technik wird nur von diesem oder jenem Browser unterstützt, in den anderen Browser müssen Sie ...« gehört. Dabei ging es stets um Techniken, die entweder nur von einigen wenigen Browsern unterstützt werden oder die in verschiedenen Browsern unterschiedlich realisiert werden müssen. Wer solche Techniken nutzen, gleichzeitig aber möglichst alle gängigen Browser unterstützen möchte, der muss nach Tricks suchen, wie er den Code so formulieren kann, dass er in allen Browsern korrekt interpretiert wird.

Manchmal ist dies bereits ohne große Verbiegungen möglich.

Beispielsweise sind sich die aktuellen Versionen der großen Browser doch sehr ähnlich und sofern Sie für den Zugriff auf die HTML-Elemente die Methode document.getElementById() statt dem Unterobjekt document.all verwenden, sollte es keine allzu große Schwierigkeit sein, Code aufzusetzen, der im Internet Explorer 5 wie im Netscape 6-Browser einwandfrei läuft (allerdings nicht in älteren Browsern).

Ein anderes Beispiel wäre die Unterstützung von Mausklicks auf Bildern. Wenn Sie auf Mausklicks in Bildern mit einem JavaScript reagieren wollen, haben Sie das Problem, dass der Netscape Navigator das Click-Ereignis für <img>-Tags nicht unterstützt. Wenn Sie die Bilder aber in Anker-Elemente verpacken und für diese die Click-Ereignisse überwachen, erhalten Sie Code, der auch im Navigator funktioniert (siehe Listing 10.3).

Irgendwann werden Sie aber an die Grenzen dieser Tricks stoßen. Dann ist es an der Zeit, getrennten Code für die verschiedenen Browser aufzusetzen. Dazu müssen Sie aber erst einmal Code aufsetzen, der erkennt, in welchem Browser die Webseite gerade ausgeführt wird. Hierfür gibt es unterschiedliche Ansätze:

Die nächste Frage ist, was macht man in den Anweisungsblöcken der if-Verzweigung?

Listing 10.13: flaggen5.html - browserunabhängige Implementierung

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">

// alles in Kleinbuchstaben umwandeln
var brw = navigator.appName.toLowerCase();

var ie = (brw.indexOf("microsoft") != -1);
var nav = (brw.indexOf("netscape") != -1) &&
(parseInt(navigator.appVersion) < 5);
var net = (brw.indexOf("netscape") != -1) &&
(parseInt(navigator.appVersion) >= 5);

function loesen(str)
{
if (str == "bld3")
document.getElementById(str).src = "richtig.gif";
else
document.getElementById(str).src = "falsch.gif";
}

</script>
</head>

<body style="background-color: #F0F0F0" onload="init()">

<h1>Welche der folgenden Flaggen ist die Flagge von Sri Lanka?</h1>


<script type="text/javascript">
// Je nach Browser unterschiedlichen HTML-Code ausgeben

if (ie || net)
{
document.write("\
<table>\
<tr>\
<td><img src='flag1.gif' id='bld1' onclick='loesen(\"bld1\")' ¬/></td>\
<td><img src='flag2.gif' id='bld2' onclick='loesen(\"bld2\")' ¬/></td>\
<td><img src='flag3.gif' id='bld3' onclick='loesen(\"bld3\")' ¬/></td>\
<td><img src='flag4.gif' id='bld4' onclick='loesen(\"bld4\")' ¬/></td>\
</tr>\
</table>\
");
}
else if (nav)
{
document.write("\
<table>\
<tr>\
<td><a href='#' onclick='alert(\"Dies ist die Flagge des ¬Senegal\");'>\
<img src='flag1.gif' /></></td>\
<td><a href='#' onclick='alert(\"Dies ist die Flagge Japans\");'>\
<img src='flag2.gif' /></></td>\
<td><a href='#' onclick='alert(\"Richtig!\");'>\
<img src='flag3.gif' /></></td>\
<td><a href='#' onclick='alert(\"Dies ist die Flagge ¬Finnlands\");'>\
<img src='flag4.gif' /></></td>\
</tr>\
</table>\
");
}

</script>


<br />
<p>Klicken Sie einfach auf die Flagge.</p>

</body>
</html>

Beachten Sie, dass die doppelten Anführungszeichen in den document.write-Ausgaben mit Hilfe des vorangehenden \-Zeichens als einfache auszugebende Zeichen gekennzeichnet wurden. Ansonsten würde der Interpreter nämlich beim ersten Anführungszeichen annehmen, dass dort der auszugebende String endet.

10.6 Rollover-Effekte für Schalter

Sicherlich sind Ihnen beim Surfen im Web auch schon Webseiten mit diesen herrlichen grafischen Schaltflächen begegnet, die aufleuchten, wenn man die Maus über sie bewegt, und vielleicht haben Sie sich schon überlegt, wie sich dies realisieren lässt.

Nun, wenn Sie bisher nicht hinter das Geheimnis dieser Schaltflächen gekommen sind, dann...

... werden Sie es an dieser Stelle auch nicht tun, denn wir haben uns entschlossen, Ihnen die Implementierung von Rollover-Schaltflächen als Übungsaufgabe zu stellen (mit Lösung im Anhang dieses Buches).

Da die Implementierung von Rollover-Schaltflächen aber nicht ganz trivial ist, erhalten Sie hier einige Hinweise und Tipps.

10.7 Dynamisch aufklappbare Listen

Ein weiteres Element, das man immer häufiger auf Webseiten findet, sind dynamische hierarchische Listen und Menüs, deren untergeordnete Ebenen durch Mausaktionen ein- und ausgeblendet werden können.

Abbildung 10.7:  Zu- und aufgeklappte dynamische Liste

Das folgende Beispiel stellt Ihnen eine relativ einfache Variante zur Implementierung einer dynamischen Liste (genauer gesagt einer Aufzählung) vor. Die Implementierung unterstützt sowohl den Internet Explorer 5 als auch den Netscape 6-Browser. In anderen Browsern, wie zum Beispiel dem Netscape Navigator, wird die Liste stets vollständig aufgeklappt dargestellt.

Listing 10.14: DynamListe.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Flaggen</title>
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>

<script type="text/javascript">

function initialisiereListe()
{
var src = document.getElementById("dynListe");
var loop1, loop2;
var kind1, kind2;

for(loop1 = 0; loop1 < src.childNodes.length; ++loop1)
{
kind1 = src.childNodes[loop1];

if(kind1.nodeName == "LI")
{
for(loop2 = 0; loop2 < kind1.childNodes.length; ++loop2)
{
kind2 = kind1.childNodes[loop2];

if (kind2.nodeName == "UL")
{
kind2.style.display = "none";
}
}
}
}
}


function dynListe(e)
{
var src = null;

if(document.all) // Internet Explorer, Version vernachlässigen wir
{
src = event.srcElement;
}
else if(document.getElementById) // Netscape 6
{
src = e.target;
}

var loop;

// Netscape 6 liefert Textelement bei Klick in Liste,
// daher in DOM-Hierarchie eine Ebene hochwandern
if (src.nodeName == "#text")
src = src.parentNode;

for(loop = 0; loop < src.childNodes.length; ++loop)
{
var kind = src.childNodes[loop];

if (kind.nodeName == "UL")
{
kind.style.display =
(kind.style.display == "none" ? "" : "none");
}
}
}

</script>
</head>

<body onload="initialisiereListe()">

<h1>Dynamische Liste</h1>

<p>Klicken Sie auf die übergeordneten Listenelemente, um die
untergeordneten Ebenen ein- und auszublenden.</p>

<ul id="dynListe" onclick="dynListe(event)">
<li>Element1
<ul >
<li>Element11</li>
<li>Element12</li>
</ul>
</li>
<li>Element2
<ul >
<li>Element21</li>
<li>Element22</li>
<li>Element23</li>
</ul>
</li>
<li>Element3
<ul >
<li>Element31
<ul >
<li>Element311</li>
<li>Element312</li>
</ul>
</li>
</ul>
</li>
</ul>

</body>
</html>

Schauen Sie sich zuerst den HTML-Code der Liste an. Die erste Ebene enthält drei Elemente, die jeweils wieder untergeordnete Listen enthalten (einmal mit zwei, einmal mit drei Elementen und einmal mit nur einem Element). Unter dem letzten Element gibt es noch eine dritte Ebene, das heißt, das Element der untergeordneten Ebene (Element31) enthält selbst auch wieder eine untergeordnete Ebene (mit zwei Elementen 311 und 312).

Alle Klickereignisse für die Liste werden in der obersten Listenebene abgefangen:

<ul id="dynListe" onclick="dynListe(event)">

Um in der Ereignisfunktion dynListe() feststellen zu können, welches Listenelement genau angeklickt wurde, müssen wir daher das globale event-Objekt bemühen. Da wir neben dem Internet Explorer 5 auch den Netscape 6-Browser unterstützen wollen, bedeutet dies, dass wir das Schlüsselwort event an die Ereignisfunktion übergeben.

Schauen wir uns nun den Code der Ereignisfunktion dynListe() an.

Nehmen wir an, der Besucher der Webseite hat irgendwo in die Liste geklickt. Unsere erste Aufgabe besteht dann darin, festzustellen, ob er auf ein Listenelement geklickt hat, zu dem es eine untergeordnete Ebene gibt (die dann ein- oder ausgeblendet werden soll). Die Information, welches Listenelement angeklickt wurde, erhalten wir von dem globalen event-Objekt. Da dieses für Internet Explorer und Netscape 6-Browser unterschiedlich implementiert ist (siehe Abschnitt 10.2), müssen wir eine if-Verzweigung aufsetzen (siehe auch Abschnitt 10.5):

function dynListe(e)
{
var src = null;

if(document.all) // Internet Explorer, Version vernachlässigen wir
{
src = event.srcElement;
}
else if(document.getElementById) // Netscape 6
{
src = e.target;
}
...

Im Internet Explorer enthält src jetzt das Listenelement, auf das der Besucher geklickt hat. Im Netscape 6-Browser enthält src dagegen das Textelement des Listenelements. Im Netscape 6-Browser müssen wir daher in der DOM-Hierarchie eine Ebene hochgehen (vom Textelement zum Listenelement).

    ...
var loop;

// Netscape 6 liefert Textelement bei Klick in Liste,
// daher in DOM-Hierarchie eine Ebene hochwandern
if (src.nodeName == "#text")
src = src.parentNode;
...

Jetzt gehen wir alle untergeordneten Elemente des angeklickten Listenelements durch (siehe auch Abschnitt 10.4.5). Treffen wir dabei auf eine untergeordnete Aufzählung (nodeName == "UL") blenden wir diese ein oder aus.

    for(loop = 0; loop < src.childNodes.length; ++loop)
{
var kind = src.childNodes[loop];

if (kind.nodeName == "UL")
{
kind.style.display =
(kind.style.display == "none" ? "" : "none");
}
}
}

Die Anweisung zum Ein- und Ausblenden der untergeordneten Listen müssen wir noch näher besprechen. Wir nutzen hier eine Stileigenschaft, die bisher noch nicht angesprochen wurde: display. Die Stileigenschaft display kann die Werte block, inline, list-item und none annehmen und weist den Browser an, nach welchem Verfahren er das Element anzeigen soll. Üblicherweise sollte man den Wert dieser Stileigenschaft nicht ändern, aber hier können wir uns zunutze machen, dass man das Element durch Zuweisung von "none" verschwinden lassen kann - und zwar so, dass keine Lücke zurückbleibt.

Wird die Ebene augenblicklich angezeigt, wollen wir sie ausblenden, ist sie ausgeblendet, soll sie eingeblendet werden. Für diese »Umschaltung« könnte man eine normale if-else- Verzweigung aufsetzen, man kann aber auch den Bedingungsoperator ?: nutzen. Der Ausdruck

kind.style.display == "none" ? "" : "none"

bedeutet:

»Wenn kind.style.display gleich "none" ist (?), dann liefere als Ergebnis des Ausdrucks "" zurück, ansonsten (:) liefere "none" zurück«

Zum guten Schluss wollen wir noch dafür sorgen, dass die Liste am Anfang zusammengeklappt ist. Dazu weisen wir der obersten Liste eine id zu und verbinden das onload-Ereignis des <body>-Tags mit einer Funktion, die die untergeordneten Ebenen der Liste ausblendet:

<body onload="initialisiereListe()">
...
<ul id="dynListe" ...">

In der Funktion initialisiereListe() greifen wir mit Hilfe der Methode getElementById() über die ID dynListe auf die Liste zu. Dann durchsuchen wir die Kindknoten der übergeordneten Liste nach Knoten vom Typ LI (Listenelemente). In einer zweiten Schleife werden diese wiederum daraufhin untersucht, ob sie untergeordnete Aufzählungen (UL) enthalten. Wenn ja werden diese ausgeblendet.

function initialisiereListe()
{
var src = document.getElementById("dynListe");
var loop1, loop2;
var kind1, kind2;

for(loop1 = 0; loop1 < src.childNodes.length; ++loop1)
{
kind1 = src.childNodes[loop1];

if(kind1.nodeName == "LI")
{
for(loop2 = 0; loop2 < kind1.childNodes.length; ++loop2)
{
kind2 = kind1.childNodes[loop2];

if (kind2.nodeName == "UL")
{
kind2.style.display = "none";
}
}
}
}
}

Wenn Sie die dynamische Liste noch ein wenig bedienerfreundlicher machen wollen, verwenden Sie Plus- und Minuszeichen als Aufzählungssymbole und setzen Sie diese so, dass der Besucher erkennen kann, ob es zu einem Listenelement eine untergeordnete Ebene gibt oder nicht.

10.8 Zusammenfassung

Heute haben wir wieder einmal viel geleistet und ein großes, aber auch überaus wichtiges Themengebiet behandelt: die Ereignisbehandlung und den Zugriff auf HTML-Elemente mittels JavaScript. Dass dieses Thema so kompliziert ist, liegt aber nicht daran, dass die dahinter stehenden Konzepte so schwer zu begreifen wären, sondern hat vielmehr damit zu tun, dass es in diesem Bereich so viele Unterschiede in den gängigen Browsern gibt. Was sollten Sie also von diesem Tag mitnehmen?

Erstens: Die grundlegende Ereignisbehandlung (JavaScript-Funktion als Wert an HTML- Ereignisattribut zuweisen) ist dabei in allen wichtigen Browsern gleich. Zu beachten ist lediglich, dass der Netscape Navigator 4 nicht alle im Standard vorgesehenen Ereignis/Tag- Kombinationen unterstützt. Manchmal kann man diese Defizite aber umgehen - wie im Falle der Klickereignisse für Bilder.

Zweitens: Die Modelle für die globale Ereignisbehandlung und die Verwendung des event-Objekts sind recht unterschiedlich. Andererseits sind sich zumindest der Internet Explorer und der Netscape 6-Browser hinsichtlich der globalen Ereignisbehandlung recht ähnlich und die Informationen im event-Objekt kann man manchmal durch die Übergabe passender Argumente an die Ereignisbehandlungsfunktionen (beispielsweise this-Objekt) ersetzen.

Drittens: Wenn Sie auf HTML-Elemente zugreifen, verwenden Sie möglichst nicht die proprietären Objekte document.all oder document.layers und auch nicht die an diese Objekte geknüpften Techniken (Zugriff über id). Nutzen Sie die allgemein unterstützten Array-Eigenschaften des document-Objekts (document.images[], document.forms[], etc.) sowie die Methoden und Techniken, die im DOM-Standard definiert sind. Letztere werden derzeit zwar nur von den aktuellsten Browsern unterstützt, doch liegt in Ihnen zweifelsohne die Zukunft.

10.9 Fragen und Antworten

Frage:
Ich habe für einen <p>-Absatz und eine eingeschlossene <b>-Textpassage jeweils das onclick-Ereignis abgefangen. Wenn ich beiden Ereignisfunktionen das Schlüsselwort this übergebe, welche Objekte repräsentiert es in den beiden Funktionen? Wenn ich in beiden Funktionen über das event-Objekt den Ursprung des Ereignisses abfrage (event.srcElement bzw. event.target), welche Objekte erhalte ich in den beiden Funktionen?

Antwort:
Das this-Objekt repräsentiert immer das Objekt, dessen onclick-Ereignisfunktion es übergeben wurde. Das Ursprungsobjekt, das über event abgefragt werden kann, repräsentiert dagegen immer das innerste Objekt, in dem das Ereignis ursprünglich ausgelöst wurde.

Frage:
In Netscape-Browsern kann man durch Aufruf von window.captureEvents() Ereignisse global abfangen lassen. Kann man das globale Abfangen eines Ereignisses auch wieder abschalten?

Antwort:
Ja! Verwenden Sie hierzu die Methode window.releaseEvents().

Frage:
Kann man in einem captureEvents-Aufruf mehrere Ereignisse angeben?

Antwort:
Ja! Sie müssen die Ereignistypen lediglich ODER-verknüpfen.

window.captureEvents(Event.CLICK | Event.MOUSEDOWN);

Frage:
Wie kann ich beim Navigieren mit den DOM-Knoteneigenschaften firstChild, lastChild, etc. sicher sein, dass der Knoten, zu dem ich wechsle, auch existiert?

Antwort:
Wenn der Knoten nicht existiert, liefern die betreffende Knoteneigenschaften - und auch die Methode getElementsById() - den Wert null zurück. Da JavaScript den Nullwert als Booleschen Wert false interpretiert, kann man leicht mit einer if-Anweisung überprüfen, ob ein Knoten existiert oder nicht:

var p1 = document.getElementById("absatz1"); 
if(!p1)
{
alert("kein p1");
}
else
{
p1.style.color = "red";

var p1Kinder = p1.childNodes;
if (!p1Kinder[1])
{
alert("kein p1Kinder[1]");
}
else
{
p1Kinder[1].style.backgroundColor = "red";
}
}

Beachten Sie, dass die Eigenschaft childNodes im Falle eines Scheiterns keinen Nullwert, sondern ein leeres Knoten-Array zurückliefert. Wenn Sie aber über die Indizierung auf ein nicht vorhandenes Array-Element zugreifen wollen, erhalten Sie null zurück.

10.10 Workshop

Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, und Übungen, die Sie anregen sollen, das eben Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Versuchen Sie, das Quiz und die Übungen zu beantworten und zu verstehen, bevor Sie zur Lektion des nächsten Tages übergehen.

Quiz

  1. Zählen Sie aus dem Gedächtnis ein paar JavaScript-Ereignisse auf.
  2. Wie greift man auf das globale event-Objekt zu? Wie greift man auf das auslösende HTML-Element oder die Koordinaten eines Mausklicks zu?
  3. Auf das wievielte Bild einer Webseite greifen Sie über document.images[2] zu?
  4. Mit welcher DOM-Methode kann man durch Angabe des id-Wertes auf HTML- Elemente zugreifen? Welche Browser unterstützen diese Methode?
  5. Wie kann man die Stileigenschaften eines Objekts ändern?
  6. Wie kann mit JavaScript erkennen, in welchem Browser die Webseite gerade angezeigt wird?

Übungen

  1. Implementieren Sie eine Tabelle mit drei grafischen Rollover-Schaltflächen.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


1234

© Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH