
🔧 JQuery: jevn rulling til anker ved navigering fra en annen side
Du la til et anker på siden, skrev #section i URL-en og forventet en fin, myk skrolling. Brukeren klikker fra en annen side, nettleseren legger pliktoppfyllende til hashen... og rykker brått til målet. Ingen skrolling. Bare et øyeblikkelig hopp.
Problemet er at nettlesere håndterer hashen umiddelbart som standard, før DOM-en er helt klar og skript får mulighet til å fange opp hendelsen. Når en bruker ankommer via en ekstern lenke, utløses click-handleren din aldri: det var ingen klikkhendelse, bare en direkte URL-navigasjon.
Vi har satt sammen to kamptestede jQuery-løsninger: et grunnleggende skript for enkle tilfeller og en avansert versjon med klikkhåndtering, støtte for sideinnlasting og konfliktunngåelse. Begge er testet på reelle prosjekter og fungerer med gjeldende jQuery-versjoner.
💡 Rask oversikt:
- Lagre hashen fra URL-en i en midlertidig variabel
- Tøm
location.hashslik at nettleseren ikke hopper brått - Skroll til ankeret via
animate()med ønsket offset - Gjenopprett hashen for en korrekt URL i adressefeltet
Hvorfor myk ankerskrolling er viktig
Når en besøkende følger en lenke som site.com/page/#pricing, forventer de å se prisblokken, ikke toppen av siden. Et brått hopp er desorienterende: brukeren forstår ikke hvor de havnet eller hva som kom før. Myk skrolling gir kontekst: øynene fanger opp mellomliggende seksjoner, og hjernen kartlegger ruten fra start til mål.
Med den opprinnelige CSS-egenskapen scroll-behavior: smooth er ting enkelt: legg den til i stilarket ditt, så skroller nettleseren automatisk til ankeret. Men denne tilnærmingen bryter sammen i det øyeblikket du trenger en tilpasset offset for en fast topptekst. En offset på 110 piksler hindrer blokken i å gli under header-en og plasserer den nøyaktig der brukeren forventer. jQuery-løsningen gir deg den kontrollen.
Det er også kryssnettleserkompatibilitet. scroll-behavior: smooth fungerer ikke i Internet Explorer (ja, slike prosjekter finnes fortsatt), mens jQuerys animate()-metode oppfører seg identisk overalt.
Grunnleggende skript: minimal kode, maksimal nytte
Det første alternativet er kompakt, bare 10 linjer. Det løser nøyaktig ett problem: myk skrolling til et anker når brukeren ankommer fra en annen side eller via en direkte lenke med en hash.
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 });
Trinn-for-trinn-gjennomgang, fordi tre linjer utfører magi, men det er viktig å forstå mekanikken:
var myHash = location.hash: les hashen fra adressefeltet (for eksempel#pricing). På dette tidspunktet har nettleseren ikke skrollet ennå.location.hash = '': det viktigste trikset. Ved å tømme hashen mister nettleseren målet sitt for det øyeblikkelige hoppet. Uten denne linjen ville skriptet «kjempe» mot nettleserens innebygde oppførsel og tape.$(myHash).offset().top - 110: beregn ankerets posisjon fra toppen av dokumentet og trekk fra 110 piksler. Dette er din offset for en fast topptekst. Hvis toppteksten din erposition: fixedog 80 piksler høy, bruk 80 (eller 90 for litt luft). Hvis det ikke er noen topptekst, fjern subtraksjonen helt.$('html, body').animate(...): skroll mykt over 700 millisekunder.'html, body'-velgeren er ikke et innfall: forskjellige nettlesere skroller entenhtmlellerbody, så vi spesifiserer begge for pålitelighet.location.hash = myHash: gjenopprett hashen. Nå viser adressefeltet#pricingigjen, og siden er allerede pent parkert ved målblokken.
Sett inn skriptet i temaets functions.php, en egendefinert JS-fil eller via en plugin som Code Snippets. Hovedkravet er at det må være inne i en jQuery(document).ready()-blokk.
Avansert versjon: klikkhåndtering, sideinnlasting og konfliktbeskyttelse
Det grunnleggende skriptet dekker de fleste scenarier, men noen ganger fungerer ikke location.hash = '' i tide: nettleseren hopper før hashen er tømt. I slike tilfeller bruker du den andre versjonen. Den er tyngre, men mer pålitelig.
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 });
Her er hva som skjer, blokk for blokk:
Blokk én: en klikkhåndterer for interne ankerlenker. jQuery(window).bind('load', ...) sørger for at alle sideelementer (inkludert bilder og iframes) er lastet før handleren bindes. Filteret a:not(.spu-clickable) ekskluderer lenker som allerede håndteres av en popup-plugin (SPU, WordPress PopUp), og forhindrer animasjonskonflikter. Legg til dine egne eksklusjonsklasser etter samme mønster.
Blokk to: håndtering av navigasjon fra en ekstern side. jQuery(window).load() utløses senere enn document.ready og garanterer at alle elementer, inkludert ankeret, er i DOM-en. goToByScroll(id)-funksjonen gjør nøyaktig det samme som det grunnleggende skriptet, men kalles først etter at vinduet er fullstendig lastet. substr(1) fjerner #-tegnet fra hashen.
Viktig merknad: jQuery(window).load() har vært foreldet siden jQuery 3.0. Hvis prosjektet ditt bruker en gjeldende jQuery-versjon, erstatt det med:
1 jQuery(window).on('load', function () { 2 // code here 3 });
Syntaksen er forskjellig, men oppførselen er identisk.
Finjustering: offset, velgere og fallgruver
Skriptet fungerer, men hver layout er unik. Her er tre vanlige justeringer som reddet reelle prosjekter.
Problem én: offset().top returnerer feil koordinater. Dette skjer når overordnede elementer har CSS-egenskapene transform, filter eller will-change, som oppretter en ny posisjoneringskontekst. offset() beregner da i forhold til den konteksten i stedet for dokumentet. Løsning: bruk offset({top: -0}):
1 jQuery('html, body').animate( 2 { scrollTop: jQuery('#' + id).offset({ top: -0 }).top }, 3 1000 4 );
Parameteren {top: -0} tvinger jQuery til å beregne posisjonen på nytt fra dokumentgrensene og ignorerer mellomliggende kontekster. Det ser ut som magi, men det fungerer.
Problem to: velgeren 'html, body' skroller feil element. I noen temaer er skrollcontaineren ikke html eller body, men en spesifikk blokk, for eksempel body.home for hjemmesiden eller .main-content for indre sider. Identifiser containeren din via DevTools (Elementer-fanen → søk etter overflow: scroll eller overflow: auto) og bytt den ut i velgeren:
1 jQuery('body.home').animate( 2 { scrollTop: target.offset().top - 37 }, 3 1000 4 );
Problem tre: hashen inneholder kyrilliske tegn eller spesialtegn. location.hash returnerer en URL-kodet sekvens i stedet for en lesbar streng, og jQuery-velgeren $(myHash) vil ikke finne elementet. Løsning: dekod hashen med decodeURIComponent() før du bruker den i velgeren.
Video: direkteeksempel på skrolling fra en ekstern lenke
En kort demo fra John Smith: myk ankerskrolling via jQuery animate() på en reell side med fast topptekst og ekstern navigasjon.
⁉️🤔 Ofte stilte spørsmål
Skriptet fungerer på samme side, men ikke ved navigering fra en annen URL. Hvorfor?
Fordi
click-handleren aldri utløses: det var ikke noe klikk. Brukeren fulgte en direkte lenke, og nettleseren behandlet hashen før JS-en din kjørte. Løsningen er sekvensenlocation.hash = ''+animate()+location.hash = myHash. Å tømme hashen avbryter det innebygde hoppet, animasjonen skroller mykt, og gjenoppretting av hashen bevarer korrekt URL i adressefeltet.
Hvilken offset bør jeg bruke for en fast topptekst?
Den nøyaktige toppteksthøyden pluss noen få piksler luft. Åpne DevTools (F12), velg nettstedets
header-element og sjekkheighti Computed-fanen. For eksempel, hvis toppteksten er 80 piksler, bruk 90 i koden din. Hvis mobilversjonen har en annen toppteksthøyde, legg til en media query med en dynamisk offset-beregning.
Er jQuery fortsatt relevant i 2026?
Ja, spesielt innenfor WordPress-økosystemet. jQuery forblir i WP-kjernen, mange plugins og temaer er avhengige av det, og migrering av hele økosystemet til ren JS vil ta år. For nye prosjekter i vanlig JavaScript gjøres myk skrolling via
element.scrollIntoView({ behavior: 'smooth' })ellerscroll-behavior: smoothi CSS, med betydelig færre kodelinjer. Men hvis du endrer et eksisterende WP-nettsted, er jQuery-løsningen fortsatt pålitelig og passende.
Kan jeg unngå jQuery helt?
Du kan og bør, hvis prosjektet er nytt. Den opprinnelige ekvivalenten til det grunnleggende skriptet:
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 });
Samme prinsipp: lagre hashen, tøm den, skroll, gjenopprett den. Forskjellen er at
behavior: 'smooth'bruker nettleserens opprinnelige CSS-motor i stedet for en jQuery-timer. Du kan ikke konfigurere hastigheten, men koden er 30 KB lettere (vekten av jQuery).
Hvorfor $('html, body') i stedet for bare $('html')?
Firefox skroller
html, Chrome brukerbody, og Safari avhenger av versjonen. Å spesifisere begge velgerne ianimate()garanterer at det fungerer på tvers av alle nettlesere: jQuery sender animasjonen til det elementet som faktisk anvender den.
Er det verdt å bruke jQuery bare for myk skrolling i 2026
Hvis du har et WordPress-nettsted eller et eldre prosjekt der jQuery allerede er lastet, ta skriptet fra denne artikkelen og ikke overkompliser ting. Ti linjer med kode som fungerer overalt, i alle nettlesere, uten behov for polyfills. For nye bygg i rent JavaScript, bruk opprinnelig scroll-behavior: smooth eller scrollIntoView(). Begge tilnærmingene produserer myk skrolling, men jQuery-metoden gir deg kontroll over hastighet, offset og velger for skrollcontainer. Opprinnelige implementeringer krever separate sjekker for å oppnå det samme.
Hovedregelen vi har lært fra dusinvis av prosjekter: tøm alltid hashen før skrolling. Uten dette trikset kan ingen handler slå nettleserens innebygde oppførsel, og brukere vil fortsette å oppleve brå hopp.



