chevron-left chevron-right

Piotr Nalepa Frontend, architektura i AI

[CSS][jQuery] Efektowne menu z tłami

Ta wersja
blog.piotrnalepa.pl/2010/05/20/cssjquery-efektowne-menu-z-tlami
Opublikowano
Autor
, Staff Software Engineer
Kategorie
CSS, JavaScript
Uwagi
Napisz do mnie · Napisz na X

Ten wpis ma 16 lat. Od tego czasu przeglądarki i narzędzia mogły się zmienić, więc zanim użyjesz kodu, sprawdź go z aktualną dokumentacją.

W dzisiejszym artykule przedstawię sposób na zbudowanie bardzo efektownego menu przypominającego animacje Flash. Głównym zamierzeniem tego efektu jest posiadanie trzech obrazków jako tło pod każdą osobną pozycją menu, który to obrazek się zmienia zależnie od tego, które pozycja z menu zostanie wskazana.
Moim zdaniem taki efekt można skutecznie wykorzystać na stronach portfolio czy stronach studiów fotograficznych.

Najpierw należy stworzyć strukturę takiego menu. W tym przypadku menu będzie wyglądało w następujący sposób:

Przykład 1HTML
<div id="kontener">
<ul class="menu" id="menu">
<li class="bg1" style="background-position:0 0;">
      <a id="bg1" href="#">Miasto</a>
<ul class="podmenu1" style="background-position:0 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<li class="bg1" style="background-position:-266px 0px;">
         <a id="bg2" href="#">Wąż</a>
<ul class="podmenu2" style="background-position:-266px 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<li class="last bg1" style="background-position:-532px 0px;">
         <a id="bg3" href="#">Niebo</a>
<ul class="podmenu3" style="background-position:-266px 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
</ul>
</div>

Dla uproszczenia wykorzystałem zagnieżdżone style CSS. To nie jest dobra praktyka webmasterska, ale musisz mi wybaczyć taki krok.

Kolejnym krokiem jest zdefiniowanie stylu CSS dla naszego menu:

