Flash? Nie, dziękuje - nietypowe menu w jQuery

Dzisiaj zaprezentuję prostą sztuczkę na stworzenie takiego przykładowego menu bez najmniejszego wykorzystania Flasha. Niektórym na początek może wydawać się to nawet niemożliwe, ale jednak - JavaScript w połączeniu z grafiką wiele potrafi.

Metoda wykonania jest banalnie prosta. Czasami dziwię się, dlaczego twórcy stron tworząc nawet najdziwniejsze menu, ciągle bazują na starej zasadzie - poruszaj elementem: góra, dół, lub: prawo, lewo. Wiadomo, z jednej strony użyteczność, ale z drugiej trochę odmienności nikomu też nie zaszkodzi (z umiarem i w odpowiednim miejscu, tworząc np. portfolio). Ja do tej pory spotykałem jedynie strony we Flashu które łamały tą zasadę wykazując nieco, nazwijmy to 'kreatywności', co jednak nie zawsze wychodziło.

Powyższy przykład pozwala na zmianę koloru dowolnego elementu menu bez konieczności zmiany grafiki, jednak do pomocy posłużę się podobnym przykładem z mniej skomplikowaną budową. Zobaczmy na ten przykład menu. Od teraz bazujemy tylko na nim. Już na starcie zauważymy, że tutaj pierwsze momenty wczytywania grafiki nie wyglądają najlepiej, ale o tym później.

W przykładach wykorzystałem jQuery, ale nie jest to konieczność - wystarczy dowolny sposób na przesuwanie tła/diva.

Jak to działa?
Mamy dwie warstwy ułożone jedna na drugiej, gdzie:

  • pierwsza jest 'dziurawym' plikiem .png
  • druga znajdująca się poniżej jest tłem, które wypełnia lukę w warstwie znajdującej się wyżej

Wystarczy tylko odpowiednio poruszać warstwą dolną, aby uzyskać efekt podkreślenia podążającego za aktywną pozycją menu.

Jak widać nic w tym trudnego :)

Kod HTML i CSS
Jeśli idea działania jest poznana, to możemy obejrzeć menu od strony kodu. Zaczynamy od podstawowej struktury menu.

 <ul id="menu">   <li class="img1"><a href="#1">Index</a></li>  <li class="img2"><a href="#2">Blog</a></li>  <li class="img3"><a href="#3">Photo</a></li>  <li class="img4"><a href="#4">E-mail</a></li></ul>

Standardowa budowa. Przypisałem kolejne klasy dla każdego <li>, co potrzebne będzie do przypisania grafiki dla każdego elementu i jego pozycjonowania.

Na początek trzeba ostylować menu 'tradycyjną' metodą. W tym przykładzie menu nie stosujemy 'dziurawych' elementów przy 'graficznym' tekście. Tekst to pliki .png ustawione jako tło.

Efekt rollover w CSS
Aby pliki reprezentujące stan :hover nie wczytywały się dopiero podczas najechaniu kursorem na element, to zastosujemy metodę opisaną kiedyś przez Riddla. Metoda znana, ale opiszę podobny sposób alternatywny, który przeze mnie został tutaj użyty ze względu na trudności IE6 związane z .png.

Okazało się, że IE6 przełknie pliki .png użyte w efekcie rollover, ale tylko wtedy, kiedy nie są przeźroczyste. W naszym przypadku są - kolor posiadają tylko litery wraz z cieniem, reszta jest całkowicie przeźroczysta.

Mogłem poszukać innego rozwiązania które by powiedziało IE6 co i jak, ale wybrałem metodę bazującą na CSS'ie. Element <li> ma wysokość 60px, a natomiast<a> aż 120px. Jak nie trudno się domyślić zamiast przesuwania tła zastosowałem przesuwanie elementu <a> wewnątrz <li>. Musiałem tylko dodać styl overflow: hidden; do <li>.

Kod dla stanu :hover wygląda następująco:

#menu a:hover {  margin-top: -60px; }

Wszystko działa tak jak należy, co można obejrzeć tutaj - etap 1.
Resztę kodu CSS można podejrzeć w źródle (tj. przypisanie grafiki, pozycjonowanie elementów, itd).

Czas na jQuery
Teraz przyszła kolej na etap w którym będziemy dodawać dodatkową funkcjonalność, czyli dynamiczne 'podkreślenie'. Będzie nam do tego potrzeby taki dodatkowy kod:

<div id="png_container">  <div id="png_background" style="left: -60px;"/>  <div id="png_img"/></div>
  • #png_container obejmuje całość (odpowiednio pozycjonujemy)
  • #png_background stanowi tło którym będziemy poruszać (ustawiamy odpowiednie wymiary, ustawiamy kolor tła, lub ewentualnie wstawiamy tło .png)
  • #png_img jest blokiem w którym nadajemy jako tło 'dziurawe' .png - tutaj jest to 'rynna' w którym porusza się podkreślenie

Ktoś może zapytać po co tyle warstw, jeśli zamiast #png_background można ustawić tło blokowi nadrzędnemu i przesuwać tylko to tło. Można i tak, ale jeśli będziemy chcieć aby poruszający się element zamiast sztywno-pionowych boków miał coś jeszcze (gradient, wcięcia, itp) to lepiej użyć diva, bo IE6 przy poruszaniu tłem będącym plikiem .png może protestować.

Do wstawienia tego kodu użyjemy jQuery, aby niepotrzebnie nie zaśmiecać kodu html. Dodatkowo użytkownicy bez JS nie zobaczą niepotrzebnych i niedziałającego podkreślenia.

$("#menu").before('wyżej pokazany kod');

Dla osób znających jQuery kod będzie zrozumiały - wstawiamy kod przed element <ul id="menu">.

Gdy już poprzez JS odpowiednie bloki są dodane, to wystarczy je odpowiednio ostylować tak, aby całość spełniała swoją rolę. Pozostaje jedynie dodanie końcowej funkcjonalności, czyli możliwości przesuwania odpowiedniego bloku po wskazaniu kolejnych pozycji menu.
Mój kod prezentuje się następująco:

$("li").mouseover(function(){  var index = $("li").index(this)+1;  switch (index) {    case 1: pozycja = "-60px"; break;    case 2: pozycja = "50px"; break;    case 3: pozycja = "165px"; break;    case 4: pozycja = "310px"; break;  }   $("#png_background").stop();  $("#png_background").animate({ left : pozycja }, 600);     });	

Co robi ten kod? Na początek przypisujemy zdarzenie dla elementów <li>. Następnie rozpoznajemy który element został wskazany (zmienna index).
Następnie tworzymy switcha w którym w zależności od indeksu wskazanego elementu przypiszemy odpowiednią pozycję w której ma znaleźć się podkreślenie.

Dwie przedostatnie linie odnoszą się do samej animacji. Dzięki stop() zatrzymamy aktualny ruch podkreślenia, a dzięki animate() sprawimy, że podkreślenie podąży w odpowiednie miejsce.

Można zapytać po co nam potrzebne zatrzymywanie animacji poprzez stop()? Bez tego skończyłoby się na szalejącej animacji która chce wykonać wszystkie zadania po tym, jak szybkim ruchem przejechalibyśmy kursorem po kilku elementach menu.

Jak widać wszystko działa tak jak należy.

Drobne szczegóły końcowe
Wcześniej wspomniałem o niezbyt estetycznym efekcie przy ładowaniu się plików strony, kiedy to jeszcze zamiast podkreślenia widać było jego tło ('dziurawy' plik .png nie wczytał się jeszcze).Można i nawet należy ten problem obejść w dowolny sposób. Ja wybrałem w pierwszym przykładzie nieco prymitywny graficznie preloader zasłaniający całość strony. Lepiej użyć rozwiązania które będzie działało następująco: skrypt sprawdza czy pliki potrzebne do animacji zostały dodane i dopiero wówczas wstawia bloki odpowiedzialne za animację. Dzięki temu odwiedzający stronę będzie mógł zacząć zapoznawać się z treścią bez konieczności czekania na wczytanie (czasami ciężkiej) grafiki.

Drobne szczegóły końcowe 2
Efekt tutaj uzyskany może nie jest jakoś nadzwyczajnie imponujący, ale bardziej zależało mi na pokazaniu samych możliwości takiego rozwiązania. Dopasowując kolorystykę, sposób zachowania, itd, można uzyskać wiele różnych efektów.
Tutaj przykładowo możemy obejrzeć wykorzystanie tej metody w połączeniu z kolorowym tłem.

Podsumowanie w linkach:

Komentarze 38:

  • » Nanka: 08.08.2009 o 19:59

    Nigdy bym nie wpadła na to że można to tak wykorzystać :)

  • » Marek: 08.08.2009 o 21:51

    Świetne menu!

    W kilku liniach kodu JS można wyeliminować konieczność używania Flash.

    Menu działa pięknie i płynnie!!! na urządzeniach mobilnych (Safari), które nie obsługują Flash.

  • » Paweł Ludwiczak: 09.08.2009 o 09:07

    Fajny a prosty trick! Na pewno wielu osobom się przyda. Nice job! :)

  • » Chris Trynkiewicz: 09.08.2009 o 14:01

    O wow. Zajebiste! I banalne w swojej prostocie :)

  • » FAIL!: 10.08.2009 o 10:07

    Wszedłem z włączonym noscriptem, ujrzałem piękny komunikat o konieczności włączenia JS oraz link do wersji alternatywnej która prowadzi do #. Fail.

  • » Adriano: 10.08.2009 o 10:48

    Drobne niedopatrzenie ;)
    Poprawiłem link.

    Konieczna włączona obsługa JavaScript. Przykład działający także bez JS: [klik].
    // Gdy będziesz projektował menu tego typu, to pamiętaj o dodaniu alternatywnego menu które będzie funkcjonalne także bez włączonego JS. Tutaj tego nie zrobiłem aby kod był czytelniejszy.

  • » himn1: 10.08.2009 o 14:48

    Świetny, kreatywny wpis jakich mało.. Co ja za menusy będę teraz wykonywał.. ;) Więcej wpisów js > flash mile widziane. Pozdrawiam!

  • » procek: 11.08.2009 o 14:26

    Generalnie wszystko co jest antyflashowe bardzo mi się podoba. Przykład bardzo dobry, ten drugi jeszcze lepszy :) Martwi mnie jednak stopień skomplikowania takiego menu - nie czarujmy się: do powszechnego użytku trick taki nie wejdzie... Problemem jest również to, że mała liczba stron, które się tworzy będzie miała dożywotnio stałą zawartość (chodzi o liczbę linków w menu), co również przeszkadza. Niemniej jednak na portfolio czy statyczną stronę o "czymś tam" rozwiązanie idealne :)

  • » chlitto: 13.08.2009 o 02:57

    Http://www.webleeddesign.com/ - scrollować na dół :)

  • » chlitto: 13.08.2009 o 11:12

    I w sumie jeszcze takie "flashowe" rozwiazanie jest ciekawe - http://simpledog.net/ - click "go"

  • » chlitto: 14.08.2009 o 01:49

    Przegladajac moje 5tysiecy bookmarkow wpadlem jeszcze na to http://jsanim.com/ ;]

  • » Adriano: 22.07.2010 o 08:59

    Przykłady z wpisu: http://7pl.pl/no/52/przyklady.rar

  • » Warchol: 04.10.2010 o 08:40

    Bardzo fajny pomysł z tym menu, jestem za rozwiązaniami które eliminują zasobożerny flash.

Dodaj komentarz:

Dostępne tagi: [link]http://adres-www[/link] [quote]cytat[/quote] [code]kod[/code] [pre]tekst preformowany[/pre] [b]bold[/b]