Alles in all
Die aktuellen Versionen des Internet Explorers und von Netscape beherrschen,
wie Ihr gesehen habt, das DOM. Die älteren Versionen aber, jeweils bis
Version 4.x, gingen leider eigene, zu einander nicht kompatible Wege. Im
Internet Explorer gab es das all-Objekt; im
Netscape Navigator gab es eine Reihe von Arrays mit Objekten und sogenannte
layers. Wenn Eure Seiten neben den aktuellen
Versionen auch mit IE4.x und NN4.x funktionieren sollen, müßt Ihr
also im schlimmsten Fall drei Versionen schreiben.
Zuerst zum IE4.x mit seinem all-Objekt. Über Unterobjekte des all-Objekts
könnt Ihr auf jedes Element des Dokuments zugreifen. Dazu gibt es zwei
Möglichkeiten. Entweder benutzt Ihr den Namen des Elements, zugewiesen
mit dem name- oder dem id-Attribut
<p name="der_text">Mein Element</p>
...
document.all["der_text"]; // entweder als Array
document.all.der_text; // oder als Unterobjekt
oder ihr benutzt die tags-Funktion. Die liefert
Euch ein Array mit allen Elementen dieses Tags
document.all.tags("img")[2]; // das dritte img-Element im Dokument
In diesem Fall muß das Element nicht irgendwie markiert sein (kein
name- oder id-Attribut). Wenn Ihr das Element auf diese Weise habt,
könnt Ihr wie beim DOM auch einfach dessen Eigenschaften bearbeiten
// Ändern der src-Attributs
document.all.tags("img")[2].src = "dasBild.jpg";
Das Ändern des Textes in einem Element läft jedoch etwas anders
als beim DOM. Dazu gibt es insgesamt vier Eigenschaften
- innerText
-
Dieses Attribut ist der Text innerhalb des HTML-Elements. Ihr könnt
es lesen und überschreiben.
<p name="der_text">Der Inhalt</p>
...
// liefert 'Der Inhalt'
document.all.der_text.innerText;
- innerHTML
-
Dieses Attribut hat Ähnlichkeit mit innerText, enthält aber
zusätzlich noch den HTML-Code aller HTML-Elemente, die sich im
aktuellen Element befinden.
<p name="der_text">Der <b>Inhalt</b></p>
...
// liefert 'Der <b>Inhalt</b>'
document.all.der_text.innerText;
- outerText
-
Auch das ist ähnlich wie innerText, hier werden allerdings der
öffnende und der schließende Tag des aktuellen Elements
mitgeliefert.
<p name="der_text">Der Inhalt</p>
...
// liefert '<p name="der_text">Der Inhalt</p>'
document.all.der_text.innerText;
- outerHTML
-
Wie Ihr vermutlich schon erraten habt, liefert diese Eigenschaft das
komplette Element inklusive öffnenden und schließendem Tag
und allen enthaltenen Elementen.
<p name="der_text">Der <b>Inhalt</b></p>
...
// liefert '<p name="der_text">Der <b>Inhalt</b></p>'
document.all.der_text.innerText;
layer
Bevor es das DOM gab, war der Zugriff auf HTML-Elemente im Netscape
Navigator recht unkomfortabel: Es gab nur eine Reihe von Arrays, die alle
Elemente dieses Tags enthalten
- anchors (a-Tags)
- applets (applet-Tags)
- forms (form-Tags)
- images (img-Tags)
- layers (layer-Tags)
- links (die Verweisziele der a-Tags)
- plugins (die installierten Plugins)
Auf andere Elemente konnte man nicht zugreifen. Der Zugriff auf die
«erlaubten» Elemente ging entweder über die Indexnummer
oder das name-Attribut
<img name="das_bild">
...
document.images["das_Bild"].src = ...; // über das name-Attribut
// über die Indexnummer, hier das dritte img-Tag im Dokument
document.images[2].src = ...;
Auf den Text innerhalb eines HTML-Elements kann man in diesem Modell nicht
ohne weiteres zugreifen: Das ist nur bei layer-Elementen möglich. Das
liegt daran, daß der Netscape Navigator ein Layer wie ein eigenes
Browser-Fenster behandelt. Daher hat ein layer-Objekt ein eigenes
document-Unterobjekt inklusive write()-Funktion
<layer name="der_layer">Der Inhalt des Layers</layer>
...
// Ändern des Layer-Inhalts
var doc = document.layers["der_layer"].document;
doc.open();
doc.write("Der neue Inhalt!");
doc.close();
Mit dieser Methode solltet Ihr allerdings recht sparsam umgehen, weil sie
- zu ausgiebig benutzt - den Netscape Navigator sogar zum Absturz bringen kann.
Jetzt stellt sich natürlich die Frage, wie Ihr herausbekommt, welches
dieser Modelle der Browser des Users unterstüzt. Das geht zum einen
über das am Anfang schon erwähnte navigator-Objekt, aber auch
leichter: In jedem der drei Modelle gibt es ja eine Funktion bzw. ein
Objekt, das nur dort existiert. Praktischerweise ist diese Funktion bzw.
Objekt gleichzeitig eine boolsche Eigenschaft. Dieser Wahrheitswert zeigt
an, ob die Funktion bzw. Objekt zur Verfügung steht
if (document.getElementById)
alert ("Dies ist ein IE ab 5.0 oder ein Netscape ab 6.0!");
if (document.all)
alert ("Dies ist ein IE bis 4.x!");
if (document.layers)
alert ("Dies ist ein NN bis 4.x!");
Damit könnt Ihr Eure Skripte für alle drei Varianten anpassen
var bild; // die Variable
if (document.getElementById)
bild = document.getElementById("das_bild");
if (document.all)
bild = document.all.das_bild;
if (document.layers)
bild = document.images["das_bild"];
// wie auch immer wir rangekommen sind,
// jetzt wird das src-Attribut überschrieben
bild.src = "einAnderesBild.jpg";
Lora will 'nen Keks!
Bevor wir uns der serverseitigen Programmierung mit PHP zuwenden, noch zwei
«Kleinigkeiten», die aber durchaus nützlich sein können.
Das erste Thema sind Cookies.
Wie bereits erwähnt, darf JavaScript nicht auf die Festplatte des
Client-Rechners zugreifen, mit einer Ausnahme - eben Cookies. Das sind
kleine Dateien, die auf der Festplatte des Users abgelegt werden
können. Darin kann die Webseite Informationen ablegen, die beim
nächsten Aufruf wieder zur Verfügung stehen. Als Beispiel nehmen
wir eine Newsticker-Seite. Der User kann angeben, für News von welchen
Verlagen er sich interessiert, die stehen dann gleich zu Beginn. Damit der
User nicht jedesmal, wenn er auf die Seite geht, diese Lieblingsverlage neu
einstellen muß, könnt Ihr sie in einem Cookie speichern.
Pro Webseite ist nur ein Cookie gleichzeitig möglich, mit genau einem
String als Inhalt. Ihr könnt nicht beliebig eine Datei auf die
Festplatte des Clients schreiben, sondern der Inhalt des Cookies steht
über eine Eigenschaft des document-Objekts zur Verfügung
// speichert den String 'site=SplashComics' im Cookie
document.cookie = "site=SplashComics";
alert (document.cookie); // liest den Inhalt des Cookies aus
Wenn Ihr mehrere Werte in einem Cookie speichern wollt, müßt Ihr
diese Werte in einem String «zusammenpacken». Das geschieht nach
dem Muster
bezeichner1=wert1;bezeichner=wert2;bezeichner3=wert3; ...
Diesen String müßt Ihr dann beim Auslesen des Cookies leider
von Hand wieder auseinanderpuzzlen (mit Hilfe der Funktionen der
string-Klasse).
Cookies haben ein eingebautes Verfallsdatum, nach dessen Ablauf sie
automatisch gelöscht werden. Wenn Ihr dieses Datum nicht explizit setzt,
ist der Cookie nur in der aktuellen Session
gültig. Die geht zu Ende, wenn der User seinen Browser schließt.
Wenn Euer Cookie darüber hinaus erhalten bleiben soll, muß
das Ablaufdatum explizit gesetzt werden. Das geschieht einfach, indem Ihr
innerhalb Eures Cookie-Strings einen Wert für den Bezeichner 'expires'
setzt. Den Wert zu diesem Bezeichner erzeugt Ihr mit der Funktion
toGMTString() aus der Klasse Date
var jetzt = new Date(); // Date-Objekt mit dem jetztigen Zeitpunkt
// addiere zu diesem Zeitpunkt die Millisekunden eines Jahrs dazu
var endzeit = new Date(jetzt.getTime() + 1000*60*60*24*365);
// dieser Cookie hat ein Jahr Gültigkeit
document.cookie = "site=SplashComics;expires="+endzeit.toGMTString()+";";
Ihr solltet Euch allerdings nicht zu sehr auf Cookies verlassen, weil die
bekanntlich im Browser abgeschaltet werden können.
Speisekarte
Zu guter Letzt noch ein Skript, nach dem oft gefragt wurde: Ein
Drop-Down-Menu. Wenn der User auf einen Menupunkt
klickt, werden die passenden Unterpunkte sichtbar. Das kann dann etwa so
aussehen
In einem «echten Menu» wären natürlich auch die
Unterpunkte Links, das ist hier zur besseren Übersichtlichkeit
weggelassen. Technisch nutzt das Menu die CSS-Eigenschaft
display. Sie entscheidet darüber, ob ein
HTML-Element vom Browser dargestellt wird oder nicht. Ihr schreibt also
einfach den HTML-Code für alle Menus und Untermenus im voll
«ausgeklappten» Zustand. Für die Teile, die nicht sichtbar
sein sollen, setzt Ihr display auf 'none'. Wieder sichtbar werden die
Untermenus mit Hilfe einer Funktion, die display auf 'block'
(als Blockelement darstellen) setzt. Diese Funktion wird vom jeweiligen
Menupunkt aufgerufen
<script type="text/javascript">
<!--
function doMenu(id)
{
// wenn eingeklappt, klappe aus
if (document.getElementById(id).style.display == "none")
document.getElementById(id).style.display = "block";
// wenn ausgeklappt, klappe ein
else
document.getElementById(id).style.display = "none";
}
//-->
</script>
...
<div>
<ul>
<!-- Der erste Menupunkt -->
<li><a href="javascript:doMenu('0')">Rezessionen</a></li>
<!-- Das erste Untermenu, auf unsichtbar geschaltet -->
<ul style="display:none" id="0">
<li>Manga</li>
<li>Frankobelgisches</li>
<li>Superhelden</li>
</ul>
<!-- Der zweite Menupunkt -->
<li><a href="javascript:doMenu('1')">Neuerscheinungen</a></li>
<!-- Das zweite Untermenu, auf unsichtbar geschaltet -->
<ul style="display:none" id="1">
<li>Verlag A</li>
<li>Verlag B</li>
<li>Verlag C</li>
</ul>
<!-- Der dritte Menupunkt -->
<li><a href="javascript:doMenu('2')">Lexikon</a></li>
<!-- Das dritte Untermenu, auf unsichtbar geschaltet -->
<ul style="display:none" id="2">
<li>Begriffe</li>
<li>Serien und Charaktäre</li>
<li>Suchen</li>
</ul>
</ul>
</div>
Diese Menu könnt Ihr graphisch noch beliebig aufpeppen, mit Grafiken,
Hintergründen, etc. Außerdem braucht Ihr natürlich keine
nicht-nummerierten Listen (ul) zu verwenden. Es gibt nur zwei
Grundsätze, die Ihr im Auge behalten müßt: Was unsichtbar
sein soll, mit 'display=none' ausschalten. Um es wieder sichtbar zu machen,
per Funktion 'display=block' (bzw. 'display=inline' für
Inline-Elemente) setzen. Ansonsten sind Euch praktisch keine Grenzen gesetzt.
|