1. díl - Tvoříme zajímavé interaktivní menu v JavaScriptu

JavaScript Objektově orientované programování Tvoříme zajímavé interaktivní menu v JavaScriptu

V tomto dvojdílném tutoriálu si zkusíme naprogramovat interaktivní menu v JavaScriptu. Naše menu bude kulaté a vysouvací. Položky vyskočí po okraji. Při programování se bude držet základu, že nebude nijak zasahovat do HTML návrhu menu. Naše menu v HTML bude velmi jednoduše seznam s položkami.

Goniometrické funkce

Jako ukázku si uděláme menu s třemi položkami, přitom interaktivní budou jen dvě. Struktura menu by mohla být následující.

  • Web
    • HTML
    • CSS
    • JS
    • PHP
    • SQL
    • ASP.NET
  • Programování
    • C#
    • Java
    • VB
    • Telefony
    • C++
  • Fórum

HTML našeho menu by mohlo vypadat následovně.

<nav data-radial-menu>
        <ul>
                <li>
                        <span><img src="images/web.png" alt="Web"/><br />Web</span>
                        <ul>
                                <li><span><a href="#html"><img src="images/html.png" alt="html" /><br />HTML</a></span></li>
                                <li><span><a href="#css"><img src="images/css.png" alt="css" /><br />CSS</a></span></li>
                                <li><span><a href="#js"><img src="images/js.png" alt="js" /><br />JavaScript</a></span></li>
                                <li><span><a href="#php"><img src="images/php.png" alt="php" /><br />PHP</a></span></li>
                                <li><span><a href="#sql"><img src="images/sql.png" alt="sql" /><br />SQL</a></span></li>
                                <li><span><a href="#asp"><img src="images/asp.png" alt="asp" /><br />ASP.NET</a></span></li>
                        </ul>
                </li>
                <li>
                        <span><img src="images/programing.png" alt="Programvání"/><br />Programování</span>
                        <ul>
                                <li><span><a href="#csharp"><img src="images/csharp.png" alt="C#" /><br />C#</a></span></li>
                                <li><span><a href="#java"><img src="images/java.png" alt="Java" /><br />Java</a></span></li>
                                <li><span><a href="#vb"><img src="images/vb.png" alt="Visual Basic" /><br />VB</a></span></li>
                                <li><span><a href="#phones"><img src="images/phones.png" alt="Mobily" /><br />Mobily</a></span></li>
                                <li><span><a href="#cpp"><img src="images/cpp.png" alt="C++" /><br />C++</a></span></li>
                        </ul>
                </li>
                <li>
                        <span><a href="#forum"><img src="images/forum.png" alt="Fórum" /><br />Fórum</a></span>
                </li>
        </ul>
</nav>

Všimněte si, že jsem menu přidal attribut data-radial-menu. HTML5 nám povoluje definovat vlastní libovolný attribut, jen musí začínat data-*. Pomocí tohoto budeme označovat všechna menu, které následně v JavaScriptu zinteraktivníme. Do projektu si přidejte soubor JavaScriptu, který si v HTML naimportujte. V JavaScriptu si definujeme Objekt RadialMenu, který v konstruktoru bude přijímat jeden parametr – element. V tomto elementu budeme očekávat element nav, ve kterém je dále zakomponováno menu.

function RadialMenu(element) {

}

Po načtení stránky (v obsluze události window.onload) získáme seznam všech elementů li, které jsou v ul a nav, který má nastavený atribut data-radial-menu. Toto provedeme pomocí metody querySelectorAll na document. Tato metoda přijímá jako první parametr textový řetězec s CSS selektorem a vrátí pole elementů, které těmto pravidlům vyhovují. CSS selektor pro výběr všech elementů, které mají nastavený atribut data-radial-menu bude postavený jednoduše z pravidla nav a do hranatých závorek dáme ten atribut dále pomocí porovnávací závorky (větší než) odkážeme na ul a li.

nav[data-radial-menu] > ul > li

Nyní vytvoříme nové instance našeho objektu RadialMenu pro každý element nav s atributem data-radial-menu. Všechny instance si dáme do pole, ať s nimi můžeme lépe pracovat.

var menuItems = new Array();

window.onload = function () {
        var navs = document.querySelectorAll("nav[data-radial-menu] > ul > li");
        for (var i = 0; i < navs.length; i++) {
                menuItems.push(new RadialMenu(navs[i]))
        }
}

Nyní se vraťme do konstruktoru a definujeme si několik proměnných, se kterými budeme pracovat:

var self = this
this.element = element
this.size;
this.name = "";
this.children = new Array();

Hned na začátku máme self, do kterého si ukládáme this. Je to proto, že JavaScript si občas změní this a my se potřebujeme dostat k naší instanci (i když jsme třeba poskočili výš). Element je jasný, tam si ho uložíme. Velikost později dosadíme. Jméno se vždy hodí a potomci, tam dáme podpoložky.

Aby náš script podporoval různé velikosti, přidáme všem hlavním li (těm, které jsme získali pomocí querySelector) attribut data-size. Velikost submenu si script zjistí sám a to tak, že to bude přesně 25% z předka. V konstruktoru si jednoduše získáme hodnotu z attributu data-size. Pokud existuje, nastavíme ji výšce i šířce elementu. Šířku bychom celkem v bez problému nastavili i s pomocí CSS, ale výšku ne, protože nikdy nevíme, jaký poměr stran bude okno prohlížeče mít. CSS vlastnosti v JavaScriptu ovlivňujeme tak, že si vezmeme onen element, který má v objektu style všechny CSS vlastnosti. Lepší IDE vám s tím pomůže.

var datasize = this.element.getAttribute("data-size")
if (datasize != null) {
        this.size = parseInt(this.element.getAttribute("data-size"))
        this.element.style.width =  this.size + "px";
        this.element.style.height = this.size + "px";
}

Nyní si projdeme všechny potomky našeho elementu. Potomci jsou uloženi v každém elementu ve vlastnosti childNodes, která je polem. Položky pole jsou pak další elementy.

for (var i = 0; i < this.element.childNodes.length; i++) {

Switchem rozebereme jaký název (nodeName) má náš potomek (ten, který procházíme cyklem). Celkem nás tam mohou potkat dva – span a ul. Span je název menu a ul je submenu. Pokud narazíme na span pouze jednoduše dosadíme name na hodnotu textContent tohoto elementu.

switch (this.element.childNodes[i].nodeName) {
        case "SPAN":
                this.name = this.element.childNodes[i].textContent;
                break;
}

U ul to bude trochu složitější. V ul si budeme muset sehnat seznam li a ty zpracovat dále. Z každého li uděláme nový objekt RadialMenu a ten přidáme do pole children, kam dáváme submenu.

for (var u = 0; u < this.element.childNodes[i].childNodes.length; u++) {
        if (this.element.childNodes[i].childNodes[u].nodeName == "LI") {
                var menu = new RadialMenu(this.element.childNodes[i].childNodes[u])
                this.children.push(menu)
        }
}

Podpoložkám musíme nastavit velikosti. Na to si vytvoříme metodu SetSizes, metodu vytvoříme v prototypu za definicí objektu.

RadialMenu.prototype.SetSizes = function () {

V této metodě si projdeme všechny submenu a pokud nemají definovaný attribut data-size, nastavíme 25% velikosti z předka. Toto dosadíme do submenu.

RadialMenu.prototype.SetSizes = function () {
        for (var i = 0; i < this.children.length; i++) {
                var menu = this.children[i]

                var datasize = menu.element.getAttribute("data-size")
                if (datasize != null) {
                        menu.size = menu.element.getAttribute("data-size");
                } else {
                        menu.size = this.size * 0.25
                }
                menu.element.style.width = menu.size + "px";
                menu.element.style.height = menu.size + "px";
        }
}

Metodu zavolejte po načtení submenu.

CSS neumí nijak dosazovat pozice kolem něčeho kulatého, tak si to musíme obsloužit sami. Vytvořte na prototypu objektu metodu SetPositions. Opět budeme proházet všechny submenu a každé umisťovat. Začneme tím, že si ujasníme, kolik stupňů bude mezi každou položkou, to jednoduše spočteme pomocí 360°/ početSubmenu. Dále si zjistíme, na jakých stupních bude položka menu otočena jednoduše pomocí i * stupnemezipoloz­kami.

Script je jen částečně hotový, příště (v pokračování) si napíšeme funkci setSizes, která podpoložky umístí kolem kruhu a jak podpoložky skrývat a zobrazovat.


 

Stáhnout

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

 

  Aktivity (1)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Celkem (7 hlasů) :
4.285714.285714.285714.28571 4.28571


 



 

 

Komentáře

Avatar
 
Odpovědět 19.3.2014 15:39
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 1 zpráv z 1.