
🔧 JQuery: sanftes scrollen zu einem anker bei navigation von einer anderen seite
Sie haben einen Anker auf der Seite hinzugefügt, #section in die URL geschrieben und erwarten einen schönen sanften Scrollvorgang. Der Nutzer klickt von einer anderen Seite aus, der Browser wendet den Hash pflichtgemäß an… und springt abrupt zum Ziel. Kein Scrollen. Nur ein sofortiger Sprung.
Das Problem ist, dass Browser den Hash standardmäßig sofort verarbeiten, bevor das DOM vollständig bereit ist und Skripte die Möglichkeit haben, das Ereignis abzufangen. Wenn ein Nutzer über einen externen Link kommt, wird Ihr click-Handler überhaupt nicht ausgelöst: Es gab kein Klick-Ereignis, sondern nur eine direkte URL-Navigation.
Wir haben zwei praxiserprobte jQuery-Lösungen zusammengestellt: ein einfaches Skript für Basisfälle und eine erweiterte Version mit Klick-Behandlung, Unterstützung für Seitenaufrufe und Konfliktvermeidung. Beide sind in realen Projekten getestet und funktionieren mit aktuellen jQuery-Versionen.
💡 Kurzüberblick:
- Den Hash aus der URL in einer temporären Variable speichern
location.hashleeren, damit der Browser nicht abrupt springt- Mit
animate()und dem gewünschten Offset zum Anker scrollen - Den Hash wiederherstellen, damit die Adresszeile die korrekte URL anzeigt
Warum sanftes Anker-Scrolling wichtig ist
Wenn ein Besucher einem Link wie site.com/page/#pricing folgt, erwartet er den Preisblock zu sehen, nicht den Seitenanfang. Ein abrupter Sprung ist desorientierend: Der Nutzer versteht nicht, wo er gelandet ist oder was davor kam. Sanftes Scrollen liefert Kontext: Die Augen erfassen die Zwischenabschnitte, und das Gehirn kartiert den Weg vom Ausgangspunkt zum Ziel.
Mit der nativen CSS-Eigenschaft scroll-behavior: smooth ist es einfach: Sie fügen sie in Ihr Stylesheet ein, und der Browser scrollt automatisch zum Anker. Aber dieser Ansatz versagt, sobald Sie einen benutzerdefinierten Offset für einen fixierten Header benötigen. Ein 110-Pixel-Offset verhindert, dass der Block unter den header rutscht, und positioniert ihn genau dort, wo der Nutzer ihn erwartet. Die jQuery-Lösung gibt Ihnen diese Kontrolle.
Hinzu kommt die browserübergreifende Kompatibilität. scroll-behavior: smooth funktioniert nicht im Internet Explorer (ja, solche Projekte gibt es noch), während die jQuery-Methode animate() überall identisch arbeitet.
Basis-Skript: minimaler Code, maximaler Nutzen
Die erste Option ist kompakt, nur 10 Zeilen. Sie löst genau ein Problem: sanftes Scrollen zu einem Anker, wenn der Nutzer von einer anderen Seite oder über einen direkten Link mit Hash kommt.
1 jQuery(document).ready(function ($) { 2 var myHash = location.hash; // save the hash 3 location.hash = ''; // clear it — browser stops jerking 4 if (myHash[1] != undefined) { // hash not empty? 5 $('html, body').animate( 6 { scrollTop: $(myHash).offset().top - 110 }, 7 700 // duration in milliseconds 8 ); 9 location.hash = myHash; // restore the hash 10 } 11 });
Schritt-für-Schritt-Erklärung, denn drei Zeilen wirken wie Magie, aber das Verständnis der Mechanik ist entscheidend:
var myHash = location.hash: Liest den Hash aus der Adresszeile (zum Beispiel#pricing). Zu diesem Zeitpunkt hat der Browser noch nicht gescrollt.location.hash = '': Der entscheidende Trick. Das Leeren des Hashs nimmt dem Browser das Ziel für den sofortigen Sprung. Ohne diese Zeile würde das Skript gegen das eingebaute Browserverhalten „ankämpfen" und verlieren.$(myHash).offset().top - 110: Berechnet die Position des Ankers vom oberen Dokumentrand und zieht 110 Pixel ab. Das ist Ihr Offset für einen fixierten Header. Wenn Ihr Headerposition: fixedund 80px hoch ist, verwenden Sie 80 (oder 90 für etwas Luft). Wenn es keinen Header gibt, entfernen Sie die Subtraktion vollständig.$('html, body').animate(...): Scrollt sanft über 700 Millisekunden. Der Selektor'html, body'ist keine Marotte: Verschiedene Browser scrollen entwederhtmloderbody, daher geben wir zur Sicherheit beide an.location.hash = myHash: Stellt den Hash wieder her. Jetzt zeigt die Adresszeile wieder#pricingan, und die Seite steht bereits sauber am Zielblock.
Fügen Sie das Skript in die functions.php Ihres Themes, eine eigene JS-Datei oder über ein Plugin wie Code Snippets ein. Die zentrale Anforderung ist, dass es sich innerhalb eines jQuery(document).ready()-Blocks befinden muss.
Erweiterte Version: Klick-Behandlung, Seitenaufruf und Konfliktschutz
Das Basis-Skript deckt die meisten Szenarien ab, aber manchmal greift location.hash = '' nicht rechtzeitig: Der Browser springt, bevor der Hash geleert wird. Verwenden Sie in solchen Fällen die zweite Version. Sie ist umfangreicher, aber zuverlässiger.
1 jQuery(document).ready(function () { 2 jQuery(window).bind('load', function () { 3 jQuery('a:not(.spu-clickable)[href*="#"]:not([href="#"])').click(function () { 4 if ( 5 location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || 6 location.hostname == this.hostname 7 ) { 8 var target = jQuery(this.hash); 9 target = target.length ? target : jQuery('[name=' + this.hash.slice(1) + ']'); 10 if (target.length) { 11 jQuery('html, body').animate( 12 { scrollTop: target.offset().top - 37 }, 13 1000 14 ); 15 return false; 16 } 17 } 18 }); 19 }); 20 }); 21 22 jQuery(window).load(function () { 23 function goToByScroll(id) { 24 jQuery('html, body').animate( 25 { scrollTop: jQuery('#' + id).offset().top - 38 }, 26 1000 27 ); 28 } 29 if (window.location.hash != '') { 30 goToByScroll(window.location.hash.substr(1)); 31 } 32 });
Hier ist, was Block für Block passiert:
Block eins: Ein Klick-Handler für interne Anker-Links. jQuery(window).bind('load', ...) stellt sicher, dass alle Seitenelemente (einschließlich Bilder und iframes) geladen sind, bevor der Handler gebunden wird. Der Filter a:not(.spu-clickable) schließt Links aus, die bereits von einem Popup-Plugin (SPU, WordPress PopUp) behandelt werden, und verhindert so Animationskonflikte. Fügen Sie nach demselben Muster Ihre eigenen Ausschlussklassen hinzu.
Block zwei: Behandlung der Navigation von einer externen Seite. jQuery(window).load() wird später als document.ready ausgelöst und garantiert, dass alle Elemente, einschließlich des Ankers, im DOM vorhanden sind. Die Funktion goToByScroll(id) tut genau das, was das Basis-Skript tut, wird aber erst aufgerufen, nachdem das Fenster vollständig geladen ist. substr(1) entfernt das #-Zeichen aus dem Hash.
Wichtiger Hinweis: jQuery(window).load() ist seit jQuery 3.0 veraltet. Wenn Ihr Projekt eine aktuelle jQuery-Version verwendet, ersetzen Sie es durch:
1 jQuery(window).on('load', function () { 2 // code here 3 });
Die Syntax unterscheidet sich, aber das Verhalten ist identisch.
Feinabstimmung: Offsets, Selektoren und Fallstricke
Das Skript funktioniert, aber jedes Layout ist einzigartig. Hier sind drei gängige Anpassungen, die reale Projekte gerettet haben.
Problem eins: offset().top liefert falsche Koordinaten. Das passiert, wenn übergeordnete Elemente die CSS-Eigenschaften transform, filter oder will-change besitzen, die einen neuen Positionierungskontext erzeugen. offset() berechnet dann relativ zu diesem Kontext statt zum Dokument. Lösung: Verwenden Sie offset({top: -0}):
1 jQuery('html, body').animate( 2 { scrollTop: jQuery('#' + id).offset({ top: -0 }).top }, 3 1000 4 );
Der Parameter {top: -0} zwingt jQuery, die Position von den Dokumentgrenzen aus neu zu berechnen und ignoriert Zwischenkontexte. Es sieht aus wie Magie, aber es funktioniert.
Problem zwei: Der Selektor 'html, body' scrollt das falsche Element. In manchen Themes ist der Scroll-Container nicht html oder body, sondern ein spezifischer Block, zum Beispiel body.home für die Startseite oder .main-content für innere Seiten. Identifizieren Sie Ihren Container über die DevTools (Tab „Elemente" → nach overflow: scroll oder overflow: auto suchen) und ersetzen Sie ihn im Selektor:
1 jQuery('body.home').animate( 2 { scrollTop: target.offset().top - 37 }, 3 1000 4 );
Problem drei: Der Hash enthält kyrillische Zeichen oder Sonderzeichen. location.hash gibt eine URL-kodierte Sequenz statt einer lesbaren Zeichenkette zurück, und der jQuery-Selektor $(myHash) findet das Element nicht. Lösung: Dekodieren Sie den Hash mit decodeURIComponent(), bevor Sie ihn im Selektor verwenden.
Video: Live-Beispiel für das Scrollen von einem externen Link
Eine kurze Demo von John Smith: sanftes Anker-Scrolling mittels jQuery animate() auf einer realen Seite mit fixiertem Header und externer Navigation.
⁉️🤔 Häufig gestellte Fragen
Das Skript funktioniert auf derselben Seite, aber nicht bei Navigation von einer anderen URL. Warum?
Weil der
click-Handler nie ausgelöst wird: Es gab keinen Klick. Der Nutzer folgte einem direkten Link, und der Browser verarbeitete den Hash, bevor Ihr JS lief. Die Lösung ist die Sequenzlocation.hash = ''+animate()+location.hash = myHash. Das Leeren des Hashs bricht den eingebauten Sprung ab, die Animation scrollt sanft, und das Wiederherstellen des Hashs bewahrt die korrekte URL in der Adresszeile.
Welchen Offset sollte ich für einen fixierten Header verwenden?
Die exakte Header-Höhe plus ein paar Pixel Luft. Öffnen Sie die DevTools (F12), wählen Sie das
header-Element Ihrer Seite aus und prüfen Sie dessenheightim Tab „Berechnet". Wenn der Header zum Beispiel 80px hoch ist, verwenden Sie 90 in Ihrem Code. Falls die mobile Version eine andere Header-Höhe hat, fügen Sie eine Media Query mit einer dynamischen Offset-Berechnung hinzu.
Ist jQuery im Jahr 2026 noch relevant?
Ja, insbesondere im WordPress-Ökosystem. jQuery ist weiterhin im WP-Core enthalten, viele Plugins und Themes hängen davon ab, und die Migration des gesamten Ökosystems zu nativem JS wird Jahre dauern. Für neue Projekte in reinem JavaScript wird sanftes Scrollen über
element.scrollIntoView({ behavior: 'smooth' })oderscroll-behavior: smoothin CSS realisiert, mit deutlich weniger Codezeilen. Wenn Sie jedoch eine bestehende WP-Seite anpassen, ist die jQuery-Lösung weiterhin zuverlässig und angemessen.
Kann ich ganz auf jQuery verzichten?
Sie können und sollten es, wenn das Projekt neu ist. Das native Äquivalent des Basis-Skripts:
1 document.addEventListener('DOMContentLoaded', () => { 2 const hash = window.location.hash; 3 if (hash) { 4 window.location.hash = ''; 5 const target = document.querySelector(hash); 6 if (target) { 7 window.scrollTo({ 8 top: target.getBoundingClientRect().top + window.pageYOffset - 110, 9 behavior: 'smooth' 10 }); 11 } 12 window.location.hash = hash; 13 } 14 });
Gleiches Prinzip: Hash speichern, leeren, scrollen, wiederherstellen. Der Unterschied ist, dass
behavior: 'smooth'die native CSS-Engine des Browsers nutzt statt eines jQuery-Timers. Sie können die Geschwindigkeit nicht konfigurieren, aber der Code ist 30 KB leichter (das Gewicht von jQuery).
Warum $('html, body') statt nur $('html')?
Firefox scrollt
html, Chrome verwendetbody, und Safari hängt von der Version ab. Die Angabe beider Selektoren inanimate()garantiert browserübergreifende Funktion: jQuery sendet die Animation an das Element, das sie tatsächlich anwendet.
Lohnt sich jQuery nur für sanftes Scrollen im Jahr 2026
Wenn Sie eine WordPress-Seite oder ein Legacy-Projekt haben, in dem jQuery bereits geladen ist, nehmen Sie das Skript aus diesem Artikel und machen Sie die Sache nicht komplizierter. Zehn Codezeilen, die überall funktionieren, in jedem Browser, ohne Polyfills. Für neue Projekte in reinem JavaScript verwenden Sie natives scroll-behavior: smooth oder scrollIntoView(). Beide Ansätze erzeugen sanftes Scrollen, aber die jQuery-Methode gibt Ihnen Kontrolle über Geschwindigkeit, Offset und den Selektor des Scroll-Containers. Native Implementierungen erfordern separate Prüfungen, um dasselbe zu erreichen.
Die wichtigste Regel, die wir aus Dutzenden von Projekten gelernt haben: Leeren Sie immer den Hash, bevor Sie scrollen. Ohne diesen Trick kann kein Handler das eingebaute Browserverhalten übertreffen, und Nutzer werden weiterhin abrupte Sprünge erleben.



