|
|
|
4.6 DHTML
|
|
|
|
|
4.6.1
Einführung
DHTML - was ist das?
Das "D" vor dem "HTML" steht für "Dynamic". Es geht also um dynamisches HTML, wobei diese Bezeichnung wohl auch nur eine Phrase wie DHTML selbst ist. Es geht darum, Web-Seiten mit interaktiven Elementen zu erstellen. Unter "aktiv" versteht man dabei mehr als simple Statusleisten-Scripts oder ähnliches.
DHTML ermöglicht viel mehr. Es ist möglich, eine komplette Anwendung in DHTML zu schreiben. Es ist auch möglich, mit DHTML seine Seiten wie mit Flash zu animieren.
|
|
|
4.6.2
Nötiges Vorwissen
JavaScript müssen Sie beherrschen. Wenn das noch nicht der Fall ist, kann das vorhergehende Kapitel Ihnen sicher helfen. Ebenso sollten Sie ein wenig von objektorientierter Programmierung verstehen, denn das DOM wird über ein OOP-Konzept zugänglich gemacht.
|
|
|
4.6.3
Das DOM
4.6.3.1 Allgemeines
Das DOM (Document Object Model) definiert, wie von einer Scriptsprache auf die Elemente einer XML-basierten Sprache zugegriffen werden soll. XML-basiert ist hier ein wenig schwammig, denn HTML selbst ist alles andere als XML-basiert. Damit wird es zum Standard-Modell, um dynamische Webseiten zu erzeugen. Ernstzunehmende Alternativen gibt es keine.
Das DOM ist ein W3C-Standard, der - wie sollte es auch anders sein - noch längst nicht vollständig und von allen Browsern interpretiert wird. Ab Netscape 6 und MSIE 5 klappt es jedoch einigermaßen.
Vor dem DOM gab es proprietäre Methoden zum dynamischen Zugriff auf Webseiten. Nun, wo es das DOM gibt, macht es keinen Sinn mehr, sich mit diesen Methoden zu beschäftigen, außer, man will beispielsweise unbedingt eine Anwendung für ältere Browser wie den NN 4.x schreiben.
In unserem Fall beziehen wir das DOM auf (X)HTML und verwenden JavaScript als Scriptsprache. Das muss aber nicht immer so sein: es gibt Perl-Module, mit denen man Server-seitig mit dem DOM arbeiten kann.
4.6.3.2 Das DOM-Objektmodell
XML-basierende Dateien lassen sich als hierarchische Baumstruktur darstellen. Einzelne Elemente des Baumes werden als "Knoten" bezeichnet und können selbst wiederum andere Knoten enthalten.
Wer Probleme hat, sich das vorzustellen, sollte jetzt seinen Dateimanager öffnen: so zeigt z.B. der Explorer von Windows ebenfalls eine Baumstruktur.
| | So könnte die Umwandlung von HTML-Quellcode in ein Baum-Modell aussehen. | Das DOM-Modell geht davon aus, dass alles, was in der Quelldatei steht, auf irgendeine Weise ein Knoten ist. Beim Code <p align="right">rechtsgerichteter Text</p> gibt es schon mehrere Knoten: zunächst einmal den p-Knoten, der in der Hierarchie ganz oben steht. Dieser Knoten hat einen zugehörigen align-Knoten und einen Text-Knoten, der den eigentlichen Inhalt des Tags speichert.
4.6.3.3 Zugriff auf Knoten
Um vernünftig mit dem DOM arbeiten zu können, muss man auf einzelne Knoten Zugriff nehmen können. Aktuelle JavaScript-Interpreter stellen dafür drei Funktionen bereit:
document.getElementById(id) gibt ein Objekt zurück. Welches, das wird durch den id-Parameter spezifiziert.
document.getElementsByName(name) gibt ein oder mehrere Objekte zurück, die den durch den name-Parameter angegebenen spezifizierten Namen tragen.
document.getElementsByTagName(tagname) gibt ein oder mehrere Objekte zurück, deren Tag dem durch das tagname-Attribut spezifizierten entspricht
Damit solche Funktionen Sinn machen, müssen bestimmte Tags mit einer ID bzw. mit einem Namen gekennzeichnet werden. ID-Werte müssen eindeutig sein, Namen können mehrmals vorkommen.
Beispiel:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function ChangeP()
{
var myobj = document.getElementById("id1");
myobj.style.color = "red";
}
</script>
</head>
<body>
<p id="id1" onClick="ChangeP();">Mein Inhalt</p>
</body>
</html>

Im Beispiel-Code findet sich eine Anweisung, die Sie noch nicht verstehen können: onClick="ChangeP();". Damit wird ein Event-Handler definiert - dazu weiter unten mehr.
|
|
|
4.6.4
Das Aussehen von Knoten mit CSS verändern
Sehen Sie sich folgenden Code im Browser an:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function ChangeP(color)
{
var myobj = document.getElementById("id1");
myobj.style.color = color;
}
</script>
</head>
<body>
<p id="id1">Farb-Zeile</p>
<p onClick="ChangeP('red');">Rot machen!</p>
<p onClick="ChangeP('green');">Grün machen!</p>
<p onClick="ChangeP('blue');">Blau machen!</p>
</body>
</html>

Je nachdem, auf welchen der drei Befehle geklickt wird, verändert sich die Farbe der obersten Zeile.
Realisiert wird das in der Zeile myobj.style.color = color;:
Knoten-Objekte (in diesem Fall myobj haben ein style-Unterobjekt. Dieses stellt sämtliche per CSS festlegbaren Eigenschaften zur Verfügung. Die Namen der Eigenschaften müssen klein geschrieben werden, Bindestriche sind nicht erlaubt. Um eine Eigenschaft wie font-family zu verwenden, schreibt man style.fontFamily - der Buchstabe, der vorher hinter dem Bindestrich stand, wird nun groß geschrieben.
|
|
|
4.6.5
Zugriff auf HTML-Attribute
Der Zugriff auf HTML-Attribute verläuft ähnlich wie der auf CSS-Eigenschaften. Wir demonstrieren das am Beispiel des Attributs align:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function ChangeA(align)
{
var myobj = document.getElementById("id1");
myobj.align = align;
}
</script>
</head>
<body>
<p id="id1">Ausrichtungs-Zeile</p>
<p onClick="ChangeA('right');">Nach rechts!</p>
<p onClick="ChangeA('center');">Mitte!</p>
<p onClick="ChangeA('left');">Links!</p>
</body>
</html>

Die Knoten-Objekte stellen also ihre HTML-Attribute als direkte Unterobjekte zur Verfügung.
|
|
|
4.6.6
Den Inhalt von Knoten ändern
Wer wirklich dynamische Seiten erstellen will, muss auch Texte und Knoteninhalte ändern können. Ein Beispiel:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function ChangeT(text)
{
var myobj = document.getElementById("id1");
var neutext = "debug";
if (text == 1)
{
neutext = "Das ist Text 1!";
}
if (text == 2)
{
neutext = "Das ist Text 2!";
}
myobj.firstChild.nodeValue = neutext;
}
</script>
</head>
<body>
<p id="id1">Noch bin ich unverändert</p>
<p onClick="ChangeT(1);">Text1</p>
<p onClick="ChangeT(2);">Text2</p>
</body>
</html>

Ein Knoten stellt seinen Inhalt über die Eigenschaft nodeValue bereit. Aber wieso verwenden wir firstChild.nodeValue? Knoten speichern ihren eigentlichen Inhalt in einem weiteren Unterknoten. Dieser erste Unterknoten (fast immer mit den Inhalten darin) lässt sich über firstChild ansprechen.
|
|
|
4.6.7
Die Baumstruktur verändern
Wer neue Knoten und damit Tags einbinden will, muss in die Baumstruktur eingreifen. Das folgende Beispiel zeigt, wie das geht. Achten Sie besonders auf die Kommentare.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function ChangeK()
{
var myobj = document.getElementById("id1");
// Neuer Nur-Text-Knoten
var neu_text = document.createTextNode("... jetzt ist ein neuer Knoten da!");
myobj.appendChild(neu_text);
// Neues anderes Objekt: Link
var neu_link = document.createElement("a");
// Unser Link braucht einen Text... den speichert er als ersten Unterknoten
var neu_linktext = document.createTextNode("Link zu AWD");
neu_link.appendChild(neu_linktext);
neu_link.href = "http://www.aboutwebdesign.de";
myobj.appendChild(neu_link);
}
</script>
</head>
<body>
<p id="id1" align="left">Noch bin ich unverändert</p>
<p onClick="ChangeK();">Mehr Text!</p>
</body>
</html>

myobj.appendChild(neu_knoten) hängt also neu_knoten in die Struktur von myobj ein.
Um einen neuen Knoten einhängen zu können, muss er zunächst einmal erzeugt werden: createTextNode(Text) und createElement(typ) erledigen das.
Schwieriger zu verstehen ist die Erzeugung des Links: zunächst einmal wird ein Link-Objekt erzeugt. Dem geben wir dann seinen Inhalt mit, indem wir ein TextNode-Objekt einklinken. Schließlich bekommt der Link noch ein Linkziel und wird in myobj eingehängt.
|
|
|
4.6.8
Timer
Gerade Bewegungen setzen zeitgesteuerte Abläufe voraus. Dafür werden - wie im folgenden Script - Timer eingesetzt:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
var insgesamt = 0;
function init()
{
var myobj = document.getElementById("id1");
myobj.style.position = "absolute";
myobj.style.left = 0;
}
function doit()
{
var myobj = document.getElementById("id1");
myobj.style.left = insgesamt * 5;
insgesamt++;
if (insgesamt < 100)
{
window.setTimeout('doit();', 50);
}
}
</script>
</head>
<body onLoad="init();">
<div id="id1">|||||||||||-||||||||||-||||||||||</div>
<br><br><p onClick="doit()">Go!</p>
</body>
</html>

Wenn auf "Go!" geklickt wird, bewegt sich der Layer (definiert durch <div> ... </div>)nach rechts.
Zum Ablauf: wenn das Script geladen wird, ruft der Event-Handler <body onLoad="init();"> die Funktion init() auf. Dort werden elementare Einstellungen vorgenommen, so z.B. der Positionierungstyp und der Abstand vom linken Rand.
Wenn der Anwender dann auf "Go!" klickt, beginnt der Spaß: über einen Event-Handler wird doit() aufgerufen. doit() verschiebt zunächst einmal den Layer, indem die globale Variable insgesamt mit einem festen Wert multipliziert wird. Da insgesamt bei jedem Durchlauf um 1 erhöht wird, wird auch insgesamt * 5 immer größer.
Dann wird überprüft, wie oft die Funktion schon aufgerufen wurde - 100 Aufrufe sind erlaubt. Wenn es weniger als 100 sind, wird ein Timer gesetzt: window.setTimeout('doit();', 50);. Das bedeutet, dass die Funktion doit() in 50 Millisekunden erneut aufgerufen wird.
|
|
|
4.6.9
Event-Handler
Konstrukte wie <body onLoad="init();"> haben Sie schon öfters gesehen. Dabei handelt es sich um Event-Handler (übersetzt "Ereignis-Behandler"), die als Brücke zwischen HTML und JavaScript gelten. Event-Handler führen einen bestimmten Code aus, wenn ein vorher festgelegtes Ereignis eintritt, so z.B. wenn der Anwender auf eine Schaltfläche klickt.
Meist werden die Event-Handler direkt in HTML-Tags notiert, wie auch in unserem Beispiel. Solche Handler beziehen sich immer auf das Tag, in dem sie notiert wurden.
Zur Syntax: Event-Handler beginnen immer mit on. Es folgt der restliche Name, in Anführungszeichen dahinter steht JavaScript-Code, der ausgeführt wird, wenn der Handler aufgerufen wird.
Es gibt natürlich noch andere Handler als onLoad (wird ausgelöst beim Laden des Tags). Wir stellen Ihnen nun einige vor, eine vollständige Liste finden Sie in SelfHTML.
- onClick (geklickt)
- onDblClick (doppelt geklickt)
- onSubmit (Formular wird abgeschickt). Wenn der dahinter folgende Code eine 0 zurückgibt, wird das Formular nicht abgeschickt, siehe dazu auch "JavaScript Know-How".
- onMouseover (Kontakt mit Mauszeiger)
- onMouseout (Mauszeiger wieder entfernt)
|
|
|
4.6.10
Fazit
Sie beherrschen nun DHTML, zumindest die Theorie dahinter. Im Endeffekt kommt es auf Ihre Kreativität an. Wenn Sie auf der Suche nach Inspiration sind, finden Sie im Internet gute weiterführende Quellen, so z.B. Milch & Zucker.
|
|
|
|