Rozwijane menu to dobry pomysł na uatrakcyjnienie stron WWW. Wykonamy je za pomocą JavaScriptu, poznając działanie pętli for i kilku innych funkcji języka.
Na początku zaprojektujemy strukturę HTML (patrz kod i rysunek poniżej):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"pl-PL\">
<head>
<title>Strona z menu</title>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\" />
<!-- Nasz kod Javascript: -->
<script type=\"text/javascript\">
</script>
</head>
<body>
<div style=\"width: 60px;\">
<ul>
<li id=\"main\">
<a href=\"#\"><strong>Kategorie</strong></a>
<ul id=\"menu\">
<li><a href=\"#\">sport</a></li>
<li><a href=\"#\">życie</a></li>
<li><a href=\"#\">gry</a></li>
</ul>
</li>
</ul>
</div>
</body>
</html>
|
Stworzyliśmy prostą listę nieuporządkowaną otoczoną divem oraz nadaliśmy dwa identyfikatory o nazwach: menu i main.
Po naprowadzeniu wskaźnika myszy na Kategorie rozwinie się lista podkategorii: sport, życie i gry, po cofnięciu wskaźnika myszy lista powinna się schować. (Z poprzednich artykułów wiemy, że rozwinięcie listy to {stala}style.display = „block”;{/stala}, a schowanie – {stala}style.display = „none”;{/stala}.)
Style CSS
Domyślnie lista z kategoriami musi być schowana. Mamy więc dwie opcje do wyboru: albo ukryć cały {html}
- {/html}, albo jego poszczególne elementy {html}
- {/html}. Wybierzemy drugi sposób i dodamy potrzebne style.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<style type=\"text/css\"> ul { margin: 0; padding: 0; } li { margin: 0; padding: 0; list-style-type: none; } #menu li { display: none; } </style>
Nasz dokument przybrał postać (patrz kod poniżej i rysunek obok):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"pl-PL\"> <head> <title>Strona z menu</title> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\" /> <style type=\"text/css\"> ul { margin: 0; padding: 0; } li { margin: 0; padding: 0; list-style-type: none; } #menu li { display: none; } </style> <!-- Nasz kod Javascript: --> <script type=\"text/javascript\"> </script> </head> <body> <div style=\"width: 60px;\"> <ul> <li id=\"main\"><a href=\"#\"><strong>Kategorie</strong></a> <ul id=\"menu\"> <li><a href=\"#\">sport</a></li> <li><a href=\"#\">zycie</a></li> <li><a href=\"#\">gry</a></li> </ul> </li> </ul> </div> </body> </html>Szkielet skryptu
Pozostaje dać znać{html}
- {/html}. Jak wiadomo, są one dziećmi {html}
- {/html}. JavaScript umożliwia nam dostanie się do elementów rodzica. Odpowiada za to funkcja {stala}odnosnik_do_rodzica.getElementsByTag-Name{/stala}.
- {/html} będzie miał właściwość {stala}onmoueover{/stala} i {stala}onmouseout{/stala}, czyli po naprowadzeniu wskaźnika myszy na Kategorie menu się rozwinie, a po jego zwolnieniu – zwinie.
1 2 3 4 5 6
function Laduj() { var li=document.getElementById(\'main\'); li.onmouseover=Pokaz; li.onmouseout=Ukryj; }
Za pomocą {stala}document.getElementById{/stala} pobraliśmy odnośnik do tagu {html}
- {/html} o {stala}id=”main”{/stala}. Następnie daliśmy mu znać, że po naprowadzeniu wskaźnika myszy ma się wykonać funkcja {stala}Pokaz{/stala}, a po jego zwolnieniu funkcja {stala}Ukryj{/stala}. Obie funkcje wywoływane będą bez argumentów. Ponieważ w szkielecie skryptu napisaliśmy {stala}window.onload=Laduj;{/stala}, po załadowaniu okienka wykona się od razu ta funkcja. Nadal jednak nic się nie dzieje, ponieważ pozostałe funkcje są puste.
Za pomocą stylów CSS ustawiliśmy, by każdy pojedynczy element listy ({html}
- {/html}) był ukryty. Aby pokazać całe menu, musimy nadać każdemu pojedynczemu {html}
- {/html} {stala}display{/stala} równe {stala}block{/stala}. Można przypisać każdemu elementowi identyfikator i odwoływać się doń poprzez {stala}document.getElementById{/stala}. Byłoby to jednak zbyt uciążliwe, tym bardziej że pozycje w menu mogą się zmieniać. Musimy więc dostać się do poszczególnych elementów bez względu na identyfikatory.
{stala}for() { }{/stala}
Konstrukcja for przyjmuje trzy argumenty, które, wyjątkowo tutaj, oddzielamy średnikami.{stala}.length{/stala}
Pozwala dostać się do liczby elementów, które zostały odnalezione i przypisane do zmiennej elements. Jeśli zmienna przechowuje wiele wartości, to taką zmienną nazywamy tablicą.Pętla for
Pewne rzeczy w programowaniu można wykonywać automatycznie kilka razy. Na przykład odliczanie do trzech:
1 2 3
alert(\'1\'); alert(\'2\'); alert(\'3\');
Taki zapis odliczania nie jest najlepszym rozwiązaniem. Odliczyliśmy, co prawda, do 3 za pomocą okienek {html}alert(){/html}, ale zapisaliśmy to wszystko ręcznie. Nie ma tu miejsca na działanie komputera, który powinien wykonać te odliczanie sam i podstawiać konkretne liczby do funkcji alert.
Z pomocą przychodzi konstrukcja {stala}for() { }{/stala}, która dzięki wpisaniu odpowiednich argumentów (oczywiście pomiędzy nawiasami) sprawia, że kod w klamrach wykonuje się dopóki warunki jego działania zawarte w argumentach będą prawdziwe. Przyjrzyjmy się temu na konkretnym przykładzie:
1 2 3 4
for (var i = 0; i < 3 ; i++) { alert(i); }
Taki kod wykonuje odliczanie od 0 do 2, wykorzystując do tego funkcję {html}alert(){/html} i wyświetlając kolejne liczby tego ciągu w okienku. Słownie przeczytać możemy to w ten sposób:
Poczynając od wartości zmiennej o nazwie i równej 0, dopóki wartość tej zmiennej jest mniejsza od 3, powiększamy ją o 1 i za każdym jej powiększeniem wykonujemy kod w klamrach.
Przyjrzyjmy się teraz poszczególnym elementom tej konstrukcji:
- {stala}var i = 0;{/stala} – definiuje wartość wyjściową, jaką jest zmienna i. Od jej wartości zaczynamy odliczanie.
- {stala}i < 3;{/stala} – ustala warunek wykonywania konstrukcji for. Jeśli warunek nie będzie spełniony, pętla nie wykona się. W tym przypadku konstrukcja odmówi współpracy, kiedy zmienna i będzie równa 3 – wtedy pętla skończy swoje działanie. {stala}”<”{/stala} jest w tym przypadku operatorem logicznym. Równie dobrze moglibyśmy wstawić w naszych przykładach inne operatory:
- {stala}i > 3;{/stala} – większe od 3,
- {stala}i >= 3;{/stala} – większe lub równe 3,
- {stala}i <= 3;{/stala} – mniejsze lub równe 3.
- {stala} i++{/stala} – zwiększa wartość zmiennej o nazwie i o 1. O zwiększeniu świadczą dwa plusy – ++. Przykład obrazujący działanie tej konstrukcji:
1 2 3
var liczba = 2; liczba++; alert(liczba);
Definiujemy zmienną liczba – nadajemy jej wartość 2. Następnie zwiększamy ją o jeden (liczba++), by wyświetlić jej wartość w alert (trzecia linijka). Ukaże się cyfra 3.
Oczywiście pętla {stala}for{/stala} nie odlicza tylko do przodu. Można również odliczać od końca:
1 2 3 4
for (var i = 5; i > 2; i--) { alert(i); }
Poczynając od wartości zmiennej o nazwie i równej 5, dopóki wartość tej zmiennej jest większa od 2, zmniejszamy ją o 1 i za każdym jej zmniejszeniem wykonujemy kod w klamrach. W tym przypadku wywołujemy funkcję {html}alert();{/html}.
Dwa minusy zmniejszają zmienną o jeden. Na przykład:
1 2 3
var liczba = 2; liczba--; alert(liczba);
wyświetli 1, bowiem zmniejszyliśmy zmienną liczba o jeden ({stala}liczba–{/stala}).
Pętla for i elementy listy
Pętla {stala}for{/stala} wyświetla w alercie aktualną wartość zmiennej {stala}i{/stala} – będą to cyfry od 0 do 2. Natomiast do naszych znalezionych elementów dostajemy się również przy użyciu cyfr (np. {html}alert(elements[1].innerHTML);{/html}). Dlaczego nie połączyć tych przykładów?
1 2 3 4 5 6
var rodzic = document.getElementById(\'blok\'); var elements=rodzic.getElementsByTagName(\'a\'); for (var i = 0; i < 3 ; i++) { alert(elements[i].innerHTML); }
Do tablicy {stala}elements{/stala} pobieramy wszystkie znalezione elementy {html}{/html}. Następnie uruchamiamy pętlę {stala}for{/stala}, która odlicza od 0 do 2 (bo zmienna {stala}i{/stala}, jak zapisaliśmy, nie może być większa od 3). Dostęp do zmiennej {stala}i{/stala} mamy oczywiście w konstrukcji {stala}for{/stala} (pomiędzy klamrami), więc podstawiamy do {stala}elements[]{/stala} właśnie tę zmienną zamiast cyfr.
Jak widać, mamy tutaj odliczanie od 0 do 2. Gdybyśmy jednak dodali kolejny link do diva, byłyby 4 linki, więc musielibyśmy odliczyć od 0 do 3 i tym samym zmienić warunek z {stala}i{/stala} < 3 na i < 4. Ponieważ {stala}elements.length{/stala} przechowuje liczbę wszystkich znalezionych linków, wystarczy podstawić ją do warunku pętli:
1 2 3 4 5 6
var rodzic=document.getElementById(\'blok\'); var elements =getElementsByTagName(\'a\'); for (var i = 0; i < ele ments.length;i++) { alert(elements[i].innerHTML); }
Ostatnie poprawki
Ponieważ funkcja {stala}Pokaz{/stala} pokazuje nasze menu, musi się dostać do wszystkich elementów {html}
- {/html} w {html}
- {/html} o {stala}id=”menu”{stala} i ustawić im {stala}display{/stala} na {stala}”block”{/stala}. W uzyskaniu tego efektu pomogą dwie poznane konstrukcje. Napiszemy więc ciało funkcji {stala}Pokaz{/stala}:
- {/html}, które nas bezpośrednio interesują. Pobieramy je poprzez {stala}ul.getElementsBy-TagName(‘li’);{/stala} – w argumencie mamy {stala}li{/stala}, bowiem szukamy tagów tego typu. Następnie uruchamiamy pętlę {stala}for{/stala}, która dodaje do zmiennej {stala}i{/stala} jeden, dopóki zmienna ta będzie mniejsza od odszukanej liczby elementów menu ({stala}elements.length{/stala}). Przy każdym odliczeniu wykonujemy kod w klamrach, czyli ustawiamy poszczególnym elementom {stala}display=”block”{/stala} (funkcja {stala}Ukryj{/stala} zmienia {stala}display{/stala} na {stala}none{/stala}). Podstawimy więc odpowiednie wartości do ciała funkcji {stala}Pokaz{/stala}, by otrzymać:
1 2 3 4 5 6 7 8 9
function Ukryj() { var ul=document.getElementById(\'menu\'); var elements =ul.getElementsByTagName(\'li\'); for (var i = 0; i < elements.length; i++ ) { elements[i].style.display=\"none\"; } }
Finał
Dokument, który powstał, działa bez problemów (patrz kod poniżej i rysunek obok) i zgodnie z naszymi zamierzenia mi: menu rozwija się po naprowadzeniu wskaźnika myszy na link Kategorie i zwija się, gdy wskaźnik zostanie odsunięty.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"pl-PL\"> <head> <title>Strona z menu</title> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\" /> <style type=\"text/css\"> ul { margin: 0; padding: 0; } li { margin: 0; padding: 0; list-style-type: none; } #menu li { display: none; } </style> <!-- Nasz kod Javascript: --> <script type=\"text/javascript\"> window.onload = Laduj; function Pokaz() { var ul = document.getElementById(\'menu\'); var elements = ul.getElementsByTagName(\'li\'); for (var i = 0; i < elements.length ; i++ ) { elements[i].style.display = \"block\"; } } function Ukryj() { var ul = document.getElementById(\'menu\'); var elements = ul.getElementsByTagName(\'li\'); for (var i = 0; i < elements.length ; i++ ) { elements[i].style.display = \"none\"; } } function Laduj() { var li = document.getElementById(\'main\') li.onmouseover = Pokaz; li.onmouseout = Ukryj; } </script> </head> <body> <div style=\"width: 60px;\"> <ul> <li id=\"main\"> <a href=\"#\"><strong>Kategorie</strong></a> <ul id=\"menu\"> <li><a href=\"#\">sport</a></li> <li><a href=\"#\">życie</a></li> <li><a href=\"#\">gry</a></li> </ul> </li> </ul> </div> </body> </html>Może Cię zainteresować:
1 2 3 4 5 6 7 8 9
function Pokaz() { var ul=document.getElementById (\'menu\'); var elements=ul.getElementsByTagName(\'li\'); for (var i = 0; i < elements.length; i++ ) { elements[i].style.display=\"block\"; } }
Na początku pobraliśmy odnośnik do rodzica {html}
- {/html} o {stala}id=”menu”{/stala}. Element ten zawiera podelementy {html}
- {/html}, które nas bezpośrednio interesują. Pobieramy je poprzez {stala}ul.getElementsBy-TagName(‘li’);{/stala} – w argumencie mamy {stala}li{/stala}, bowiem szukamy tagów tego typu. Następnie uruchamiamy pętlę {stala}for{/stala}, która dodaje do zmiennej {stala}i{/stala} jeden, dopóki zmienna ta będzie mniejsza od odszukanej liczby elementów menu ({stala}elements.length{/stala}). Przy każdym odliczeniu wykonujemy kod w klamrach, czyli ustawiamy poszczególnym elementom {stala}display=”block”{/stala} (funkcja {stala}Ukryj{/stala} zmienia {stala}display{/stala} na {stala}none{/stala}). Podstawimy więc odpowiednie wartości do ciała funkcji {stala}Pokaz{/stala}, by otrzymać:
Funkcja ta pobierze elementy dokumentu HTML po nazwie tagu. Tę z kolei wpisujemy jako argument funkcji, czyli przykładowe wywołanie wyglądać może np. tak:
1
odnosnik_do_rodzica.getElementsByTagName(\'div\');
W ten sposób pobrane zostaną wszystkie elementy {html}
{/html} znalezione pomiędzy tagami rodzica. Działanie tej funkcji na przykładzie:1 2 3 4 5
<div id=\"blok\"> <a href=\"#\">lalala</a> <a href=\"#\">sialalala</a> <a href=\"#\">kici kici</a> </div>
Powiedzmy, że chcemy pobrać wszystkie elementy {html}{/html} elementu blokowego {html}var rodzidiv>{/html} i {stala}id=”blok”{/stala}. Posłużymy się funkcją {stala}getElements-ByTagName{/stala}. Najpierw pobierzemy odnośnik do rodzica linków, jakim jest nasz div:
1
var rodzic=document.getElementById(\'blok\');
Teraz możemy użyć funkcji:
1 2
var rodzic=document.getElementById(\'blok\'); var elements=rodzic.getElementsByTagName(\'a\');
Jak widać, do zmiennej elements pobraliśmy wynik działania funkcji {stala}getElementsByTagName{/stala}, a jest nim lista odnośników do linków {html}{/html} pomiędzy {html}
{/html} o {stala}id=”blok”{/stala}. Aby dostać się do pierwszego z linków, możemy użyć zapisu (patrz rysunek obok):1 2 3
var rodzic=document.getElementById(\'blok\'); var elements=rodzic.getElementsByTagName(\'a\'); alert(elements[0].innerHTM);
Do pierwszego pobranego elementu dostaliśmy się używając nawiasów kwadratowych z liczbą 0 (w programowaniu liczymy od zera, a nie od jedynki, dla tego też odwoła nie poprzez zero do pierwszego elementu). Dalej mamy innerHTML, które zawiera wszystko, co znajduje się pomiędzy tagami elementu. W tym przypadku wyświetli się w okienku treść – lalala.
Wartość drugiego linka:
1
alert(elements[1].innerHTML);
oraz trzeciego:
1
alert(elements[2].innerHTML);
JavaScript umożliwia również wyświetlenie liczby wszystkich elementów znalezionych przez
funkcję {stala}getElementsByTagName{/stala}.1 2 3
var rodzic=document.getElementById(\'blok\'); var elements=rodzic.getElementsByTagName(\'a\'); alert(elements.length);
Do znalezionych elementów można dostać się między inny mi w ten sposób:
1 2 3
alert(ele ments[0].innerHTML); alert(ele ments[1].innerHTML); alert(ele ments[2].innerHTML);
Spójrzmy teraz na nasz przykład z działania konstrukcji {stala}for{/stala}:
1 2 3 4
for (var i = 0; i < 3 ; i++) { alert(i); }
onload, onmouseover, onmouseout
Funkcja {stala}Laduj{/stala} ma sprawić, że po załadowaniu strony element {html}
0 komentarzy »
- {/html} będzie miał właściwość {stala}onmoueover{/stala} i {stala}onmouseout{/stala}, czyli po naprowadzeniu wskaźnika myszy na Kategorie menu się rozwinie, a po jego zwolnieniu – zwinie.
{/html}, że naprowadzenie nań wskaźnika myszy spowoduje ustawienie display na block. Zaś zwolnienie wskaźnika ustawi tę wartość na {stala}none{/stala}.
Jako że nie mamy zamiaru bawić się w {html}onmouseover=”"{/html} i {html}onmouseout=”"{/html} wewnątrz dokumentu HTML, należy je ustawić tuż po załadowaniu okienka przeglądarki z naszą stroną. Jak wielu z Was pewnie pomyślało, przyda nam się w tym celu zdarzenie {stala}onload{/stala}. Przyjmijmy też, że menu pokazywane będzie przez funkcję {stala}Pokaz{/stala}, a ukrywane przez {stala}Ukryj{/stala}.
Wykorzystamy też trzecią funkcję o nazwie {stala}Laduj{/stala}, która da znać dokumentowi, że naprowadzeni wskaźnika myszy na nagłówek Kategorie spowoduje rozwinięcie menu, a zwolnienie wskaźnika myszy – jego ukrycie. Szkielet skryptu przybierze więc następującą postać:
1 2 3 4 5 6 7 8 9 |
<script type=\"text/javascript\"> window.onload = Laduj; function Pokaz() {} function Ukryj() {} function Laduj() {} </script> |
Pora uzupełnić powyższy kod. Zaczniemy od funkcji {stala}Laduj{/stala}.
Funkcja getElementsByTagName
Musimy dostać się do poszczególnych elementów {html}





