Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Menu item highlighting v jQuery

V minulé lekci, Nahrazování obsahu & klonování v jQuery (DOM), jsme se naučili nahrazovat a klonovat obsah stránky pomocí javascriptové knihovny jQuery.

Velmi důležitá a často používaná věc je menu item highlighting, neboli zvýrazňování aktivní položky v menu. Používá se na fixním menu, jinak bychom samozřejmě efekt neviděli, kde vám ukazuje kde se právě nacházíte. Daná položka je pak nějak zvýrazněna, třeba barvou pozadí, barvou písma atp.

Jako vždy si uděláme základní kostru v HTML a JS souboru.

JS:

$(function(){

  ... kód ...

});

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>
         <li><a href="#epsilon" class="tlacitko"><span>EPSILON</span></a></li>
         <li><a href="#zeta" class="tlacitko"><span>ZÉTA</span></a></li>
         <li><a href="#eta" class="tlacitko"><span>ÉTA</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">
      ... dlouhý text ...
   </article>
   <article id="delta">
      ... dlouhý text ...
   </article>
   <article id="epsilon">
      ... dlouhý text ...
   </article>
   <article id="zeta">
      ... dlouhý text ...
   </article>
   <article id="eta">
      ... dlouhý text ...
   </article>
</section>

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

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

K tomuto si nezapomeňte přidat i smooth scrool, který najdete v předchodím dílu, zde. Bude to pak vypadat lépe.

Takže, nejdříve bych chtěl poukázat na chyby, kterých se lidé často dopouští.

  1. Kód píší tak, že si zjistí ručně souřadnice a ty pak porovnávají s scrollTopem, tzn. pokud je scrollTop větší než třeba 479, zabarvi toto. Opravdu, takto ne, to je snad nejhorší co se dá udělat. Jednak stačí dopsat 2 odstavce textu a už vám kód nebude fungovat a za druhé je s tím i strašně práce.
  2. Zjistí si jen offset().top jednotlivých article a ty porovnávají s scrollTopem. Všechno dělají po jednom - pomocí ifů - a řeší tedy jenom horní hranici, pokud sjedete tam, kde je obsah, který nemáte v menu, zabarvení zůstává.
  3. Po kliku na menu item se rovnou zabarví. Při scrollu na stránce se to nemění. Tady asi musím říci, že je to také dost špatné, jelikož když budete scrollovat, tak se vám pochopitelně nebude zvýraznění měnit, tudíž to není použitelné. Navíc to nevypadá hezky.

A jak by se to mělo dělat správně? No, určitě by se mělo dělat vše automaticky, snažte si automatizovat vše, musí se brát nejen začátek, ale i konec. To je velmi důležité, jelikož ne všechny části webu musíte mít v menu.

Další důležitá věc je, že se vám při kliku na item v menu musí měnit menu podle stránky, ne naopak, tedy ne stránka podle menu. Pro ty, kteří se zamotali: Pokud scrollujete na stránce, menu se vám podle toho mění. Pokud kliknete do menu, stránka scrolluje, ale menu se vám také mění podle toho, kde na stránce jste.

Vytvoříme si nějakou stránku, nezapomeňte si vytvořit také třídu .active, kterou bude obsahovat element li, která nám bude měnit styly menu itemů.

Menu highlighting v jQuery - jQuery - Dynamické doplňky webu snadno a rychle

Takže, jsme připraveni a již víme jak na to.

Vytvoříme si funkci:

function activeItem()
{
   ...
}

Nyní si musíme rozmyslet, jaké proměnné vytvoříme. Do začátku si do proměnné uložíme selektor 'menu ul', vytvoříme si scroll_top a jako poslední proměnnou odchylka, ta nám bude udávat naší odchylku od začátku articlu.

Jak jistě víme, normálním kódem by se nám menu item nastyloval až po tom, co by byl scroll_top větší než offset().top. Touto odchylkou posuneme offset().top o nějakou část nahoru, tedy to bude i odpovídat tomu, kde se právě nacházíme - tedy co právě čteme.

var menu = $('nav ul');
var odchylka = 200;
var scroll_top = $(window).scrollTop();

Nyní už potřebujeme zjistit offset().top = minimum každého articlu a také jeho konečnou vzdálenost = maximum. Od toho samozřejmě odečteme naší odchylku. Přímo se nabízí použití .each(), který pro každý element, který vyhovuje selektoru, provede určitou funkci.

$("#main section article").each(function(){
   var toto = this;
   var article_top = $(toto).offset().top;
   var article_height = $(toto).innerHeight();
   var article_id = $(toto).attr('id');

   var min = article_top - odchylka;
   var max = article_top + article_height - odchylka;

this, tedy aktuální article, který právě .each() prochází, si uložíme do proměnné toto.

Důležité je, abychom pro zjišťování výšky articlu používali innerHeight(). Ten nám k normální výšce přičte i padding. Pokud bychom chtěli přičíst i margin, použijeme outerHeight().

Teď už máme vše potřebné pro podmínku.

if ( (scroll_top > min) && (scroll_top < max) )

Podmínka nám funguje, takže stačí vymyslet jak měnit aktivní item v menu. Nejjednodušší bude, když všem 'nav ul li' odebereme třídu .active, to uděláme takto. Mimochodem, toto si přidejte pod proměnnou stroll_top.

menu.find('li').removeClass('active');

Následně třídu .active dáme takovému li, které má stejný href, jako náš article_id.

if ( (scroll_top > min) && (scroll_top < max) )
{
   menu.find('li a[href="#'+article_id+'"]').parent().addClass('active');
}

Jelikož nám menu prezentuje $('menu ul'), musíme nějak označit naše 'li a'. Ovšemže menu.$('li a') fungovat NEbude. Pro tuto situaci, kdy bychom potřebovali dále hledat, zde máme .find() nebo .filter().

.find() nám prohledává další potomky, kdežto .filter() nám prohledává selektor, v našem případě 'nav ul'. My tedy použijeme .find(). Do něho jsme dali vyhledávat 'li a', a to přesněji takovéto 'a[href="#'+ar­ticle_id+'"]'. Následně najdeme rodiče - tedy li a tomu přidělíme třídu.

Naší funkci tedy ještě musíme volat i v

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

, jinak by nám to samozřejmě při scrollování nefungovalo.

Pro zkoušku si odebereme třeba a#delta z menu a zkontrolujeme si, zda-li nám to funguje, tedy respektive nefunguje. Když budeme na article#delta tak se nám nesmí nic zabarvit. Také si zkuste dát footer třeba na 7000px, jestli vám tam nic nezvýrazňuje.

Menu highlighting v jQuery - jQuery - Dynamické doplňky webu snadno a rychle

Každopádně je to všechno a funguje to. :)

V příští lekci, Odstraňování obsahu v jQuery (DOM), se budeme věnovat odstraňování obsahu v jQuery :)


Galerie

Program byl vytvořen v roce 2014.

 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 641x (8.87 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Nahrazování obsahu & klonování v jQuery (DOM)
Všechny články v sekci
jQuery - Dynamické doplňky webu snadno a rychle
Přeskočit článek
(nedoporučujeme)
Odstraňování obsahu v jQuery (DOM)
Program pro vás napsal Honza Bittner
Avatar
Uživatelské hodnocení:
11 hlasů
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity