Tvoríme zaujímavé interaktívne menu v JavaScripte
V predchádzajúcom kvíze, Kvíz - Dedičnosť, polymorfizmus a vlastnosti v JavaScripte, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V tomto dvojdielnom tutoriále si skúsime naprogramovať interaktívne menu v JavaScripte. Naše menu bude okrúhle a vysúvacie. Položky vyskočí po okraji. Pri programovaní sa bude držať základu, že nebude nijako zasahovať do HTML návrhu menu. Naše menu v HTML bude veľmi jednoducho zoznam s položkami.
Ako ukážku si urobíme menu s troma položkami pritom interaktívne budú len dve. Štruktúra menu by mohla byť nasledujúce.
- web HTML
CSS
JS
PHP
SQL
ASP.NET
- HTML
- CSS
- JS
- PHP
- SQL
- ASP.NET
- Programovanie C#
Java
VB
telefóny
C ++
- C#
- Java
- VB
- telefóny
- C ++
- Fórum
HTML nášho menu by mohlo vyzerať nasledovne.
<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šimnite si, že som menu pridal Attribut data-radial-menu. HTML5 nám povoľuje definovať vlastné ľubovoľný Attribut, len musí začínať data- *. Pomocou tohto budeme označovať všetky menu, ktoré následne v JavaScripte zinteraktivníme. Do projektu si pridajte súbor JavaScriptu, ktorý si v HTML importujte. V JavaScriptu si definujeme Objekt RadialMenu, ktorý v konstruktoru bude prijímať jeden parameter - element. V tomto elementu budeme očakávať element nav, v ktorom je ďalej zakomponované menu.
function RadialMenu(element) { }
Po načítaní stránky (v obsluhe udalosti window.onload) získame zoznam všetkých elementov li, ktoré sú v ul a nav, ktorý má nastavený atribút data-radial-menu. Toto vykonáme pomocou metódy querySelectorAll na document. Táto metóda prijíma ako prvý parameter textový reťazec s CSS selektorom a vráti pole elementov, ktoré týmto pravidlám vyhovujú. CSS selektor pre výber všetkých elementov, ktoré majú nastavený atribút data-radial-menu bude postavený jednoducho z pravidla nav a do hranatých zátvoriek dáme ten atribút ďalej pomocou porovnávacej zátvorky (väčšie ako) odkážeme na ul a li.
nav[data-radial-menu] > ul > li
Teraz vytvoríme nové inštancie nášho objektu RadialMenu pre každý element nav s atribútom data-radial-menu. Všetky inštancie si dáme do poľa, nech s nimi môžeme lepšie pracovať.
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])) } }
Teraz sa vráťme do konstruktoru a definujeme si niekoľko premenných, s ktorými budeme pracovať:
var self = this this.element = element this.size; this.name = ""; this.children = new Array();
Hneď na začiatku máme self, do ktorého si ukladáme this. Je to preto, že JavaScript si občas zmení this a my sa potrebujeme dostať k našej inštanciu (aj keď sme potrebné poskočili vyššie). Element je jasný, tam si ho uložíme. Veľkosť neskôr dosadíme. Meno sa vždy hodia a potomkovia, tam dáme podpoložky.
Aby náš script podporoval rôzne veľkosti, pridáme všetkým hlavným li (tým, ktoré sme získali pomocou querySelector) Attribut data-size. Veľkosť submenu si script zistí sám a to tak, že to bude presne 25% z predka. V konstruktoru si jednoducho získame hodnotu z Attribut data-size. Ak existuje, nastavíme ju výške i šírke elementu. Šírku by sme celkom v bez problému nastaviť aj s pomocou CSS, ale výšku nie, pretože nikdy nevieme, aký pomer strán bude okno prehliadača mať. CSS vlastnosti v JavaScriptu ovplyvňujeme tak, že si vezmeme onen element, ktorý má v objekte style všetky CSS vlastnosti. Lepšie 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"; }
Teraz si prejdeme všetky potomkami nášho elementu. Potomkovia sú uložení v každom elementu vo vlastnosti childNodes, ktorá je poľom. Položky polia sú potom ďalšie elementy.
for (var i = 0; i < this.element.childNodes.length; i++) {
Switchom rozoberieme aký názov (nodename) má náš potomok (ten, ktorý prechádzame cyklom). Celkom nás tam môžu stretnúť dvaja - span a ul. Span je názov menu a ul je submenu. Ak narazíme na span iba jednoducho dosadíme name na hodnotu textContent tohto elementu.
switch (this.element.childNodes[i].nodeName) { case "SPAN": this.name = this.element.childNodes[i].textContent; break; }
U ul to bude trochu zložitejšie. V ul si budeme musieť zohnať zoznam chcete a tie spracovať ďalej. Z každého Ak urobíme nový objekt RadialMenu a ten pridáme do poľa children, kam dávame 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 nastaviť veľkosti. Na to si vytvoríme metódu SetSizes, metódu vytvoríme v prototype za definíciou objektu.
RadialMenu.prototype.SetSizes = function () {
V tejto metóde si prejdeme všetky submenu a ak nemajú definovaný Attribut data-size, nastavíme 25% veľkosti z predka. 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"; } }
Metódu zavolajte po načítaní submenu.
CSS nevie nijako dosadzovať pozície okolo niečoho okrúhleho, tak si to musíme obslúžiť sami. Vytvorte na prototype objektu metódu SetPositions. Opäť budeme prehádzať všetky submenu a každej umiestňovať. Začneme tým, že si ujasníme, koľko stupňov bude medzi každou položkou, to jednoducho spočítame pomocou 360 ° / početSubmenu. Ďalej si zistíme, na akých stupňoch bude položka menu otočená jednoducho pomocou i * stupnemezipolozkami.
Script je len čiastočne hotový, nabudúce (v pokračovanie) si napíšeme funkciu setSizes, ktorá podpoložky umiestni okolo kruhu a ako podpoložky skrývať a zobrazovať.
V nasledujúcom cvičení, Riešené úlohy k 20.-22. lekciu OOP v JavaScripte, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 809x (219.47 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript