Skip to content

Kõik WordPressist, veebiarendusest — ja mitte ainult

🖱 Sujuv kerimine ankruni: CSS, JavaScript ja jQuery - kolm töötavat lähenemist

🖱 Sujuv kerimine ankruni: CSS, JavaScript ja jQuery - kolm töötavat lähenemist

Kasutaja klõpsab ankruga lingil ja leht hüppab hetkega sihtkohta. Ei mingit animatsiooni, sujuvust ega arusaama, kuhu sa maandusid. Järsk üleminek tekitab segadust, eriti pikkadel sihtlehtedel ja dokumentatsioonis.

Sujuva kerimise lisamine ankrutele võtab 5 minutit. Kuid kurat peitub detailides: link võib tulla väliselt saidilt, URL-is on juba räsi ja üleval on fikseeritud päis, mis ankru kinni katab. Tavaline scroll-behavior: smooth neid nüansse ei lahenda.

Allpool on kolm töötavat lähenemist: puhas CSS, natiivne JavaScript ja jQuery. Igaühe juures on kood, mille saad kopeerida ja oma projekti kleepida. Lisaks käsitleme eraldi väliseid üleminekuid, et kerimine toimiks ka siis, kui kasutaja tuleb teiselt lehelt või otsingutulemustest.

💡 Kiirülevaade:

  • Luba sujuv kerimine ühe CSS-i reaga, ilma JavaScriptita
  • Lisa fikseeritud päise jaoks nihe, kasutades scroll-margin-top
  • Kirjuta natiivne JS scrollIntoView'ga väliste üleminekute ja peenhäälestuse jaoks
  • Käsitle jQuery varianti animate()'ga, kui vajad kohandatud kiirust ja kontrolli
  • Tegele välise räsiga: leht laaditud, ankur URL-is ja sujuv kerimine sihtmärgini

Miks sujuv kerimine on oluline

Järsk hüppamine ankruni tekitab segadust. Kasutaja kaotab konteksti: kus ma olin, kuhu ma maandusin, mis jäi kahe silma vahele? Sujuv kerimine säilitab ruumilise orientatsiooni, andes silmale midagi jälgida, kuni leht liigub.

Tajumise seisukohast näeb sujuva kerimisega sait viimistletud välja. See on eriti märgatav pikkadel lehtedel: sihtlehed, dokumentatsioon, KKK jaotised, artiklite sisukorrad. Kasutaja klõpsab menüüs "Hinnakiri" ja leht ei tõmble, vaid libiseb õrnalt hinnakirja plokini.

Tehniliselt jaguneb ülesanne kaheks: kerimine sisemise lingi klõpsul (kasutaja on juba lehel) ja kerimine välisel üleminekul (URL sisaldab juba #anchor). Teisel juhul hüppab brauser vaikimisi ankruni koheselt, isegi enne täielikku laadimist, ja seda tuleb peatada.

CSS scroll-behavior, üks rida skripti asemel

Lihtsaim ja moodsaim lähenemine. Brauserid õppisid sujuva kerimise selgeks natiivselt, piisab vaid ühest CSS-i reeglist:

1html {
2 scroll-behavior: smooth;
3}

See on kõik. Igasugune üleminek ankru lingi kaudu muutub sujuvaks. Pole JavaScripti ega teeke.

Tugi: kõik kaasaegsed brauserid alates 2022. aastast: Chrome 61+, Firefox 36+, Safari 15.4+, Edge 79+. Ainus erand on IE11, kuid selle liiklusosakaal läheneb nullile.

Fikseeritud päis: scroll-margin-top

Kui fikseeritud päis (kleepuv päis) ripub sisu kohal, jääb ankur pärast kerimist selle alla. Lahendatav ühe reaga:

1h2, h3, [id] {
2 scroll-margin-top: 80px; /* header height + offset */
3}

Brauser lisab sihtelemendini kerides automaatselt nihke. Varem kirjutati häkke padding-top ja negatiivse margin'iga, nüüd pole seda vaja.

Puhta CSS-i piirangud

CSS-i lähenemisel puudub kontroll animatsiooni kiiruse ja leevendusfunktsiooni üle. Brauser kasutab sisseehitatud kõverat, tavaliselt ease-in-out. Kui vajad kohandatud kiirust või mittelineaarset animatsiooni, liigu JavaScripti juurde.

Natiivne JavaScript: scrollIntoView

Kui CSS-ist üksi ei piisa, tuleb appi scrollIntoView() meetod koos behavior: 'smooth' valikuga:

1document.querySelectorAll('a[href^="#"]').forEach(anchor => {
2 anchor.addEventListener('click', function(e) {
3 e.preventDefault();
4 const target = document.querySelector(this.getAttribute('href'));
5 if (target) {
6 target.scrollIntoView({
7 behavior: 'smooth',
8 block: 'start'
9 });
10 }
11 });
12});

See kood püüab kinni klõpsud kõikidel #-ga linkidel, tühistab standardse ülemineku ja käivitab sujuva kerimise. Töötab ilma jQuery ja täiendavate teekideta.

Eelis: saad seda programmeeritult juhtida: muuta kiirust CSS-i scroll-behavior kaudu <html> elemendil, lisada tingimusi (näiteks välistada teatud lingid), kombineerida päise jaoks scroll-margin-top'iga.

Puudus: scrollIntoView ei võimalda animatsiooni kiirust otse määrata. Kohandatud kerimisaja jaoks (ütleme 800 ms brauseri ~500 ms asemel) on vaja kas jQuery't või käsitsi requestAnimationFrame'i.

JQuery animate, täielik kontroll animatsiooni üle

Kui projekt kasutab juba jQuery't või vajad peenhäälestust (kiirus, nihe päise jaoks, linkide filtreerimine), siis siin on ajakohane skript. Allpool on kohandatud versioon klassikalisest lähenemisest, ümber kirjutatud kaasaegse jQuery jaoks:

1jQuery(document).ready(function($) {
2 // Smooth scroll on anchor link click
3 $('a[href*="#"]:not([href="#"])').on('click', function() {
4 if (
5 location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '')
6 && location.hostname === this.hostname
7 ) {
8 var target = $(this.hash);
9 target = target.length ? target : $('[name="' + this.hash.slice(1) + '"]');
10 if (target.length) {
11 $('html, body').animate({
12 scrollTop: target.offset().top - 80
13 }, 800);
14 return false;
15 }
16 }
17 });
18
19 // Scroll on external transition with hash in URL
20 if (window.location.hash) {
21 var hash = window.location.hash.substring(1);
22 var $target = $('#' + hash);
23 if ($target.length) {
24 setTimeout(function() {
25 $('html, body').animate({
26 scrollTop: $target.offset().top - 80
27 }, 800);
28 }, 100);
29 }
30 }
31});

