Problemstellung

Falls die Navigation für das Browserfenster zu lang ist, soll sie nur so weit gescrollt werden, bis der untere Rand der Navigation am unteren Fensterrand angekommmen ist. Eine Grafik veranschaulicht die Situation.

Veranschaulichung

Im skizzierten Fall soll die Unterkante der Navigation an der Unterkante des Browserfensters ausgerichtet werden. Die Unterkante der Navigation hat die untere Begrenzung des Fensters erreicht, wenn dist_html_nav + hoehe_nav = scrollweite + hoehe_fenster gilt.

Wie man der Grafik entnehmen kann, ist eine Fixierung der Navigation nur notwendig, wenn der Inhalt länger als die Navigation ist.

Das Script ist im Gegensatz zu dem auf Seite 2 so aufgebaut, dass auf die Existenzabfragen der benötigten Elemente navigation und content verzichtet wird. Sie als Autor tragen also die Verantwortung für das Vorhandensein dieser Elemente.

Darstellung gehört ins CSS

Es ist eine Tugend, die Darstellung einer Seite vollständig in die CSS-Ressourcen zu verlagern und Javascript nur für dynamische Änderungen zu verwenden. Für Sie als Autor bedeutet dies Anpassungen an zwei Stellen. Zudem wird das Script nicht funktionieren, wenn die Navigation schon irgendeiner anderen Klasse angehört. Wenn es unterschiedliche Darstellungen des Menüs geben soll, wäre es denkbar, dem body eine Klasse zu verpassen und mit dem Kindselektor zu arbeiten.

Unsere gewünschte Darstellung stecken wir also ins CSS,

#navigation { // hier erscheinen alle gewünschten Optionen } #navigation.fixiert_oben { position: fixed; top: 8px; } #navigation.fixiert_unten { position: fixed; bottom: 4px; }

sodass wir mit Javascript nur noch die Klassenzugehörigkeit der Navigation ändern brauchen.

Das Script

Zusätzlich zu den bereits im Script der Seite 2 ermittelten Werte benötigen wir die Fensterhöhe und die Höhe des Inhalts. Diese beiden Werte sind jedesmal neu zu ermitteln, denn sie ändern sich zum Beispiel bei einem Resizing. Die Höhe des Elementes mit der ID "Inhalt" bestimmen wir auf dieselbe Weise wie auch die Höhe der Navigation.

Moderne Browser kennen window.innerHeight; für Internetexplorer < 9 benötigen wir document.documentElement.clientHeight. Unter Verwendung des ternären Operators wird daraus:

window.innerHeight ? hoehe_fenster = window.innerHeight : hoehe_fenster = document.documentElement.clientHeight;

Im Script sind jetzt zwei mögliche Fälle zu beachten: Entweder die Navigation passt vollständig in das Browserfenster oder nicht. Im ersten Fall soll sie nicht über den oberen Fensterrand hinaus scrollen, im zweiten soll sie am unteren Fensterrand bleiben.

/* IE < 7 ausschließen und Ereignisüberwachung hier weggelassen */ var nav = document.getElementById("navigation"), content = document.getElementById("content"), html = document.getElementsByTagName("html")[0], top_html = Math.round(html.getBoundingClientRect().top), top_nav = Math.round(nav.getBoundingClientRect().top), dist_html_nav = top_nav - top_html, hoehe_nav = nav.offsetHeight; function fixieren() { var hoehe_fenster, hoehe_content = content.offsetHeight, scrollweite; if (hoehe_content > hoehe_nav) { window.innerHeight ? hoehe_fenster = window.innerHeight : hoehe_fenster = document.documentElement.clientHeight; window.getComputedStyle ? scrollweite = pageYOffset : scrollweite = document.documentElement.scrollTop; if (hoehe_nav < hoehe_fenster) { if (nav.className == "fixiert_unten") nav.className = ""; //zuvor war sie länger als das Fenster (scrollweite + 8 > dist_html_nav) ? nav.className = "fixiert_oben" : nav.className = ""; } else { if (nav.className == "fixiert_oben") nav.className = ""; //zuvor war sie kürzer als das Fenster (hoehe_fenster + scrollweite - hoehe_nav + 4 > dist_html_nav) ? nav.className = "fixiert_unten" : nav.className = ""; } } }

Browsertests

Firefox 3.16
ok
Chrome 9
ok
MSIE 7, 8, 9
ok
Opera 11
ok
Safari 4
ok
MSIE 6
keine Funktionalität

Voraussetzungen

Download

scroll.js (Rechtsklick, "Ziel speichern unter" o.ä.)

Variante ohne Berücksichtigung veralteter Browser: scroll-modern.js (Rechtsklick, "Ziel speichern unter" o.ä.)

Seite 2