| ## Allgemeine DHTML-Bibliothek
| Hinweise zu diesem Beispiel Quelltext mit Erläuterungen Test der DHTML-Bibliothek DHTML-Bibliothek erweitern

## Hinweise zu diesem Beispiel

Angesichts der vielen verschiedenen DHTML-Modelle, die derzeit noch kursieren, ist es für Programmierer oft nicht einfach, sich die ganzen unterschiedlichen Befehle und Zugriffsmöglichkeiten zu merken. Außerdem werden Dateien bei größeren Scripts ganz schön stark aufgebläht, wenn man immer wieder die gleichen Browser-Abfragen und Konstrukte für den Elementzugriff notiert. Besser ist es deshalb, einmal eine Bibliothek an allgemein geschriebenen DHTML-Funktionen zu schreiben, diese in eine externe JavaScript-Datei auszulagern, und die JavaScript-Datei dann in denjenigen Dateien mit einzubinden, wo der Code der DHTML-Funktionen benötigt wird.

Das Beispiel auf dieser Seite stellt eine solche Bibliothek für DHTML-Funktionen vor. Die einzelnen Funktionen werden dabei auch genau erklärt. In den anderen Beispielen in diesem Kapitel kommt die hier erstellte Bibliothek dann zum praktischen Einsatz.

Selbstverständlich können Sie die Funktionenbibliothek für Ihre Zwecke beliebig erweitern. So ist es z.B. denkbar, allgemein geschriebene Funktionen zur CSS-Formatierung oder -Positionierung von Elementen hinzuzufügen. Der hier vorgestellte Grundstock an Funktionen soll vor allem den Zugriff auf Elemente erleichtern und Browser-Abfragen reduzieren.

## Quelltext mit Erläuterungen

Der folgende Quelltext zeigt die vollständige DHTML-Bibliothek. Kopieren Sie sich den vollständigen Quelltext und speichern Sie ihn in einer Textdatei mit dem Namen dhtml.js. Dann haben Sie die externe JavaScript-Datei mit den DHTML-Funktionen.

### Beispiel - Datei dhtml.js:

    /* DHTML-Bibliothek */

    var DHTML = 0, DOM = 0, MS = 0, NS = 0, OP = 0;

    function DHTML_init() {

     if (window.opera) {
         OP = 1;
     }
     if(document.getElementById) {
       DHTML = 1;
       DOM = 1;
     }
     if(document.all && !OP) {
       DHTML = 1;
       MS = 1;
     }
    if(document.layers && !OP) {
       DHTML = 1;
       NS = 1;
     }
    }

    function getElem(p1,p2,p3) {
     var Elem;
     if(DOM) {
       if(p1.toLowerCase()=="id") {
         if (typeof document.getElementById(p2) == "object")
         Elem = document.getElementById(p2);
         else Elem = void(0);
         return(Elem);
       }
       else if(p1.toLowerCase()=="name") {
         if (typeof document.getElementsByName(p2) == "object")
         Elem = document.getElementsByName(p2)[p3];
         else Elem = void(0);
         return(Elem);
       }
       else if(p1.toLowerCase()=="tagname") {
         if (typeof document.getElementsByTagName(p2) == "object" ||
            (OP && typeof document.getElementsByTagName(p2) == "function"))
         Elem = document.getElementsByTagName(p2)[p3];
         else Elem = void(0);
         return(Elem);
       }
       else return void(0);
     }
     else if(MS) {
       if(p1.toLowerCase()=="id") {
         if (typeof document.all[p2] == "object")
         Elem = document.all[p2];
         else Elem = void(0);
         return(Elem);
       }
       else if(p1.toLowerCase()=="tagname") {
         if (typeof document.all.tags(p2) == "object")
         Elem = document.all.tags(p2)[p3];
         else Elem = void(0);
         return(Elem);
       }
       else if(p1.toLowerCase()=="name") {
         if (typeof document[p2] == "object")
         Elem = document[p2];
         else Elem = void(0);
         return(Elem);
       }
       else return void(0);
     }
     else if(NS) {
       if(p1.toLowerCase()=="id" || p1.toLowerCase()=="name") {
       if (typeof document[p2] == "object")
         Elem = document[p2];
         else Elem = void(0);
         return(Elem);
       }
       else if(p1.toLowerCase()=="index") {
        if (typeof document.layers[p2] == "object")
         Elem = document.layers[p2];
        else Elem = void(0);
         return(Elem);
       }
       else return void(0);
     }
    }

    function getCont(p1,p2,p3) {
       var Cont;
       if(DOM && getElem(p1,p2,p3) && getElem(p1,p2,p3).firstChild) {
         if(getElem(p1,p2,p3).firstChild.nodeType == 3)
           Cont = getElem(p1,p2,p3).firstChild.nodeValue;
         else
           Cont = "";
         return(Cont);
       }
       else if(MS && getElem(p1,p2,p3)) {
         Cont = getElem(p1,p2,p3).innerText;
         return(Cont);
       }
       else return void(0);
    }

    function getAttr(p1,p2,p3,p4) {
       var Attr;
       if((DOM || MS) && getElem(p1,p2,p3)) {
         Attr = getElem(p1,p2,p3).getAttribute(p4);
         return(Attr);
       }
       else if (NS && getElem(p1,p2)) {
           if (typeof getElem(p1,p2)[p3] == "object")
            Attr=getElem(p1,p2)[p3][p4]
           else
            Attr=getElem(p1,p2)[p4]
             return Attr;
           }
       else return void(0);
    }

    function setCont(p1,p2,p3,p4) {
       if(DOM && getElem(p1,p2,p3) && getElem(p1,p2,p3).firstChild)
         getElem(p1,p2,p3).firstChild.nodeValue = p4;
       else if(MS && getElem(p1,p2,p3))
         getElem(p1,p2,p3).innerText = p4;
       else if(NS && getElem(p1,p2,p3)) {
         getElem(p1,p2,p3).document.open();
         getElem(p1,p2,p3).document.write(p4);
         getElem(p1,p2,p3).document.close();
       }
    }

    DHTML_init();

### Erläuterung:

Die externe JavaScript-Datei darf nichts anderes als JavaScript-Code enthalten, so wie im Beispiel gezeigt. Im folgenden werden die globalen Variablen und die Funktionen beschrieben. Denn mit diesen Variablen und Funktionen können Sie arbeiten, wenn Sie die Bibliothek verwenden wollen.

#### Globale Variable `DHTML`:

Diese Variable speichert, ob Dynamisches HTML bei dem vom Anwender eingesetzten Browser verfügbar ist oder nicht. Innerhalb der Funktion `DHTML_init()` wird diese Variable mit einem Wert versorgt, der anschließend nicht mehr geändert werden sollte. Wenn Dynamisches HTML nach irgendeinem der bekannten DHTML-Modelle verfügbar ist, dann erhält sie den Wert `1`, wenn nicht, dann den Wert `0`. Mit der ganz simplen und eleganten Abfrage `if(DHTML)` können Sie dann im Verlauf eines eigenen Scripts überprüfen, ob überhaupt Dynamisches HTML möglich ist.

#### Globale Variable `DOM`:

Diese Variable speichert, ob Dynamisches HTML nach DOM-Syntax möglich ist oder nicht (Wert `1` oder Wert `0`). Innerhalb der Funktion `DHTML_init()` wird diese Variable mit einem entsprechenden Wert versorgt, der anschließend nicht mehr geändert werden sollte. Mit `if(DOM)` können Sie anschließend abfragen, ob ein neuerer Browser am Werk ist, der das DOM bereits in seiner JavaScript-Implementierung unterstützt.

#### Globale Variable `MS`:

Auch diese Variable wird innerhalb der Funktion `DHTML_init()` mit einem Wert versorgt. Wenn ihr Wert anschließend `1` ist, dann läuft Ihr Script mit ziemlicher Sicherheit auf einem MS Internet Explorer. Handelt es sich um einen Browser der 4er-Generation, ist in der Variablen `DOM` der Wert `0` gespeichert, bei neueren Browsern dagegen `1`. Mit `if(MS && !DOM)` können Sie also in Ihrem Script abfragen, ob mit der DHTML-Syntax des Internet Explorer 4.x gearbeitet werden muss.

#### Globale Variable `NS`:

Wie `MS` wird auch diese Variable innerhalb der Funktion `DHTML_init()` mit einem Wert versorgt. Wenn ihr Wert anschließend `1` ist, dann läuft Ihr Script mit ziemlicher Sicherheit auf einem Netscape-Browser der 4er-Generation. Denn wenn ein 6er-Netscape oder ein anderer Abkömmling des neu programmierten Mozilla-Browsers eingesetzt wird, ist stattdessen die Variable `DOM` gleich `1`, während `NS` gleich `0` ist. Mit `if(NS)` können Sie also in Ihrem Script abfragen, ob mit der DHTML-Syntax des alten 4er-Netscape gearbeitet werden muss.

#### Globale Variable `OP`:

Wie `MS` wird auch diese Variable innerhalb der Funktion `DHTML_init()` mit einem Wert versorgt. Wenn ihr Wert anschließend `1` ist, dann läuft Ihr Script mit ziemlicher Sicherheit auf einem Opera-Browser. Mit `if(OP)` können Sie also in Ihrem Script abfragen, ob ein Opera-Browser am Werk ist. Handelt es sich außerdem um einen neueren Opera-Browser, ist in den Variablen `DOM` und in `DHTML` der Wert `1` gespeichert.

#### Funktion `DHTML_init()` - Bibliothek initialisieren:

Aufruf:
`DHTML_init();`

Diese Funktion wird automatisch aufgerufen, wenn Sie die hier vorgestellte Bibliothek verwenden wollen. Dazu ist am Ende der Bibliotheksdatei der Aufruf `DHTML_init()` notiert. Anschließend sind die wichtigen globalen Variablen mit ihren Werten versorgt. Wenn `DHTML_init()` nicht vor allen anderen Aufrufen von Funktionen dieser Bibliothek aufrufen wird, passiert nicht das Gewünschte, da dann eine veraltete Browserversion angenommen wird. Die Wirkungsweise der übrigen Funktionen ist davon abhängig, dass die globalen Variablen mit korrekten Werten versorgt sind. Durch die Notation am Ende der Datei ist dies jedoch sichergestellt und die globalen Variablen sind in allen Dokumenten verfügbar, die diese Bibliothek einbinden.
Die Funktion `DHTML_init()` bedient sich der Möglichkeit, abzufragen, ob ein Objekt existiert. Bereits in der ersten Abfrage wird getestet, ob ein Opera-Browser vorliegt. Das ist notwendig, da Opera je nach Nutzereinstellung auch angibt, `document.all` oder `document.layers` zu kennen. Zum Testen auf DOM-Verfügbarkeit eignet sich die Frage, ob `document.getElementById` verfügbar ist, denn das ist eine wichtige DOM-Methode, die in allen DOM-Implementierungen existieren sollte.
Zum Testen auf die ältere Microsoft- und Netscape-Syntax wird auf deren zentrale DHTML-Objekte hin abgefragt. Wenn `document.all` verfügbar ist, ist Syntax nach dem älteren Microsoft-Modell angesagt. Wenn `document.layers` verfügbar ist, Syntax nach dem älteren Netscape-Modell. In beiden Fällen wird mit `!OP` der Opera-Browser ausgeschlossen, für den Fall, dass die Nutzereinstellungen die Kenntnis dieser Objekte ermöglichen.

#### Funktion `getElem()` - Elementobjekt ermitteln:

Beispielaufrufe:
`Elementobjekt = getElem("id","Hinweis",null);`
`Elementobjekt = getElem("name","Eingabefeld",0);`
`Elementobjekt = getElem("tagname","p",8);`
`Layerobjekt = getElem("index",2,null,null);`

Diese Funktion ist eigentlich die zentrale Funktion der hier vorgestellten Biblothek. Sie greift auf ein bestimmtes Element im Dokument zu und gibt das Objekt dieses Elements zurück. Das funktioniert mit DOM-fähigen Browsern ebenso wie mit dem älteren Internet Explorer 4.x und in eingeschränkter Form (nur im Zusammenhang mit `layer`- oder `div`-Elementen) auch mit Netscape 4.x.
In den meisten Fällen müssen Sie diese Funktion nicht selber aufrufen. Es handelt sich vielmehr um eine Basisfunktion, die von den übrigen Funktionen der Bibliothek benutzt wird. Dennoch gibt es auch Fälle, in denen ein Direktaufruf dieser Funktion Sinn macht. Die Funktion erwartet folgende Parameter:

`p1` ist die Art und Weise, wie auf ein Element zugegriffen werden soll. Es gibt vier erlaubte Werte für diesen Parameter: `"id"`, `"name"`, `"tagname"` und `"index"`. Übergeben Sie `"id"`, wenn Sie auf ein Element zugreifen wollen, das ein `id`-Attribut hat, z.B. `<div id="Bereich">`. Übergeben Sie `"name"`, wenn das Element, auf das Sie zugreifen wollen, kein `id`-Attribut, aber dafür ein `name`-Attribut hat, z.B. `<a name="Anker">`. Übergeben Sie `"tagname"`, wenn das Element, auf das Sie zugreifen wollen, weder ein `id`- noch ein `name`-Attribut hat. Übergeben Sie `"index"` nur dann, wenn es sich um Netscape-Layer handelt, die über das `layers`-Objekt mit Hilfe von Indexnummern angesprochen werden sollen.

`p2` ist die nähere Angabe zu dem, was Sie bei `p1` festgelegt haben: wenn Sie bei `p1` den Wert `"id"` übergeben, dann erwartet die Funktion bei `p2` den Wert des `id`-Attributs. Wenn Sie bei `p1` den Wert `"name"` übergeben, dann erwartet `p2` den Wert des `name`-Attributs. Wenn Sie bei `p1` den Wert `tagname` übergeben haben, dann erwartet `p2` den gewünschten Elementnamen, also z.B. `h1` oder `div`. Wenn Sie bei `p1` den Wert `"index"` übergeben haben, erwartet `p2` die Indexnummer für den gewünschten Netscape-Layer.

`p3` wird nur dann benötigt, wenn bei `p1` einer der beiden Werte `"name"` oder `"tagname"` angegeben wurde. In diesem Fall müssen Sie bei `p3` eine Indexnummer angeben, mit der Sie festlegen, das wie vielte Element im Dokument mit dem entsprechenden Namen oder Elementnamen Sie meinen. Das erste Element hat die Indexnummer `0`, das zweite Nummer `1` usw.

Übergeben Sie bei Parametern, für die Sie keinen Wert angeben, einfach das Wort `null` (ohne Anführungszeichen!).

Die Funktion `getElem()` geht der Reihe nach die möglichen DHTML-Modelle durch und fragt zuerst mit `if(DOM)` die globale Variable `DOM` daraufhin ab, ob DOM-Syntax verfügbar ist. Wenn ja, dann wird abhängig von den übergebenen Parametern das gewünschte Element nach DOM-Syntax ermittelt und zurückgegeben. Nur wenn keine DOM-Syntax verfügbar ist, wird versucht, die älteren DHTML-Modelle anzuwenden. Zunächst wird mit `if(MS)` geprüft, ob das ältere DHTML-Modell von Microsoft verfügbar ist. Wenn ja, wird das Element nach dessen Syntax über das `document.all`-Objekt ermittelt. Wenn auch die Microsoft-Syntax nicht greift, bleibt noch die ältere Netscape-Syntax, die mit `if(NS)` abgefragt wird. In diesem Fall wird aus den übergebenen Parametern der Zugriff auf ein Layer-Objekt konstruiert.

Gleichzeitig erfolgt in der Funktion eine Fehlerbehandlung. In jedem Zweig der Funktion wird mit dem typeof-Operator geprüft, ob das gewünschte Element überhaupt existiert und ob dieses ein Objekt darstellt. Tritt dieser Fall ein, wird das Element erzeugt und zurückgegeben. Andernfalls wird mit Hilfe des void-Operators undefined zurückgegeben.

#### Funktion `getCont()` - Elementinhalt ermitteln:

Beispielaufrufe:
`if(! NS) Elementinhalt = getCont("id","Hinweis",null);`
`if(! NS) Elementinhalt = getCont("name","Verweis",3);`
`if(! NS) Elementinhalt = getCont("tagname","p",8);`

Über diese Funktion, die ihrerseits auf die Funktion `getElem()` zurückgreift, können Sie auf bequeme Weise den Inhalt eines Elements ermitteln - zumindest wenn das DOM-Modell oder das ältere Microsoft-Modell für DHTML verfügbar sind. Das ältere Netscape-Modell kennt kein Auslesen von Elementinhalten. In den Beispielaufrufen ist der Funktionsaufruf deshalb davon abhängig gemacht, dass nicht nach älterer Netscape-Syntax gearbeitet wird (`if(!NS)`).
Die Funktion liefert bei Verwendung des DOM-Modells eine leere Zeichenkette zurück, falls der Inhalt des Element kein Text ist, sondern ein weiteres Element. Wenn also beispielsweise notiert ist:
`<p>der Text</p>`
Dann liefert die Funktion den Wert `der Text` zurück. Wenn aber notiert ist:
`<p><b>der Text</b></p>`
Dann liefert die Funktion bei Anwendung des DOM-Modells eine leere Zeichenkette zurück, da es keinen Text als Elementinhalt von `p` gibt, sondern der Inhalt ein anderes Element, nämlich ein `b`-Element ist.
Die Parameter sind bei `getCont()` die gleichen wie bei `getElem()`. Nur der Wert `"index"` bei Parameter `p1` wird von dieser Funktion nicht verarbeitet. Übergeben Sie bei Parametern, für die Sie keinen Wert angeben, das Wort `null`.

Die Funktion `getCont()` bedient sich also der Basisfunktion `getElem()` und reicht ihre drei übergebenen Parameter einfach an jene durch. Bei DOM-Syntax versucht sie, an den Textinhalt des Elements mit `firstChild.nodeValue` zu kommen, bei Microsoft-Syntax über die Eigenschaft `innerText` des `all`-Objekts. An der Art, wie die Funktion `getCont()` die Funktion `getElem()` aufruft, können Sie auch sehen, wie Sie die Basisfunktion `getElem()` anderweitig direkt aufrufen können. Da diese Funktion ein Elementobjekt zurückgibt, können Sie direkt Eigenschaften und Methoden eines solchen Objekts an den Funktionsaufruf hängen. Allerdings müssen Sie dazu selber abfragen, nach welchem Modell gearbeitet wird. Wenn nach DOM-Modell gearbeitet wird (abfragbar mit `if(DOM)`), dürfen beim Aufruf von `getElem()` Methoden und Eigenschaften der HTML-Elementobjekte angehängt werden oder auch solche des node-Objekts.

Die Funktion `getCont()` kümmert sich auch um Browser wie Opera, die Inhalte noch nicht dynamisch lesen können, jedoch andere Teile der Bibliothek interpretieren. Bevor der Versuch unternommen wird, Inhalte zu lesen, fragt sie mit `if (DOM && getElem(p1,p2,p3) && getElem(p1,p2,p3).firstChild))` ab, ob das gewünschte Objekt existiert und ob auch das Objekt firstChild vorhanden ist. Erst wenn diese Bedingung erfüllt ist, wird versucht den Inhalt zu lesen. Dadurch wird in jedem Fall eine Fehlermeldung vermieden.

#### Funktion `getAttr()` - Attributinhalt ermitteln:

Beispielaufrufe:
`Attribut=getAttr("name","Bildname",0,"height");`
`Attribut=getAttr("id","Bereich",null,"id");`
`if (!NS) Attribut=getAttr("name","Anker",0,"href")`
`if (NS) Attribut=getAttr("name","links",0,"href")`

Über diese Funktion, die ihrerseits auf die Funktion `getElem()` zurückgreift, können Sie auf bequeme Weise den Wert eines Attributs in einem Element ermitteln - zumindest wenn das DOM-Modell oder das ältere Microsoft-Modell für DHTML verfügbar sind. Für einige Objekte ist es auch im Netscape 4 möglich. Neben den drei bereits bekannten ersten Parametern erwartet diese Funktion einen vierten Parameter `p4`. Bei diesem müssen Sie den Namen des gewünschten Attributs übergeben. Übergeben Sie bei Parametern, für die Sie keinen Wert angeben, das Wort `null`.

Die Funktion `getAttr()` benutzt die Objektmethoden `getAttribute()`, die sowohl im DOM-Modell als auch im älteren Microsoft-Modell verfügbar sind.
Bei Netscape 4 dagegen wird die gewünschte Eigenschaft direkt abgefragt. Bei diesem Browser ist es in einigen Fällen nur möglich, über Unterobjekte auf die gewünschte Eigenschaft zuzugreifen, z.B. bei Verweisen und Ankern. Sie können darauf zugreifen, indem im Parameter `p2` den Namen des Unterobjektes (z.B. `links` oder `elements`) und im Parameter `p3` den Namen bzw. die Indexnummer des Objektes notieren.
Die Auswahl des richtigen Objekts übernimmt die Basisfunktion `getElem()`. Natürlich erfolgt auch in jedem Fall die Überprüfung, ob das gewünschte Objekt überhaupt existiert.

#### Funktion `setCont()` - Elementinhalt neu dynamisch ändern:

Beispielaufrufe:
`setCont("id","Hinweis",null,"neuer Hinweistext");`
`setCont("name","Verweis",3,"neuer Verweistext");`
`setCont("tagname","p",8,"neuer Textinhalt des Elements");`
`if(NS) setCont("index","2",null,"neuer Inhalt des Layers");`

Mit dieser Funktion können Sie den Inhalt eines Elements dynamisch ändern. Die Funktion `setCont()` bedient sich für den Zugriff auf das gewünschte Element der Basisfunktion `getElem()`. Die ersten drei Parameter, die bei dieser Funktion die gleichen sind wie bei den übrigen Funktionen, werden dazu an `getElem()` weitergereicht. Als vierten Parameter `p4` erwartet die Funktion `setCont()` den gewünschten Textinhalt. Beachten Sie, dass dieser Text zumindest beim DOM-Modell und beim älteren Microsoft-Modell nur als reiner Text interpretiert wird. HTML-Formatierungen im Text werden dabei als Klartext interpretiert.
Übergeben Sie bei Parametern, für die Sie keinen Wert angeben, das Wort `null`.
Bei Netscape-Layern benutzt die Funktion `setCont()` automatisch die üblichen Befehle zum Öffnen des Layer-Dokuments (`document.Layer.document.open()`), zum Schreiben (`document.Layer.document.write()`) und zum Schließen (`document.Layer.document.close()`).

Die Funktion `setCont()` kümmert sich auch um Browser wie Opera, die Inhalte noch nicht dynamisch ändern können, jedoch andere Teile der Bibliothek interpretieren. Bevor der Versuch unternommen wird, Inhalte zu ändern, fragt sie mit `if (DOM && getElem(p1,p2,p3) && getElem(p1,p2,p3).firstChild))` ab, ob das gewünschte Objekt existiert und ob auch das Objekt firstChild existiert. Erst wenn diese Bedingung erfüllt ist, versucht sie den Inhalt zu ändern. Dadurch wird in jedem Fall eine Fehlermeldung vermieden.

## Test der DHTML-Bibliothek

Das folgende Beispiel zeigt, wie Sie die DHTML-Bibliothek verwenden können. Die einzelnen Funktionen werden in dieser Beispieldatei mit konkreten Beispielen aufgerufen. Am besten können Sie die Funktionsweise testen, wenn Sie das Anzeigebeispiel mal mit verschiedenen Browsern aufrufen.

### Beispiel:

Anzeigebeispiel: So sieht's aus

    <html><head><title>Test</title>
    <script type="text/javascript" src="dhtml.js"></script>
    <script type="text/javascript">
    <!--
    function Testen() {
       var Ausgabetext = "";
       if(DHTML) Ausgabetext += "DHTML ist aktiviert!\n"
       else      Ausgabetext += "DHTML ist nicht aktiviert!\n";
       if(DOM)   Ausgabetext += "DOM wird unterstützt!\n";
       else      Ausgabetext += "DOM wird nicht unterstützt!\n";
       if(MS)    Ausgabetext += "Alte Microsoft-Technologie ohne DOM!\n";
       if(NS)    Ausgabetext += "Alte Netscape-Technologie ohne DOM!\n";

       h1_Inhalt = getCont("tagname","h1",0);
       if(h1_Inhalt)  Ausgabetext += "Inhalt des h1-Elements: " + h1_Inhalt + "!\n";
       else           Ausgabetext += "Inhalt des h1-Elements konnte nicht ermittelt werden!\n";

       p_Inhalt = getCont("id","Hinweisabsatz",null);
       if(p_Inhalt)   Ausgabetext += "Inhalt des p-Elements: " + p_Inhalt + "!\n";
       else           Ausgabetext += "Inhalt des p-Elements konnte nicht ermittelt werden!\n";

       if (NS)  Verweis = getAttr("name","anchors","Anker","text");
       else Verweis = getCont("name","Anker",0);
       if(Verweis)    Ausgabetext += "Verweistext: " + Verweis + "!\n";
       else           Ausgabetext += "Verweistext konnte nicht ermittelt werden!\n";

       h1_align = getAttr("tagname","h1",0,"align");
       if(h1_align)   Ausgabetext += "Ausrichtung des h1-Elements: " + h1_align + "!\n";
       else           Ausgabetext += "Ausrichtung des h1-Elements konnte nicht ermittelt werden!\n";

       Bild_hoehe= getAttr("name","auge",0,"height");
       if(Bild_hoehe) Ausgabetext += "Bildhöhe: " + Bild_hoehe + "px.\n";
       else          Ausgabetext += "Die Bildhöhe konnte nicht ermittelt werden!\n";

       Bereich_id = getAttr("id","Bereich",null,"id");
       if(Bereich_id) Ausgabetext += "id-Name des Bereichs: " + Bereich_id + "!\n";
       else           Ausgabetext += "id-Name des Bereichs konnte nicht ermittelt werden!\n";

       setCont("id","Bereich",null,"Tests sind fertig!");

       alert(Ausgabetext);
    }
    //-->
    </script>
    <style type="text/css">
    <!--
    #Bereich {position:absolute; top:200px; left:10px; width:500px; height:100px; }
    -->
    </style>
    </head><body>
    <h1 align="left">Test der dhtml.js</h1>
    <hr noshade size="1">
    <p id="Hinweisabsatz">Die Tests testen die Funktionen der DHTML-Bibliothek</p>
    <p><img name="auge" src="../../../src/auge.gif" width="24" height="16"
      border="0" alt="Testbild">
    <a name="Anker" href="javascript:Testen()">Test starten</a></p>
    <div id="Bereich">&nbsp;</div>
    </body></html>

### Erläuterung:

Das Beispiel enthält im sichtbaren Bereich der HTML-Datei eine Überschrift erster Ordnung, einen Textabsatz, einen weiteren Textabsatz mit einem Verweis, vor dem außerdem eine Grafik eingebunden ist, und schließlich einen `div`-Bereich, der mit Hilfe von CSS absolut positioniert ist. Die entsprechenden CSS-Angaben zur Positionierung stehen im Dateikopf in einem `style`-Bereich, wo die Formate für `#Bereich` notiert sind. Generell ist es wegen einiger Schwächen von Netscape 4.x besser, die CSS-Formatierungen der simulierten Layer in einem zentralen Stylesheet gleich im Dateikopf zu notieren und nicht im einleitenden `<div>`-Tag.

Im Dateikopf sind ferner zwei JavaScript-Bereiche definiert. Der erste ist leer und bindet lediglich die DHTML-Bibliothek ein, die in der externen JavaScript-Datei `dhtml.js` gespeichert ist. Der zweite Scriptbereich enthält den JavaScript-Code, der die Testaufrufe durchführt.

Das JavaScript innerhalb des Dateikopfes wird aufgerufen, wenn der Anwender auf den Verweis klickt, der in der Datei notiert ist. Dann wird die Funktion `Testen()` aufgerufen. Diese Funktion wie auch das gesamte JavaScript kann ohne weitere Umwege auf alle globalen Variablen und die Funktionen der DHTML-Bibliothek zugreifen.

Zunächst greift die Funktion `Testen()` auf die initialisierten globalen Variablen der DHTML-Bibliothek zu und prüft, welches DHTML-Modell verfügbar ist. Abhängig davon, was verfügbar ist, wird die Variable `Ausgabetext` um einen Text erweitert.

Als nächstes wird mit der Funktion `getCont()` aus der DHTML-Bibliothek gespielt.
Mit `getCont("tagname","h1",0)` wird via Elementname auf das erste `h1`-Element (Indexzähler 0) zugegriffen. Der Rückgabewert von `getCont()` wird in der Variablen `h1_Inhalt` gespeichert. Abhängig davon, ob diese nach dem Funktionsaufruf eine Zeichenkette mit einer Länge größer 0 enthält (`if(h1_Inhalt)`), wird die Variable `Ausgabetext` wieder um einen weiteren Text erweitert.

Zwei weitere Aufrufe von `getCont()` folgen, die andere Varianten der Parameterversorgung ausprobieren.
Mit `getCont("id","Hinweisabsatz",null)` wird auf das Element mit dem Attribut `id="Hinweisabsatz"` zugegriffen.
Mit `getCont("name","Anker",0)` wird auf das erste Element im Dokument zugegriffen, bei dem das Attribut `name="Anker"` notiert ist. Da auch mit Netscape 4 auf den Text eines Verweises zugriffen werden kann, wird für diesen Browser nicht die Funktion `getCont()` aufgerufen, sondern `getAttr()`. Berücksichtigt wurde zudem, dass sobald ein Verweis gleichzeitig ein Anker ist, der Verweistext nur über das Anchorobjekt ausgelesen werden kann.

Daran anschließend probiert die Funktion `Testen()` die Bibliotheksfunktion `getAttr()` mit drei Aufrufen aus, einmal über den Elementnamen, einmal über den Tagnamen und einmal über das `id`-Attribut.

Schließlich wird auch noch `setCont()` aufgerufen. Damit es in allen Browsern inklusive Netscape 4.x funktioniert, wird der Inhalt des absolut positionierten `div`-Bereichs neu gesetzt, den Netscape als Layer erkennt.

Am Ende gibt die Funktion `Testen()` die gesammelten Einzelergebnisse, die sie in der Variablen `Ausgabetext` zusammengetragen hat, in einem Meldungsfenster aus.

## DHTML-Bibliothek erweitern

Die hier vorgestellte DHTML-Bibliothek leistet nur einige wenige Grundfunktionen, erleichtert den Zugriff auf Elemente etwas und macht in vielen Fällen den JavaScriptCode etwas übersichtlicher und besser lesbar. Es gibt aber noch vieles, was sie nicht leistet. Wenn Sie häufig mit Dynamischem HTML arbeiten, empfiehlt es sich, wenn Sie die DHTML-Bibliothek um eigene, andere Funktionen erweitern. Wichtig ist bei so einer Funktionen-Bibliothek, dass alle Funktionen allgemein geschrieben sind. Deshalb erwarten die Funktionen in der Regel mehrere Parameter, um ihren Input für die zu verarbeitenden Daten zu erhalten.

Denkbar wären beispielsweise noch Funktionen, die direkt auf CSS-Eigenschaften von Elementen zugreifen, oder Funktionen, die in der Lage sind, ein Element dynamisch neu zu positionieren. Ausgegend davon sind auch Funktionen möglich, die bestimmte Bewegungsabläufe wie Kreisbahnen usw. berechnen und Elemente entsprechend positionieren. Andere denkbare Funktionen könnten sich dem leider noch ziemlich komplizierten, weil sehr unterschiedlich implementierten Event-Handling widmen und dort einiges vereinfachen.

Eine Funktionen-Bibliothek sollte andererseits jedoch nicht zu groß werden. Denn wenn Sie am Ende zig Kilobyte externes JavaScript einbinden, um drei triviale Anweisungen zu notieren, dann ist eine Funktionen-Bibliothek nicht angemessen. In solchen Fällen ist es besser, die paar Befehle ohne Zuhilfenahme einer Funktionen-Bibliothek zu notieren.

Achten Sie stets darauf, dass Ihre Bibliotheken eine Fehlerhandlung durchführen und jeweils die Verfügbarkeit der angesprochenen Objekte überprüft.

| Dynamische Navigationsleiste
| Dynamische Filter (nur Microsoft)

© 2001 selfhtml@teamone.de