Anzeige
Smartes Cloud Hosting für anspruchsvolle Projekte.
↬ Loslegen und Spaces testen ↬ Jetzt testen!
Marcel Weber 26. August 2009

Animiertes Scrollen mit jQuery

Kein Beitragsbild

Sie klicken auf einen Link und anstatt einfach zum entsprechenden Anker zu springen, wird sanft zum gewünschten Anker gescrollt. Ich sehe diesen Effekt in letzter Zeit immer öfter und war erstaunt, wie einfach er mit jQuery umgesetzt werden kann. Selbst die Erhaltung der „richtigen“ URL (www.url.de#anker) stellt keine Probleme dar. Demo im neuen Fenster

jQuery Code

$(document).ready(function() {
	$('a[href*=#]').bind("click", function(event) {
		event.preventDefault();
		var ziel = $(this).attr("href");

		$('html,body').animate({
			scrollTop: $(ziel).offset().top
		}, 2000 , function (){location.hash = ziel;});
});
return false;
});

Erkläuterung

$(document).ready(function() {

Der Effekt soll natürlich erst angewendet werden, wenn die Seite fertig geladen ist.

$('a[href*=#]').bind("click", function(event) {

Mit a[href*=#] wählen wir alle Links aus, deren Ziel mit einer Raute beginnt, also alle Anker-Links. Mit der bind() Funktion binden wir den folgenden Code an das Klick-Ereignis der Links, so dass er nach dem Klick ausgeführt wird.

Anzeige

event.preventDefault();

Der Code wird jetzt zwar erst nach dem Klick ausgeführt, jedoch versucht der Browser immer noch zuerst zum Anker zu springen, was zu einem Flackern vor dem Scrollen führt. Dieses Standardverhalten wird durch die preventDefault() Methode unterbunden. Beispiel zum Flackern

var ziel = $(this).attr("href");

Um gleich einfacher auf das Link-Ziel zugreifen zu können, wird dieses in die Variable „ziel“ geschrieben.

$('html,body').animate({

Nun wählen wir den Bereich aus, den wir animieren wollen, die komplette Seite, als html. Da der Browser Safari den html-selektor nicht erkennt, muss noch „body“ angehängt werden. Die Seite wird nun mit der animate() Funktion animiert.

scrollTop: $(ziel).offset().top

Die scrollTop() Funktion scrollt zu dem Wert, der ihr übergeben wird. scrollTop(400) würde die Seite beispielsweise um 400 Pixel nach unten scrollen. Die genaue Position des Ankers, zu dem wir scrollen wollen, bekommen wir mit der offset() Funktion. Mit ihr kann die genaue Position eines Elementes von links und von oben im Dokument ermittelt werden. Da wir hier nur den Abstand von oben benötigen, nutzen wir „offset().top“.

}, 2000 , function (){location.hash = ziel;});
});
return false;
});

Die Zahl nach der Klammer gibt die Dauer der Animation in Millisekunden an (duration). Jetzt kommt die meiner Meinung nach wichtigste Funktion ins Spiel. Die Callback-Funktion der Animation wird ausgeführt, sobald die Animation vollständig beendet ist, also wenn die Seite zum gewünschten Anker gescrollt ist. Diese Funktion brauchen wir, da wir ja das Standardverhalten des Links unterdrückt haben, also den Sprung zum Anker und die Anpassung der URL. Mit location.hash setzen wir eine neue Textmarke und passen so die URL an. Ohne diese Funktion würde der Anker beim Klick nicht an die URL angehängt.

Beispiel

Ausgangs URL
www.url.de

Nach Sprung zu einem Anker OHNE location.hash
www.url.de

Nach Sprung zu einem Anker MIT location.hash
www.url.de#anker

Fazit

Es darf über die Notwendigkeit dieses Kniffs gestritten werden, ich persönlich halte ihn für einen ansprechenden und interessanten Effekt, der in vielen Seiten gut zur Wirkung kommt und dem Benutzer vielleicht auch besser verdeutlicht, wo er denn nach einem Klick landet. ™

Ergänzung für Opera

Da ich durch den Kommentar von NightWalker auf das Fehlverhalten in Opera hingewiesen wurde ist hier nun der für Opera optimierte Code.

$(document).ready(function() {
	$('a[href*=#]').bind("click", function(event) {
		event.preventDefault();
		var ziel = $(this).attr("href");
                
                if ($.browser.opera) {
                    var target = 'html';
                }else{
                    var target = 'html,body';
                }

		$(target).animate({
			scrollTop: $(ziel).offset().top
		}, 2000 , function (){location.hash = ziel;});
});
return false;
});

Opera Demo im neuen Fenster

Marcel Weber

Student der Kommunikations- und Softwaretechnik

63 Kommentare

  1. Das Script funktioniert gut. Als Anpassung für eine meiner Websites muss ich jedoch dem Anker-Sprungziel einen Abstand von 180px mitgeben, da ein div-Kasten mit dieser Höhe oben fixiert ist. Den Abstand habe ich noch „.top“ im Script eingefügt “ scrollTop: $(ziel).offset().top -180 “ Nun das Problem: Klicke ich auf den Link, scrollt er mir exakt an die richtige Position. Man sieht dass er es gemacht hat. Dann führt er leider noch einen Schritt aus und verschiebt den Scrollvorgang an die normale Browseroberkante. Kann man diesen letzten Scrollschritt irgendwie aufhalten?
    Danke für eure Antworten … wäre wichtig

  2. Nicht schlecht! Ich habe jedoch ein Problem. Auf meine Seite können die Besucher Bewertungen abgeben. Doch da muss man jetzt den Link „Bewertungen“ oder „Bewertung schreiben“ zweimal klicken bevor man zu den Tab springt.

    Schaue Mal hier http://www.devildeals.de/produkt/acer-aspire-z3-600-dq-stheg-002-all-in-one-desktop-pc/

    Klicke dort auf „Bewertungen“ oder „Bewertung schreiben“. Wenn du einmal klickst dann scrollt es noch nicht. Beim zweiten Mal hat man den gewünschten Effekt.

    Gib es dafür eine Lösung so, dass man beim ersten Klick direkt scrollt?

    Gruß, Eugen

  3. scrollLeft: $(ziel).offset().left,

    …ist die Lösung fürs horizontale scrollen,

    den Abstand habe ich noch nicht …

    Tipps?

    besten Dank

  4. Hallo,
    super gut erklärt, danke! Und ein Script, das im Gegensatz zu einigen anderen auch funzt, hab nun noch Verschiedenes probiert, um die Ankernavi auch horizontal und mit einem Abstand zwischen Anker und Browserfenster (oben) hinzubekommen, hat leider nix geklappt, wäre sehr dankbar für Tipps

    beste Grüße, Camira

  5. Hi Marcel,

    geile Seite! Die erste zu dem Thema, die ich zzumindest nach Blick in Deinen kommentierten Webseitencode verständlich fand. Dieckes Lob dafür. Ich habe nun das Problem, dass bei mir auf der Seite http://www.high-potential.net/wie-es-funktioniert.html nur diejenigen Links sauber funktionieren, die nach oben scrollen. Diejenigen, die nach unten scrollen sollen, gehen auch erst langsam nach oben, um dann anschließend leicht verzögert aprupt nach unten zum Anker zu springen.

    Kann mir da einer der Experten bitte behilflich sein? Hier in den Comments oder per Mail?

    Vielen Dank!!!

    Liebe Grüße

    Sven

  6. Hallo,

    also script ist sehr gut nun habe ich eine Fachfrage.
    Ich habe eine HTML 5 animation mit einem Click event zu einem Anker, was dann nicht so schön scrollt sondern springt.

    Welche möglichkeit habe ich in dem click event einen a href link zu erzeugen dann würde es denk ich mal gehen oder ich muss das scroll script ansich ändern weil das ja nur auf a href wirkt.

    Verwende das LocalScroll Plugin.

    Bitte um Hilfe auf mein Email.

  7. erst einmal großes lob für das tolle script zum animierten scrollen. funktioniert echt top. kann man das script so ändern, dass auch anker auf einer anderen unterseite die ich anspringen möchte angescollt wird? also in etwa so dass die unterseite erst ganz normal geladen wird und dann automatisch zum anker gescrollt wird?

  8. Schönes Script!
    Wenn man übrigens die normale Anker-Struktur bedienen will (also zum Ziel und ), kann man schreiben:

    scrollTop: $(‚a[name=’+ziel.replace(/#/g, „“)+‘]‘).offset().top

  9. …spitze Marcel!
    Vielen vielen Dank!

  10. Hallo Marcel,

    vielen Dank. Animiert srollen klappt bei mir aber dennoch nicht… :(

  11. @Michael

    $(document).ready(function() {
    // Alle internen Links auswählen
    $(‚a[href*=#]‘).bind(„click“, function(event) {
    // Standard Verhalten unterdrücken
    event.preventDefault();
    // Linkziel in Variable schreiben
    var ziel = $(this).attr(„href“);
    var target = ‚#scrollbereich‘;
    //Scrollen der Seite animieren, body benötigt für Safari
    $(target).animate({
    //Zum Ziel scrollen (Variable)
    scrollTop: ($(ziel).offset().top)-($(target).offset().top) + ($(target).scrollTop())
    // Dauer der Animation und Callbackfunktion die nach der Animation aufgerufen wird, sie stellt das Standardverhalten wieder her und ergänzt die URL
    }, 2000 , function (){location.hash = ziel;});
    });
    return false;
    });

  12. Hallo,

    wie könnte ich es hinbekommne, die Absätze in einem DIV mit fester Breite und Höhe einzubinden, dass diese auch darin soft gescrollt werden?

    Würde alles bis auf die „Navi“ in den div#scrollbereich einfügen.
    Bsp-CSS dazu:

    #scrollbereich {
    height: 300px;
    width: 800px;
    overflow: scroll;
    }

    -> damit läuft allerdings der „softscroll“ nicht mehr.

    Grüße

    Michael

  13. Hallo, super Script.
    Gibt es auch die Möglichkeit das ganze für eine horizontale Slidefunktion um zu bauen.

  14. Also ehrlich gesagt habe ich das was ich frabriziert hatte schon wieder weggeworfen.

    Habe versucht das mit dem Script hier zu kombinieren.

    function goto_1(anker){
    if(window.location.hash==““){
    window.location.href = anker;
    }
    }

    <?php
    if ($seite==“versicherungen“){
    echo “bodymitonloadfunktion“;}
    else{
    echo “bodyohneonloadfuktion“;
    }

    Gruß
    Matthias

  15. @Matthias kannst du mal ein Beispiel posten, wie dein code im moment aussieht?

    Gruß Marcel

  16. Hallo
    finde das ganze recht gut, nur ich bräuchte das ganze im body mit onload statt klick. Versuche das schon 4 Std hat aber irgendwie nicht so richtig funktioniert.

    Gruß
    Matthias

  17. Danke für diese super Erklärung und die Demo. Hat mir wirklich sehr geholfen!

    Gruß.

  18. Ein weiteres Problem dieser an sich schönen Methode (schön, weil der User sieht, wohin der Sprung führt):

    Die Zurück-Funktion des Browsers wird kaputt gemacht. Im Klartext: nach einen „gewöhnlichen“ Sprung zu einem Anker komme ich mit der Zurück-Taste (oder alt + Pfeiltaste links o. ä.) wieder zum Ausgangspunkt des Sprungs. Nach dem Sanft Scrollen leider nicht.
    Damit wird der User verunsichert. Sein Browser funktioniert plötzlich nicht mehr wie gewohnt.
    Eigentlich schade. Die Browserhersteller sollten wirklich mal darüber nachdenken, dieses feature einzubauen.

  19. @Sven

    Versuch mal folgenden Code :-)
    Als ergänzung musst du in deinen Sprungzielen einen Tabindex setzen!

    $(document).ready(function() {
    	$('a[href*=#]').bind("click", function(event) {
    		event.preventDefault();
    		var ziel = $(this).attr("href");
                    
                    var active = ziel.substring(1,ziel.length);
                    if ($.browser.opera) {
                        var target = 'html';
                    }else{
                        var target = 'html,body';
                    }
    
    		$(target).animate({
    			scrollTop: $(ziel).offset().top
    		}, 2000 , function (){location.hash = ziel;
     document.getElementById(active).focus(); });
    });
    return false;
    });
    
  20. @Marcel:
    Richtig, es liegt am IE (wen wundert’s ;-) und nicht am Script. Geeignete Suchbegriffe sind z.B. „in-page keyboard navigation“, über die ich eben auf folgenden Artikel gestoßen bin [url]http://juicystudio.com/article/ie-keyboard-navigation.php[/url] [juicystudio.com].

    Das waren noch IE6-Zeiten, und das Problem besteht im IE offenbar bis heute. Es werden mehrere Lösungsmöglichkeiten aufgezeigt, die ich eben aus Zeitgründen nur auf die Schnelle durchprobiert habe, von denen aber leider keine in meiner Testumgebung funktionierte.

    Damals wurde das hasLayout-Konzept dafür verantwortlich gemacht (z.B. im o.g. Artikel, auf den auch Ingo Chao in seinem berühmten Artikel über das hasLayout-Konzept Bezug nahm), aber da das hasLayout-Konzept im IE8 ja m.W. nicht mehr Anwendung findet, muss es an was anderem liegen.

    Interessierte können ja mal mit den auf juicystudio.com gezeigten Lösungen testen und und hier evtl. über positive Ergebnisse berichten.

    Vielleicht gibt’s auf drweb ja demnächst sogar einen eigenen Artikel zu dieser speziellen Problematik. Mein Wunschautor: Marcel Weber ;-)

  21. @Sven: Ich habe versucht eine Lösung für das Problem zu finden, bis jetzt bin ich aber noch nicht fündig geworden.

    Jedoch bin ich bei meiner Suche auf etwas anderes gestoßen, was ich bisher garnicht beachtet habe.

    Als wenn ich als Beispiel diese Seite die kein JavaScript enthält im IE öffne dann funktioniert, zumindest bei mir, die Tab-Navigation ebenfalls nicht. Somit sehe ich das Problem allgemein bei IE und nicht direkt im Script.

  22. @Wolfgang Weber:

    Das sollte ich noch hinzufügen: Für ein einfaches „nach oben“ bzw. „Zum Seitenanfang“ klappt das Script von Marcel auch im IE. Aber es geht uns ja um die korrekte Fokus-Zuweisung über den gesamten Vorgang der Tab-Navigation hinweg.

    @Gerd:
    Vielen Dank für den Hinweis auf Dein Script. Leider besteht hier dasselbe Manko wie beim Script von Marcel: Auch hiermit klappt die Tab-Navigation im IE nicht (außer dem einfachen „nach oben“-Link). Auch hier erfolgt der Sprung zum Sprungziel, aber beim nächsten Tab gehts nicht von da aus weiter, sondern zurück zum ersten Link. Also hapert es noch mit der Fokus-Zuweisung.

    Mal sehen, vielleicht findet doch noch ein Spezialist die Lösung für den IE.

  23. Nur zur Info für Interessierte. So etwas Ähnliches wurde ohne JQuery bereits vor einigen Jahren von uns gemacht: http://www.kryogenix.org/code/browser/smoothscroll

    Ist ein netter und oft nützlicher Effekt, den ich schon mehrfach auf Wunsch eingesetzt habe.

  24. @Sven:

    Danke für die Info bezüglich Internet Explorer 8! Wenn die Accessibility leidet, kommt das Script natürlich nicht in Frage. Schade, denn das animierte Scrollen ist wirklich ein netter Effekt.

    Ich habe übrigens derzeit eine andere Variante im Einsatz, und theoretisch sollte das auch im IE keine Probleme machen (habe es allerdings noch nicht getestet):

    $(‚div.nach_oben a‘).click(function(event)
    {
    $(this).blur();
    $.scrollTo(‚#top‘, 800);
    $(‚#sprungmarke_1‘).focus();
    event.preventDefault();
    });

    Voraussetzung dafür ist das Plugin „jQuery.ScrollTo – Easy element scrolling using jQuery“ von Ariel Flesler.

    Das Problem dabei ist, dass obiges Code-Schnippsel halt nur für „nach oben“- bzw. „zum Seitenanfang“-Links gedacht ist, während Marcels Code viel allgemeiner funktioniert. Wenn nur die Nebenwirkungen nicht wären…

    @David:

    Der Sinn des von mir genannten Links ist leicht erklärt. Und zwar handelt es sich dabei um interne Links zur Glossar-Seite, wobei die Links halt auch einen Anker besitzen.

    Ich habe mir ein kleines Templatesystem programmiert, sodass ich in der Templatedatei, wenn ich auf einen Glossar-Eintrag verweisen möchte, z.B. nur

    T_GLOSSAR#Zu_erklärendes_Wort–

    schreiben muss, und das Templatesystem bastelt mir den Link zum entsprechenden Eintrag mittels preg_replace_callback() zusammen – einschließlich eines Links auf der Glossar-Seite, der zu der Stelle, von welcher der Eintrag aufgerufen wurde, zurückführt.
    Und damit das Ganze auch ohne JavaScript (history.back()) funktioniert, werden bestimmte Parameter in der URL übergeben.

    Die Links sehen also so aus:

    href= „glossar.php?QUERYSTRING#ANKER“

    Und diese Art von Links funktionieren mit Marcels Script ($(‚a[href*=#]‘)) aufgrund des * halt nicht. Das ist aber kein wirkliches Problem.

    Es wäre nur toll, wenn jenes Element, zu dem gescrollt wird, auch verlässlich den Focus bekäme, und zwar auch in IE 6-8.

    LG, Wolfgang

  25. @Pert (#35)
    Gib statt der 2000 mal testweise z.B. 1200 ein, dann geht’s schneller. Mir ging’s ähnlich wie Dir.

    @David
    Danke für Deine freundlichen Erläuterungen und Tipps!

    @Wolfgang (#33)
    Gute Frage bzgl. der Tabnavigation im IE, die ich in #15 ja auch schon andeutete: Zumindest im IE8 klappt die Tabnavigation in Verbindung mit dem animierten Scrollen nicht; wer es ausprobieren will, füge in der Demo in jedem Abschnitt mal ein paar Links ein und teste dann das Verhalten der Tabnavigation im IE: leider unzumutbar. Solange das nicht auch im IE klappt, ist das Script für mich im Produktivbetrieb leider nicht einsetzbar. Sehr schade…

    Falls jemand in der Lage ist, das Script für den IE so zu ändern, dass die Tabnavigation beim animierten Scrollen so wie beim Firefox klappt, wäre das sensationell!

  26. Schööön… aber mir wird dabei schwindelig!

  27. Hi Wolfgang,

    Ich verstehe den Sinn des von dir angegeben Links nicht so ganz…: „glossar.php?dies=5&das=6#Test“

    Wenn du dem PHP-Script Parameter übergibst, möchtest du doch in der Regel einen Seitenreload oder sehe ich das falsch? Wenn du also einen Reload willst, dann greift das im Artikel beschriebene Script ohnehin nicht mehr, da es ja nicht bei einem Pageload automatisch prüft, ob sich in der URL ein Anker befindet (ein Vorschlag, wie man das umsetzen könnte, habe ich weiter oben geposted).

    Wenn es dir CMS-bedingt nicht anders möglich ist, die Links zu gestalten, kann ich das natürlich verstehen. Habe dir mal das Script so umgeschrieben, dass es für deine Zwecke funktioniert:


    $(document).ready(function() {
    $('a[href*=#]').bind("click", function(event) {
    event.preventDefault();
    var linkHref=$(this).attr("href");
    //Sprungmarke extrahieren
    var ziel=linkHref.substr(linkHref.lastIndexOf("#"));
    $('html,body').animate({
    scrollTop: $(ziel).offset().top
    }, 2000 , function (){location.hash = ziel;});
    });
    return false;
    });

  28. Links der folgenden Art funktionieren bei mir damit überhaupt nicht mehr (Firefox 3.0.13, die aktuelle Version für Ubuntu 8.04):

    „glossar.php?dies=5&das=6#Test“

    Dem kann aber einfach abgeholfen werden, indem man das * in $(‚a[href*=#]‘) durch ein ^ ersetzt.

    Nun meine Frage: Welche Erfahrungen habt Ihr gemacht, wenn man die Tabulatortaste zum Navigieren benutzt? Verstehen die Browser, wo sie bei einem Druck auf die Tab-Taste hinsollen, wenn man zuvor einen seiteninternen Link mittels animiertem Scrollen angesteuert hat? Oder gerät die Reihenfolge komplett durcheinander?

    Mein Firefox 3.0.13 verhält sich diesbezüglich korrekt. Interessieren würden mich insbesondere die Internet Explorer Versionen 7, 8 und 6.

    Danke und Grüße aus der Steiermark!
    Wolfgang

  29. Vielen Dank für eure Hilfe.

    Liebe Grüsse.

  30. @Thomas St.: Versthe ich das richtig, du gibst die komplette URL als Ankerziel an?

    Scrolle zu Anker 2

    Dann musst du diesen String wieder kürzen, da jQuery ja nicht den offset der Kompletten Seite berechnen kann.

    var ziel = $(this).attr("href");
    var raute = ziel.indexOf("#");
    var ziel = ziel.substr(raute, ziel.length);
    

    So funktioniert dass dann auch mit der kompletten URL, jedoch verstehe ich den Sinn dahinter nicht wirklich. Ausser natürlich dass es CMS bedingt keine andere Möglichkeit gibt.

  31. @Frank: Ich habe den Artikel soeben am Ende ergänzt.

    @David Müller: Du meinst den Selektor in der else Anweisung? Der zusätzlichen body wird für Safari benötigt. Opera hingegen erkennt body nicht richtig. Man könnte natürlich auch eine Browserweiche für Safari schreiben.

  32. Bei einfachen Links wie „test.html#Anker1“ klappt das ja noch. Aber bei Links wie z.B.

    http://test.de/index.php5?page=seite4#Anker2
    http://test.de/index.php5?page=seite1&ID=1#Anker3

    versagt das Ganze (zumindest bei mir).
    Solche Links sind ja bei dynamischen Seiten absolut normal.

    Aber href*=# sollte doch eigentlich immer greifen sobald sich ein „#“ im href befindet – oder sehe ich das falsch?

  33. @Frank: Ich bin mal so frei..


    var sprung = function(event) {
    event.preventDefault();
    var ziel = $(this).attr("href");
    var target = ($.browser.opera) ? 'html' : 'html,body';
    $(target).animate({
    scrollTop: $(ziel).offset().top
    }, 2000 , function (){location.hash = ziel;});
    }
    $(document).ready(function() {
    $('a[href*=#]').bind("click", sprung);
    return false;
    });

    /edit: Obgleich mir etwas schleierhaft ist, warum man sowohl html als auch body als Selector verwenden sollte. Täte es denn nicht der body alleine auch?

  34. Vielen Dank für das tolle Script.

    ICh bin leider ein absoluter Neuling, hun hab auch das Problem mit Opera, du hast ja schon die Lösung für dieses Problem gepostet. Könntest du mir bitte den kompletten Code (mit Browserweiche) vieleicht noch einmal posten. Vielen herzlichen Dank.

    Liebe Grüsse
    Frank

  35. @NightWalker: Ich habe das Opera Problem gelöst. Opera kommt mit $('html,body').animate({ nicht klar, da er beide Selektoren kennt und beide zu animieren versucht.

    Wenn man nur ‚html‘ verwendet funktioniert alles, jedoch nicht mehr in Safari.

    Deshalb habe ich auf die schnelle einfach eine Browserweiche eingefügt, und den entsprechenden Selektor in eine Variable geschrieben.

    if ($.browser.opera) {
    var target = 'html';
    }else{
    var target = 'html,body';
    }

    $(target).animate({

    Mit diesem Code funktioniert nun alles auch in Opera.

    Ich werde es gleich noch im Artikel ergänzen.

  36. Hi Björn,

    man könnte das ganze noch etwas weiterspinnen und direkt onload schauen, ob ein Anker mit übergeben wurde, um so direkt das scrollen zu initialisieren.

    Ich stelle mir das etwa so vor, das man den selben Code welcher für die Links benutzt wird gleich wiederverwenden kann:


    if (location.hash) sprung();

    Das würde zwar in der Form nicht funktionieren, ist aber mit wenig Arbeit schnell umzugestalten. Und dann hätte auch der *=-Selektor seine Daseinsberechtigung. Nichtsdestotrotz hast du natürlich recht, das man bei pageinternen Verweißen auf den Pagename getrost verzichten kann (und sollte).

    lg

  37. @Sven: David hat den unterschied ja schon erklärt. Es handelt sich hierbei ja lediglich um CSS3 Selektoren, welche mit jQuery schon heute nutzbar sind.
    Der andere Selektor hat allerdings keine Auswirkungen auf die Validierung.

    @David: Hatte den Selektor nur vorgeschlagen, da im Artikel von der Auswahl aller Links mit einer Raute AM ANFANG war. :)

    IMHO macht es keinen Sinn, z. B. auch externe Links wie etwa http://www.andere-domain.tld/home.html#anker mit auszuwählen, da das Script dort dann sowieso nicht mehr ausgeführt wird.

    Dein Beispiel macht natürlich auch Sinn. Es kommt eben darauf an, wie das HTML der Seite aufgebaut ist. :)

    lg

  38. @Klawischnigg:
    Naja, Mehrwert für Benutzer ist schon vorhanden.

    Er sieht nämlich, was passiert.

    Beim Klick-und-schwupp-ist-der-neue-Inhalt-sichtbar ist nicht offensichtlich, dass der Inhalt sich auf der gleichen Seite befindet, beim weichen Scrollen wird es ihm dagegen mit einfachen, selbsterklärenden Mitteln klar verdeutlicht.

    Du kannst diese Visualisierung natürlich auch ohne das Framework machen, ist dann halt ein wenig mehr individueller Code. Aber warum das Rad nochmal neu erfinden?

  39. @NightWalker: Das Problem mit Opera war mir leider nicht bekannt, da ich nur mit Firefox, Safari und IE getestet habe.

    Opera ermittelt den .offset().top-Wert korrekt, jedoch springt Opera bei einem kleineren Wert als der Aktuellen Position wieder zum Seitenanfang und versucht dann um den kleineren Wert wieder nach unten zu Scrollen, dies führt zu dem Flackern.

    Jedoch fällt mir auf die schnelle keine Lösung ein dieses Problem zu beheben.

  40. Naja – Mehrwert für Benutzer – Null.
    Viel mehr gibts dazu nicht zu sagen, ausser daß man sich zusätzlich noch den Speicher mit niemals gebrauchten im Framework verbogenen Funktionen vollmüllt.

  41. Seit wann ist jQuery eigentlich so fett? 55 Kb finde ich schon heftig.

  42. @Sven: Ich habe (FF3.52, versucht mit Webdev-Toolbar, Firebug und FF-interner Fehlerkonsole (die ja letztendlich alle auf dem gleichen Error-Modell basieren) keinerlei Fehlermeldungen / Warnungen. Bezüglich dem von Björn angesprochenen Seletor würde ich diese Seite empfehlen: http://docs.jquery.com/Selectors (unter „Attributes“).

    $(‚a[href*=#]‘) matcht alle Links mit einer Raute irgendwo im href-Attribut.

    $(‚a[href^=#]‘) (Björns Vorschlag) matcht alle Links mit einer Raute AM ANFANG des href-Attributs.

    Allerdings würde ich auch eher zum ursprünglichen Selektor *= greifen, weil du somit sowohl auch href=“index.html#Eintrag15″ als auch auf href=“#Eintrag15″ verweisen kannst. Performancetechnisch ist da kaum ein Unterschied zu erwarten, gerade bei nicht selbstgeschriebenem Code ist man so zumindest für alle Eventualitäten gewappnet.

    lg

  43. @ NightWalker: Ich denk mal, dass das bei dir am Anker „#top“ liegt, der (genau wie #bottom) nicht fest definiert werden muss, sondern einfach verwendet werden kann. Logischerweise hat dieser auch keine „reale“ Position, d.h. jQuery kann den .offset().top-Wert nicht ermitteln. Wenn du beinem allerdings die id=“top“ gibst, sollte das wieder funktionieren.

    lg

  44. Ich persönlich sehe darin keinen wirklichen Usability gewinn. Ausserdem scheint es mit Opera nicht zu funktionieren. Runter scrollen klappt aber wenn man auf „wieder nach oben“ klickt sprint er sofort nach oben aber das Bild flackert noch ein paar sekunden

  45. Schönes Tutorial, danke!

    Björn, könntest Du vielleicht Deinen Vorschlag kurz einem JS-Neuling erklären? Ich hatte schon gehofft, es könnte die Lösung für das Validierungsproblem sein, war aber nicht so. Die Webdeveloper-Toolbar zeigt (auch auf der Demoseite) folgende Warnung:

    Warnung: Indentifikator oder String für Wert in Attribut-Selektor erwartet, aber ‚#‘ gefunden.
    Quelldatei: http://www.drweb.de/magazin/wp-content/uploads/animiertesscrollen.html
    Zeile: 0

    Oder je nach ausgewähltem Anker:

    Warnung: Indentifikator oder String für Wert in Attribut-Selektor erwartet, aber ‚#‘ gefunden.
    Quelldatei: http://www.drweb.de/magazin/wp-content/uploads/animiertesscrollen.html#anker4
    Zeile: 0

    Hat jemand einen Tipp, wie man das JS verändert, um keine Warnung mehr zu bekommen, oder ist das unvermeidlich, weil eine richtige URL erwartet wird?

    Noch eine andere Frage:

    A propos Zugänglichkeit: Im Firefox 3.5.2 klappt das wunderbar mit der Tab-Navigation – Fokus auf Sprungmarke, Sprung zum Anker, wieder auf TAB drücken, Fokus auf Sprungmarke zurück nach oben. Oder man tabbt weiter zum nächsten Link unter dem Sprungziel. Besser gehts nicht.

    Im IE8 ist das mit der Tab-Navigation eher suboptimal (einfach mal ausprobieren), sodass man z.B. nicht vom Sprungziel direkt zum nächsten Link tabben kann. Hat da jemand eine Lösung oder ist das beim IE unvermeidlich?

  46. Möchte man nur Links auswählen die mit einer Raute beginnen, sollte man besser $(‚a[href^=#]‘) verwenden.

  47. Ich finde es einen netten Effekt. Mag ihn pers. auch. Allerdings ist es das auch – ein Effekt – und nicht mehr. Einen Vorteil gegenüber der ’normalen‘ Anker Nutzung sehe ich nicht. Allerdings auch keinen Nachteil, abgesehen davon das es halt ein paar ms ‚dauert‘ :-)

  48. Die vorgestellte Lösung ist aber bei einer Seite, die exzessiven Gebrauch von Sprungmarken macht, noch optimierungsfähig.

    Durch $('a[href*=#]').bind("click", function(event) { wird an die Event-Listener jedes entsprechenden Links eine neue Funktion gebunden. Bei 100 Sprungmarken entstehen so 100 identische Funktionen. Sinnvoller ist es also die Funktion erst zu definieren und der Bind-Methode dessen Namen zu übergeben:

    
    var sprung = function(event) {
    	event.preventDefault();
    	var ziel = $(this).attr("href");
    	$('html,body').animate({
    		scrollTop: $(ziel).offset().top
    	}, 2000 , function (){location.hash = ziel;});
    
    }
    $(document).ready(function() {
    	$('a[href*=#]').bind("click", sprung);
    	return false;
    });
    
    

    Grüße,
    Dominik

  49. Wollt ich nur mal loswerden: Ich finde Deine Artikel rund um jquery echt klasse! Eine Bereicherung!

  50. @Andreas: Anker werden häufig auch bei JavaScript-Tabs genutzt, um z.B. über die URL einen bestimmten Tab direkt „anzuspringen“. Anker sind IMHO alles andere als veraltet, im Gegenteil.

  51. Ist noch niemanden der lustige Tippfehler aufgefallen?

    Erkläuterung

  52. Sehr nützlich sind da auch die plugins
    jQuery.LocalScroll
    jQuery.SerialScroll

    http://flesler.blogspot.com/2007/10/jqueryscrollto.html

    Da sieht es so aus, dass wenn du den „body“ zu einem Element scrollen willst:
    $.scrollTo($(ziel), 800);

  53. @Jens:

    Der Vorteil von „bind“ ist, dass du dem Element einen Event-Handler anhängst. Der Unterschied ist also, dass du mit einem jquery-plugin – was man für diesen Zweck schreiben könnte – nicht die vom User des Plugins eventuell an anderer Stelle bereits per „click()“ definierten Funktionen überschreibt, sondern das neue Verhalten einfach „anhängt“. Ganz gut zu sehen ist das mit window.onload: Wenn jeder Javascript entwickler die window.onload-Funktion mit seiner eigenen Funktion belegen würde, wäre ein „Gerangel“ vorprogrammiert. Darum anstelle von „window.onload=function() { … }“ einfach

    window.addEventListener(„load“, fnc1, false);
    window.addEventListener(„load“, fnc2, false);

    (gut beschrieben hier: http://www.mediaevent.de/javascript/event_listener.html).

    Hoffe, dasses verständlich ist;).

    lg

  54. Schön erklärt, danke! Ich mag diese Usability-Verbesserung.

    Was spricht dagegen, anstatt bind() das ebenso existente click() zu nehmen? Das erscheint mir kürzer. Oder ist bind() performanter?

  55. Besonders schön ist, dass das ganze unobstrusiv funktioniert, der Benutzer mit ausgeschaltetem Javascript also von dem ganzen Spaß garnix mitbekommt und der Sprung dann eben nicht mehr „smooth“ sondern so wie gewohnt – in einem Rutsch – verläuft. So sollte Javascript auch immer zum Einsatz kommen: Als „Aufhübscher“ und Accessibility verbesserender Faktor, der aber niemals für eine Benutzung essentiell ist.

  56. Sehe ich auch durchaus positiv!
    Eines der wenigen Gimmicks mit hohem Wert für die Usability.
    Eigentlich sollte das fast schon ein Standard-Browser-Verhalten sein.

  57. Tja, entweder Paging oder Scrolling. Jedes Prinzip hat seine Vor- und Nachteile. Ich finde überflüssige Klickerei (Paging) nervig. Ob die User sich an den sanften Scrolllauf gewöhnen? Hier gibts auch noch die »harte« Lösung.

  58. Ich dachte bisher eigentlich, exzessive Ankernutzung innerhalb einer Seite sei so langsam aus der Mode, weil man oft besser solche Inhalte auf mehrere Seiten aufteilt.

  59. In meinen Augen ist dies eine sinnvolle Ergänzung. Wikipedia nutzt diese Funktion gelegentlich auch. Ich als Anwender kann so genauer auf einen Bereich verweisen.

Schreibe einen Kommentar zu Michel Otto Antworten abbrechen

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