Anzeige
Tutorialbeschreibung

Javascript und Ajax - DOM

Javascript und Ajax - DOM

Das nun folgende Tutorial ist ein Auszug aus der 7. Auflage des Buches: JavaScript und Ajax von Christian Wenz.

Kapitel 16 DOM

JavaScript entwickelt sich natürlich weiter. Ein gutes Beispiel dafür ist JavaScript 1.5. Diese Version schließt die Lücke, die bisher zwischen den JavaScript-Versionen und dem ECMAScript-Standard, 3. Revision, bestand. Dieser Sprachstandard (die offizielle Spezifikation finden Sie unter http://www.ecma.ch/ oder auf der Buch-DVD) entspricht in etwa dem Sprachumfang von JavaScript 1.1, wurde aber bisher noch von keinem Browser komplett unterstützt. Der Internet Explorer 4 war sehr nahe dran, und der Internet Explorer 5.x/6/7 unterstützt (bis auf ein paar Bugs) vollständig ECMAScript (oder kurz: ECMA-262). Auch aktuelle Mozilla-Browser (inklusive Nebenprodukten wie Firefox, Camino und Galeon) sind ECMA-compliant.

Wenn jedoch im Zusammenhang mit JavaScript von Standards gesprochen wird, dann ist die Rede von DOM, dem Document Object Model. Vereinfacht gesagt, soll ein HTML-Dokument so modelliert werden, dass mit JavaScript darauf zugegriffen werden kann. Wie in den vier DHTML-Kapiteln schon angedeutet wurde, geht der Internet Explorer (ab Version 4) hier viel weiter als der Netscape Navigator 4. Die zueinander inkompatiblen DOM-Umsetzungen der beiden Browser-Hersteller sind für den Programmierer ein stetes Ärgernis. Da zudem noch sowohl Netscape als auch Microsoft ihre Umsetzung für die jeweils bessere hielten, war zunächst keine Einigung in Sicht. Für solche Fälle gibt es glücklicherweise (mehr oder weniger) unabhängige Gremien wie das W3C, die mittlerweile einen DOM-Standard abgesegnet haben. Die Konsequenz daraus ist, dass sich der Internet Explorer seit Version 5 an den Standard hält und die Mozilla-Browser ebenfalls (und natürlich auch Safari/Konqueror und Opera). Da die meisten der DOM-Effekte auch mit herkömmlichen Mitteln zu erzielen und damit abwärtskompatibel zu älteren Browsern sind, ist die Zielgruppe für DOM-Effekte noch nicht allzu groß. In Zusammenhang mit AJAX allerdings sieht das schon ganz anders aus: Dort gewinnt DOM zunehmend an Bedeutung.


16.1 Der DOM-Baum 
topBilder
topBilder

Das HTML-Dokument wird in einen Baum umgewandelt. Jedes HTML-Element und auch jeder Text, der nicht von Tags umgeben ist, wird zu einem Knoten (engl. node) in dem Baum. Elemente zwischen einem öffnenden und dem dazugehörigen schließenden Tag sind Kindknoten (engl. child nodes), so dass auch eine Hierarchie gegeben ist. In diesem Kapitel betrachten wir folgendes Beispieldokument:

<html>
<head>
<title>DOM-Demo</title>
</head>
<body id="alles">
<h3 id="Ueberschrift">DOM-Demo</h3>
<img src="ball.gif" id="Ball1" />
<img src="ball.gif" id="Ball2" />
<img src="ball.gif" id="Ball3" />
<img src="ball.gif" id="Ball4" />
</body>
</html>

In Abbildung 2.1 sehen Sie, wie der DOM-Baum für das oben gezeigte Dokument aussieht.

Beachten Sie, dass jedes Tag ein id-Attribut trägt. Hiermit kann das Tag dann von JavaScript aus angesprochen werden. Sie ahnen bereits: Es geht wohl auch um irgendein Array mit irgendeinem Index, wie bisher immer, aber der Übersichtlichkeit halber ist es auch hier besser, sprechende Namen zu verwenden.

Bilder

Abbildung 16.1     Der DOM-Baum des HTML-Dokuments

In manchen Mozilla-Browsern gibt es einen so genannten DOM Inspector (etwa im Firefox: Extras N DOM Inspector). Der zeigt die DOM-Struktur schön übersichtlich an:

Bilder

Abbildung 16.2     Der DOM-Baum im DOM Inspector von Firefox

 

 

16.2 Navigation im Baum 
topBilder
topBilder

Ähnlich wie bei Frame-Hierarchien kann man auch in dem DOM-Baum von Ebene zu Ebene springen. Die entsprechenden Methoden und Eigenschaften heißen hier nur anders, aber ansonsten bleibt alles beim Alten. Die Kindknoten eines Elements im DOM-Baum befinden sich im Array childNodes. Von einem Knoten (bzw. HTML-Element) aus kann man mit den Eigenschaften, die in der folgenden Tabelle aufgeführt sind, auf andere Knoten zugreifen.

Tabelle 16.1     Eigenschaften eines Knotens im DOM-Baum

Eigenschaft Beschreibung
firstChild Der erste Kindknoten (erstes Element im childNodes-Array)
lastChild Der letzte Kindknoten (letztes Element im childNodes-Array)
nextSibling Das nächste Kind des Elternknotens
parentNode Der Elternknoten
previousSibling Das vorherige Kind des Elternknotens

 

Die Eigenschaften aus der folgenden Tabelle liefern nähere Informationen über einen Knoten zurück:

Tabelle 16.2     Eigenschaften, die nähere Informationen über einen Knoten liefern

Eigenschaft Beschreibung
nodeName HTML-Tag des Knotens als Zeichenkette (z.  B. "h3")
nodeType 1 = Tag, 2 = Attribut, 3 = Text

 

In Abbildung 16.3 sehen Sie den DOM-Baum noch einmal, diesmal mit den Beziehungen zwischen den einzelnen Knoten.

AbbildungBilder

Hier klicken, um das Bild zu Vergrößern

Abbildung 16.3     Navigationsmöglichkeiten innerhalb des DOM-Baums

 

 

16.3 Den Baum modifizieren  

Der große Vorteil von DOM gegenüber DHTML und den früheren DOM-Implementierungen besteht darin, dass man Elemente nicht nur ändern, sondern auch entfernen und sogar neue Elemente einfügen kann. Die Baumstruktur ist hier von großem Vorteil, da das Löschen eines Knotens nicht die Baumintegrität gefährdet.


16.3.1 Wichtige Methoden  

In der folgenden Tabelle sehen Sie eine grobe Übersicht über die verschiedenen Methoden.

Tabelle 16.3     Methoden zur Veränderung des DOM-Baums

Methode Syntax Beschreibung
appendChild Vater.appendChild(Kind) Hängt Kind als Kindknoten an Vater an.
cloneNode Original.cloneNode (alles) Erzeugt einen Knoten, der identisch mit Original ist. Ist alles gleich true, so werden auch alle Kindknoten von Original mit dupliziert; bei false lediglich der Knoten selbst.
createElement document.createElement (HTML-Tag) Erzeugt einen Knoten, der aus dem in Klammern angegebenen HTML-Element (z.  B. h3) besteht.
hasChildNodes Knoten.hasChildNodes() Boolescher Wert, der angibt, ob Knoten Kinder hat oder nicht.
insertBefore Vater.insertBefore(Kind, Schwester) Kind wird als Kindknoten von Vater eingefügt, und zwar direkt vor Schwester.
removeNode Knoten.removeNode(alles) Knoten wird aus dem DOM-Baum entfernt. Ist alles gleich true, dann werden auch alle Kindknoten von Knoten entfernt.
replaceNode Alt.replaceNode(Neu) Der Knoten Alt wird durch den Knoten Neu ersetzt.
setAttribute Knoten.setAttribute( Name, Wert) Der Knoten enthält ein neues Attribut.

 

In einem kleinen Beispiel soll dies einmal ausprobiert werden. Wir gehen von dem obigen Beispiel-HTML-Dokument aus und bauen die folgenden Effekte ein:

gpBilder
 
Wenn der Benutzer mit der Maus auf eine der Grafiken klickt, soll diese durch eine andere Grafik ausgetauscht werden.
gpBilder
 
Wenn der Benutzer noch einmal auf die Grafik klickt, soll sie komplett verschwinden (eine Art armseliges Ballerspiel mit JavaScript also).

Der Einfachheit halber werden die Event-Handler der Grafiken schon im ursprünglichen HTML-Dokument gesetzt. Es muss also nur noch eine Funktion geschrieben werden, die überprüft, ob die Grafik schon einmal angeklickt worden ist, und dann entweder die Grafik austauscht oder den Knoten aus dem DOM-Baum entfernt. Alternative Möglichkeiten des Event-Handlings finden Sie in Kapitel 14.


 

16.3.2 Zugriff auf einzelne Elemente  

Jetzt benötigen Sie nur noch eines: den Startpunkt. Dafür gibt es eine weitere Methode des document-Objekts, und zwar getElementById(). Diese ermöglicht Ihnen den Zugriff auf jedes HTML-Element, solange es nur eine ID besitzt. Diese ID nämlich übergeben Sie als Parameter. So greifen Sie beispielsweise per document.getElementById("alles") auf das <body>-Element zu und können von dort ab alle Kindknoten (sprich: die Elemente der HTML-Seite) erreichen.

Der folgende Code ist kurz und einleuchtend und wird daher ohne längere Vorrede abgedruckt. Er enthält allerdings noch einen kleinen (absichtlichen) Fehler, dazu später mehr.

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
function mausklick(Nummer){
   var obj = document.getElementById("alles").childNodes[Nummer + 1];
   var gfx = obj.src;
   if (gfx.indexOf("ball.gif") > –1) {
      obj.src="kreuz.gif";
   } else {
      obj.removeNode(false);
   }
}
//--></script>
</head>
<body id="alles">
<h3 id="Ueberschrift">DOM-Demo</h3>
<img src="ball.gif" id="Ball1" onclick="mausklick(1);" />
<img src="ball.gif" id="Ball2" onclick="mausklick(2);" />
<img src="ball.gif" id="Ball3" onclick="mausklick(3);" />
<img src="ball.gif" id="Ball4" onclick="mausklick(4);" />
</body>
</html>

Bilder

Abbildung 16.4     Die DOM-Demo im Internet Explorer

Wie Ihnen sicherlich nicht entgangen ist, spuckt der Browser hin und wieder Fehlermeldungen bei der Ausführung dieses Skripts aus, beispielsweise, wenn Sie auf die dritte Grafik von links klicken. Sehr merkwürdig! Zum Testen sollten Sie in die Funktion mausklick() den folgenden Debug-Code einfügen (am besten gleich am Anfang):

function mausklick(Nummer) {
   var meldung = "";
   for (var i=0; i<document.getElementById("alles").childNodes.length; i++) {
      meldung += document.getElementById("alles").childNodes[i].nodeName + 
"|" + document.getElementById("alles").childNodes[i].nodeType + "
";
   }
   alert(meldung);
   var obj = document.getElementById("alles").childNodes[Nummer + 1];
   var gfx = obj.src;
   if (gfx.indexOf("ball.gif")>-1) {
      obj.src="kreuz.gif";
   } else {
      obj.removeNode(false);
   }
}

Bilder

Abbildung 16.5     Die Debug-Ausgabe

In Abbildung 16.5 (oder auch im DOM Inspector) sehen Sie die Ursache des Übels: Anscheinend befinden sich zwischen den einzelnen Grafiken noch Textstücke. Auch das ist nicht weiter verwunderlich: Auch wenn ein Zeilenumbruch im HTML-Code in der Anzeige quasi nie Auswirkungen hat, ist das beim DOM-Baum ein Textelement. Sie sollten also die Zeilenumbrüche entfernen, dann gibt es beim ersten Anklicken einer Grafik auch keine Fehlermeldungen mehr.

Um diese Fehlermeldungen zu vermeiden, sollten Sie die HTML-Elemente, die Sie in Ihrem Skript verwenden wollen, mit den oben gezeigten Methoden (createElement(), setAttribute() und appendChild() bzw. insertBefore()) erzeugen. Das obige HTML-Dokument kann auch folgendermaßen erzeugt werden (von der Klick-Funktionalität mal abgesehen):

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
function init() {
   var basis = document.getElementById("alles");
   var h3 = document.createElement("h3");
   h3.setAttribute("id", "Ueberschrift");
   h3.innerText = "Überschrift";
   basis.appendChild(h3);
   for (var i=1; i<=4; i++) {
      img = document.createElement("img");
      img.setAttribute("id", "Ball" + i);
      img.src = "ball.gif";
      basis.appendChild(img);
   }
}
//--></script>
</head>
<body id="alles" onload="init();">
</body>
</html>

Ein kleiner Vorgriff war dabei: innerText bezeichnet den Text innerhalb eines HTML-Elements. Eine Alternative dazu gibt es auch noch: Der Text innerhalb eines HTML-Elements ist wie bereits gesehen ein Knoten, und zwar ein Textknoten. Mit den DOM-Methoden von JavaScript können Sie auch einen solchen Knoten erzeugen (die dazugehörige Methode heißt document.createTextNode()) und diesen dann in den DOM-Baum einhängen – als Unterknoten des übergeordneten Elements natürlich:

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
function init() {
   var basis = document.getElementById("alles");
   var h3 = document.createElement("h3");
   h3.setAttribute("id", "Ueberschrift");
   textknoten = document.createTextNode("Überschrift");
   h3.appendChild(textknoten);
   basis.appendChild(h3);
   for (var i=1; i<=4; i++) {
      img = document.createElement("img");
      img.setAttribute("id", "Ball" + i);
      img.src = "ball.gif";
      basis.appendChild(img);
   }
}
//--></script>
</head>
<body id="alles" onload="init();">
</body>
</html>

Wie Sie in einer Aufgabe am Ende des Kapitels jedoch noch sehen werden, ist das ursprüngliche Skript nicht ganz fehlerfrei. Es ist einfach gefährlich, über den Index auf ein Element zuzugreifen, wenn zwischendurch Elemente entfernt werden sollen. Aber Sie haben ja bereits an anderer Stelle schon gesehen, dass es fast immer besser ist, per Identifikator auf ein Element zuzugreifen. Hier ist das auch der Fall – verwenden Sie einfach getElementById() für die einzelnen Bälle. Im folgenden Code finden Sie das für unser kleines Beispiel einmal umgesetzt. Anhand der Nummer, die an mausklick() übergeben wird, kann der Identifikator der angeklickten Grafik ermittelt werden, und dieser Wert wird dann an getElementById() übergeben.

function mausklick(Nummer){
   var obj = document.getElementById("Ball" + Nummer);
   var gfx = obj.src;
   if (gfx.indexOf("ball.gif") > –1) {
      obj.src="kreuz.gif";
   } else {
      obj.removeNode(false);
   }
}


16.3.3 Zugriff auf Tags  

Es gibt noch eine Alternative zum Knotenzugriff via ID: Sie können auch spezifisch auf Tags zugreifen. Die entsprechende Methode des document-Objekts heißt getElementsByTagName(). Beachten Sie den Plural (Elements), denn Sie erhalten auf jeden Fall ein Array zurück, auch wenn es nur ein entsprechendes Element auf der Seite gibt. Damit lässt sich im ursprünglichen, absichtlich fehlerhaften Beispiel etwa die ID für das <body>-Element einsparen:

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
function mausklick(Nummer){
   var basis = document.getElementsByTagName("body")[0];
   var obj = basis.childNodes[Nummer + 1];
   var gfx = obj.src;
   if (gfx.indexOf("ball.gif") > –1) {
      obj.src="kreuz.gif";
   } else {
      obj.removeNode(false);
   }
}
//--></script>
</head>
<body>
<h3 id="Ueberschrift">DOM-Demo</h3> <img src="ball.gif" id="Ball1" onclick="mausklick(1);" /> <img src="ball.gif" id="Ball2" onclick="mausklick(2);" /> <img src="ball.gif" id="Ball3" onclick="mausklick(3);" /> <img src="ball.gif" id="Ball4" onclick="mausklick(4);" /> </body> </html>


16.3.4 Beispiele 
topBilder

Zum Abschluss dieser DOM-Einführung noch zwei kleine Beispiele, die aufzeigen, wie Sie per DOM schnell Elemente der aktuellen Seite hinzufügen können – eine Technik, die in Kapitel 18 wichtig werden wird. Wir beginnen mit einer Aufzählungsliste:

<ul id="Liste"></ul>

Wie Sie sehen, ist die Liste leer. Die Daten für die Liste stehen in folgendem Objekt:

var daten = [
   {"text": "Mozilla", "url": "http://www.mozilla.com/"},
   {"text": "Microsoft", "url": "http://www.microsoft.com/"},
   {"text": "Opera", "url": "http://www.opera.com/"}
];

Unser Ziel ist es nun, diese Daten in die Liste einzufügen, und zwar als verlinkten Text. Werfen wir einen Blick auf das entsprechende Markup für ein Listenelement:

<li><a href="http://www.mozilla.com/">Mozilla</a></li>

Wir müssen also die folgenden DOM-Elemente erzeugen:

gpBilder
 
Das <li>-Element
gpBilder
 
Das <a>-Element samt dem Attribut href
gpBilder
 
Den Textknoten mit dem Linktext

Am Ende müssen Sie diese Elemente untereinander einhängen: den Textknoten unterhalb des Links, den Link unterhalb des Listenelements, und natürlich abschließend das Listenelement unterhalb der Liste selbst.

Sie sehen: Das ist zu Anfang ein wenig ungewohnt und auch etwas aufwändig, geht aber nach wiederholtem Üben sehr leicht von der Hand. Hier ist das vollständige Listing:

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
var daten = [ {"text": "Mozilla", "url":
"http://www.mozilla.com/"}, {"text": "Microsoft", "url":
"http://www.microsoft.com/"}, {"text": "Opera", "url": "http://www.opera.com/"}
];

window.onload = function() {
   var liste = document.getElementById("Liste");
   for (var i = 0; i < daten.length; i++) {
      var link = daten[i];
      var li = document.createElement("li");
      var a = document.createElement("a");
      a.setAttribute("href", link.url);
      var txt = document.createTextNode(link.text);
      a.appendChild(txt);
      li.appendChild(a);
      liste.appendChild(li);
   }
}
//--></script>
</head>
<body>
<ul id="Liste"></ul>
</body>
</html>

Natürlich können Sie statt document.getElementById("Liste") im vorliegenden Beispiel auch document.getElementsByTagName("ul")[0] verwenden.

Bilder

Abbildung 16.6     Die dynamisch per DOM erzeugte Liste

Das zweite Beispiel soll etwas komplexer sein: Diesmal soll eine komplette Tabelle erzeugt und in den DOM-Baum eingehängt werden. Dabei gibt es eine wichtige Besonderheit: Unter bestimmten Umständen ist der Internet Explorer sehr wählerisch, was den (korrekten) Aufbau einer per DOM erzeugten Tabelle betrifft. Die Tabellenzellen müssen nämlich im <tbody>-Element platziert werden (und etwaige <th>-Zellen innerhalb von <thead>).

Von der Technologie her ist das nichts Neues: Sie erzeugen Elemente mit createElement() und hängen sie per appendChild() untereinander. Hier der Code für <thead>:

var table = document.createElement("table");
var thead = document.createElement("thead");
var tr = document.createElement("tr");
var th1 = document.createElement("th");
var th1text = document.createTextNode("Hersteller");
th1.appendChild(th1text);
var th2 = document.createElement("th");
var th2text = document.createTextNode("URL");
th2.appendChild(th2text);
tr.appendChild(th1);
tr.appendChild(th2);
thead.appendChild(tr);
table.appendChild(thead);

Auch der <tbody>-Abschnitt bietet wenig Neues, Sie müssen nur eine Menge Elemente erstellen. Eine kleine Besonderheit gibt es jedoch schon: Der Linktext und der Text in der linken Spalte sollen identisch sein. Sie können aber einen Knoten nicht an zwei Stellen in den DOM-Baum einhängen, denn Knoten werden wie Referenzen oder Zeiger gehandhabt, nicht wie Kopien. Das heißt, Sie müssen zunächst eine Knotenkopie erzeugen, was die Methode cloneNode() erledigt. Diese Methode erwartet als Parameter die Angabe, ob auch Unterknoten mit dupliziert werden sollen (true) oder nicht (false). Da der Textknoten selbst keine Unterknoten besitzt, genügt die Angabe false:

var tbody = document.createElement("tbody");
for (var i = 0; i < daten.length; i++) {
   var link = daten[i];
   var tr = document.createElement("tr");
   var td1 = document.createElement("td");
   var td1txt = document.createTextNode(link.text);
   td1.appendChild(td1txt);
   var td2 = document.createElement("td");
   var a = document.createElement("a");
   a.setAttribute("href", link.url);
   a.appendChild(td1txt.cloneNode(false));
   td2.appendChild(a);
   tr.appendChild(td1);
   tr.appendChild(td2);
   tbody.appendChild(tr);
}

Das war es auch schon fast, die Tabelle muss nur noch fertiggestellt und in das Dokument eingefügt werden:

table.appendChild(tbody);
var body = document.getElementsByTagName("body")[0];
body.appendChild(table);

Hier noch einmal der komplette Code im Überblick:

<html>
<head>
<title>DOM-Demo</title>
<script type="text/javascript"><!--
var daten = [ {"text": "Mozilla", "url":
"http://www.mozilla.com/"}, {"text": "Microsoft", "url":
"http://www.microsoft.com/"}, {"text": "Opera", "url": "http://www.opera.com/"}
];

window.onload = function() {
   var body = document.getElementsByTagName("body")[0];
   var table = document.createElement("table");

   var thead = document.createElement("thead");
   var tr = document.createElement("tr");
   var th1 = document.createElement("th");
   var th1text = document.createTextNode("Hersteller");
   th1.appendChild(th1text);
   var th2 = document.createElement("th");
   var th2text = document.createTextNode("URL");
   th2.appendChild(th2text);
   tr.appendChild(th1);
   tr.appendChild(th2);
   thead.appendChild(tr);
   table.appendChild(thead);

   var tbody = document.createElement("tbody");
   for (var i = 0; i < daten.length; i++) {
      var link = daten[i];
      var tr = document.createElement("tr");

      var td1 = document.createElement("td");
      var td1txt = document.createTextNode(link.text);
      td1.appendChild(td1txt);
      var td2 = document.createElement("td");
      var a = document.createElement("a");
      a.setAttribute("href", link.url);
      a.appendChild(td1txt.cloneNode(false));
      td2.appendChild(a);

      tr.appendChild(td1);
      tr.appendChild(td2);
      tbody.appendChild(tr);
   }
   table.appendChild(tbody);

   body.appendChild(table);
}
//--></script>
</head>
<body>
</body>
</html>

Bilder

Abbildung 16.7     Die dynamisch per DOM erzeugte Tabelle

Sie sehen also: Das ist viel Tipparbeit, aber doch eigentlich gar nicht so schwierig.

Die JavaScript-Programmierung wird sich zweifelsohne mehr in Richtung DOM bewegen – das steht außer Frage. Da die Browser der Versionsnummer 4 ausgestorben sind (so kennen weder der Internet Explorer 4 noch der Netscape 4 die DOM-Methoden wie beispielsweise getElementById() oder document.getElementsByTagName()), kann man mittlerweile DOM mit gutem Gewissen einsetzen. Allerdings ist das Denken in Baumstrukturen nicht immer intuitiv; schöner ist es doch, mit dem bekannten JavaScript-Objekten wie etwa Image oder den Formularfeldern zu arbeiten. Der Trend geht jedoch langsam, aber sicher hin zu DOM. Warum? Weil Sie damit vor allem Text auf einer Seite verändern und neue HTML-Elemente hinzufügen können, wie weiter oben gezeigt wurde. Die folgenden Kapitel stehen ganz im Zeichen dieser Einsatzszenarios und zeigen DHTML und insbesondere AJAX: moderne Ansätze für die JavaScript-Programmierung, die der Sprache einen neuen Aufwind gegeben haben.

Das Tutorial ist ein Auszug aus der 7. Auflage des Buches von Christian Wenz:

JavaScript und Ajax - Das umfassende Handbuch
Galileo Computing, 853 Seiten, 8. aktualisierte Auflage

Die Veröffentlichung des Kapitels erfolgt mit freundlicher Genehmigung von Galileo Press.

Mehr Informationen zum aktualisierten Fachbuch für Webentwickler gibt es hier: JavaScript und Ajax
 
Alle Kapitel des Buches:
1 Grundlagen
2 JavaScript-Praxis
3 Professionelles JavaScript
4 Web 2.0 und Ajax
5 Kommunikation
6 Serverseitige Programmierung
7 Sicherheit
8 Praxis
9 Anhang
Bilder


 

DVD-Werbung
Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von tanzfrosch
  • 11.01.2018 - 14:56

Dankeschön, tolles Tut. !

Portrait von schmidtalbertsc745
Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 30.04.2008 - 07:31

Sehr nützlich dieser Auszug.

x
×
×