| # Dynamische Navigationsleiste
| Hinweise zu diesem Beispiel Quelltext mit Erläuterungen Anzeigebeispiel: So sieht's aus

## Hinweise zu diesem Beispiel

Auf vielen Web-Seiten nimmt die Navigation eigentlich viel zu viel Platz weg. Da wird oft ein Drittel des Anzeigefensters geopfert, um eine oder zwei Handvoll Links zu anderen Projektseiten anzubieten. Mit diesen Platzproblemen macht das Beispiel auf dieser Seite Schluss. Bei dieser Lösung gehört die Web-Seite der freien inhaltlichen Gestaltung und dem Text. Die Navigation blendet sich nur dann ein, wenn der Anwender es will. Dazu muss er auch nicht extra irgendwo hinklicken. Er bewegt einfach die Maus Richtung linken Fensterrand, und schon blendet sich dort die Navigationsleiste ein. Bewegt er die Maus wieder weg vom linken Fensterrand, blendet sich die Navigationsleiste automatisch wieder aus. Diesen Effekt kennen viele Anwender in ähnlicher Form von der Windows-Taskleiste und sind deshalb damit vertraut.

Das Beispiel funktioniert mit den Browsern ab der 4er-Generation. Das Beispiel zeigt vor allem, wie man das Problem der unterschiedlichen Event-Handling-Modelle bei den Browsern in den Griff bekommen kann. Das Beispiel benutzt ferner die DHTML-Bibliothek, um auf Elemente zuzugreifen.

## Quelltext mit Erläuterungen

Das Beispiel zeigt eine vollständige HTML-Datei mit der dynamischen Navigation. Wenn Sie die Navigation auf mehreren Seiten haben wollen, müssen Sie den JavaScript-Code entweder in alle Seiten einbauen, oder Sie lagern ihn in eine externe JavaScript-Datei aus und binden diese einfach nur ein.

Die Datei `dhtml.js`, in der die Funktionen der DHTML-Bibliothek enthalten sind, muss vorhanden sein und sich im Beispiel im gleichen Verzeichnis befinden wie die HTML-Datei.

### Beispiel:

Anzeigebeispiel: So sieht's aus ( DHTML-Bibliothek)

    <html><head><title>Test</title>
    <script type="text/javascript" src="dhtml.js"></script>
    <script type="text/javascript">
    function Menue () {
      if (typeof window.pageYOffset == "number") {
        if (NS4) {
          getElement("id", "Nav").top = window.pageYOffset + 50;
        } else {
          getElement("id", "Nav").style.top = window.pageYOffset + 50;
        }
      } else {
        if (typeof document.body.scrollTop == "number")
          getElement("id", "Nav").style.top = document.body.scrollTop + 50;
      }
      if (OP)
        getElement("id", "NavLinks").style.pixelTop = NavLinksPos;
      if (NS4) {
        getElement("id", "Nav").visibility = "show";
      } else {
        getElement("id", "Nav").style.visibility = "visible";
      }
    }

    function noMenue () {
      if (NS4) {
        getElement("id", "Nav").visibility = "hide";
      } else {
        getElement("id", "Nav").style.visibility = "hidden";
      }
    }

    function handleMove (ev) {
      if (!ev)
        ev = window.event;
      var mausposition = ev.pageX ? ev.pageX : ev.clientX;
      if (mausposition < 20) {
          Menue();
      } else {
        if (mausposition > 250) {
          noMenue();
        }
      }
    }

    function Event_init () {
      if (document.addEventListener) {
        document.addEventListener("mousemove", handleMove, true);
      } else {
        if (NS4) {
          document.captureEvents(Event.MOUSEMOVE);
          document.onmousemove = handleMove;
        } else {
          document.body.onmousemove = handleMove;
        }
      }
      if (OP) {
        NavLinksPos = 42; // Position des Bereiches NavLinks
        getElement("id", "NavLinks").style.pixelTop = NavLinksPos;
      }
    }
    </script>
    <style type="text/css">
    body { color:black; background-color:white; background-image:url(navigation_back.gif);
      margin:0; padding:20px 50px; font-family:Tahoma,sans-serif; }
    #Nav { position:absolute; top:50px; left:0; visibility:hidden; }
    #NavLinks { position:absolute; top:42px; left:42px; }
    #Nav a:link {color:#000080; font-weight:bold; font-size:13px; text-decoration:none; }
    #Nav a:visited { color:#000080; font-weight:bold; font-size:13px; text-decoration:none; }
    #Nav a:hover { color:#FFFFFF; background-color:#000080; font-weight:bold;
      font-size:13px; text-decoration:none; }
    #Nav a:active { color:#000080; font-weight:bold; font-size:13px; text-decoration:none; }
    </style>
    </head>
    <body onload="Event_init()">

    <div id="Nav">
     <img src="navigation.gif" width="250" height="450" border="0" alt="">
     <div id="NavLinks">
      <a href="http://de.selfhtml.org/">SELFHTML</a><br>
      <a href="http://aktuell.de.selfhtml.org/">SELFHTML aktuell</a><br>
      <a href="http://forum.de.selfhtml.org/">SELFHTML-Forum</a><br>
      <a href="http://aktuell.de.selfhtml.org/artikel/">Artikel</a><br>
     </div>
    </div>

    <h1>Die Seite mit der pfiffigen Navigation</h1>

    <p>Einfach mit die Maus Richtung linken Fensterrand bewegen.
    Um das Men&uuml; wieder wegzubekommen, Maus wieder zum rechten Fensterrand bewegen.</p>

    <p>Und jetzt kommen noch etliche leere Abs&auml;tze, damit auch sichtbar wird,
    dass das Men&uuml; immer an der gleichen Stelle angezeigt wird, egal wie weit man scrollt.</p>

    <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
    <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
    <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
    <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
    <p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>

    <p>Na, das d&uuml;rfte reichen :-)</p>

    </body>
    </html>

### Erläuterung:

Im sichtbaren HTML-Bereich der Datei ist zunächst ein größerer `div`-Bereich notiert, der mit Hilfe von CSS-Eigenschaften im `style`-Bereich im Dateikopf absolut positioniert wird. Durch die Angabe `visibility:hidden` wird zunächst einmal alles, was sich in diesem Bereich befindet, nicht angezeigt. Innerhalb dieses Bereichs mit dem id-Namen `Nav` ist zunächst eine Grafik notiert (navigation.gif) und anschließend ein weiterer, absolut positionierter `div`-Bereich, wobei aber dort CSS-Zuweisungen wie `top:42px` oder `left:42px` als relativ zur oberen linken Ecke des Eltern-`div`-Bereichs zu interpretieren sind. Die Grafik navigation.gif ist einfach eine optische Unterlage für den nachfolgenden `div`-Bereich, der die eigentlichen Verweise der Navigationsleiste enthält.

Der Rest des in der Datei notierten statischen HTML-Codes ist für das Beispiel nicht wichtig. Die vielen Textabsätze mit dem erzwungenen Leerzeichen `&nbsp;` dazwischen dienen nur dazu, viel Dokumenthöhe zu erzeugen, sodass man in der Datei scrollen kann. Denn es soll demonstriert werden, dass die dynamische Navigationsleiste immer an der gleichen Stelle erscheint, auch wenn im Dokument gescrollt wird.

Im einleitenden `<body>`-Tag der Datei ist der Event-Handler `onload` notiert. Wenn das Dokument vollständig geladen ist, wird die Funktion `Event_init()` aufgerufen. `Event_init()` stößt die Überwachung der Mausbewegungen im Dokument an. Denn nur wenn eine solche Überwachung stattfindet, kann die Navigationsleiste dynamisch eingeblendet werden.

Event-Handling ist leider ein schwieriges Kapitel, da die Implementierungen bislang doch noch recht unterschiedlich sind. Das Beispiel versucht es erst mal nach der neueren DOM-Syntax. Die Abfrage `if (document.addEventListener)` stellt sicher, dass nur die Browser in den diesen Ausführungszweig nicht gelangen, die Event-Handling nach DOM-Syntax interpretieren. In den entsprechenden Zweig gelangt aber Netscape 6, der die Methode `addEventListener()` versteht. Mit `addEventListener()` wird nach DOM-Syntax eine Funktion bestimmt, die aufgerufen wird, wenn ein bestimmtes Ereignis eintritt. Im Beispiel wird das Ereignis `mousemove` überwacht. Während der Anwender im Dokumentbereich die Maus bewegt, bewirkt diese "Registrierung", dass dann so oft es geht die Funktion `handleMove()` aufgerufen wird. Zur Bestimmung des zu überwachenden Elementes wird die Funktion `getElement()` der DHTML-Bibliothek aufgerufen.

Mit `if (NS4)` fragt die Funktion `Event_init()` ab, ob ein Netscape-Browser der 4er-Generation am Werk ist. Dort gibt es ebenfalls eine "Registrierung" für Ereignisse. Mit `document.captureEvents(Event.MOUSEMOVE)` wird das Ereignis "Mausbewegung" registriert, und mit `document.onmousemove = handleMove` wird die Funktion `handleMove()` aufgerufen, wenn das Ereignis eintritt.

Für die übrigen Browser erfolgt die Initialisierung der Eventüberwachung mit `document.onmousemove = handleMove`. Da Opera 5 unter Windows offensichtlich die Position des Div-Bereich `NavLinks` vergisst, wird die im Stylessheet-Bereich festgelegte Position in der Variablen `NavLinksPos` gespeichert. Anschließend wird der Bereich `NavLinks` neu positioniert. Damit auch ältere Versionen von Opera 5 damit zurecht kommen, wird die Eigenschaft `pixelTop` verwendet. Zur Bestimmung des Elementes wird die Funktion `getElement()` der DHTML-Bibliothek aufgerufen.

In der Funktion `handleMove()` sind verschiedene Fallunterscheidungen nötig, um die Mausposition in Erfahrung zu bringen. Im Internet Explorer wird auf das Event-Objekt, das die Daten des Ereignisses enthält, über window.event zugegriffen. In DOM-kompatiblen Browsern sowie in Netscape 4 wird das Event-Objekt als Parameter an die Funktion übergeben, im Beispiel trägt er den Namen `ev`. Mit `if (!ev)` wird abgefragt, ob der Parameter gesetzt wurde. Wenn dies nicht der Fall ist, wird mit in `ev` eine Referenz auf `window.event` gespeichert. Somit kann das Event-Objekt in jedem Fall über `ev` angesprochen werden.
Neben den verschiedenen Arten, auf das Event-Objekt zuzugreifen, werden zwei Varianten verwendet, um je nach Browser die Mausposition abzufragen. Die Eigenschaft `pageX` enthält die horizontale Mausposition gemessen vom linken Dokumentrand, die Eigenschaft `clientX` gemessen vom linken Fensterrand. In der Praxis sollte dies keinen Unterschied machen. Während `clientX` dem Internet Explorer und älteren Opera-Versionen bekannt ist, wird `pageX` von Netscape 4, Netscape 6 sowie neueren Opera-Versionen verstanden. Der Wert der jeweiligen Eigenschaft wird in der Variable `mausposition` gespeichert.
Wenn nun der Abstand des Mauszeigers vom linken Rand geringer ist als 20 Pixel, wird die Funktion `Menu()` aufgerufen. Wenn er höher als 250 Pixel ist, die Funktion `noMenu()`.

Die Funktion `Menu()` blendet die Navigationsleiste ein, und die Funktion `noMenu()` sorgt dafür, dass die Navigationsleiste nicht oder nicht mehr sichtbar ist. Beide Funktionen führen zu diesem Zweck wieder diverse `if`-Abfragen zur DHTML-Modellunterscheidung durch und ändern letztendlich hauptsächlich die CSS-Eigenschaft `visibility` (Sichtbarkeit) des großen `div`-Bereichs mit dem ID-Namen `Nav`. Die Funktion `Menu()` sorgt allerdings außerdem dafür, dass der von ihr auf sichtbar geschaltete Navigationsbereich auch immer schön im sichtbaren Bereich des Dokuments angezeigt wird, egal, wohin der Anwender im Dokument gescrollt hat. Dazu muss die Funktion die aktuelle Pixelposition der "Klopapierrolle" ermitteln, die ein langes Dokument darstellt. Auch dabei ist die Syntax leider wieder völlig unterschiedlich bei den Browsern. Beim Internet Explorer kommt die Funktion über die Eigenschaft `document.body.scrollTop` an den gewünschten Wert, und bei Netscape-Browsern und Opera über `window.pageYOffset`. Zu dem ermittelten Wert werden noch mal 50 Pixel dazugezählt, denn in dem `div`-Bereich mit dem ID-Namen `Nav` ist ja als `top`-Angabe, also als Startposition von oben gesehen, ebenfalls der Wert 50 angegeben.
Da Opera 5 beim Ändern der Fenstergröße mit JavaScript gesetzte Positionen "vergisst", wird vor jedem Einblenden des Menüs dem Bereich `NavLinks` die in der Variablen `NavLinksTop` gespeicherte Position zugewiesen.

### Beachten Sie:

Erklären Sie dem Anwender auf der ersten Seite, wo Sie eine solche Navigation verwenden, kurz mit einem Satz das Handling der Navigation. Seien Sie sich auch im Klaren darüber, dass Anwender mit nicht DHTML-fähigen Browsern oder deaktiviertem JavaScript so wie das Beispiel oben notiert ist überhaupt keine Möglichkeit zur Navigation haben. Um zumindest Anwendern, die JavaScript deaktiviert haben, ein Navigieren zu ermöglichen, könnten Sie beispielsweise an einer geeigneten Stelle im normalen Text einen noscript-Bereich notieren, in dem Sie die Navigationsverweise noch mal notieren.

| Laufende Datums-/Uhrzeitanzeige
| Allgemeine DHTML-Bibliothek

© 2007 Impressum