Przykład 2CSS
#kontener {
    font-size: 15px;
    font-style: normal;
    font-weight: normal;
    text-transform: uppercase;
    letter-spacing: normal;
    line-height: 1.45em;
    position: relative;
    margin: 20px auto;
    height: 542px;
    width: 797px;
    background-position: 0 0;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu {
    list-style: none;
    width: 797px;
}
ul.menu > li {
    float: left;
    width: 265px;
    height: 542px;
    border-right: 1px solid #777;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu > li.last {
    border: none;
}
.bg1 {
    background-image: url(../images/1.jpg);
}
.bg2 {
    background-image: url(../images/2.jpg);
}
.bg3 {
    background-image: url(../images/3.jpg);
}
ul.menu > li > a {
    float: left;
    width: 265px;
    height: 50px;
    margin-top: 450px;
    text-align: center;
    line-height: 50px;
    color: #ddd;
    background-color: #333;
    letter-spacing: 1px;
    cursor: pointer;
    text-decoration: none;
    text-shadow: 0px 0px 1px #fff;
}
ul.menu > li ul {
    list-style: none;
    float: left;
    margin-top: -180px;
    width: 100%;
    height: 110px;
    padding-top: 20px;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu > li ul li {
    display: none;
}
ul.menu > li ul.podmenu1 {
    background-image: url(../images/bg1.png);
}
ul.menu > li ul.podmenu2 {
    background-image: url(../images/bg2.png);
}
ul.menu > li ul.podmenu3 {
    background-image: url(../images/bg3.png);
}
ul.menu > li ul li a {
    color: #fff;
    text-decoration: none;
    line-height: 30px;
    margin-left: 20px;
    text-shadow: 1px 1px 1px #444;
    font-size: 11px;
}
ul.menu > li ul.podmenu1 li {
    display: block;
}
ul.menu > li ul li a:hover {
    border-bottom: 1px dotted #fff;
}

Ostatnim krokiem jest stworzenie skryptu JavaScript, który będzie odpowiednio animował nasze menu.
Szczegóły tego kodu są opisane w komentarzach w kodzie.

Przykład 3JavaScript
$(function() {
	/* pozycja znacznika
<li> który jest obecnie pokazany */
	var stanObecny = 0;
 
	var stanZaladowany  = 0;
	for(var i = 1; i &lt;4; ++i)
		$('<img />').load(function(){
			++stanZaladowany;
			if(stanZaladowany == 3){
				$('#bg1,#bg2,#bg3').mouseover(function(e){
 
					var $this = $(this);
					/* jeśli najedziemy na pokazany znacznik to nic nie robi */
					if($this.parent().index() == stanObecny)
						return;
 
					/* obiektami najazdu są bg1 lub bg2 lub bg3, zależnie od tego który wskażemy kursorem */
					var obiektMenu = e.target.id;
 
					/*
					tutaj ustawiamy tło podmenu.
					Ustawiamy kierunek ruchu animacji zależnie od tego z której strony
					najedziemy kursorem.
					Jeśli najedziemy z lewej strony obrazka to animacja będzie
					szła od prawej do lewej, a jeśli z prawej strony najedziemy
					to animacja będzie szła od lewej do prawej
					 */
					if(obiektMenu == 'bg1' || stanObecny == 2)
						$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(-266px 0)"},300,function(){
							$(this).find('li').hide();
						});
					else
						$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(266px 0)"},300,function(){
							$(this).find('li').hide();
						});
 
					if(obiektMenu == 'bg1' || stanObecny == 2){
						/* animacja od lewej do prawej */
						$('#menu > li').animate({backgroundPosition:"(-800px 0)"},0).removeClass('bg1 bg2 bg3').addClass(obiektMenu);
						move(1,obiektMenu);
					}
					else{
						/* animacja od prawej do lewej */
						$('#menu > li').animate({backgroundPosition:"(800px 0)"},0).removeClass('bg1 bg2 bg3').addClass(obiektMenu);
						move(0,obiektMenu);
					}
 
					/*
					Część środkowa menu, też powinna ulec animacji, gdy będziemy przejeżdżać
					kursorem nad częścią środkową.
					Animacja ma być zależna od kierunku najazdu.
					To jest ważne w przypadku przechodzenia od pierwszego do ostatniego lelemntu menu
					lub na odwrót.
					 */
					if(stanObecny == 2 && obiektMenu == 'bg1'){
						$('#menu .podmenu'+parseInt(stanObecny)).stop().animate({backgroundPosition:"(-266px 0)"},300);
					}
					if(stanObecny == 0 && obiektMenu == 'bg3'){
						$('#menu .podmenu'+parseInt(stanObecny+2)).stop().animate({backgroundPosition:"(266px 0)"},300);
					}
 
					/* zmień obecny element */
					stanObecny = $this.parent().index();
 
					/* nakładanie tła dla podmenu */
 
					$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(0 0)"},300,function(){
						$(this).find('li').fadeIn();
					});
				});
			}
		}).attr('src', 'images/'+i+'.jpg');
 
		 function move(dir,obiektMenu){
			  if(dir){
					$('#bg1').parent().stop().animate({backgroundPosition:"(0 0)"},200);
					$('#bg2').parent().stop().animate({backgroundPosition:"(-266px 0)"},300);
					$('#bg3').parent().stop().animate({backgroundPosition:"(-532px 0)"},400,function(){
						 $('#kontener').removeClass('bg1 bg2 bg3').addClass(obiektMenu);
					});
			  }
			  else{
					$('#bg1').parent().stop().animate({backgroundPosition:"(0 0)"},400,function(){
						 $('#kontener').removeClass('bg1 bg2 bg3').addClass(obiektMenu);
					});
					$('#bg2').parent().stop().animate({backgroundPosition:"(-266px 0)"},300);
					$('#bg3').parent().stop().animate({backgroundPosition:"(-532px 0)"},200);
			  }
		 }
	});
</li>

Należy pamiętać o tym, aby dodać do naszego pliku HTML bibliotekę jQuery oraz plugin jquery.bgpos. Dzięki temu nasz efekt zadziała tak jak tego chcemy.

To byłoby wszystko, jeśli chodzi o ten artykuł.
Działający przykład możesz zobaczyć pod tym linkiem: efektowne menu z przewijanymi tłami


Tak jak obiecałem, dorzucam spakowaną wersję demo tego efektu do pobrania: pobierz efektowne menu z tłami

Udostępnij
Uwagi

O autorze

Staff Software Engineer

Piszę na tym blogu od 2009 roku, a strony i aplikacje webowe tworzę zawodowo od 14 lat. Obecnie w Bishop Fox prowadzę frontend platformy Cosmos, od samego początku projektu. Wcześniej pracowałem m.in. w OLX, KUDO, Auto1 i eZ Systems. Piszę tu o tym, czego nauczyłem się w praktyce: o JavaScripcie, TypeScripcie, Reakcie, CSS-ie i architekturze frontendu. Występowałem też jako prelegent na konferencjach w Polsce i Europie. Masz pytanie albo pomysł na wpis? Daj znać!