Sticky menu a sidebar v jQuery

JavaScript Hotová řešení Sticky menu a sidebar v jQuery

Další hodně používaná věc na stránkách je sticky menu či sidebar. Co to vlastně je? Je to třeba to menu nebo sidebar, které se po překročení určité hranice scrollTop-u okna přilepí, tzn. je fixní, na stránku. Jsou to poměrně jednoduché kódy, ale vídám i hrůzy, které se běžně používají, řekneme si tedy čeho se vyvarovat.

Takto bude vypadat naše stránka:

Sticky menu v jQuery

Vidíme, že budeme mít nejdříve nějaký jiný obsah nad menu, nejčastěji nějaká hlavička s nadpisem. Vpravo pod menu také vidíme náš sidebar. Místo sidebaru můžeme použít klidně i nějaké menu, které však nesmí být delší než výška stránky, jelikož bychom nikdy nemohli zobrazit všechny položky.

Začneme zase přidáním JS

$(function(){

  ... kód ...

});

a HTML

<body>
<header>
   ... text ...
</header>

<div id="menu">
   <nav>
      <ul>
         <li><a href="#alfa" class="tlacitko"><span>ALFA</span></a></li>
         <li><a href="#beta" class="tlacitko"><span>BETA</span></a></li>
         <li><a href="#gama" class="tlacitko"><span>GAMA</span></a></li>
      </ul>
   </nav>
</div>

<div id="main">
<section>
   <article id="alfa">
      ... dlouhý text ...
   </article>
   <article id="beta">
      ... dlouhý text ...
   </article>
   <article id="gama" class="last">
      ... dlouhý text ...
   </article>
</section>

<aside>
   <div class="sticky">
      <p> ... text ... </p>
      <p> ... text ... </p>
   </div>
</aside>
</div>

<footer>
   ... text ...
</footer>
</body>

Menu

Nyní začneme tedy s menu. Nejdříve si promyslíme jak to uděláme. Samozřejmě nás asi všechny napadne, že musíme porovnávat souřadnice menu s scrollTop-em okna. Nesmíme však zapomenout, že scrollTop musíme při scrollování vždy nastavit na novou hodnotu. Pokud bude scrollTop větší, menu nastavíme na fixní, pokud menší, nastavíme ho na relativní.

No jo, ale kdybychom to takto nakódovali, zjistili bychom, že nám stránka vždy divně škubne. Je to způsobeno tím, když přenastavíme pozici menu, tak nám menu ze stránky jakoby zmizí. To nám samozřejmě zmenší stránku o výšku menu. Toho se vyvarujeme tak, že jsme přidali ještě jeden element, pojmenoval jsem ho div#menu, který nám bude uchovávat rozměry menu.

Dobře, jdeme na kód. Nejdříve si zase vytvoříme funkci a do ní dáme pár proměnných.

function fixMenu()
   {
   var menu_place = $('#menu').offset().top;
   var menu = $('nav');

Proměnnou menu_place nám bude rovnou vracet pozici menu. Tady už máme všechno hotové, pojďme tedy přidat event na scrollování okna. Rovnou si vytvoříme i anonymní funkci, v níž bude probíhat zbytek našeho kódu.

$(window).scroll(function(){ ... });

Nejdříve, jak jsem se již zmínil, vytvoříme proměnnou, která bude obsahovat hodnotu scrollTop-u. Ta musí být v této funkci, aby se nám její hodnota měnila.

var scroll_top = $(window).scrollTop();

Teď již máme vše co budeme potřebovat pro podmínku. Zopakuji, že musíme porovnat, zda je scroll_top větší než menu_place.

if ( scroll_top > menu_place )

Pokud ano, nastavíme menu fixní pozici a top na nulu. Pokud ne, pozici nastavíme relativní.

if ( scroll_top > menu_place )
   {
      menu.css({ 'position': 'fixed', 'top': 0 });
   }
else
   {
      menu.css({ 'position': 'relative' });
   }

A je to hotové. Je to opravdu jednoduché.

Pro ukázku tu je obrázek, jak to vypadá při scrollu. Vidíme tedy, že vše funguje.

Scrollování v jQuery

Sidebar

Sidebar se dělá vlastně docela podobně.

Nejprve si řekněme, jak by se to dalo udělat, ale jak je to rozhodně nevýhodné či zdlouhavé:

  1. Mohli bychom si dát aside přímo do body, nastavili na absolute, a počítali složitě jeho pozici - left a top. Tady je ta nevýhoda, že když budeme chtít změnit stránku, přidat ještě jeden box, nebo něco jiného, výpočet nám nemusí počítat správně a může se něco překrývat.
  2. Odsazovat aside pomocí margin-topu nebo topu. Když to uděláte špatně, při scrollu se to bude jakoby sekat, to se dá vyřešit použitím .animate(). Tady chci říct, že se to někdy může hodit, pokud se dobře napíše kód. Jelikož se tu dá udělat animace posunu, tu jste už určitě na nějakých webech viděli. Scrollujete a za chvíli vám vždy "přijede" reklama, tzn. neroluje pořád s vámi.

V podstatě si uděláte výpočet scrollTop - aside.parent()­.offset().top a to dosadíte do top. Aside se musí dát samozřejmě na relativní pozici. Rozhodně si to doporučuji vyzkoušet.

Jak bych to udělal nejlépe, pokud chci, aby se mnou sidebar pořád scrolloval? Nejdříve přidáme do aside jeden element, třeba div, který bude mít třídu .sticky. Do tohoto divu již dáme různé paragrafy, obrázky, reklamy, či podobně. Je to kvůli tomu, jelikož nám aside určuje směr v #main - float. Pokud bychom dali .sticky na aside, přesune se nám to doleva - vyruší se nám float. Také je ještě dobré dáš asidu nějaký padding, my použijeme padding: 50px 0;, aby to nebylo vše tak naplácané na menu.

Jako první si tedy zase vytvoříme proměnné, menu a sticky. Menu zde potřebujeme proto, jelikož máme fixní menu, které by nám sidebar zakrývalo. Sticky zase kvůli označení toho, co se má fixnout.

Vytvoříme si tedy funkci, do které vytvoříme i proměnné:

function fixAside()
{
   var menu = $('nav');
   var sticky = $('.sticky').offset().top;

Hned pod tímto už budeme mít podmínku. Ta bude stejná jako u menu, porovnáme zda-li je hodnota scrollTop větší než pozice asidu.

if ( scroll_top > sticky )

Když ano, nastavíme fixní pozici a jako top nastavíme výšku menu, to je kvůli tomu překrývání.

{
   $('.sticky').css({ 'position': 'fixed', top: menu.height() });
} else
{
   $('.sticky').css('position','static');
}

No a to bude všechno. Celkový JS kód si můžete stáhnout v příloze.

Musíte si dávat ale u obou částí - menu i sidebaru - "pozor", jelikož je to napsáno tak, že to počítá pouze s jedním prvkem na stránce. Pokud chci mít 2 různé menu - první půlku jedno, druhou půlku druhé - musí se to mírně upravit. Podobně tak i u sidebaru. Pokud byste měli zájem i o rozšíření tohoto tutoriálu, napište do komentářů, nebo se případně ptejte.


 

Stáhnout

Staženo 841x (8.71 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 (10 hlasů) :
4.64.64.64.64.6


 


Miniatura
Předchozí článek
Smooth scroll v jQuery
Miniatura
Všechny články v sekci
Hotová řešení v JavaScriptu
Miniatura
Následující článek
Menu item highlighting v jQuery

 

 

Komentáře

Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:

Krásnej a jednoduchej kód, teď jsem to použil na devbooku :)

Odpovědět  +1 24.3.2014 11:23
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
dyabol
Člen
Avatar
dyabol:

Proč používáš pro komprimaci souborů formát rar nebyl by vhodnější zip, který je ve windows standardně dostupný?

 
Odpovědět  ±0 21.7.2014 15:42
Avatar
admin
Člen
Avatar
admin:

vite nekdo, proc pri testovani na localu je vse ok a kdyz to nahodim na server tak mi side bar nesjizdi hned od zhora, ale pripoji se mi az v polovine, od poloviny dolu funguje, kdyz se vracim nahoru tak se v pulce ztrati a ceka nahore...diky za radu co s tim :)

Odpovědět 12.12.2014 14:14
wine is fine but whisky's quicker
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 3 zpráv z 3.