Interaktiv Scrollen mit DHTML

1. Formatierung
2. Vorbereitung
3. Aufruf
4. Seitenwechsel
5. Scrollen
6. Ereignisse auslösen
nach Oben
nach Unten
Seite 1: Formatierung

Stylesheets erlauben nicht nur eine zentrale Farb- und Schriftformatierung, sondern auch eine pixelgenaue Positionierung der verwendeten HTML-Elemente:

<style type="text/css">
#title { position:absolute; left:80px; top:20px;}
#refs { position:absolute; left:530px; top:190px;}
#up { position:absolute; left:530px; top:80px;}
#down { position:absolute; left:530px; top:370px;}
#content { position:absolute; left:80px; top:80px; width:410px; height:320px; overflow:hidden;}
.scrolling { position:absolute; left:auto; top:auto; margin:0px; padding:10px; font:12px Verdana; background-color:#00FFFF; border:none; visibility:hidden;}
</style>

Zuerst notieren wir die Individualformate für die div-Bereiche mit den vergebenen id-Namen, dann das Format für die Klasse namens scrolling. Mit einer absoluten Positionierung wird erreicht, dass die Elemente unabhängig von der Bildschirmauflösung immer den angegebenen Abstand zum linken und oberen Fensterrand einnehmen.

Die Eigenschaft overflow:hidden sorgt dafür, dass nur der definierte Ausschnitt des Layers zur Darstellung gelangt, nicht dessen gesamter Inhalt.

margin definiert den allgemeinen Abstand zu den Nachbarelementen, und padding denjenigen zu seinen eigenen Elementgrenzen. Mit background-color können Sie eine Hintergrundfarbe angeben. Damit sie auch von Netscape 4 korrekt dargestellt wird, sollte unbedingt border:none notiert werden. Um zu verhindern, dass sämtliche Layer beim Aufruf der Seite sofort angezeigt werden, setzen wir die Eigenschaft visibility zunächst auf hidden.

Weiter...

Seite 2: Vorbereitung

Zu Beginn des Scripts definieren Sie - wie üblich - die globalen Variablen, um auf die verschiedenen Script-Bereiche verzweigen zu können:

var dom=document.getElementById?1:0;
var ns4=document.layers?1:0;
present="first";
onResize=loadAgain;
function loadAgain() {
if (ns4)
self.location.reload();
}

Zuerst stellen wir über die Variablen dom und ns4 fest, welcher Ausdruck dem Browser bekannt ist, damit wir in der Lage sind, die Script-Bereiche klar voneinander zu trennen.

Wichtig ist auch, dass Sie der Variablen present jenen Layer zuweisen, der zuerst angezeigt werden soll, da diese Angabe von einigen der folgenden Funktionen benötigt wird.

Mit dem Event-Handler onResize wird noch zusätzlich die Änderung der Fenstergröße überwacht. Das ist insbesondere erforderlich für Netscape 4, der bei Größenänderungen des Browser-Fensters häufig Stylesheet-Anweisungen unterschlägt. Um zu verhindern, dass die Seite unvollständig angezeigt wird, soll in diesem Fall die gesamte Seite neu geladen werden.

Obwohl Opera dasselbe Manko aufweist, läßt sich hier die Änderung der Fenstergröße mit dem Event-Handler onResize leider nicht überwachen.

Weiter...

Seite 3: Aufruf

Beim ersten Aufruf der Seite soll ebenfalls der erste zu scrollende Inhalt an der beabsichtigten Stelle erscheinen. Das erreichen Sie, indem Sie einige Stylesheet-Angaben manipulieren. Bei Seitenaufruf muß daher die folgende Funktion in Aktion treten:

function init() {
if(dom) {
layer=document.getElementById("content"). getElementsByTagName("div");
layer['first'].style.visibility="visible"
layer['first'].style.top=0;
}
else if(ns4) {
layer="document['content'].document";
eval(layer+"['first']"+'.visibility="visible"');
eval(layer+"['first']"+'.top=-15');
}
}

Leider müssen Sie die Elemente in den beiden Zweigen recht unterschiedlich ansprechen.

Mit der Methode getElementById() läßt sich nach dem Document Object Model (DOM) auf ein HTML-Element zugreifen, das den zughörigen id-Namen besitzt. Da jedoch die zu scrollenden Seiten, auf die zugegriffen werden soll, in einem übergeordneten div-Bereich verschachtelt sind, müssen Sie die Methode getElementsByTagName() zusätzlich anfügen, um sie ansprechen zu können.

Im anderen Zweig können Sie für jedes anzusprechende Unterobjekt lediglich ein neues document-Objekt anhängen. Durch das korrekte Setzen von Anführungszeichen sollten Sie hier allerdings zwischen Variablen und Strings strikt unterscheiden.

In beiden Zweigen übergeben wir jeweils dem ersten Layer die gewünschten Werte für die Eigenschaften visibility und top. Indem wir die obere Startposition des Layers im ns4-Zweig auf -15 anstatt auf 0 setzen, sollen abermals die Unzulänglichkeiten dieses Browsers korrigiert werden.

Weiter...

Seite 4: Seitenwechsel

Damit die zu scrollenden Seiten durch Anklicken der Links nach Belieben gewechselt werden können, ist eine weitere Funktion erforderlich:

function change(page) {
if(dom) {
layer[present].style.visibility="hidden";
layer[page].style.visibility="visible";
layer[page].style.top=0;
}
else if (ns4) {
eval(layer+"[present]"+'.visibility="hidden"');
eval(layer+"[page]"+'.visibility="visible"');
eval(layer+"[page]"+'.top=-15');
}
present=page;
}

Die lokale Variable page ermöglicht es, die anzuzeigende Seite im Verweis zu übergeben. Beim Anzeigen einer neuen Seite soll jedoch gleichzeitig die gerade angezeigte Seite ausgeblendet werden. Da beim wiederholten Aufruf der Funktion change() bekannt sein muß, welche Seite ausgeblendet werden soll, speichern wir den Namen der aktuellen Seite in der Variablen present ab.

In den jeweiligen Code-Zweigen wird mit der entprechenden Syntax die Eigenschaft für die Sichtbarkeit des aktuellen Layers auf hidden gesetzt, und jene des übergebenen Layers auf visible. Die Werte für die obere Startposition bleiben die gleichen wie gehabt.

Bei der Funktion eval() handelt es sich um eine sehr mächtige Funktion, die Ausdrücke interpretiert und einzelne oder mehrere zusammengesetzte Javascript-Anweisungen ausführt. In den obigen Beispielen benutzen wir eval(), um nicht jedesmal die gesamten Layerangaben aussschreiben zu müssen, sondern einfach mit der Variablen layer übergeben zu können.

Weiter...

Seite 5: Scrollen

Dass man auf sämtliche Layer aber auch ohne eval() zugreifen kann, zeigen wir in der nächsten Funktion, die für das Scrollen zuständig ist. Da diese Funktion etwas umfangreicher ist, stellen wir sie in zwei Teilen vor:

function scroll(direction, speed) {
if (dom) {
var layertop=parseInt(layer[present].style.top);
var scrollheight=(document.getElementById('content'). offsetHeight - layer[present].offsetHeight);
}
else if (ns4) {
var layertop=parseInt(document['content']. document[present].top);
var scrollheight=(document['content'].clip.height - document['content'].document[present].clip.height);
}

Unsere Seite verfügt über einen Anzeigebereich, in dem sich ein eigener Scrollbereich befindet. Weil davon nur letzterer bewegt werden darf und nicht weiter als nötig gescrollt werden soll, müssen wir besonders darauf achten, die genauen Abstände zu ermitteln.

Damit alle Seiten nur im Anzeigebereich gescrollt werden, benötigen wir die obere Startposition des aktuellen Layers sowie die Höhe des Scrollbereichs. Da der Name des aktuellen Layers in present gespeichert ist, können wir mit der vordefinierten Funktion parseInt() seinen Abstand zum oberen Ende des Anzeigebereichs ermitteln. Diesen Wert, der sich beim Scrollen verändert, weisen wir der Variablen layertop zu.

Um nicht den gesamten Anzeigebereich mitzuscrollen, benötigen wir überdies die aktuelle Layerhöhe, die von der jeweils aufgerufenen Seite abhängt. Mit offsetHeight bzw. clip.height können wir auf die tatsächliche Anzeigehöhe eines Elements zugreifen.

Um zur Höhe des Scrollbereichs zu gelangen, müssen wir von der Höhe des definierten Anzeigebereichs die Höhe des aktuellen Layers subtrahieren. Der so ermittelte, statische Wert wird in scrollheight abgespeichert. Beide Werte benötigen wir für den zweiter Teil der Funktion:

if(direction=="down"&&layertop-10>scrollheight) {
if (dom)
layer[present].style.top=(layertop-speed)+"px";
else if(ns4)
document['content'].document[present]. top=(layertop-speed);
}
else if(direction=="up"&&layertop<-10) {
if (dom)
layer[present].style.top=(layertop+speed)+"px";
else if(ns4)
document['content'].document[present]. top=(layertop+speed);
}
timer=setTimeout("scroll('"+direction+"', "+speed+")",10);
}

Sowohl die Richtung, nach der gescrollt wird, als auch die Scroll-Geschwindigkeit werden durch die übergebenen Argumente direction und speed bestimmt.

Durch die übergeordnete if-else-Anweisung ermitteln wir, welche Richtung durch den Event-Handler übergeben wird, und wie weit der Layer gescrollt werden darf. Wir müssen deshalb mit Hilfe der Vergleichsoperatoren dafür sorgen, dass sich die zu scrollenden Seiten nicht über den Anzeigebereich hinaus bewegen und rechtzeitig zum Stillstand gelangen.

Innerhalb der if-else-Anweisung wird dann wieder auf den entprechenden Code für die unterschiedlichen Browser verzweigt.

Durch setTimeout() ruft sich schließlich die Funktion scroll() alle 10 Millisekunden selbst auf, wodurch der aktuelle Layer um die übergebene Anzahl von Pixel - hier 3 - nach unten oder oben gescrollt wird.

Zum Abschluß der Script-Anweisungen ist jetzt nur noch eine kurze Funktion erforderlich, um das Scrollen zu stoppen:

function stop() {
clearTimeout(timer);
}

Die Methode clearTimeout() stoppt die im Funktionszeiger timer abgespeicherte setTimeout()-Anweisung und beendet damit das Scrollen.

Weiter...

Seite 6: Ereignisse auslösen

Damit die notierten Script-Anweisungen korrekt ausgeführt werden, müssen Sie im Body der HTML-Datei noch die entprechenden Event-Handler referenzieren. Zum Aufrufen der init()-Funktion ist zunächst der Event-Handler onLoad im body-tag notwendig:

<body onLoad="init()">

Bei jedem Laden der Seite wird dadurch automatisch die init()-Funktion ausgeführt. Den Event-Handler onClick benötigen Sie, um durch einen Klick auf den entprechenden Link die Seiten zu wechseln:

<div id="refs">
<a href="#" onClick="change('first')">
Seite 1</a></div>

Auf diese Weise wird bei Anklicken des Links der Event-Handler onClick aktiviert, um der Funktion change() den jeweiligen Layernamen zu übergeben.

Um das Scrollen einzuleiten und zu stoppen werden die Event-Handler onMouseover und onMouseout eingesetzt:

<div id="up">
<a href="javascript:void(0)"
onMouseover="scroll('up', 3)"
onMouseout="stop()">
<img src="up.gif" border="0">
</a></div>

Da es nicht unbedingt erwünscht ist, dass eine andere Seite geladen wird, wenn der User vielleicht aus Versehen einen Scrollbutton anklickt, notieren wir im Verweis den void-Operator. Dadurch können Sie erreichen, dass bei Anklicken des Links gar nichts geschieht.

Durch den Zahlenwert, der der Funktion scroll() als zweiter Parameter übergeben wird, läßt sich gegebenenfalls noch die Scroll-Geschwindigkeit manipulieren.

Jetzt brauchen Sie nur noch den Inhalt der einzelnen Seiten einbinden:

<div id="content">
<div id="first" class="scrolling">
<b>Seite 1</b><p>
Text von Seite 1<br>
</div> </div>

Hier sollten Sie darauf achten, die div-Bereiche genau in der angegebenen Weise zu verschachteln. Wenn Ihnen die Datei aufgrund mehrerer eingebundener Seiten zu groß zu werden droht, lassen sich die zu scrollenden Seiten natürlich auch aus externen Dateien aufrufen.

 




































Internet Explorer: Ja
Netscape: Ja