Mis on siin muutunud võrreldes blogides ringlevate vanade versioonidega:

  • .bind() asendatud .on()'iga, .bind() kuulutati jQuery 3.0-s aegunuks ja eemaldatakse jQuery 4.0-s.
  • Selektor 'a:not(.spu-clickable)[href*="#"]:not([href="#"])' on lihtsustatud, konkreetne klass .spu-clickable oli seotud kindla pluginaga (Popups by OptinMonster) ja üldiselt pole seda vaja.
  • jQuery(window).bind("load", ...) eemaldatud, skripti teine osa välise räsi jaoks elab nüüd $(document).ready() sees ega vaja eraldi load sündmust.
  • Lisatud viivitus setTimeout(..., 100), et DOM oleks garanteeritult renderdatud enne ankru asukoha arvutamist (asjakohane laisa laadimisega piltide ja dünaamilise sisuga lehtede puhul).

Kuhu kood paigutada

Valimiseks kolm võimalust:

  • Teema faili kaudu. Lisa skript functions.php'sse wp_enqueue_script() kaudu, standardmeetod alamteema jaoks.
  • Plugin Code Snippets. Sisesta kood uue katkendina automaatse käivitamisega, see ei kao teema uuendamisel.
  • Kohandatud JS plugin. Kui sait kasutab juba pluginat suvalise JavaScripti sisestamiseks (näiteks WPCode), lisa kood sinna.

Välise ülemineku käsitlemine räsiga, üksikasjalik analüüs

Ülesande kõige keerulisem osa. Kasutaja järgib lingile https://site.com/page/#pricing teiselt saidilt või otsingust. Brauser hüppab vaikimisi koheselt #pricing juurde niipea, kui element DOM-is ilmub, ilma animatsioonita ja sageli enne lehe täielikku laadimist.

Ülaltoodud jQuery skript lahendab selle kahes etapis:

  • Tuvastab räsi olemasolu window.location.hash kaudu. Kui räsi on olemas, loeb selle väärtuse (ilma #-ta).
  • Leiab sihtmärgi ja kerib. $('#' + hash) leiab elemendi, setTimeout annab lehele aega renderdamiseks, animate() viib sihtmärgini 80 piksli suuruse nihkega.

100 millisekundiline viivitus on empiiriline. Kiiretel lehtedel piisab 50 ms, rasketel (taustavideo, kaartide, diagrammidega sihtlehed) on parem suurendada 200-300 ms-ni. Alternatiiv: oodata window.load sündmust document.ready asemel, kuid siis toimub kerimine alles pärast kõigi piltide laadimist, mis võib võtta aega.

Mida teha, kui ankur sihtmärki ei leia

Mõnikord viitab räsi URL-is olematule elemendile. Näiteks tegi kasutaja trükivea või lehte muudeti. Sel juhul ei anna CSS ega JS lähenemine veateadet, lihtsalt midagi ei juhtu. Brauser ignoreerib olematut ankrut. Ka sujuv kerimine toimib hääletult (if (target.length) tingimus ei lase sellel edasi minna).

Kolme lähenemise võrdlus

Kriteerium

CSS scroll-behavior

JS scrollIntoView

jQuery animate

Rakendamise keerukus

1 rida CSS-i

10-15 rida JS-i

25-30 rida JS-i + jQuery

Kiiruse kontroll

Ei

Ei (brauseri vaikeseade)

Jah (ms)

Väline räsi

Jah, natiivselt

Vajab lisakoodi

Vajab lisakoodi

Päise nihe

scroll-margin-top

scroll-margin-top

Käsitsi offset().top'is

Sõltuvused

Puuduvad

Puuduvad

jQuery 3.x

Brauseri tugi

96%+

96%+

99%+ (jQuery'ga)

Enamiku kaasaegsete projektide jaoks on CSS-i lähenemine optimaalne: üks rida, null sõltuvust, natiivne jõudlus. Kui vajad päise jaoks nihet, lisa scroll-margin-top. Kui vajad kohandatud kiirust või tuge iidsetele brauseritele, siis jQuery koos animate()'ga.

Allpool on video kõigi kolme lähenemise live-esitlusega, CSS-ist jQuery'ni:

⁉️🤔 Korduma kippuvad küsimused

Miks sujuv kerimine mobiilseadmetes ei tööta?

iOS Safaris enne versiooni 15.4 ei olnud scroll-behavior: smooth toetatud. Nüüd on tugi olemas (Safari 15.4+, märts 2022). Kui kerimine vanadel iPhone'idel ei tööta, lisa JavaScripti varulahendus scrollIntoView või requestAnimationFrame'iga. Samuti kontrolli, et kerimist ei blokeeriks overflow: hidden body elemendil, mõned mobiilimenüüd määravad selle avanemisel. 2026. aasta juuni seisuga on scroll-behavior globaalne tugi 96,3% brauseritest (Can I Use andmetel).

Kuidas teha sujuvat kerimist mitte ankruni, vaid suvalise elemendini nupuklõpsul?

Anna elemendile id ja kasuta sama JavaScripti, kuid seotuna nupuga, mitte ankru lingiga. Näiteks nupp "Tagasi üles": document.querySelector('#back-to-top').addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' })). jQuery variandi jaoks: $('#back-to-top').on('click', () => $('html, body').animate({ scrollTop: 0 }, 600)). Ankruid pole vaja, keri koordinaatideni.

Kas 2026. aastal on vaja jQuery't lisada ainult sujuva kerimise jaoks?

Ei. jQuery kaalub min-versioonis umbes 87 KB (30 KB gzip). Kui jQuery't ei kasutata saidil kusagil mujal, on selle lisamine ühe kerimise jaoks ebaratsionaalne. Kasuta CSS-i lähenemist scroll-behavior: smooth või natiivset scrollIntoView. jQuery on õigustatud ainult siis, kui sait on juba sellele ehitatud (jQuery teemad, pärandprojektid) ja soovid lisada kerimist olemasolevale koodibaasile.

Kas kerimist saab animeerida erineva kiirusega, algul kiiresti, siis aeglaselt?

Jah, läbi $.animate() koos jQuery UI-ga või läbi requestAnimationFrame koos leevendusfunktsiooniga. Standardne jQuery animate() kasutab lineaarset või swing-funktsiooni. Mittestandardsete kõverate jaoks lisa jquery.easing või kirjuta oma tsükkel requestAnimationFrame'il kohandatud leevendusfunktsiooniga, näiteks easeInOutQuad. See annab täieliku kontrolli kiiruse, trajektoori üle ega vaja väliseid teeke.

Kuidas kontrollida, et kerimine töötab välisel üleminekul räsiga?

Ava uus vahekaart, kleebi URL ankruga (näiteks https://yoursite.com/page/#contacts) ja vajuta Enter. Leht peaks laadima ja sujuvalt plokini kerima. Teine võimalus: brauseri konsoolis avatud lehel käivita location.hash = '#contacts'. Kui kerimine on sujuv, siis skript töötab. Kui leht tõmbles hetkega, pole välise räsi töötleja seadistatud.

Milline lähenemine oma ülesande jaoks valida

Kui sait on kaasaegne, ilma jQuery'ta, katab CSS scroll-behavior: smooth valdava enamuse stsenaariume. Üks rida, kohene tulemus. Lisa päise jaoks scroll-margin-top ja ongi valmis.

Kui sait on WordPressil koos jQuery'ga teemas, siis jQuery skript koos animate()'ga. Annab kontrolli kiiruse ja nihke üle, käsitleb väliseid üleminekuid, ei lähe vastuollu teiste pluginatega.

Kui kirjutad nullist ega taha teeki kaasa tõmmata, siis natiivne scrollIntoView() koos välise räsi töötlejaga. Kuldne kesktee: puhas, kiire, sõltuvusteta.

Võta artiklist kood, kleebi oma projekti ja kontrolli välist üleminekut, see on ainus juhtum, mida on testimise käigus lihtne märkamata jätta.