Interaktivní menu v JavaScriptu s jQuery

JavaScript Hotová řešení Interaktivní menu v JavaScriptu s jQuery

Dnes si ukážeme jak vytvořit jednoduché interaktivní menu s řadou efektů jako například schovávání/zo­brazení po scrollu. Jako vždy si nejdříve vytvoříme HTML, CSS a JS soubor, do kterých přidáme následující kód.

JS **

$(function(){

  ... kód ...

});

HTML

<div id="menu">
   <nav>
      <ul>
         <li class="item">
            <a href="#1">Jedi</a>
            <ul>
               <li><a href="#1-1">Yoda</a></li>
               <li><a href="#1-2">Luke Skywalker</a></li>
               <li><a href="#1-3">Mace Windu</a></li>
               <li><a href="#1-4">Obi-Wan Kenoby</a></li>
            </ul>
         </li>
         <li class="item">
            <a href="#2">Sith</a>
            <ul>
               <li><a href="#2-1">Darth Sidious</a></li>
               <li><a href="#2-2">Darth Maul</a></li>
               <li><a href="#2-3">Darth Bane</a></li>
               <li><a href="#2-4">Darth Tyranus</a></li>
               <li><a href="#2-5">Darth Vader</a></li>
            </ul>
         </li>
         <li class="item">
            <a href="#3">LOTR</a>
            <ul>
               <li><a href="#3-1">Aragorn</a></li>
               <li><a href="#3-2">Gandalf</a></li>
               <li><a href="#3-3">Legolas</a></li>
               <li><a href="#3-4">Sauron</a></li>
            </ul>
         </li>
         <li class="item">
            <a href="#4">HP</a>
            <ul>
               <li><a href="#4-1">Harry Potter</a></li>
               <li><a href="#4-2">Ronald Weasley</a></li>
               <li><a href="#4-3">Hermione Granger</a></li>
               <li><a href="#4-4">Albus Dumbledore</a></li>
               <li><a href="#4-5">Tom Marvolo Riddle</a></li>
            </ul>
         </li>
      </ul>
   </nav>
   <div id="subnav" class="active">
   </div>
</div>

<!-- zbytek stránky -->

CSS

/*** menu ***/

#menu
{
   width: 100%;
   height: 50px;
   position: fixed;
   top: 0;
   left: 0;
}

nav
{
   width: 100%;
   height: 50px;
   background: #fff;
   margin: 0px auto;
   border-bottom: 1px solid #ddd;
   z-index: 100;
   position: relative;
}

/* 1 */

nav ul, #subnav ul
{
   float:left;
   position:relative;
   left:50%;
}

nav ul li, #subnav ul li
{
   float:left;
   position:relative;
   right:50%;
}

nav ul li a
{
   padding: 0px 15px;
   color: #575757;
   display: block;
   font-size: 22px;
   line-height: 50px;
}

nav ul li:hover, nav > ul > li.active
{
   border-bottom: 1px solid #dc1041;
}

/* 2 */

nav > ul > li > ul
{
   display: none;
}

#subnav
{
   width: 100%;
   height: 40px;
   background: #fff;
   border-bottom: 1px solid #ddd;
   top: -41px;
   position: relative;
   z-index: 50;
}

#subnav.active
{
   top: 0;
}

#subnav ul li:hover
{
   border-bottom: 1px solid #dc1041;
}

#subnav ul li a
{
   padding: 0px 15px;
   color: #979797;
   display: block;
   font-size: 15px;
   line-height: 40px;
}

Tak, již máme nastylované celé menu. Bez našeho JS kódu, nebo s vypnutým JS, by se nám ale zobrazily obě dvě úrovně a to my přeci nechceme. Druhou úroveň menu - #subnav - vyplňujeme až v JS, tudíž ho musíme dát pryč. Toho docílíme připsáním CSS vlastnosti display: none; do #subnav.

Nezapomeňte si také do hlavičky přidat jQuery a jQuery UI.

Interaktivní menu v JavaScriptu

Efekty

Zobrazení 2. úrovně

Jako první efekt bude zobrazení 2. úrovně menu. Toho docílíme najetím nebo klikem na položku v 1. úrovni menu. Aktivní položka bude mít vždy upravený styl, který obsahuje třída .active.

Tedy:

$(".item").on("click mouseover", function(){

   ... kód ...

});

Ze všeho nejdříve musíme odstranit třídu .active z již aktivní položky. Toho dosáhneme jednoduše tak, že odstraníme z elementů, které nám vybere selektor $('.item'), třídu .active.

$(".item").removeClass("active");

Následně na položku, na kterou jsme klikli, přidáme třídu .active. Zde využijeme klíčového slova this, které použijeme jako selektor.

$(this).addClass("active");

Změna třídy položky nám již funguje a nyní musíme vkládat 2. úroveň menu do naší #subnav. Zde využijeme funkce .html(), které předáme klon 2. úrovně menu.

$("#subnav").html( $(this).find("ul").clone(true) );

Nyní ještě nemáme viditelný výsledek. Musíme #submenu zobrazit a kliknout na první položku menu. Vytvoříme si tedy pomocnou funkci init(), kterou budeme volat nakonci kódu.

var init = function(){
    $("nav > ul > li:nth-of-type(1)").click();
    $("#subnav").css('display', 'block');
}

Nyní již vidíme menu tak jak máme.

Interaktivní menu v jQuery

Skrytí/zobrazení menu

Nyní chceme po každém pohybu kolečkem myši skrýt či zobrazit menu. V CSS kódu máme #subnav.active, což nám skryje menu (nastaví top: 0;).

Nejdříve potřebujeme nabindovat při pohybu kolečkem nějakou funkci, kterou si pojmenujeme třeba kolecko().

$("body").bind("mousewheel DOMMouseScroll", kolecko);

Ve funkci kolecko() bude následně kód, který zjistí jakým směrem jsme se posunuli a skryje/zobrazí menu.

var kolecko = function(e){
   e = e.originalEvent;
   var delta = e.wheelDelta>0||e.detail<0?1:-1;
   $("#subnav").toggleClass('active', delta === 1, 250);
}

První 2 řádky kódu nám zjistí jakým směrem jsme se pohnuli. Kód jsem našel někde na internetu a měl by fungovat v každém prohlížeči. Delta 1 je nahoru, -1 je dolů.

Poslední řádek je podmíněná změna třídy, která nám mění pozici menu díky změně třídy.

Můžete si vyzkoušet, že se nám opravdu menu skrývá a zobrazuje s poměrně hezkým efektem.

Na začátek stránky

Nyní si uděláme efekt, kdy nám po kliknutí na menu (pouze na první úroveň) vyjede stránka úplně nahoru.

Vytvořme si funkci vyjedNahoru(), kam vložíme animaci pro pohyb stránky a také hezký efekt, který nám skryje menu. Stránka se přesune a menu nám zase zobrazí.

var vyjedNahoru = function(){
   $("html, body").stop().animate(
      { scrollTop: 0 },
      1000, "easeInOutExpo"
   );

   $("#subnav").stop(true, true).removeClass('active', 400).delay(600).addClass("active", 300);
   }

Dobře, ale kde zavoláme tuto funkci? No přeci po kliku na #menu.

$("#menu").on("click", function(){
   vyjedNahoru();
});

No, efekt nám funguje, avšak provede se kdykoli klikneme na #menu. To je docela nepříjemné. Ve skutečnosti se právě naším klikem klikne na všechny elementy, které se nacházejí pod kurzorem. Tedy pokud klikneme na položku, tak klikneme na a, li, ul a na nav až na naše #menu, kde provede efekt.

Ukažme si jak se tomu dá zabránit. Použijeme e.stopPropaga­tion();, který nám zastaví propagaci, tedy nám zakáže jakékoli jiné situace kliku krom té, které jsou přímo na daný element. Tento kód aplikujeme na #menu li a #subnav.

$("#menu li, #subnav").on("click", function(e){
   e.stopPropagation();
});

Klávesové zkratky

Přidáme také pár klávesových zkratek, abychom mohli menu ovládat i z klávesnice.

Na to použijeme tuto jednoduchou funkci.

$(document).keydown(function(e) {

   switch(e.which || e.keyCode)
   {
       ... kód ...
   }
});

Po stisku klávesy X by se nám menu mělo zavřít nebo otevřít a po stistu klávesy T by mělo vyjet nahoru. Klávesa X má číslo 88 a T má číslo 84. Upravme náš switch:

case 88:
   $("#subnav").stop(true,true).toggleClass('active', 250);
break;
case 84:
   vyjedNahoru();
break;

Na závěr ještě zamezíme vypisování odkazu do url pomocí e.preventDefau­lt(), který použijeme na #menu li, #subnav li.

$("#menu li, #subnav li").on("click", function(e){
   e.preventDefault();
});

Menu máme hotové :)


 

Stáhnout

Staženo 785x (101.82 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 (13 hlasů) :
55555


 


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

 

 

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

Avatar
freearea
Člen
Avatar
freearea:

V jednoduchosti je síla !

 
Odpovědět  +1 8.2.2015 20:41
Avatar
Ondřej Langr (andysekcze):

Čau,
prosím tě pošleš mi to trochu upraveny?
Chci jen aby to místo kolečka reagovalo na přejetí myši ;)
Předem díky

Odpovědět  -6 18.5.2015 19:35
I have a charger. I have Note 7. Umh I haven't Note7.
Avatar
Odpovídá na Ondřej Langr (andysekcze)
Josef Kuchař (Pepa489):

Tady ti to nikdo dělat nebude! Nauč se programovat ;) !

Odpovědět  +4 18.5.2015 19:44
2x piš, jednou debuguj
Avatar
Odpovídá na Josef Kuchař (Pepa489)
Ondřej Langr (andysekcze):

No tak když ti JS nejde, tak se ho na pohodu naučíš že?

Odpovědět  -1 18.5.2015 19:53
I have a charger. I have Note 7. Umh I haven't Note7.
Avatar
Odpovědět  +2 18.5.2015 19:58
Nesnáším {}, proto se jim vyhýbám.
Avatar
tomasmanhal
Člen
Avatar
Odpovídá na Ondřej Langr (andysekcze)
tomasmanhal:

Proč chceš implementovat něco co ti nejde, nebo tomu nerozumíš?...To postrádá logiku...zvláště u webů...

Odpovědět 18.5.2015 19:59
Kdyby nám dodali k životu zdrojový kód, vše by bylo jednodušší...
Avatar
Odpovídá na tomasmanhal
Ondřej Langr (andysekcze):

Protože prostě nevím jak to udělat? to z fora mi nejde... (verze pomocí css)

Odpovědět 18.5.2015 20:10
I have a charger. I have Note 7. Umh I haven't Note7.
Avatar
tomasmanhal
Člen
Avatar
Odpovídá na Ondřej Langr (andysekcze)
tomasmanhal:

A co budeš dělat pokud se něco posere třeba za měsíc a nebudeš si to umět sám nebo u klienta fixnout? :-) Máme Tě čekat zde na fóru s žádostí o předělání? :-D

Odpovědět  +3 18.5.2015 20:14
Kdyby nám dodali k životu zdrojový kód, vše by bylo jednodušší...
Avatar
Richard
Člen
Avatar
Richard:

Hezký, jen se zeptám, proč to skrývání/odkrývání není postavené tak aby to reagovalo i na posun posuvníkem? Já většinou "scrolluju" přes posuvník a divil jsem se že mi to nefunguje :D

Odpovědět  +3 18.5.2015 20:18
$action = $_GET['Life']; | Když dáš mínus, napiš proč!
Avatar
Honza Bittner
Redaktor
Avatar
Odpovídá na Richard
Honza Bittner:

Je to tam nabindované jen na 'mousewheel DOMMouseScroll' a upřímně mě nějak nenapadlo zkoušet scrolovat posuvníkem. :)

Pak tam někdy, až budu mít čas, snad doplním i událost na posuv posuvníkem. :)

Odpovědět  +1 19.5.2015 18:29
Ptejte se mě na cokoli na https://github.com/HoBi/ama a followujte mě na Twitteru https://twitter.com/tenhobi. :-)
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 11. Zobrazit vše