IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Menu item highlighting v jQuery

Veľmi dôležitá a často používaná vec je menu item highlighting, čiže zvýrazňovanie aktívnej položky v menu. Používa sa na fixnom menu, inak by sme samozrejme efekt nevideli, kde vám ukazuje kde sa práve nachádzate. Daná položka je potom nejako zvýraznená, treba farbou pozadia, farbou písma atp.

Ako vždy si urobíme základnú kostru v HTML a JS súboru.

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 nezabudnite pridať aj smooth scrool, ktorý nájdete v předchodím dielu, tu. Bude to potom vyzerať lepšie.

Takže, najprv by som chcel poukázať na chyby, ktorých sa ľudia často dopúšťa.

  1. Kód píšu tak, že si zistí ručne súradnice a tie potom porovnávajú s scrollTopem, tzn. ak je scrollTop väčšia než napríklad 479, zafarbí toto. Naozaj, takto nie, to je snáď najhoršie čo sa dá urobiť. Jednak stačí dopísať 2 odseky textu a už vám kód nebude fungovať a za druhé je s tým aj strašne práce.
  2. Zistí si len offset (). Top jednotlivých article a tie porovnávajú s scrollTopem. Všetko robia po jednom - pomocou IFU - a rieši teda len hornú hranicu, ak zídete tam, kde je obsah, ktorý nemáte v menu, zafarbenie zostáva.
  3. Po kliku na menu item sa rovno zafarbí. Pri scroll na stránke sa to nemení. Tu asi musím povedať, že je to tiež dosť zlé, pretože keď budete scrollovať, tak sa vám pochopiteľne nebude zvýraznenie meniť, teda to nie je použiteľné. Navyše to nevyzerá pekne.

A ako by sa to malo robiť správne? No, určite by sa malo robiť všetko automaticky, snažte si automatizovať všetko, musí sa brať nielen začiatok, ale aj koniec. To je veľmi dôležité, pretože nie všetky časti webu musíte mať v menu.

Ďalšia dôležitá vec je, že sa vám pri kľučku na item v menu musí meniť menu podľa stránky, nie naopak, teda nie stránka podľa menu. Pre tých, ktorí sa zamotali: Ak scrollujete na stránke, menu sa vám podľa toho mení. Pokiaľ kliknete do menu, stránka scrolluje, ale menu sa vám tiež mení podľa toho, kde na stránke ste.

Vytvoríme si nejakú stránku, nezabudnite si vytvoriť tiež triedu .active, ktorú bude obsahovať element li, ktorá nám bude meniť štýly menu itemov.

Menu highlighting v jQuery - Hotová riešenie v JavaScripte

Takže, sme pripravení a už vieme ako na to.

Vytvoríme si funkciu:

function activeItem()
{
   ...
}

Teraz si musíme rozmyslieť, aké premenné vytvoríme. Do začiatku si do premennej uložíme selektor 'menu ul', vytvoríme si scroll_top a ako posledný premennú odchýlka, tá nám bude udávať našej odchýlku od začiatku article.

Ako iste vieme, normálnym kódom by sa nám menu item nastyloval až po tom, čo by bol scroll_top väčší ako offset (). Top. Touto odchýlkou posunieme offset (). Top o nejakú časť hore, teda to bude aj zodpovedať tomu, kde sa práve nachádzame - teda čo práve čítame.

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

Teraz už potrebujeme zistiť offset (). Top = minimum každého Article a tiež jeho konečnú vzdialenosť = maximum. Od toho samozrejme odpočítame našej odchýlku. Priamo sa ponúka použitie .each (), ktorý pre každý element, ktorý vyhovuje selektora, vykoná určitú funkciu.

$("#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, teda aktuálne article, ktorý práve .each () prechádza, si uložíme do premennej toto.

Dôležité je, aby sme pre zisťovanie výšky Article používali innerHeight (). Ten nám k normálnej výške pripočíta aj padding. Ak by sme chceli pripísať aj margin, použijeme outerHeight ().

Teraz už máme všetko potrebné pre podmienku.

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

Podmienka nám funguje, takže stačí vymyslieť ako meniť aktívny item v menu. Najjednoduchšie bude, keď všetkým 'nav ul chcete' odoberieme triedu .active, to urobíme takto. Mimochodom, toto si pridajte pod premennú stroll_top.

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

Následne triedu .active dáme takému li, ktoré má rovnaký href, ako náš article_id.

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

Keďže nám menu prezentuje $ ( 'menu ul'), musíme nejako označiť naše 'ak a'. Pravdaže menu. $ ( 'Ak a') fungovať nebudú. Pre túto situáciu, kedy by sme potrebovali ďalej hľadať, tu máme .find () alebo .filter ().

.find () nám prehľadáva ďalšie potomkov, kdežto .filter () nám prehľadáva selektor, v našom prípade 'nav ul'. My teda použijeme .find (). Do neho sme dali vyhľadávať 'ak a', a to presnejšie takéto 'a [href = "#' + article_id + '"]'. Následne nájdeme rodičia - teda ak a tomu pridelíme triedu.

Našou funkciu teda ešte musíme volať aj v

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

, Inak by nám to samozrejme pri scrollovanie nefungovalo.

Na skúšku si odoberieme treba a # delta z menu a skontrolujeme si, či ak nám to funguje, teda respektíve nefunguje. Keď budeme na article # delta tak sa nám nesmie nič zafarbiť. Tiež si skúste dať footer trebárs na 7000px, či vám tam nič nezvýrazňuje.

Menu highlighting v jQuery - Hotová riešenie v JavaScripte

Každopádne je to všetko a funguje to. :)


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 642x (8.87 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Všetky články v sekcii
Hotová riešenie v JavaScripte
Článok pre vás napísal Honza Bittner
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity