Unaufdringliches Scrollen in großen Webseiten

Bei der Verwendung von JavaScript in einer Webseite ist es nach wie vor wichtig, dass man die mächtige Scriptsprache “unobtrusive” (engl.: unaufdringlich) einsetzt. Das bedeutet, dass die eingebundenen Funktionen nur aufgerufen und genutzt werden, wenn der Browser dies unterstützt. Kann der Browser JavaScript nicht verwenden, kommen stattdessen die standardmäßig vorhandenen HTML-Funktionen zum Einsatz. So wird gewährleistet, dass die Benutzung der Seite mit als auch ohne clientseitigem Scripting funktioniert.Normalerweise präpariert man in diesem Sinne zunächst die HTML-Funktionen und lädt die gewünschten JavaScript-Funktionen über den Eventhandler onload dazu. Die Webseite wird dadurch zunächst vom Browser normal geladen, erst nach Abschluss des Ladevorgangs werden die JavaScript-Funktionen hinzugefügt, welche nachträglich einige Standardfunktionen (z. B. Hyperlinks) ergänzen oder ersetzen. Jeremy Keith hat diesem Thema in seinem (hervorragenden) Buch Dom Scripting ganze Kapitel gewidmet. In einem Beispiel-Abschnitt seines Buches beschreibt er unter anderem diese Unaufdringlichkeit.

Der Anwendungsfall

Beim Redesign der Webseite der Kölner Agentur mediastyles, beschlossen wir zum einen, die gesamten Informationen auf einer Seite abzubilden und zum anderen, die freie, unaufdringliche Diashow lightbox2 von Lokesh Dhakar zu verwenden. Lightbox2 öffnet – sofern JavaScript aktiviert oder verfügbar ist – verlinkte Bilder in einer Ebene oberhalb des Inhalts und blendet die Webseite mit einem halb-transparenten Layer aus. Die Bibliothek ist sogar in der Lage, automatisiert Diashows zu erzeugen, wenn die Links zu den Bildern entsprechend attributiert sind. Ist JavaScript nicht verwendbar, werden die Bilder wie gewohnt im Browserfenster angezeigt. Den Effekt kann man mit den Beispielen auf der offiziellen Webseite nachvollziehen.Lightbox2 verwendet dazu die in letzter Zeit oft erwähnten JavaScript-Bibliotheken, bzw. -Frameworks prototype und script.aculo.us, um die entsprechenden Bild- und Diashoweffekte zu erzeugen. Während prototype als sogenanntes Framework (man mag über diesen Titel streiten) ergänzende Funktionen zum Standardumfang von JavaScript bereitstellt, enthält script.aculo.us eine Vielzahl von Effekten, die – je nachdem – die Verwendung einer Webseite oder einer Web-Applikation durch bestimmte Visualisierungen vereinfachen.Unter anderem gibt es in der Bibliothek script.aculo.us einen Scrolleffekt, der das herkömmliche Anspringen eines Ankerlinks durch ein langsames Scrolling ergänzt. Da nun die mediastyles-Webseite sehr gross war, empfanden wir diese Art Scrolling als eine unterstützende Massnahme bei der Navigation durch die Seite. Der Usability-Aspekt mag diskutierbar bleiben, aber den Effekt an sich empfanden wir als sehr angenehm, da die Bewegung durch die Seite für den Benutzer nachvollziehbar wurde. Effect.ScrollTo erwartet als Parameter die #id des anzuspringenden Elementes.

Die Umsetzung

Es wurde also geplant, zunächst normale Ankerlinks zu verwenden (…a href=”#objektid…). Nach Laden des Dokumentes und bei vorhandener JavaScript-Unterstützung seitens des Browsers sollte ein onload-Handler eine JavaScript-Funktion aufrufen, die das normale Sprungverhalten, durch den Scrolleffekt ergänzt. Um die Ankerlinks per JavaScript ansprechen zu können, wurden sie alle mit der Klasse “softscroll” versehen. prototype führt unter anderem das Äquivalent zur nativen JavaScript-Funktion getElementsByID für Klassen ein: getElementsByClassName – so blieb das selbstgebastelte Klettern durch einen Array von Links auf der Suche nach den korrekten Klassen schon einmal aus – sehr hilfreich.Der Funktionsablauf in der Theorie:

  1. Sicherheitscheck zur Fehlervermeidung (Prüfung ob die benötigte Funktion zur Verfügung steht)
  2. Alle mit der Klasse “softscroll” versehenen Links in einen Array lesen
  3. Den Array durchlaufen
  4. In der Schleife für jeden Link einen onclick-Eventhandler hinzufügen, der den Effekt aufruft und als Parameter den vormaligen Wert des Ankerlinks verwendet

Jetzt an das Eingemachte:Zunächst wollten wir prüfen, ob überhaupt ein mit “softscroll”-attributierter Link da ist, um ggf. ohne Fehlermeldung abbrechen zu können, gleichfalls wird überprüft, ob der Browser das DOM unterstützt:

function loadSoftScroll (){if (!document.getElementsByClassName('softscroll')) {return false;}}

Nun werden die Links in den Array “links” gelesen:

function loadSoftScroll (){if (!document.getElementsByClassName('softscroll')) {return false;}var links = document.getElementsByClassName('softscroll');}

Es folgt der Aufbau der Schleife und darin die Erzeugung eines onclick-Handlers für die Links:

function loadSoftScroll (){if (!document.getElementsByClassName('softscroll')) {return false;}var links = document.getElementsByClassName('softscroll');for (var i = 0; i < links.length; i++) {links[i].onclick = function () {}}}

Schliesslich muss noch der Anker aus dem Link gezogen (Browser ergänzen dort den gesamten URL) und der Effekt hinzugefügt werden:

function loadSoftScroll (){if (!document.getElementsByClassName('softscroll')) {        return false;}var links = document.getElementsByClassName('softscroll');for (var i = 0; i < links.length; i++) {links[i].onclick = function (){var parts = this.href.split('#');new Effect.ScrollTo(parts[1]);return false;}}}

Ein onload-Handler sorgt für den Abruf der Funktion:

window.onload = function (){loadSoftScroll ();}

Das wär’s, klappt prima :) Alle Ankerlinks (die auch ohne JavaScript funktionieren) werden nach Laden des Dokumentes mit dem script.aculo.us-Scrolleffekt versehen, so dass dem Benutzer beim Navigieren durch eine große Seite veranschaulicht wird, wohin und wie weit er sich denn gerade bewegt. Der Effekt kann auf der mediastyles-Webseite angesehen und ausprobiert werden.

Weitere Links (Update: 11. März 2007)

Viel Spass beim Basteln!

Dieser Beitrag wurde unter Unsortiert abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

17 Antworten auf Unaufdringliches Scrollen in großen Webseiten

  1. macx sagt:

    Super! Hab es auf einer Webseite gleich eingebaut. Tausend Dank für die Hinweise!

  2. Christine sagt:

    Der Scroll-Effekt ist ganz schön, hat aber einen Nachteil: Der Back-Button funktioniert nicht mehr wie gewohnt. Ich denke, viele Leute benutzen den ganz gern, um wieder nach oben zu springen. Der ist nun mal eine häufig benutzte – vermutlich die am häufigsten benutze – Funtkion des Browsers.Es gibt zwar andere Möglichkeiten, wieder auf Anfang zu springen (Tasten z.B.), aber ich denke, ein wenig bedenklich ist es immer, wenn Browser-Standard-Verhalten beeinflusst wird, das gilt besonders für Back (in gewissem Maß auch und Forward). Unangenehm wird es nämlich dann, wenn der Benutzer einfach nur nach oben wollte, aber per Back auf der Seite landet, auf der er zuvor war.Was könnte man tun?Am besten wäre IMHO eine Möglichkeit, die Funktionen zu erhalten. Eine spontane Idee dazu habe ich auch nicht – auf irgend eine Art Veränderungen des URLs zulassen. Man müsste mal nachdenken, ob so etwas hinzukriegen ist.Nicht vermeiden, aber ein wenig mildern könnte man durch “Nach-oben”-Links innerhalb der langen Seite. Die finde ich übrigens bei langen Seiten ohnehin angebracht. Ob die Leute die benutzen oder doch Back? Keine Ahnung, aber wningstens anbieten würde ich.

  3. Sacha sagt:

    Schicker Effekt! Was ich mich allerdings frage: Normalerweise bieten die Frameworks (oder Bibliotheken, oder was auch immer) doch zumindest einen Funktionsparameter, mit dem man die Geschwindigkeit bzw. Dauer des Effekts bestimmen kann (hier die Scrollgeschwindigkeit). Ist so etwas nicht verfügbar oder ist es schlicht als optionaler Parameter eingebaut, den du weggelassen hast?

  4. Oliver sagt:

    @Christine: Ja, der Back-Button. Ein leidiges Thema, wenn es um JavaScript, AJAX und Co. geht. Es ist relativ schwierig, bei einer erweiterten Funktionalität durch Scripte noch den goldenen Mittelweg zu den Standard-Instrumenten des Browsers zu finden. Ich persönlich benutze ihn so gut wie nie, aber ich werde mich hüten, mein Verhalten zu verallgemeinern. Leider fällt mir für die Scroll-Methode und den Back-Button auch keine Lösung ein. An den angesprungenen Stellen der Seite darf natürlich der obligatorische “Nach oben”-Link nicht fehlen, der dann wiederum ein Scrolling auslöst.@Sacha: Doch, der Funktionsparameter für die Geschwindigkeit ist da, aber optional. Die Methode Effect.ScrollTo erwartet grundsätzlich nur den Parameter elementid, kann aber ebenfalls weitere Parameter in einer Zusatzsyntax enthalten: Effect.ScrollTo(‘elem’, {duration:4}).Im Standard ist die Dauer “1″ (Sekunde). Das Problem an der Sache ist, dass bei dem Auslesen aller Ankerlinks per Javascript die Abstände zwischen den Links ungleich groß sind. Ein höherer Wert führt dann zu unterschiedlichen Scrollgeschwindigkeiten, je nachdem, wie weit gescrollt wird.

  5. molily sagt:

    Da bindet man riesige Bibliotheken wie Prototype ein (46,5 KB), aber nutzt sie letztlich nur ganz sporadisch und macht immer noch ganz viel von Hand. (Gut, Prototype ist undokumentiert und deshalb weiß niemand, was alles drinsteckt. Und niemand kapiert den Code, deshalb ist Modularisierung unmöglich.)Jedenfalls ist Prototype nicht bloß eine Sammlung von netten Funktionen, sondern ein Framework, das den Programmierstil grundlegend ändern kann. Das Ausreizen von Prototype sähe etwa so aus:Event.observe(window, “load”, function () {$A(document.getElementsByClassName(‘softscroll’)).each(function (link) {Event.observe(link, “click”, function () {new Effect.ScrollTo(this.hash);}, false);});}, false);(Ich bin Prototype-Laie – wer ist das nicht.)Ich finds bemerkenswert, das selbst Prototype-Anwendungen wie Lightbox2 Prototype längst nicht ausreizen. Ich will damit Prototype nicht hochhalten, im Gegenteil.Wichtiger als diese Prototype-Syntaxmagie, die durch ein 46,5-KB-Script möglich ist und die letztlich an der Funktionalität nichts verbessert, wäre der Einsatz von DOMContentLoaded anstatt window.onload:http://dean.edwards.name/weblog/2006/06/again/Denn man merkt deutlich, dass all der JavaScript-Kram erst hinzugefügt wird, wenn alle Bilder usw. geladen wurden. Das liegt natürlich an den dicken Scripten, die die Leitung in Anspruch nehmen. ;)

  6. Oliver sagt:

    Hallo molily,vielen Dank für Deinen Beitrag. Zum Thema “Prototype als Framework” habe ich schon viele unterschiedliche Meinungen gehört (insbesondere im Vergleich zu Frameworks wie Dojo), ich mag mich da auf kein Urteil versteifen, zumal ich niemals die Zeit/Kapazität haben werde, da richtig einzusteigen.Allerdings ist der kurze Ansatz, den Du da aufzeigst natürlich der absolut richtige. Ich werde meine eigenen Skripte in dieser Hinsicht sicherlich überarbeiten (und empfehle das auch jedem, der das hier liest).

  7. Christine sagt:

    Mir hat das keine Ruhe gelassen! Die Sache mit dem Back-Button meine ich. :-)Ich habe mal ein wenig gebastelt – eigentlich ist es nur ein Denkansatz, keineswegs rund.Die Idee:Nachdem man zum Anker gescrollt ist, muss man ihn direkt anspringen, damit URL dazu passt. Das klappt sogar. [1]Der Haken, an den ich in der Theorie natürlich nicht gedacht hatte:Wenn man eine Seite scrollt (auch von Hand), verändert sich die Position, aber nicht der URL. Und genau das passiert bei unserem weichen Scrollen von oben. Der nachträgliche Sprung verändert zwar den URL, aber innerhalb der Seite wird keine Distanz zurückgelegt. Damit geht “Back” zwar zum vorhergehenden URL, aber innerhalb der Seite bewegt sich nichts.Einfall dazu:Position des vorhegenden URLs, resp. Ankers merken und von da aus springen. Im Code wird klar, was ich damit meine. [2] u. [3]http://netz-notizen.de/testereien/scroll-mit-back.html zeigt die Idee in Aktion.Das Ganze ist ein Schnellschuss, ausprobiert mit IE, Mozilla/Firefox (Win)- die tun es schon mal recht brav. Opera mag noch nicht so ganz. Aber es geht! :-)Wenn jemand noch ein wenig feilen möchte… – nur zu!Und hier noch der Codevar X, Y;var oldPosition = Array;function loadSoftScroll (){if (!document.getElementsByClassName(‘softscroll’)){return false;}var links = document.getElementsByClassName(‘softscroll’);for (var i = 0; i

  8. Christine sagt:

    var X, Y;var oldPosition = Array;function loadSoftScroll (){if (!document.getElementsByClassName(‘softscroll’)){return false;}var links = document.getElementsByClassName(‘softscroll’);for (var i = 0; i < links.length; i++){links[i].onclick = function (){var parts = this.href.split(‘#’);oldPosition = self.location.href.split(‘#’); /* [2] */new Effect.ScrollTo(parts[1],{beforeStart: function (){if (typeof (oldPosition[1]) == “undefined”){X = 0;Y = 0;}else{Position.prepare();X = Position.realOffset($(oldPosition[1]))[0];Y = Position.realOffset($(oldPosition[1]))[1];}},afterFinish: function (){window.scrollTo(X,Y); /* [3] */self.location.href = parts[0] + ‘#’ + parts[1]; /* [1] */}});return false;}}}window.onload = function (){loadSoftScroll();}PS: Oliver, es war das “<”-Zeichen. Sei bitte so nett und lösche mindestens den verkorksten Kommentar von eben. Mangels Vorschau-Funktion merkt man leider solche Tücken nicht selbst. :-(

  9. killercup sagt:

    hab so was ähnliches auch schon mit moo.fx gesehen, und moo ist viel kleiner (4kb!).

  10. Martin sagt:

    Ich finde, sowas gehört eher in den Browser eingebaut – damit man es zentral abschalten kann. Ich bevorzuge eine schnellstmögliche Reaktion des Browsers. Außerdem könnte ich mir vorstellen, dass das im heruntergetakteten Akkubetrieb oder auf älteren Rechnern ruckelt. Zudem dürfte es die Akkulaufzeit (wenn auch nur geringfügig) verkürzen.

    Ich persönlich benutze ihn [den Zurück-Knopf] so gut wie nie, aber ich werde mich hüten, mein Verhalten zu verallgemeinern.

    Ich nehme an, des Herrn Maus hat keine Seitentasten? ;)

  11. Oliver sagt:

    Danke für die mittlerweile zahlreichen Antworten.@killercup: Ja, moo.fx setze ich mittlerweile auch in einigen Projekten ein. Es ist einfach eine Frage der Anforderungen und Rahmenbedingungen. Bei eher applikationsartigen Webseiten (oder direkt: Webapplikationen) macht u. U. der Einsatz eines “richtigen” Frameworks a la Dojo Sinn, je nach Einsatzzweck greift man aber eben auch gerne mal zu Alternativen. Im Rahmen von moo.fx finde ich besonders moo.ajax erwähnenswert. Viel “X” ist da zwar nicht, aber für kleine Lösungen ist das durchaus interessant.@Martin: Klar, die Kompatibilität ist ein wichtiges Thema, darum muss JavaScript mindestens “skalieren”, d. h. sollte es mal nicht laufen, müssen die Sprungpunkte auch ohne das schöne Scrollen erreichbar sein. Zum Thema “Maus”: Nein, keine Seitentasten, wenn wir über den Notebook-Einsatz im Akkubetrieb reden, habe ich aber meistens auch gar keine Maus ;)@Christine: Einen guten Ansatz zeigst Du dort auf, ich halte es aber dazu noch eher mit molily. Wenn ich ein solches Framework schon einsetze, dann sollte ich (eigentlich) auch die zur Verfügung stehenden Handler nutzen, d. h. in diesem Fall tatsächlich Event.observe (). Aber wer hat in Projekten, die eher in Stunden als in Tagen gerechnet werden schon Zeit ;)Allgemein: Einzelseiten, wie sie z. B. auf Design Meltdown gelistet werden, haben immer die Notwendigkeit von Ankern im Kontext, die ein gehöriges Maß an Orientierungsfähigkeit vom Benutzer verlangen. Habt ihr noch ein paar Beispiele, wo das gut gelöst ist?

  12. Pingback: Softscroll mit jQuery » macximal

  13. Pingback: Die etwas andere Navigation... - jswelt - Forum (Javascript, PHP, MySQL, AJAX, Webdesign)

  14. Matthias sagt:

    heey super sache … wie kann ich die anker denn aus einem flash öffnen ???

  15. Pingback: zum Seitenanfang springen - jswelt - Forum (Javascript, PHP, MySQL, AJAX, Webdesign)

  16. Pingback: graubrot.net » Blog Archive » Script gesucht

  17. Pingback: » Das Problem mit scrip.aculo.us Effect.scroll() - webmatze.de

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>