DOM und Ajax
Das Document Object Model (DOM) bescheibt eine HTML-Seite so, dass mit JavaScript auf jedes einzelne Element zugegriffen werden kann. Diese Modellierung lässt auch das Einfügen oder Löschen von Elementen einer HTML-Seite zu, ohne das die Seite neu geladen und aufgebaut werden muss.
DOM bildet ein HTML-Dokument als Baumstruktur ab. Jedes Element bildet einen Kind- (child-) und Elternknoten (parent-node) sowie evtl. Folgekoten (nextSibling) und Vorgängerknoten (previousSibling) haben kann.
<table> <thead> <tr> <th>Vorname</th> <th>Name</th> </tr> </thead> <tbody> <tr> <td>Donald</td> <td>Duck</td> </tr> </tbody> </table>
Im obrigen Beispiel hat <tbody> ein Elternknoten (<table>) und einen Kindknoten (<tr>).
Eigenschaften eines DOM-Knotens
firstChild | Erster Kindknoten |
lastChild | Letzter Kindknoten |
nextSibling | Nächster Knoten auf gleicher Ebene |
previousSibling | Vorhergehender Knoten auf gleicher Ebene |
parentNode | Elternknoten |
Weitere Eigenschaften eines Knotens
nodeName | Name des HTML-Tags (z.B. "table") |
nodeType | 1 = Tag, 2 = Attribut, 3 = Text |
Das DOM stellt ein Array mit Unterarrays dar, das sich nun mit JavaScript ansprechen lässt. Da man gewöhnlich nicht den Index des Array zählen will, sollten den einzelnen Elementen ID-Parameter zugewiesen werden. So kann man Elemente aus dem DOM komfortabel mit sprechenden Namen ansteuern.
<table ID="tabelle"> <thead ID="kopf"> <tr ID="kopfzeile"> <th ID="vname">Vorname</th> <th ID="nname">Name</th> </tr> </thead> <tbody ID="inhalt"> <tr ID="erste Zeile"> <td ID="feld11">Donald</td> <td ID="feld12">Duck</td> </tr> </tbody> </table>
Für das Ändern, Einfügen oder Löschen von Knoten im DOM-Baum stehen folgende Funktionen zu Verfügung:
x.appendChild(Kind) | Einen Kindknoten an das Element anhängen |
x.cloneNode(boolean) | Erzeugt ein Duplikat vom Knoten. Ist der Parameter true, werden auch alle Kindknoten dupliziert. |
x.createElement(Tag) | Erzeugt ein Element aus dem angegebenen Tag |
x.hasChildNodes() | Gibt zurück ob Kindknoten bestehen, boolean |
x.insertBefore(Kind, Schwester) | Einen Kindknoten direkt vor Schwester einfügen |
x.removeNode(Kinder) | Entfernt einen Knoten. Ist Kindet true werden auch alle Kindknoten entfernt |
x.areplaceNode(neu) | Ändert einen Knoten |
x.setAttribute(Name,Wert) | Setzt ein neues Attribut des Knotens |
In JavaScript können Sie konfortabel auf einzelne Objekte mit folgenden Funktionen zugreifen:
var obj = document.getElementById("feld11");
var obj = document.getElementsByName("feld11");
var obj = document.getElementsByClassName("feld11");
Ein Anwendungsbeispiel könnte eine Literaturdatenbank sein. Je nachdem ob eine Monographie oder eine Aufsatz eingegeben werden soll, muss sich die Anzahl der Eingabefelder ändern. Siehe hierzu Beispiel 19.
Ajax steht für Asynchronous JavaScript and XML. Ajax selbst ist ein Verfahren, bei dem verschiedene Techniken auf bestimmte Weise zusammenwirken: HTML (bzw. DOM), JavaScript und XML.
Das Verfahren ist bereits seit ca. 1998 bekannt, erlebte aber erst 2006 durch Google seinen Durchbruch.
Das Problem bei vielen Anfragen an den Webserver ist, dass, obwohl nur ein kleiner Teil der Webseite verändert werden soll (z.B. ein Kontextmenue soll eingeblendet werden), die ganze Webseite neu übertragen werden muss. Mit Hilfe des DOMs können nun nur einzelne Teile der Webseite ersetzt oder ergänzt werden.
Dabei wird mittels eines in die Webseite eingebetteten JavaScripts ein HTTP-Request ausgeführt, der nicht eine komplett neue Webseite anfordert, sondern nur den Teil der Seite, der sich geändert hat. DOM erlaubt dann gezielt den Rücklauf des Webservers in das HTML-Dokument im Browser einzusetzen ohne die ganze Seite neu zu laden.
Die Antwort des Webservers ist in der Regel ein XML-Dokument, das interpretiert und dann als HTML-Schnipsel in das DOM eingesetzt wird.
Dieses Verfahren hat verschiedene Vorteile:
Dahinter steckt das Ziel, Webseiten funktionell so reichhaltig und schnell zu machen, das sie von Desktop-Anwendungen kaum mehr zu unterscheiden sind (Rich User Interfaces). Man will sich vom Seitenparadigma lösen, hin zu einem Applikations-Paradigma.
Wie nicht anders zu erwarten hat(te) diese Technik gerade in ihren Anfängen Probleme mit der Browser-Kompatibilität.
Andererseits könnte Ajax der Motor sein, der das Interesse der Softwarefirmen verschiebt und so eine Standardisierung der JavaScript-Implementationen vorantreibt.
Das Bookmarking solcher Anwendungen ist dann natürlich nicht mehr möglich, da es keine statischen Ressourcen mehr gibt auf die verwiesen werden könnte. Der Backbutton führt hier zu unerwarteten Ergebnissen. Vielmehr müssten sich diese Applikationen dann eine „Wiederrufen“-Funktion bedienen.
Ein Beispiel 20:
Zunächst benötigen wir eine HTML-Seite die lediglich einen Link zum Auslösen der Ajax-Anfrage dient und ein Container (hier <span>) um das Ergebnis anzuzeigen. Der Span-Tag hat eine ID bekommen um ihn später über den DOM-Baum besser ansprechen zu können.
<a href="javascript:sayHello();">Say Hello</a><br />
<span id="result"></span>
Jetzt folgt der HTTP-Request, also die Anfrage über HTTP. Dazu benötigen wir ein Objekt, das diese Anfrage senden kann und das Ergebnis liefert. Da Microsoft mal wieder sein eigenes Süppchen kocht und sich nicht an den Standard hält, muss beim HTTP-Request-Objekt unterschieden wedren.
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest)
return new XMLHttpRequest();
else if (window.ActiveXObject)
return new ActiveXObject("Microsoft.XMLHTTP");
else
alert ("Ihr Browser unterstützt keine HTTPRequest-Objekte.");
}
Jetzt kann ein konkretes Request Objekt erzeugt werden:
var requestObject = getXmlHttpRequestObject();
Nachdem wir ein Objekt haben können wir die Ajax-Aufruf schreiben, der ausgelöst wird, wenn der Nutzer den Link anklickt.
function sayHello() {
// Wenn der XmlHttpRequest nicht gerade dabei ist einen Aufrunf abzuarbeiten
if (requestObject.readyState == 4 || requestObject.readyState == 0) {
// GET Request zur Datei sayHello aufbauen
requestObject.open("GET","sayHello.html", true);
// Die Funktion festlegen, die aufgerufen werden soll,
// wenn sich der Status des XmlHttpRequest ändert
requestObject.onreadystatechange = handleSayHello;
// Request endgültig auslösen
requestObject.send(null);
}
}
Wird nun der Link angeklickt und der Request ist erfolgreich wird die Methode handleSayHello aufgerufen.
// Diese Funktion wird bei jedem Statuswechsel des Request Objekts aufgerufen!
function handleSayHello() {
// nachsehen ob der Request beendet ist
if (requestObject.readyState == 4) {
// Mittels DOM das span-Element ändern
document.getElementById('result').innerHTML = requestObject.responseText;
}
}
Klickt man nun auf den Link, wird "Hello World!" in den Span-Tag eingebaut. Im Quellcode ist das nicht zu sehen.