Smooth scroll v jQuery

JavaScript Hotová řešení Smooth scroll v jQuery

Po častých dotazech na různé jQuery vymoženosti jsem se rozhodl sepsat seriál jQuery - praktické využití. Nebudeme se zde moc učit jQuery, tedy JS, jako takové, budeme si zde spíše ukazovat efektivní cesty, kterými si můžeme ušetřit čas a zkrátit kód.

Smooth scroll

Smooth scroll neboli hladké scrollování je snad nejčastěji využívaná funkce na moderním webu, hlavně tedy na minisites. Princip této funkce je v plynulé změně pozice obrazovky po kliku na nějaké tlačítko, nejčastěji v menu.

Mnoho lidí píše strašně zdlouhavý a neefektivní kód (myšleno hodně kódu a mizerný výsledek). Tuto funkci lze však napsat v podstatě na 3 řádky.

Jako obvykle, kód píšeme mezi

$(function(){

  ... kód ...

});

Tak, začátek máme. Připravte si také nějaký pokusný web s navigačním menu a delším textem s nadpisy, mezi kterými budeme stránkou rolovat. Já jsem stránku rozdělil na 3 barevné části a na ty odkázal z menu. Každá část se nalézá v divu s příslušným Id, na které se odkazuje z menu. Zkrácený kód v body by vypadal asi takto:

<body>

<nav id="menu">
  <ul>
      <li><a href="#red" class="tlacitko"><span>RED</span></a></li>
      <li><a href="#green" class="tlacitko"><span>GREEN</span></a></li>
      <li><a href="#blue" class="tlacitko"><span>BLUE</span></a></li>
  </ul>
</nav>

<div id="red">
   ...dlouhý text...
</div>
<div id="green">
   ...dlouhý text...
</div>
<div id="blue">
   ...dlouhý text...
</div>

</body>

Výsledek:

Ukázkový web

Jak začneme? Určitě vás již napadlo, že musíme nějak odchytit klik na tlačítko. Naše tlačítka musí obsahovat jednak atribut href, pro odchycení kam se má stránka scrollovat, a také třídu, díky které vymezíme jen naše chtěná tlačítka.

<a href="#red" class="tlacitko">RED</a>

Pro výběr našich tlačítek nám bude sloužit

$('a.tlacitko')

Na něj napojíme událost click.

$('a.tlacitko').on('click', function(){

});

Do této anonymní funkce budeme psát zbytek našeho scriptu. Nejdříve je třeba určit kam budeme směřovat, tedy náš cíl.

var cil = $(this).attr('href');

Pokud používáme fixní menu, které se na minisites většinou používá, je třeba určit i jej.

var menu = $('#menu');

A na závěr je třeba nastavit rychlost animace. Ta se udává vždy v milisekundách.

var rychlost = 2 * 1000;

Moment, ještě by se nám hodil nějaký hezký efekt. Efektem se rozumí jiné rozložení animace, pomalejší začátek, pomalejší konec atp. Vybral jsem easeInOutExpo. Tento a další efekty můžete najít a podívat se jak vypadají, třeba na stránce http://api.jqueryui.com/easings/

var efekt = "easeInOutExpo";

Nezapomeňte, že tyto efekty jsou součástí jQuery UI. Tudíž si přidejte do hlavičky i link na tuto knihovnu.

efekty

To bychom měli všechno co se týče nastavení. Nyní je čas na animaci. K tomu použijeme funkci .animate(), ve které budeme animovat ScrollTop na pozici našeho cíle. Pozici cíle získáme z offset().top a navíc od ní odečteme výšku menu, tu však odečítejte pouze je-li fixní.

Ale co budeme animovat? Bude to body a html.

$("html, body").animate(
  { scrollTop: $(cil).offset().top - menu.height() },
  rychlost, efekt
);

To bychom v základu měli. Ještě ale přidáme zamezení vypisování našeho cíle do url adresy. To se udělá úplně jednoduše. Mimochodem, do té anonymní funkce si přidejte parametr e.

e.preventDefault();

Pokud si nyní otestujeme náš kód, můžeme si všimnout, že při rychlém naklikání např. 10ti položek menu nám obrazovka skáče sem a tam. Je to tím že po kliku na tlačítko se nám spustí animace a když klikneme na další tlačítko, animace se nám přesune jakoby do fronty. Tento efekt můžeme zamezit přidáním

.stop();

To nám ukončí aktuální animaci a zahájí nám naší novou.

V našem "nastavení" máme definovanou každou proměnnou zvlášť, určitě bude lepší když je spojíme do jednoho zápisu:

var odkaz = $(this).attr('href'),
menu = $('#menu'),
rychlost = 2 * 1000,
efekt = "easeInOutExpo";

A jsme u konce... Krása, že? Celkový script bude vypadat nějak takto:

$('a.tlacitko').on('click', function(e){
  var odkaz = $(this).attr('href'),
      menu = $('#menu'),
      rychlost = 2 * 1000,
      efekt = "easeInOutExpo";

  $("html, body").stop().animate(
   { scrollTop: $(odkaz).offset().top - menu.height() },
   rychlost, efekt );

  e.preventDefault();
});

Kód se dá samozřejmě ještě zmenšit o nastavování proměnných atp., ale myslím že takto to bude bohatě stačit. Hotový web je ke stažení níže.

Pro správnou funkčnost kódu musíte mít naimportovanout knihovnu jQuery UI.


 

Stáhnout

Staženo 1071x (7.87 kB)
Aplikace je včetně zdrojových kódů v jazyce javascript

 

  Aktivity (1)

Článek pro vás napsal Honza Bittner
Avatar
Autor je vášnivý web developer. Ptejte se mě na cokoli na https://github.com/HoBi/ama a followujte mě na Twitteru https://twitter.com/tenhobi. :-)

Jak se ti líbí článek?
Celkem (20 hlasů) :
4.800014.800014.800014.800014.80001


 


Miniatura
Všechny články v sekci
Hotová řešení v JavaScriptu
Miniatura
Následující článek
Sticky menu a sidebar v jQuery

 

 

Komentáře
Zobrazit starší komentáře (7)

Avatar
Xin_
Člen
Avatar
Xin_:

ono ten odkaz když na něho kliknu tak najede na ten blok s tím id, to funguje i bez JS, no a apk až se to začne animovat :/

Editováno 30.1.2014 17:58
Odpovědět 30.1.2014 17:58
Zvědavost nás žene vpřed :)
Avatar
Tommy
Člen
Avatar
Tommy:

Čo ak človek nemá fixné menu ? Konkrétne napr. ja.

Popíšem situáciu:
Na vrchu stránky mám banner(1024x220). Pod ním mam menu. Menu sa mi fixne (na top:0) až po scrolovaní a použití Jquery skriptu.

Chapem tomu spravne, ze tam musim doplnit podmienku, ci je menu fixne alebo nie a podla toho pocitat tu danu suradnicu ?

 
Odpovědět 19.2.2014 10:15
Avatar
Tommy
Člen
Avatar
Tommy:

Aby som to doplnil, tak po prvom kliknuti na nejake tlacitko sa prescroluje text, tak ako keby bral, ze to menu este nie je zafixovane. Po tom uz nech kliknem na hociktore tlacitko v menu to funguje. Ked sa znova vratim na top stranky, tak opät prvy krok je zly a potom to funguje. Ako na to ?

 
Odpovědět 19.2.2014 10:48
Avatar
Honza Bittner
Redaktor
Avatar
Odpovídá na Tommy
Honza Bittner:

To fixnutí menu po nějaké pozici máš udělané dobře? Tedy jestli ti to nijak neskočí?

Odpovědět 19.2.2014 14:12
Ptejte se mě na cokoli na https://github.com/HoBi/ama a followujte mě na Twitteru https://twitter.com/tenhobi. :-)
Avatar
Tommy
Člen
Avatar
Odpovídá na Honza Bittner
Tommy:

Uz som to vyriesil. Dal som to do podmienky a porovnaval top mojho menu so scroll topom.

 
Odpovědět 19.2.2014 15:50
Avatar
cmaja
Člen
Avatar
cmaja:

Kód na konci tutoriálu nefunguje:

$('a.tlacitko').on('click', function(){
  var odkaz = $(this).attr('href'),
      menu = $('#menu'),
      rychlost = 2 * 1000,
      efekt = "easeInOutExpo";

  $("html, body").stop().animate(
   { scrollTop: $(odkaz).offset().top - menu.height() },
   rychlost, efekt );

  e.preventDefault();
});

Kód, který je v příloze, je pozměněn oproti uvedenému. Hlavně v něm není použit efekt, takže funguje defaultní animace. Jakmile se napíše do funkce animate, proměnná efekt, přestane skript fungovat. Jak to napravit?

Odpovědět 3.3.2014 23:40
"Jen dvě věci jsou nekonečné - vesmír a lidská hloupost. Tím prvním si ovšem nejsem tak jist" ALBERT EINSTEIN
Avatar
Juraj Mlich
Redaktor
Avatar
Odpovídá na cmaja
Juraj Mlich:

V kóde na konci článku nieje naimportovaná knižnica jQuery UI, v ktorej je efekt - easeInOutExpo - nadefinovaný.

Odpovědět 4.3.2014 6:35
Vždy je lepšie učiť sa z cudzích chýb, než z vlastných chýb.
Avatar
done
Člen
Avatar
Odpovídá na cmaja
done:

Pokud nechceš importovat jQuery UI, tak ten efekt můžeš vynechat. Bude se to scrollovat konstantně.

 
Odpovědět  +1 4.3.2014 7:44
Avatar
cmaja
Člen
Avatar
cmaja:

Jo, tak už to funguje, díky. Použil jsem tuhle:

<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
Odpovědět 4.3.2014 17:52
"Jen dvě věci jsou nekonečné - vesmír a lidská hloupost. Tím prvním si ovšem nejsem tak jist" ALBERT EINSTEIN
Avatar
Odpovídá na cmaja
Ľubomír Prokopovič:

Vedel by si tu hodit svoj kod. Ja som to skusal s efektom mam aj kniznicu jQuery importovanu ale akosi to nejde

Odpovědět 21.2.2015 17:55
"Počítače jsou jako Bůh ve Starém zákoně - hodně příkazů a žádné slitování." Joseph Campbell
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 17. Zobrazit vše