Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

Sticky menu a sidebar v jQuery

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

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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 894x (8.71 kB)
Aplikace je včetně zdrojových kódů v jazyce javascript

 

 

Článek pro vás napsal Honza Bittner
Avatar
Jak se ti líbí článek?
10 hlasů
Student FIT ČVUT. Sleduj mě na https://twitter.com/tenhobi a zeptat na cokoli se mě můžeš na https://github.com/HoBi/ama.
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
Aktivity (1)

 

 

Komentáře

Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:24.3.2014 11:23

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:21.7.2014 15:42

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:12.12.2014 14:14

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.