Skip to content

Kõik WordPressist, veebiarendusest — ja mitte ainult

🔧 JQuery: sujuv kerimine ankruni teiselt lehelt navigeerides

🔧 JQuery: sujuv kerimine ankruni teiselt lehelt navigeerides

Sa lisasid lehele ankru, panid URL-i #section ja ootad ilusat sujuvat kerimist. Kasutaja klikib teiselt lehelt, brauser rakendab kuulekalt räsi... ja tõmbleb järsult sihtmärgini. Ei mingit kerimist. Lihtsalt hetkeline hüpe.

Probleem on selles, et brauserid käsitlevad räsi vaikimisi koheselt, enne kui DOM on täielikult valmis ja skriptid jõuavad sündmust pealt kuulata. Kui kasutaja saabub välise lingi kaudu, ei käivitu sinu click töötleja üldse: klikisündmust ei toimunud, toimus lihtsalt otsene URL-i navigeerimine.

Oleme koostanud kaks lahingus testitud jQuery lahendust: põhilise skripti lihtsate juhtumite jaoks ja täiustatud versiooni koos klikikäsitluse, lehe laadimise toe ja konfliktide vältimisega. Mõlemad on testitud reaalsetes projektides ja töötavad praeguste jQuery versioonidega.

💡 Kiire ülevaade:

  • Salvesta räsi URL-ist ajutisse muutujasse
  • Tühjenda location.hash, et brauser ei hüppaks järsult
  • Keri ankruni animate() abil soovitud nihkega
  • Taasta räsi, et aadressiribal oleks korrektne URL

Miks on sujuv ankrukerimine oluline

Kui külastaja järgib linki nagu site.com/page/#pricing, ootab ta hinnabloki nägemist, mitte lehe ülaosa. Järsk hüpe on desorienteeriv: kasutaja ei saa aru, kuhu ta maandus või mis oli enne. Sujuv kerimine annab konteksti: silmad tabavad vahepealseid sektsioone ja aju kaardistab teekonna lähtepunktist sihtkohta.

Omadusega scroll-behavior: smooth on asi lihtne: lisa see oma stiililehele ja brauser kerib automaatselt ankrini. Kuid see lähenemine laguneb kohe, kui vajad fikseeritud päise jaoks kohandatud nihet. 110-piksline nihe hoiab bloki päise alla libisemast ja positsioneerib selle täpselt sinna, kuhu kasutaja ootab. jQuery lahendus annab sulle selle kontrolli.

Lisaks on veel brauseritevaheline ühilduvus. scroll-behavior: smooth ei tööta Internet Exploreris (jah, selliseid projekte on endiselt), samas kui jQuery animate() meetod käitub igal pool identselt.

Põhiskript: minimaalne kood, maksimaalne kasu

Esimene variant on kompaktne, kõigest 10 rida. See lahendab täpselt ühe probleemi: sujuva kerimise ankrini, kui kasutaja saabub teiselt lehelt või otselingi kaudu koos räsiga.

1jQuery(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});

Samm-sammuline selgitus, sest kolm rida teevad imet, kuid mehhanismi mõistmine on oluline:

  • var myHash = location.hash: loeb räsi aadressiribalt (näiteks #pricing). Sellel hetkel ei ole brauser veel kerinud.
  • location.hash = '': võtmetrikk. Räsi tühjendamine paneb brauseri kaotama oma sihtmärgi hetkeliseks hüppeks. Ilma selle reata „võitleks" skript brauseri sisseehitatud käitumisega ja kaotaks.
  • $(myHash).offset().top - 110: arvutab ankru asukoha dokumendi ülaosast ja lahutab 110 pikslit. See on sinu nihe fikseeritud päise jaoks. Kui sinu päis on position: fixed ja 80px kõrge, kasuta 80 (või 90, et jätta veidi hingamisruumi). Kui päist pole, eemalda lahutamine täielikult.
  • $('html, body').animate(...): kerib sujuvalt 700 millisekundi jooksul. 'html, body' selektor pole kapriis: erinevad brauserid kerivad kas html või body elementi, seega määrame töökindluse huvides mõlemad.
  • location.hash = myHash: taastab räsi. Nüüd näitab aadressiriba jälle #pricing ja leht on juba kenasti sihtbloki juures pargitud.

Lisa skript oma teema functions.php faili, kohandatud JS-faili või pluginaga nagu Code Snippets. Peamine nõue on, et see peab olema jQuery(document).ready() ploki sees.

Täiustatud versioon: klikikäsitlus, lehe laadimine ja konfliktikaitse

Põhiskript katab enamiku stsenaariume, kuid mõnikord ei tööta location.hash = '' õigel ajal: brauser hüppab enne, kui räsi tühjendatakse. Sellistel juhtudel kasuta teist versiooni. See on raskem, kuid usaldusväärsem.

1jQuery(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
22jQuery(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});

Siin on plokkide kaupa selgitus, mis toimub:

Esimene plokk: klikitöötleja sisemiste ankurlinkide jaoks. jQuery(window).bind('load', ...) tagab, et kõik lehe elemendid (sealhulgas pildid ja iframe'id) on laaditud enne töötleja sidumist. Filter a:not(.spu-clickable) välistab lingid, mida juba käsitleb hüpikakna plugin (SPU, WordPress PopUp), vältides animatsioonikonflikte. Lisa oma välistusklassid sama mustri järgi.

Teine plokk: navigeerimise käsitlemine väliselt lehelt. jQuery(window).load() käivitub hiljem kui document.ready ja garanteerib, et kõik elemendid, sealhulgas ankur, on DOM-is. Funktsioon goToByScroll(id) teeb täpselt seda, mida põhiskript, kuid seda kutsutakse alles pärast akna täielikku laadimist. substr(1) eemaldab räsist # märgi.

Oluline märkus: jQuery(window).load() on alates jQuery 3.0 versioonist aegunud. Kui sinu projekt kasutab praegust jQuery versiooni, asenda see järgmisega:

1jQuery(window).on('load', function () {
2 // code here
3});

Süntaks erineb, kuid käitumine on identne.

Peenhäälestus: nihked, selektorid ja konksud

Skript töötab, kuid iga paigutus on unikaalne. Siin on kolm levinud kohendust, mis päästsid reaalseid projekte.

Probleem üks: offset().top tagastab valed koordinaadid. See juhtub, kui vanemelementidel on CSS-omadused transform, filter või will-change, mis loovad uue positsioneerimiskonteksti. offset() arvutab siis selle konteksti, mitte dokumendi suhtes. Lahendus: kasuta offset({top: -0}):

1jQuery('html, body').animate(
2 { scrollTop: jQuery('#' + id).offset({ top: -0 }).top },
3 1000
4);

Parameeter {top: -0} sunnib jQueryt asukohta dokumendi piiridest ümber arvutama, ignoreerides vahepealseid kontekste. Näeb välja nagu maagia, kuid see töötab.

Probleem kaks: selektor 'html, body' kerib valet elementi. Mõnes teemas ei ole kerimiskonteineriks html või body, vaid konkreetne plokk, näiteks body.home kodulehe jaoks või .main-content sisemiste lehtede jaoks. Tuvasta oma konteiner DevToolsi abil (Elements vahekaart → otsi overflow: scroll või overflow: auto) ja asenda see selektoris:

1jQuery('body.home').animate(
2 { scrollTop: target.offset().top - 37 },
3 1000
4);

Probleem kolm: räsi sisaldab kirillitsat või erimärke. location.hash tagastab URL-kodeeritud jada loetava stringi asemel ja jQuery selektor $(myHash) ei leia elementi. Lahendus: dekodeeri räsi decodeURIComponent() abil enne selle selektoris kasutamist.

Video: kerimise elav näide välislingilt

Lühike demo John Smithilt: sujuv ankrukerimine jQuery animate() abil reaalsel lehel koos fikseeritud päise ja välise navigeerimisega.

⁉️🤔 Korduma kippuvad küsimused

Skript töötab samal lehel, kuid mitte teiselt URL-ilt navigeerides. Miks?

Sest click töötleja ei käivitu kunagi: klikki ei toimunud. Kasutaja järgis otselinki ja brauser töötles räsi enne sinu JS-i käivitumist. Lahendus on jada location.hash = '' + animate() + location.hash = myHash. Räsi tühjendamine tühistab sisseehitatud hüppe, animatsioon kerib sujuvalt ja räsi taastamine säilitab korrektse URL-i aadressiribal.

Millist nihet peaksin fikseeritud päise jaoks kasutama?

Päise täpne kõrgus pluss mõni piksel hingamisruumi. Ava DevTools (F12), vali oma saidi header element ja kontrolli selle height väärtust Computed vahekaardil. Näiteks kui päis on 80px, kasuta koodis 90. Kui mobiiliversioonil on erinev päise kõrgus, lisa meediapäring dünaamilise nihke arvutusega.

Kas jQuery on 2026. aastal endiselt asjakohane?

Jah, eriti WordPressi ökosüsteemis. jQuery on jätkuvalt WP tuumas, paljud pluginad ja teemad sõltuvad sellest ning kogu ökosüsteemi migreerimine puhtale JS-ile võtab aastaid. Uute projektide puhul puhtas JavaScriptis tehakse sujuv kerimine element.scrollIntoView({ behavior: 'smooth' }) või scroll-behavior: smooth abil CSS-is, oluliselt vähemate koodiridadega. Kuid kui muudad olemasolevat WP saiti, on jQuery lahendus endiselt usaldusväärne ja asjakohane.

Kas ma saan jQuery üldse vältida?

Saad ja peakski, kui projekt on uus. Põhiskripti natiivne vaste:

1document.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});

Sama põhimõte: salvesta räsi, tühjenda see, keri, taasta see. Erinevus on selles, et behavior: 'smooth' kasutab brauseri natiivset CSS-mootorit, mitte jQuery taimerit. Kiirust ei saa seadistada, kuid kood on 30 KB kergem (jQuery kaal).

Miks $('html, body') lihtsalt $('html') asemel?

Firefox kerib html elementi, Chrome kasutab body elementi ja Safari sõltub versioonist. Mõlema selektori määramine animate() sees garanteerib toimimise kõigis brauserites: jQuery saadab animatsiooni sellele elemendile, mis seda tegelikult rakendab.

Kas jQueryt tasub 2026. aastal ainult sujuva kerimise jaoks kasutada

Kui sul on WordPressi sait või pärandprojekt, kus jQuery on juba laaditud, haara skript sellest artiklist ja ära aja asja keeruliseks. Kümme koodirida, mis töötavad igal pool, igas brauseris, ilma polüfillideta. Uutele puhta JavaScripti projektidele kasuta natiivset scroll-behavior: smooth või scrollIntoView(). Mõlemad lähenemised annavad sujuva kerimise, kuid jQuery meetod annab sulle kontrolli kiiruse, nihke ja kerimiskonteineri selektori üle. Natiivsed teostused nõuavad sama saavutamiseks eraldi kontrolle.

Peamine reegel, mille oleme kümnetest projektidest õppinud: tühjenda räsi alati enne kerimist. Ilma selle trikita ei suuda ükski töötleja brauseri sisseehitatud käitumisest jagu saada ja kasutajad kogevad jätkuvalt järske hüppeid.