Ajax meistern, Teil 4: Mit dem DOM die Web Response optimal verwerten
Brett McLaughlin (brett@newInstance.com), Autor und Editor, O'Reilly Media Inc.
Deutsche Übersetzung: Claudia Nölker
Seit langer Zeit besteht eine tiefe Kluft zwischen Programmierern (die an Backend-Anwendungen arbeiten) und Web-Programmierern (die ihre Zeit mit HTML, CSS und JavaScript verbringen). Das Document Object Model (DOM) schließt diese Kluft und ermöglicht sowohl im Backend als auch im Frontend das effektive Arbeiten mit XML. In diesem Artikel stellt Brett McLaughlin das Document Object Model vor, erläutert seine Verwendung in Webseiten und zeigt, wie JavaScript dabei eingesetzt werden kann.
Wie viele Web-Programmierer arbeiten Sie wahrscheinlich mit HTML. Mit HTML beginnen Programmierer die Arbeit an der Webseite und mit HTML schließen sie diese auch ab, um der Anwendung oder Website bei der Positionierung, den Farben und Styles den letzten Schliff zu geben. Genauso weit verbreitet wie die Verwendung von HTML ist auch die irrige Meinung über das, was mit dem HTML passiert, sobald es zur Darstellung an den Browser geschickt wurde. Doch bevor ich darauf eingehe, was da Ihrer Meinung nach wohl passiert -- und das ist vermutlich falsch -- möchte ich, dass Sie ein klares Verständnis vom Prozess der Erstellung und Auslieferung von Webseiten haben:
- Jemand (üblicherweise Sie) erstellt HTML in einem Text-Editor oder einer IDE.
- Dann laden Sie das HTML auf einen Webserver wie Apache HTTPD und veröffentlichen es damit im Internet oder Intranet.
- Ein User fordert Ihre Webseite mit einem Browser wie Firefox oder Safari an.
- Der Browser des Users stellt an Ihren Webserver eine Anfrage nach dem HTML.
- Der Browser stellt die erhaltene Seite graphisch und textlich dar; der User sieht und verwendet dann die Webseite.
Auch wenn Ihnen dieses noch banal vorkommt, wird es hier doch bald spannend. In diesem Artikel kümmern wir uns um die gewaltige Menge an "Zeugs", das zwischen den Schritten 4 und 5 passiert. Der Ausdruck "Zeugs" ist dabei bewusst gewählt, denn die meisten Programmierer haben sich noch nie Gedanken darüber gemacht, was mit ihrem Markup geschieht, sobald der Browser eines Users es ausgeben soll:
- Liest der Browser nur das HTML und stellt es dar?
- Was ist mit dem CSS, insbesondere wenn das CSS in einer separaten Datei ausgelagert ist?
- Und was ist mit dem JavaScript (auch das kann in einer externen Datei sein)?
- Wie verarbeitet der Browser diese Dinge und wie verknüpft er Event-Handler, Funktionen und Styles mit diesem textuellen Markup?
Es stellt sich heraus, dass die Antwort auf all diese Fragen das Document Object Model ist. Also, stürzen wir uns nun ohne weitere Vorrede auf das DOM.
Für die meisten Programmierer hört der Job da auf, wo der Web-Browser beginnt. Mit anderen Worten: Sobald die HTML-Datei in einem Verzeichnis auf dem Webserver abgelegt wurde, ist die Sache für Sie erledigt und Sie denken (hoffentlich) nie wieder daran! Das ist auch ein klasse Ziel, wenn es darum geht, sauberen Code und gut organisierte Seiten zu erstellen. Es ist nichts falsch daran, dass Ihr Markup unabhängig von Browsern und verschiedenen Versionen von CSS und JavaScript ausgibt, was es soll.
Das Problem ist nur, dass diese Vorgehensweise das Verständnis eines Programmierers über die Abläufe im Browser einschränkt. Und noch wichtiger: Es schränkt auch Ihre Fähigkeit ein, Teile der Webseite mit client-seitigem JavaScript zu aktualisieren, zu ändern und neu zu strukturieren. Überwinden Sie diese Grenzen und gönnen Sie Ihren Webseiten mehr Interaktion und Kreativität.
Als typischer Web-Programmierer starten Sie wahrscheinlich Ihren Text-Editor oder Ihre IDE und legen dann mit HTML, CSS oder sogar JavaScript los. Es ist nahe liegend, sich diese Tags, Selektoren und Attribute als kleine Aufgaben vorzustellen, die dafür sorgen, dass die Seite aussieht wie gewünscht. Doch diese Vorstellung müssen Sie überwinden -- begreifen Sie, dass Sie Inhalt organisieren. Keine Bange, ich verspreche Ihnen, dass dies hier nicht zu einem Vortrag über die Schönheit von Markup ausartet oder dass Sie das wahre Potential einer Webseite erkennen sollten oder etwas anderes Metaphysisches. Was Sie verstehen müssen, ist einfach nur Ihre Rolle bei der Web-Entwicklung.
Wie eine Seite aussehen soll, können Sie allenfalls vorschlagen. Wenn Sie ein CSS-Stylesheet bereitstellen, kann der User sich über Ihre Auswahl von Styles hinwegsetzen. Wenn Sie eine Schriftgröße vorgeben, kann der Browser des Users diese Größen für Sehbehinderte verändern oder auf riesigen Monitoren (mit einer entsprechend riesigen Auflösung) herunterskalieren. Sicher sollten Sie beim Stylen einer Seite Ihr Bestes geben, doch das ist nicht der größte Einfluss, den Sie auf die Seite haben.
Was Sie wirklich total kontrollieren, ist die Struktur Ihrer Webseite. Ihr Markup ist nicht veränderbar und die User können es nicht verpfuschen; ihre Browser können es nur vom Web-Server abholen und darstellen (wenn auch mit Styles, die den Usern besser gefallen als Ihre). Aber der Aufbau der Seite -- ob ein Wort innerhalb eines Abschnitts steht oder in einem weiteren div -- liegt ganz in Ihrer Hand. Wenn es dann ans Verändern der Seite geht (und darauf zielen die meisten Ajax-Anwendungen ab), gehen Sie an die Struktur der jeweiligen Seite. Auch wenn es nett sein mag, die Farbe eines Stückchen Texts zu verändern; viel einschneidender ist es, etwas Text oder gar einen Abschnitt zu einer bestehenden Seite hinzuzufügen. Egal mit welchen Styles der User sich das darstellen lässt, den Aufbau der Seite bestimmen Sie selbst.
Wenn Ihnen klar ist, dass es beim Markup um die Organisation der Seite geht, können Sie es mit anderen Augen betrachten. Anstatt zu denken, dass ein h1 den Text groß, schwarz und fett gedruckt macht, fassen Sie ein h1 nun als Überschrift auf. Wie die User das sehen, steht an zweiter Stelle-- dabei ist es egal, ob sie nun Ihr CSS, das eigene oder eine Kombination von beidem verwenden. Machen Sie sich also klar, dass es beim Markup darum geht, die Organisation der Seite festzulegen: Ein p bezeichnet einen Absatz, img kennzeichnet ein Bild, div teilt die Seite in Abschnitte ein und so weiter.
Sie sollten sich auch bewusst machen, dass Style und Verhalten (Event-Handler und JavaScript) erst nachträglich auf diesen Aufbau angewendet werden. Das Markup muss an Ort und Stelle sein, bevor damit gearbeitet werden kann. Genau wie sich das CSS für Ihr HTML in einer separaten Datei befinden kann, ist auch der Aufbau des Markup getrennt von seinem Style, seiner Formatierung und seinem Verhalten. Auch wenn Sie natürlich den Style eines Elements oder Stück Texts mit JavaScript ändern können, ist es viel interessanter, den durch das Markup festgelegten Aufbau der Seite an sich zu verändern.
Solange Sie im Hinterkopf behalten, dass das Markup nur den Aufbau (oder das Gerüst) Ihrer Seite bestimmt, sind Sie mit von der Partie. Gleich werden Sie auch sehen, wie der Browser all diesen textuellen Aufbau nimmt und in etwas deutlich Interessanteres verwandelt -- in eine Menge von Objekten, die alle einzeln verändert, erweitert oder gelöscht werden können.
|
Bevor wir zum Web-Browser kommen, lohnt es sich darüber nachzudenken, warum einfacher Text die absolut beste Wahl ist, um HTML zu speichern. (Mehr hierzu finden Sie im Abschnitt Ein paar Gedanken zum Markup.) Ohne jetzt tief in die Vor- und Nachteile einzusteigen, denken Sie einfach daran, dass Ihr HTML bei jedem Laden der Seite durch das Netz zum Browser geschickt wird. (Der Einfachheit halber ignorieren wir hier mal Caching und ähnliche Techniken.) Es gibt einfach keinen effizienteren Ansatz, um Text weiterzugeben. Binäre Objekte, graphische Repräsentationen der Seite, ein re-strukturierter Brocken Markup ... all das ist schwerer durch das Netz zu schicken als simple Textdateien.
Hinzu kommt, was ein Browser in die Waagschale legt. Aktuelle Browser erlauben es dem User, die Textgröße zu ändern, Bilder zu skalieren, (meistens) das CSS oder JavaScript einer Seite herunter zu laden und noch viel mehr -- dies alles wäre nicht möglich, wenn eine graphische Repräsentation der Seite an den Browser gesendet würde. Der Browser benötigt also das reine Text-HTML, um die weitere Verarbeitung durchzuführen, er kann sich nicht darauf verlassen, dass der Server die Arbeit erledigt. Wenn man dann noch das CSS vom JavaScript trennen will und beides wiederum vom HTML-Markup, verlangt das nach einem Format welches leicht zu, naja, separieren ist. Textdateien sind hierfür einfach bestens geeignet.
Zu guter Letzt denken Sie dann noch daran, was die neuen Standards wie HTML 4.01 und XHTML 1.0 und 1.1 versprechen: die Trennung des Inhalts (den Daten auf Ihrer Seite) von der Präsentation und den Styles (üblicherweise durch CSS festgelegt). Wenn Programmierer HTML und CSS trennen, der Browser dann aber beides doch zu irgendeiner Form von Repräsentation der Seite zusammenfügt, wären die Vorteile dieser Standards zunichte gemacht. Es ist schon sinnvoll, diese verschiedenen Teile auf dem gesamten Weg vom Server bis zu Browser getrennt voneinander zu halten -- so ist die Flexibilität am größten.
Der Browser aus der Nähe betrachtet
Manchen von Ihnen wird alles Bisherige wie ein kurioser Abriss Ihrer Rolle im Prozess der Web-Entwicklung vorkommen. Doch was wirklich hinter den Kulissen des Browsers abläuft, wissen viele der zumeist cleveren Webdesigner und -Entwickler nicht. In diesem Abschnitt geht es genau darum. Und keine Bange, Sie bekommen auch noch Quellcode zu sehen, doch haben Sie noch etwas Geduld, bevor Sie zur Tastatur greifen -- ein genaues Verständnis der Abläufe im Webbrowser ist wichtig, damit Ihr Code richtig funktioniert.
Ebenso wie Text-Markup sagenhafte Vorteile für die Designer oder Ersteller einer Seite bietet, hat es gleichzeitig auch erhebliche Nachteile für den Browser. Dabei geht es insbesondere darum, dass es für die Browser nicht einfach ist, das Text-Markup für den User visuell aufzubereiten. (Mehr hierzu unter Ein paar Gedanken zum Markup.) Denken Sie mal an folgende Situationen:
- CSS Styles anhand von Element-Typen, Klassen, IDs und deren Position innerhalb vom HTML-Dokument anwenden -- oft von mehreren Stylesheets in externen Dateien
- Styles und Formatierung abhängig von JavaScript-Code auf verschiedene Teile vom HTML-Dokument anwenden -- und auch das JavaScript ist oft in externen Dateien
- Die Werte von Formular-Feldern mit Hilfe von JavaScript-Code verändern
- Visuelle Effekte wie das Austauschen von Bilder mit JavaScript unterstützen
Die Komplexität hierbei liegt nicht in der Programmierung (die ist ziemlich einfach), sondern liegt beim Browser, der die verlangte Aktion anschließend ausführen muss. Wenn das Markup als Text vorliegt und Sie zum Beispiel Text in einem p-Element mit einer center-text-Klasse zentrieren (text-align: center) wollen, wie stellen Sie das an?
- Fügen Sie dem Text Inline-Styling hinzu?
- Wenden Sie die Styles auf den HTML-Text im Browser an und passen auf, wo der Inhalt zentriert wird und wo nicht?
- Stellen Sie das HTML erst einmal ohne Styles dar und formatieren es im Nachhinein?
Wegen diesen schwierigen Fragen programmieren heutzutage so wenige Leute Browser. (Ein herzliches "Danke!" an diejenigen, die es tun!)
Ganz klar, einfacher Text ist nicht gerade der beste Weg, um HTML für den Browser bereitzustellen, selbst wenn Text eine gute Lösung war, um das Markup an Ort und Stelle zu bringen. Wenn dann noch die Möglichkeiten von JavaScript hinzukommen, die Struktur einer Seite zu ändern, wird es richtig kniffelig. Soll der Browser die veränderte Struktur auf der Festplatte speichern? Wie kann er über den Stand des Dokuments auf dem Laufenden bleiben?
Offensichtlich kann Text hier nicht die Antwort sein. Text ist schwierig zu ändern, es ist umständlich, Styles und Verhalten hinzuzufügen -- kurz, Text wird der dynamischen Natur von heutigen Websites kaum gerecht.
Die Lösung für dieses Problem -- zumindest für die Webbrowser von heute -- ist eine Baum-Struktur, um das HTML zu repräsentieren. Werfen Sie einen Blick auf Listing 1, dort sehen Sie das Text-Markup für eine eher einfache und langweilige HTML-Seite.
Listing 1. Einfache HTML-Seite im Text-Markup
<html>
<head>
<title>Trees, trees, everywhere</title>
</head>
<body>
<h1>Trees, trees, everywhere</h1>
<p>Welcome to a <em>really</em> boring page.</p>
<div>
Come again soon.
<img src="come-again.gif" />
</div>
</body>
</html>
|
Der Browser nimmt das und wandelt es in eine baum-ähnliche Struktur wie in Abbildung 1 um.
Abbildung 1. Die Baum-Ansicht zu Listing 1
Der Einfachheit halber lasse ich für diesen Artikel ein paar Dinge außer Acht. Experten für DOM oder XML werden anmerken, dass Leerräume (Whitespace) einen Einfluss darauf haben, wie Text in einem Dokument für die Baum-Struktur des Browsers zerlegt und dargestellt wird. Sich an dieser Stelle näher hiermit zu beschäftigen würde jedoch nur von der eigentlichen Sache ablenken. Wenn Sie also über die Wirkung von Whitespace Bescheid wissen, prima; wenn nicht, lesen Sie einfach weiter und machen Sie sich keinen Kopf darum. Sobald es für Sie zum Thema wird, werden Sie alles Notwendige herausfinden.
Neben dem eigentlichen Baum-Hintergrundbild wird Ihnen als Erstes auffallen, dass alles im Baum mit dem ganz unten liegenden HTML-Element beginnt, also dem html-Element. Dieses wird Wurzel-Element genannt, um bei der Baum-Metapher zu bleiben. Auch wenn dieses ganz unten im Baum ist, sollten Sie als Erstes hierhin schauen um den Baum zu analysieren. Wenn es Ihnen hilft, stellen Sie das Ganze einfach auf den Kopf -- auch wenn das die Baum-Metapher ein wenig strapaziert.
Ausgehend von der Wurzel zeichnen Sie nun Linien, die die Beziehung zwischen verschiedenen Markup-Teilen wiedergeben. Die head- und body-Elemente sind direkte Kinder des html-Wurzel-Elements; title ist ein Kind von head, der Text "Trees, trees, everywhere" ist wiederum ein Kind-Element von title. Der komplette Baum wird in dieser Form organisiert, bevor der Browser eine solche Struktur wie in Abbildung 1 bekommt.
Wir bleiben bei der Baum-Metapher: head und body werden die Zweige des html-Elements genannt. Sie sind Zweige, weil sie selbst auch wieder Kind-Elemente haben. Wenn Sie die Extremitäten des Baums erreichen, wird das meistens Text sein, wie zum Beispiel "Trees, trees, everywhere" und "really.". Diese heißen Blätter, da sie keine eigenen Kind-Elemente mehr haben. Sie brauchen sich diese Begriffe nicht alle merken; stellen Sie sich einfach die Baum-Struktur vor, wenn Sie herausfinden wollen, was ein bestimmter Begriff bedeutet.
Da Sie nun die grundlegende Terminologie kennen, wird es Zeit, dass wir uns diesen kleinen Rechtecken mit Element-Namen und Text darin widmen (Abbildung 1). Jedes Rechteck ist ein Objekt. Dieses nutzt der Browser, um ein paar der Probleme mit Text zu lösen. Wenn wir Objekte für die Repräsentation jedes Teils des HTML-Dokuments verwenden, vereinfacht das die Organisation, die Anwendung von Styles, den Zugriff per JavaScript auf das Dokument und vieles mehr.
Objekt-Typen und -Eigenschaften
Jeder mögliche Typ von Markup bekommt seinen eigenen Objekt-Typ. So werden z.B. Elemente in Ihrem HTML mit dem Objekt-Typ Element dargestellt. Der Text im Dokument bekommt den Text-Typ, Attribute werden durch Attribute-Typen dargestellt, und so weiter.
Der Web-Browser erhält also nicht nur ein Objekt-Modell mit der Repräsentation Ihres Dokuments -- so dass er sich nicht mehr mit dem statischen Text befassen muss -- sondern bekommt gleich noch den jeweiligen Objekt-Typ mitgeliefert. Das HTML-Dokument wird geparst und in eine Menge von Objekten (wie in Abbildung 1 gezeigt) umgewandelt, und schon sind eckige Klammern und Escape-Sequenzen (zum Beispiel < für < und > für >) kein Problem mehr. Das erleichtert den Job des Browsers, zumindest den Teil nach dem Parsen vom HTML. Herauszufinden, ob etwas ein Element oder ein Attribut ist und entscheiden, was mit diesem Objekt-Typ zu tun ist, ist dann ein Leichtes.
Durch die Verwendung von Objekten kann der Browser auch die Eigenschaften dieser Objekte verändern. So hat jedes Objekt zum Beispiel ein Eltern-Element und eine Liste von Kind-Elementen. Ein neues Kind-Element hinzuzufügen bedeutet dann einfach nur das neue Kind-Element an die Liste der Kind-Elemente anzuhängen. Diese Objekte haben auch eine style-Eigenschaft, dadurch wird es kinderleicht, den Style eines Elementes oder eines Stück Textes zu ändern. Zum Beispiel könnten Sie die Höhe eines div-Elements mit JavaScript wie folgt verändern:
someDiv.style.height = "300px"; |
Mit anderen Worten: Der Web-Browser kann auf diese Weise das Erscheinungsbild und die Struktur des Baumes mit solchen Objekt-Eigenschaften leicht verändern. Vergleichen Sie das mal mit den komplizierten Sachen, die der Browser tun müsste, wenn die Seite intern als Text repräsentiert wäre; bei jeder Änderung einer Eigenschaft oder der Struktur müsste der Browser die statische Datei neu erstellen, noch einmal parsen und sie erneut auf dem Bildschirm ausgeben. All dieses wird mit Objekten möglich.
Nehmen Sie doch an dieser Stelle mal ein paar Ihrer eigenen HTML-Dokumente und zeichnen Sie den Baum davon auf. Auch wenn sich diese Aufforderung seltsam anhören mag -- insbesondere in einem Artikel, der nur sehr wenig Code enthält -- muss Ihnen die Struktur solcher Bäume vertraut sein, wenn Sie diese manipulieren wollen.
Während dieses Vorgangs werden Sie vielleicht auf einige seltsame Dinge stoßen. Denken Sie doch mal über Folgendes nach:
- Was passiert mit Attributen?
- Wie kann man Text mit darin enthaltenen Elementen
emundbdarstellen? - Und was geschieht mit HTML, das nicht korrekt strukturiert ist (wenn zum Beispiel ein abschließendes
p-Tag fehlt)?
Wenn Sie sich diese Art von Problemen vor Augen geführt haben, werden Sie die nächsten Abschnitte viel besser verstehen.
Wenn Sie die Übung gemacht haben, werden Sie wahrscheinlich einige der potentiellen Schwierigkeiten für die Baum-Ansicht des Markup selbst entdeckt haben. (Falls Sie das nicht ausprobiert haben, müssen Sie es mir so glauben!) Tatsächlich sind auch schon in Listing 1 und Abbildung 1 ein paar davon bei der Darstellung des p-Elements enthalten. Wenn Sie einen typischen Web-Entwickler fragen, was der Text-Inhalt des p-Elements im obigen Baum ist, wird die häufigste Antwort sein: "Welcome to a really boring Web page." Wenn Sie das aber mit Abbildung 1 vergleichen, sehen Sie, dass diese Antwort -- auch wenn Sie logisch ist -- keinesfalls korrekt ist.
Es zeigt sich, dass das p-Element drei verschiedene Kind-Objekte beinhaltet, keiner von denen jedoch den gesamten Text "Welcome to a really boring Web page." enthält. Teile des Textes, wie "Welcome to a " und " boring Web page" werden Sie finden, aber nicht den kompletten Text. Um das zu verstehen, rufen Sie sich ins Gedächtnis, dass alles in Ihrem Markup in Objekte irgendeines Typs umgewandelt werden muss.
Darüber hinaus ist die Reihenfolge wichtig! Können Sie sich vorstellen, was User sagen würden, wenn der Browser ihnen zwar das korrekte Markup zeigen würde, aber in einer anderen Reihenfolge als von Ihnen vorgesehen? Wenn Abschnitte zwischen Titeln und Überschriften auftauchen würden, obwohl Sie das gar nicht so strukturiert haben? Offensichtlich muss der Browser sich an die vorgegebene Reihenfolge von Elementen und Text halten.
In unserem Fall hat das p-Element drei unterschiedliche Teile:
- den Text vor dem
em-Element - das
em-Element selbst - den Text nach dem
em-Element
Wenn Sie diese Reihenfolge durcheinander bringen, könnte die Betonung (durch das em-Element) auf den falschen Text-Teil angewendet werden. Um den Inhalt einwandfrei auszugeben, hat das p-Element drei Kind-Objekte, und zwar in der Reihenfolge wie sie im HTML in Listing 1 aufgeführt sind. Weiter ist der hervorgehobene Text "really" gar kein Kind-Element von p; es ist ein Kind-Element von em, welches wiederum ein Kind-Element von p ist.
Es ist sehr wichtig, dass Sie dieses Konzept verstehen. Auch wenn der "really"-Text möglicherweise gemeinsam mit dem Rest des p-Elements dargestellt wird, ist er doch immer noch ein direkter Nachkomme des em-Elements. Er kann eine andere Formatierung haben als der Rest des p-Elements und kann unabhängig vom Rest des Textes verschoben werden.
Um dieses noch stärker in Ihrem Gehirn zu verankern, versuchen Sie mal das HTML in den Listings 2 und 3 in einem Diagramm darzustellen. Achten Sie dabei darauf, Text bei den richtigen Eltern-Elementen zu belassen (egal wie der Text auf dem Bildschirm aussehen mag).
Listing 2. Markup mit etwas kniffeliger Verschachtelung von Elementen.
<html>
<head>
<title>This is a little tricky</title>
</head>
<body>
<h1>Pay <u>close</u> attention, OK?</h1>
<div>
<p>This p really isn't <em>necessary</em>, but it makes the
<span id="bold-text">structure <i>and</i> the organization</span>
of the page easier to keep up with.</p>
</div>
</body>
</html>
|
Listing 3. Noch kniffeligere Verschachtelung von Elementen
<html>
<head>
<title>Trickier nesting, still</title>
</head>
<body>
<div id="main-body">
<div id="contents">
<table>
<tr><th>Steps</th><th>Process</th></tr>
<tr><td>1</td><td>Figure out the <em>root element</em>.</td></tr>
<tr><td>2</td><td>Deal with the <span id="code">head</span> first,
as it's usually easy.</td></tr>
<tr><td>3</td><td>Work through the <span id="code">body</span>.
Just <em>take your time</em>.</td></tr>
</table>
</div>
<div id="closing">
This link is <em>not</em> active, but if it were, the answers
to this <a href="answers.html"><img src="exercise.gif" /></a> would
be there. But <em>do the exercise anyway!</em>
</div>
</div>
</body>
</html>
|
Die Lösung zu diesen Übungen sehen Sie in den GIF-Dateien tricky-solution.gif in Abbildung 2 und trickier-solution.gif in Abbildung 3 am Ende dieses Artikels. Schielen Sie nicht schon darauf, ehe Sie sich selbst daran versucht haben. Nach der Bearbeitung der Übungen werden Sie viel besser verstehen, wie akkurat die Regeln auf die Baum-Struktur angewendet werden. Dann sind Sie ein gutes Stück auf dem Weg weiter gekommen, HTML und seine Baum-Struktur zu meistern.
Sind Sie auf das Problem gestoßen, wie Attribute repräsentiert werden? Wie ich schon erwähnte, haben Attribute ihren eigenen Objekt-Typ, doch ist ein Attribut keinesfalls das Kind des Elements, in dem es auftritt -- verschachtelte Elemente und Text sind noch auf dem gleichen "Level" bei einem Attribut und Sie werden sehen, dass die Antworten zu den Übungen aus Listing 2 und 3 gar keine Attribute enthalten.
Tatsächlich werden Attribute im Objekt-Modell des Browsers gespeichert, doch sie sind eine Art Sonderfall. Jedes Element hat eine Liste von möglichen Attributen, getrennt von der Liste der Kind-Objekte. Das div-Element könnte zum Beispiel eine Liste haben, in der ein Attribut namens "id" und ein anderes namens "class" aufgeführt sind.
Behalten Sie im Hinterkopf, dass Attribute eines Elements eindeutige Namen haben müssen. Anders ausgedrückt: Ein Element kann nicht zwei "id"- oder "class"-Attribute haben. Dadurch bleibt die Liste recht einfach zu handhaben. Im nächsten Artikel dieser Serie werden Sie sehen, dass Sie einfach eine Methode wie getAttribute("id") aufrufen können, um den Wert eines Attributes anhand seines Namens zu erhalten. Sie können mit ähnlichen Methoden-Aufrufen auch Attribute hinzufügen oder den Wert von bestehenden Attributen (neu) setzen.
Es sei darauf hingewiesen, dass die Eindeutigkeit von Attributnamen diese Liste von der Liste der Kind-Objekte unterscheidet. Ein p-Element könnte mehrere em-Elemente beinhalten, die Liste der Kind-Objekte kann also doppelte Einträge enthalten. Auch wenn die Liste der Kind-Elemente und die Liste der Attribute sich ähnlich verhalten, kann die eine Duplikate enthalten (die Kind-Elemente eines Objekts), die andere jedoch nicht (die Attribute des Element-Objekts). Weiterhin können nur Elemente Attribute haben; bei Text-Objekten gibt es also keine Liste um Attribute zu speichern.
Bevor wir weitergehen, gibt es noch ein Thema, dem wir etwas Zeit widmen sollten. Es geht darum, wie der Browser bei der Umwandlung von Markup zu einer Baum-Darstellung mit nicht wohlgeformtem Markup umgeht. Der Begriff "wohlgeformt" (engl.: well-formed) wird für XML verwendet und bedeutet im Wesentlichen zwei Dinge:
- Jedes öffnende Tag hat ein schließendes Tag. So muss also jedes
<p>im Dokument mit einem</p>beendet werden, jedes<div>mit einem</div>, und so weiter. - Das am weitesten innen liegende öffnende Tag muss zum am weitesten innen liegenden schließenden Tag gehören; genauso mit dem am zweitweitesten innen liegenden Tag, und so weiter. Deshalb ist
<b><i>fettgedruckt und kursiv</b></i>illegal, da der innerste öffnende Tag<i>nicht zu dem innersten schließenden Tag<b>gehört. Um dieses wohlgeformt zu machen, müssen Sie entweder die Reihenfolge der öffnenden Tags oder der schließenden Tags verändern. (Wenn Sie beides ändern, haben Sie immer noch ein Problem.)
Befassen Sie sich mit diesen beiden Regeln eingehend. Es sind beides Regeln, die nicht nur einfach die Organisation eines Dokuments verbessern, sondern sie beseitigen auch die Mehrdeutigkeit. Soll zuerst die Fettschrift angewandt werden und dann die Kursivschrift? Oder anders herum? Falls Ihnen die Reihenfolge und Mehrdeutigkeit als nicht sonderlich wichtig erscheint, sollten Sie daran denken, dass in CSS nachfolgende Regeln die vorigen überschreiben können. Wenn sich also zum Beispiel der Text-Font innerhalb des b-Elements von dem Font für das i-Element unterscheidet, dann ist die Reihenfolge, in der die Formatierung erfolgt, sehr wichtig. Darum kommt an dieser Stelle die Wohlgeformtheit einer HTML-Seite mit ins Spiel.
Wenn der Browser ein nicht wohlgeformtes Dokument bekommt, versucht er, daraus einfach das Beste zu machen. Die resultierende Baum-Struktur kann bestenfalls eine Annäherung an das sein, was der Autor der Seite beabsichtigte, schlechtestenfalls kommt etwas total anderes heraus, Haben Sie schon einmal eine Seite im Browser geladen und dann etwas komplett Unerwartetes gesehen? Das könnte das Ergebnis eines Browsers gewesen sein, der versucht hat, die gewünschte Seitenstruktur zu erraten -- und das eher schlecht als recht erledigt hat. Offensichtlich ist die Reparatur ziemlich einfach: Sorgen Sie dafür, dass Ihre Dokumente wohlgeformt sind! Wenn Ihnen nicht klar ist, wie Sie am besten standardisiertes HTML schreiben, finden Sie in den Ressourcen weiterführende Links.
Bis hierher haben Sie erfahren, dass Browser eine Webseite in eine Objekt-Repräsentation umwandeln. Vielleicht haben Sie auch schon erraten, dass es sich bei dieser Objekt-Repräsentation um einen DOM-Baum handelt. DOM steht für Document Object Model (Dokument-Objekt-Modell) und ist eine Spezifikation des World Wide Web Consortium (W3C). (Einige relevante Links zum DOM finden Sie in den Ressourcen.)
Noch wichtiger ist allerdings, dass das DOM die Objekt-Typen und -Eigenschaften definiert, die dem Browser ermöglichen, das Markup zu repräsentieren. (Im nächsten Artikel dieser Serie geht es in die Details über die Verwendung von DOM mit JavaScript und Ajax-Code.)
Als Allererstes müssen Sie jedoch auf das Modell selbst zugreifen können. Das ist erstaunlich einfach: Um die integrierte document-Variable in einem beliebigem JavaScript-Code auf Ihrer Webseite zu verwenden, schreiben Sie Code wie diesen:
var domTree = document; |
Natürlich ist dieser Code an sich ziemlich nutzlos, aber er demonstriert dennoch, dass jeder Web-Browser das document-Objekt für JavaScript verfügbar macht und dass dieses Objekt den gesamten Markup-Baum repräsentiert (Abbildung 1).
Ganz klar, das document-Objekt ist wichtig, aber es ist nur der Anfang. Bevor wir weiter gehen können, müssen Sie einen anderen Begriff lernen: Knoten (engl.: node). Sie wissen bereits, dass jedes Stück Markup durch ein Objekt repräsentiert wird, aber es ist mehr als nur irgendein Objekt -- es ist ein besonderer Typ von Objekt, ein DOM Knoten (DOM node). Diese speziellen Typen -- wie Text, Elemente und Attribute -- sind Erweiterungen des grundlegenden Knotentyps. Es gibt also Textknoten, Elementknoten und Attributknoten.
Falls Sie schon häufiger JavaScript programmiert haben, merken Sie jetzt vielleicht, dass Sie tatsächlich schon DOM-Code verwendet haben. Wenn Sie an die vorherigen Artikel dieser Serie denken, haben Sie dort definitiv schon eine Weile DOM-Code eingesetzt. Zum Beispiel wird in der Zeile var number = document.getElementById("phone").value; das DOM verwendet, um auf den Wert eines speziellen Elementes (in diesem Fall ein Form-Element) zuzugreifen. Selbst wenn Sie es gar nicht registrierten, haben Sie dennoch bereits document in Ihrem JavaScript-Code getippt.
Um das sauber zusammenzufassen: Ein DOM-Baum ist ein Baum von Objekten, genauer gesagt ein Baum von Knoten-Objekten. In Ajax-Anwendungen -- oder jedem anderen JavaScript -- können Sie mit diesen Knoten arbeiten, um solche Effekte wie das Verschieben eines Elements mit seinem Inhalt, das Hervorheben eines bestimmten Stücks von Text oder das Hinzufügen eines neuen Bild-Elements zu erzielen. Da all dieses auf der Client-Seite passiert (also Code, der in Ihrem Browser läuft), passiert das quasi sofort ohne eine Kommunikation mit dem Server. Das Ergebnis ist eine Anwendung, die viel prompter wirkt, da die Änderungen auf der Webseite erfolgen, ohne dass eine Pause entsteht, während der eine Anfrage zum Server und wieder zurück geht.
In den meisten Programmiersprachen müssen sie die tatsächlichen Objekt-Namen für jeden Knotentyp lernen, außerdem die verfügbaren Eigenschaften und noch anderes über Typen und Casting. Nichts hiervon ist für JavaScript notwendig. Sie können einfach eine Variable erstellen und ihr ein beliebiges Objekt zuweisen (wie Sie gleich noch sehen werden):
var domTree = document;
var phoneNumberElement = document.getElementById("phone");
var phoneNumber = phoneNumberElement.value;
|
Es gibt keine Typen. JavaScript kümmert sich um die Erstellung der Variablen und weist ihnen den korrekten Typ selbst zu. Das macht es ziemlich trivial, das DOM von JavaScript aus zu verwenden. (In einem weiterem Artikel dieser Serie dreht sich alles um das DOM in Relation zu XML -- dann werden die Dinge etwas vertrackter.)
Jetzt, wo es gerade spannend wird, ist dieser Artikel am Ende. Offensichtlich war dieses keine komplette und erschöpfende Darstellung des DOM; tatsächlich ist dieser Artikel nur wenig mehr als eine Einführung in das DOM. Das DOM ist viel mehr als ich Ihnen heute gezeigt habe!
Im nächsten Artikel dieser Serie kehren wir noch einmal zum DOM zurück und schauen uns die Verwendung in JavaScript an. Wir werden Webseiten aktualisieren, on-the-fly Änderungen am HTML machen und damit die Anwendung viel interaktiver für den User gestalten. Ein weiteres Mal werde ich zum DOM zurückkehren, wenn es um die Verwendung von XML in Ihren Ajax-Anfragen geht. Machen Sie sich also vertraut mit dem DOM; es ist ein essentieller Teil von Ajax-Anwendungen.
An dieser Stelle wäre es ziemlich einfach, tiefer in das DOM einzusteigen, darauf einzugehen, wie Sie sich im DOM-Baum bewegen und die Werte von Elementen und Text bekommen, durch Listen zu iterieren und vieles mehr. Das würde bei Ihnen jedoch möglicherweise den Eindruck hinterlassen, dass es beim DOM um Code geht -- und das ist nicht richtig.
Bevor Sie den nächsten Artikel lesen, denken Sie doch mal über Baum-Strukturen nach und arbeiten Sie sich durch Ihren eigenen HTML-Code, um zu sehen, wie der Browser das HTML zu einer Baum-Ansicht des Markups umwandelt. Lassen Sie sich auch mal durch den Kopf gehen, wie ein DOM-Baum aufgebaut ist und machen Sie sich Gedanken über die Sonderfälle, die in diesem Artikel behandelt wurden: Attribute, Text mit darin enthaltenen Elementen und Elemente ohne Text-Inhalt (wie das img -Element).
Wenn Sie diese Konzepte intus haben und dann (im nächsten Artikel) die Syntax von JavaScript und dem DOM kennenlernen, wird es Ihnen viel leichter fallen, schnell reagierende Anwendungen zu erstellen.
Zum Schluss sind noch die Lösungen zu den Listings 2 und 3 -- die gibt es auch zusammen mit dem Beispiel-Code!
Figure 2. Die Lösung zu Listing 2
Figure 3. Die Lösung zu Listing 3
- Die DOM Homepage beim World Wide Web Consortium: Besuchen Sie den Ausgangspunkt für alle DOM-verwandten Themen.
- Die DOM Level 3 Core Spezifikation: Hier erfahren Sie alles über das Document Object Model, von den verfügbaren Typen und Eigenschaften bis hin zum Zugriff auf das DOM mit verschiedenen Sprachen.
- Die ECMAScript Sprachbindungen für das DOM: Wenn Sie ein JavaScript-Programmierer sind und DOM in Ihrem Code nutzen möchten, wird Sie der Anhang zu den Level 3 Document Object Model Core Definitionen interessieren.
- "Building Dynamic Java Applications" (developerWorks, September 2005) wirft einen Blick auf Ajax aus Serversicht, aus der Java-Perspektive.
- "Ajax for Java developers: Java object serialization for Ajax" (developerWorks, October 2005): Erläutert fünf Ansätze zur Serialisierung von Java-Objekten und untersucht, wie Objekte über das Netzwerk geschickt werden und mit Ajax interagieren.
- "Call SOAP Web services with Ajax, Part 1: Build the Web services client" (developerWorks, October 2005): Ein ziemlich fortgeschrittener Artikel über die Integration von Ajax in bestehende SOAP-basierte Web-Services.
- "Ajax: A New Approach to Web Applications" ist der Artikel, in dem der Begriff Ajax das erste Mal eingesetzt wurde. Ajax-Entwickler sollten ihn unbedingt gelesen haben.
- Ajax von Kopf bis Fuß von Elisabeth Freeman, Eric Freeman und Brett McLaughlin (September 2006, O'Reilly): Im bewährten "Von Kopf bis Fuß"-Stil
- Java and XML, Third Edition by Brett McLaughlin (2007, O'Reilly Media, Inc.): Besonders interessant: XHTML- und XML-Transformationen
- JavaScript - Das umfassende Referenzwerk, 3. Auflage von David Flanagan (April 2007, O'Reilly): Das wichtigste Buch für Web-Designer
-
HTML mit CSS & XHTML von Kopf bis Fuß von Elizabeth und Eric Freeman (August 2006, O'Reilly Media): Das Lehrbuch für XHTML und CSS - und wie die beiden zusammen kommen
- developerWorks Web architecture zone: Expand your Web-building skills.