Dynamická menu v DHTML – vysunovací menu

11. února 2002

Tentokrát se podíváme na to, jak vytvořit menu, které se objeví při přejetí myší nad nabídkou. Opět bude funkční ve všech dnes nejpoužívanějších prohlížečích.

Jako minule, i dnes začneme příkladem.

HTML kód tvořící menu

Vycházet budu z principů, které jsem popsal v druhém a třetím díle. HTML kód bude téměř stejný, až na to, že tentokrát budete potřebovat zachytit události onMouseOver a onMouseOut (odlišnosti od kódu minulého menu jsou zvýrazněny):

<div id=“menuHolder“>
<div id=“visibleMenu1″ onmouseover=“showMenu(1);“ onmouseout=“hideMenu(1);“><div class=“menuItem“>Portály<script type=“text/javascript“>function onMouseOver() {showMenu(1);} function onMouseOut() {hideMenu(1);}</script><span class=“cssSupport“><br></span></div></div>
<div id=“hiddenMenu1″ onmouseover=“dontHideMenu();“ onmouseout=“hideMenu(1);“><div class=“menuItem“><a href=“http://atlas.cz“ class=“menuLink“>Atlas</a><br><a href=“http://centrum.cz“ class=“menuLink“>Centrum</a><br><a href=“http://seznam.cz“ class=“menuLink“>Seznam</a><script type=“text/javascript“>function onMouseOver() {dontHideMenu();} function onMouseOut() {hideMenu(1);}</script><span class=“cssSupport“><br></span></div></div>
<div id=“visibleMenu2″ onmouseover=“showMenu(2);“ onmouseout=“hideMenu(2);“><div class=“menuItem“>Zpravodajství<script type=“text/javascript“>function onMouseOver() {showMenu(2);} function onMouseOut() {hideMenu(2);}</script><span class=“cssSupport“><br></span></div></div>
<div id=“hiddenMenu2″ onmouseover=“dontHideMenu();“ onmouseout=“hideMenu(2);“><div class=“menuItem“><a href=“http://cnn.com“ class=“menuLink“>CNN</a><br><a href=“http://ceskenoviny.cz“ class=“menuLink“>České Noviny</a><br><a href=“http://idnes.cz“ class=“menuLink“>iDNES</a><br><a href=“http://www.lidovky.cz“ class=“menuLink“>Lidovky</a><script type=“text/javascript“>function onMouseOver() {dontHideMenu();} function onMouseOut() {hideMenu(2);}</script><span class=“cssSupport“><br></span></div></div>
<div id=“visibleMenu3″ onmouseover=“showMenu(3);“ onmouseout=“hideMenu(3);“><div class=“menuItem“>Zábava<script type=“text/javascript“>function onMouseOver() {showMenu(3);} function onMouseOut() {hideMenu(3);}</script><span class=“cssSupport“><br></span></div></div>
<div id=“hiddenMenu3″ onmouseover=“dontHideMenu();“ onmouseout=“hideMenu(3);“><div class=“menuItem“><a href=“http://www.techno.cz“ class=“menuLink“>Czech Techno</a><br><a href=“http://flashfun.cz“ class=“menuLink“>FlashFun</a><br><a href=“http://www.kompost.cz“ class=“menuLink“>Kompost</a><br><a href=“http://novinky.cz“ class=“menuLink“>Novinky</a><script type=“text/javascript“>function onMouseOver() {dontHideMenu();} function onMouseOut() {hideMenu(3);}</script><span class=“cssSupport“><br></span></div></div>
</div>

Tím, které konkrétní funkce jsou z ovladačů událostí volány, se zatím nebudeme zabývat. Všimněte si ale na první pohled zvláštního bloku kódu mezi tagy <script> a </script>, který se nachází uvnitř jednotlivých tagů DIV a kde definujete funkce onMouseOver() a onMouseOut(). Jak už možná někteří z vás tuší, je to další manýr NS4. Ten umí používat výše zmíněné události u layeru jen tehdy, jsou-li zapsány tímto způsobem.

Jedeme dál…

Dále postupujete stejně, jako u minulého menu (viz zdrojový kód dnešního příkladu). Kosmetická odlišnost přichází v definici vizuálních stylů, když místo hodnoty hand vlastnosti cursor u visibleMenu1, 2, 3 nastavíte default. Nechcete tedy, aby se vám při přejetí myší nad nabídkou ukazoval kurzor pro výběr textu. Zásadní odlišnost přichází u JavaScriptových funkcí pro vytvoření a rozhýbání menu, kterému se nyní budu věnovat.

Vytvoření menu a jeho rozhýbání

Nejdříve popíši funkci menu(), která je volána ihned za HTML kódem menu – jejím úkolem je menu upravit podle uživatelem používaného prohlížeče a nakonec vše zviditelnit. V dnešním příkladě bude její syntaxe opravdu jednoduchá:

function menu()
{
  if (dhtml)
  {
    if (opera) for (i = 1; i <= 3; i++) document.getElementById(‚hiddenMenu‘ + i).style.top = 20;
    if (ie4) for (i = 1; i <= 3; i++) document.all[‚hiddenMenu‘ + i].style.top = 18;
    setVisibility(‚menuHolder‘,’visible‘);
  }
}

Vzhledem k tomu, že jsme nemuseli používat metodu captureEvents pro zachycení událostí v NS4, se nám celý kód zkrátil jenom na posunutí hiddenMenu1, 2, 3 o 1, respektive 3 pixely nahoru (kvůli chybné interpretaci CSS v Opeře, respektive v IE4). Funkce setVisibility() pro zviditelnění libovolného prvku je totožná s funkcí setVisibility() z minulého menu.

Nyní se již dostáváme k rozhýbání menu. Nejprve si celý problém rozebereme:

  1. Příslušné menu se musí objevit, když uživatel přejede myší nad horní nabídkou. Proto přiřadíte události onmouseover horních nabídek funkci showMenu(). Jako parametr předáváte číslo menu, které se má objevit.
  2. V momentě, kdy uživatel odjede kurzorem myši z horní nabídky, musí se příslušné menu schovat. Proto přiřadíte události onmouseout horních nabídek funkci hideMenu(), které jako parametr předáváte číslo menu, které se má schovat.
  3. Kdybyste teď skončili, nemohl by si uživatel z menu nic vybrat – v momentě, kdy myš opustí horní nabídku, se menu prostě schová. Proto musíte ve funkci hideMenu() nastavit časovač (timeout), který nabídku schová až po uplynutí určité časové doby. Samotnému menu přiřaďte funkci dontHideMenu() události onmouseover. Tato funkce zastaví časovač a nabídka zůstane viditelná.
  4. Menu je třeba schovat, když uživatel odjede kurzorem jinam. Proto přiřaďte události onmouseout jednotlivých menu opět funkci hideMenu(). Jako parametr budete předávat číslo menu, které chcete schovat.
  5. V této souvislosti musíte počítat ještě s jednou situací – když uživatel přejede kurzorem z menu nad horní nabídku, která patří k právě viditelnému menu. Zde tato situace nastan, když přejedete z položky „Atlas“ nad nabídku „Portály“. V takovém případě nevypadá příliš dobře, když se nabídka na malou chvíli schová a pak hned zase ukáže. Proto použijte u funkce hideMenu() opět časovač, který nabídku schová až po určité době. Tento časovač nulujete v momentě, kdy uživatel najede kurzorem nad horní nabídku (nulování se provede ve funkci showMenu()).

V praxi jsem těchto pět pouček zrealizoval přiřazením odpovídajících funkcí příslušným událostem v HTML kódu (viz výše) a těmito JavaScriptovými funkcemi:

var timer, i, menuId; // několik proměnných, se kterými budete pracovat
function showMenu(id)
{
  if (dhtml) // opět podmiňujete běh menu proměnnou dhtml
  {
    clearTimeout(timer); // viz [5]
    for (i = 1; i <= 3; i++) if (i != id) setVisibility((ns4 ? ‚menuHolder.document.‘ : “) + ‚hiddenMenu‘ + i,’hidden‘); // nejdříve všechna menu zneviditelníte (kromě jednoho, viz [5])
    setVisibility((ns4 ? ‚menuHolder.document.‘ : “) + ‚hiddenMenu‘ + id,’visible‘); // viz [1]
  }
}
function hideMenu(id)
{
  if (dhtml)
  {
    menuId = (ns4 ? ‚menuHolder.document.‘ : “) + ‚hiddenMenu‘ + id;
    timer = setTimeout(„setVisibility(menuId,’hidden‘)“,50); // viz [2], [3]
  }
}
function dontHideMenu() // viz [3]
{
  if (dhtml) clearTimeout(timer);
}

Dnešní menu bylo úspěšně testováno v IE 4+, NS 4+, Opeře 4+ a Mozille. NS4 a Opera 4 špatně interpretují CSS, a proto v nich nemůže nabídka vypadat stejně, jako v ostaních prohlížečích. Funkčnost je ale i v těchto prohlížečích stejná. Jisté omezení se vyskytuje v případě IE 5+. Pokud z nabídky nenajedete přímo na odkaz v menu, tak se nabídka ztratí. Je to zapříčiněno obsahem pod menu (v našem příkladě je to text „další obsah stránky“), který chce IE 5+ nesmyslně označovat do bloku a kvůli tomu nabídku skryje. Na řešení tohoto problému jsem nemohl přijít – pokud budete úspěšnější, budu rád, když se zmíníte v diskusi pod článkem.

Stejně tak pokud používáte nějaký prohlížeč nebo platformu, na které menu nebylo testováno, budu rád, pokud se o své zkušenosti podělíte v diskusi pod článkem – ta je otevřena i vašim námětům, rozšířením menu, a vůbec čemukoliv co se této problematiky týká.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *