Paolo De Feo
a- a+

Menų dinamico JavaScript e CSS3 pronto all'uso

Vediamo come creare un menų animato con elementi interattivi.

Le librerie JavaScript jQuery ci permettono di creare pagine ed elementi interattivi molto accattivanti. Oggi vedremo come creare un menu animato, che mostra all’utente una finestra informativa più ampia quando le voci vengono cliccate.
Non solo: l’immagine di sfondo cambierà secondo la voce selezionata. La base pratica del nostro esempio sarà un menu digitale categorico per un ristorante.

Il markup HTML

Il markup HTML principale è una struttura  che andrà a contenere elementi dell’immagine di sfondo, l’icona di caricamento ed il menu principale. Il markup per lo sfondo sarà simile a questo:

<div id="ac_background" class="ac_background">
	<img class="ac_bgimage" src="immagini/background.jpg" alt="Background"/>
	<div class="ac_overlay"></div>
	<div class="ac_loading"></div>
</div>

Lo useremo per creare il file Index.html (o immerso in altre combinazioni). Come immagine di sfondo abbiamo impostato “background.jpg”, che apparirà quando si caricherà la pagina. Ricordiamo che, successivamente, l’immagine di sfondo cambierà a seconda della categoria selezionata.

Il contenuto del “menu del ristorante” verrà implementato in un DIV con una classe CSS chiamata per comodità “ac_content”. In questo modo proviamo a creare una categoria alimentare tramite una lista non ordinata:

<div id="ac_content" class="ac_content">
	<h1><span>Ristorante</span>Borgo</h1>
	<div class="ac_menu">
		<ul>
			<li>
				<a href="immagini/antipasti.jpg">Antipasti</a>
				<div class="ac_subitem">
					<span class="ac_close"></span>
					<h2>Antipasti</h2>
					<ul>
						<li>
					Venite ad assaggiare le nostre specialità
						</li>
						<li>tartine</li>
						<li>quiche</li>
						<li>olive</li>
						<li>salumi</li>
						<li>formaggi</li>
						<li>bruschette</li>
						<li>pesce</li>
					</ul>
				</div><!-- ac_subitem-->
			</li>
			...
		</ul>
	</div><!-- ac_menu -->
</div><!-- ac_content -->

Per ogni categoria menu avremo un sottomenu che conterrà le informazioni (ac_subitem). Ovviamente, su questa falsariga potremo continuare la creazione del vostro menu per tutte le altre sezioni. Nello stesso markup è stata inserita anche l’immagine che farà da sfondo volta per volta.

CSS

Il design delle pagine verrà gestito tramite 2 fogli di stile CSS che abbiamo chiamato reset.css e style.css. Il file resett.css contiene le informazioni di stile generali quali grandezza font, margini e pudding per i vari elementi pagina eccetera. Il file style.css contiene informazioni di formattazione più specifiche.

Reset.css

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
	margin:0;
	padding:0;
}
html,body {
	margin:0;
	padding:0;
	height:100%;
}
table {
	border-collapse:collapse;
	border-spacing:0;
}
fieldset,img { 
	border:0;
}
input{
	border:1px solid #b0b0b0;
	padding:3px 5px 4px;
	color:#979797;
	width:190px;
}
address,caption,cite,code,dfn,th,var {
	font-style:normal;
	font-weight:normal;
}
ol,ul {
	list-style:none;
}
caption,th {
	text-align:left;
}
h1,h2,h3,h4,h5,h6 {
	font-size:100%;
	font-weight:normal;
}
q:before,q:after {
	content:'';
}
abbr,acronym { border:0;
}	

Reset.css dovrà essere importato con una “@ import rule” nel foglio di stile principale style.css. e dovrà essere posizionato in cima a tutto. La regola d’importazione è la seguente:

@import url('reset.css');

Style.css

@import url('reset.css');

body{
	background:#000;
	color:#fff;
	font-family: 'PT Sans Narrow', Arial, sans-serif;
	text-transform:uppercase;
}
a{
	color:#fff;
	text-decoration:none;
}
img.ac_bgimage{
	position:fixed;
	left:0px;
	top:0px;
	width:100%;
	opacity:0.8;
	display:none;
}
.ac_overlay{
	width:100%;
	height:100%;
	position:fixed;
	top:0px;
	left:0px;
	background:transparent url(../immagini/tuaimmagine.png) repeat top left;
}
.ac_loading{
	position:fixed;
	top:10px;
	right:10px;
	background:#000 url(../immagini/immagineloader.gif) no-repeat center center;
	width:50px;
	height:50px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px 10px 10px 10px;
	z-index:999;
	opacity:0.7;
	display:none;
}
.ac_content{
	position:fixed;
	height:90px;
	width:100%;
	top:50%;
	left:0px;
	margin-top:-65px;
}
.ac_content h1{
	background:transparent url(../immagini/immaginebackground.png) repeat top left;
	display:block;
	float:left;
	width:90px;
	height:50px;
	padding:20px;
	font-size:36px;
	font-weight:bold;
	line-height:20px;
	margin-right:1px;
}
.ac_content h1 span{
	display:block;
	font-weight:normal;
	font-size:14px;
}
.ac_menu{
	background:transparent url(../immagini/backgroundmenu) repeat top left;
	float:left;
	position:relative;
	height:90px;
	width:0px; 
}
.ac_menu > ul{
	float:right;
}
.ac_menu > ul > li{
	float:left;
	position:relative;
	height:90px;
	overflow:hidden;
}
.ac_menu > ul > li a{
	margin-top:60px;
	opacity:0;
	display:block;
	height:90px;
	padding:0px 10px;
	text-align:center;
	line-height:90px;
	outline:none;
	font-size:18px;
	font-weight:bold;
	text-shadow:1px 1px 1px #000;
}
.ac_subitem{
	width:400px;
	height:0px;
	top:50%;
	right:0px;
	margin-top:0px; 
	position:fixed;
	z-index:99;
	overflow:hidden;
	background:transparent url(../immagini/immaginebackground2.png) repeat top left;
}
.ac_subitem h2{
	font-size:22px;
	font-weight:bold;
	color:#fff;
	padding: 40px 0px 0px 40px;
	text-shadow:0px 0px 1px #000;
}
.ac_subitem ul{
	padding:0px 40px;
}
.ac_subitem ul li{
	margin:10px 0px;
}
.ac_subitem ul li:first-child{
	font-size:14px;
	text-transform:none;
	border-bottom:1px dotted #333;
	padding-bottom:15px;
	margin-bottom:15px;
}
span.ac_close{
	float:right;
	margin:10px;
	width:11px;
	height:12px;
	cursor:pointer;
	background:transparent url(../immagini/xchiusuraimmagine.png) no-repeat top left;
	opacity:0.4;
}
span.ac_close:hover{
	opacity:1.0;
}
.ac_footer{
	position:fixed;
	bottom:0px;
	left:0px;
	width:100%;
	font-size:13px;
	background:#000;
	opacity:0.9;
	height:20px;
	padding-bottom:5px;
}
.ac_footer a{
	padding:5px 10px;
	letter-spacing:1px;
	text-shadow:1px 1px 1px #000;
	color:#ddd;
	float:right;
}
.footer a:hover{
	color:#fff;
}
.ac_footer a span{
	font-weight:bold;
}
.ac_footer a.ac_left{
	float:left;
}

Il JavaScript

Il JavaScript è l’ultima operazione da compiere per rendere il nostro menu web operativo. Il codice di seguito andrà implementato nella nostra pagina (che nell’esempio è stata chiamata index.html) sotto al markup insieme al plugin JavaScript jQuery Easing (richiamato tramite link). Ricordatevi di implementarlo prima dei tag di chiusura </body> e </html>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
		<script type="text/javascript" src="js/jquery.easing.1.3.js"></script>
		<script type="text/javascript">
			$(function() {
				var $ac_background	= $('#ac_background'),
				$ac_bgimage		= $ac_background.find('.ac_bgimage'),
				$ac_loading		= $ac_background.find('.ac_loading'),
				
				$ac_content		= $('#ac_content'),
				$title			= $ac_content.find('h1'),
				$menu			= $ac_content.find('.ac_menu'),
				$mainNav		= $menu.find('ul:first'),
				$menuItems		= $mainNav.children('li'),
				totalItems		= $menuItems.length,
				$ItemImages		= new Array();
				
				
				$menuItems.each(function(i) {
					$ItemImages.push($(this).children('a:first').attr('href'));
				});
				$ItemImages.push($ac_bgimage.attr('src'));
					  
				
				var Menu 			= (function(){
					var init				= function() {
						loadPage();
						initWindowEvent();
					},
					loadPage			= function() {
						

						$ac_loading.show();//show loading status image
						$.when(loadImages()).done(function(){
							$.when(showBGImage()).done(function(){
								//hide the loading status image
								$ac_loading.hide();
								$.when(slideOutMenu()).done(function(){
										$.when(toggleMenuItems('up')).done(function(){
										initEventsSubMenu();
									});
								});
							});
						});
					},
					showBGImage			= function() {
						return $.Deferred(
						function(dfd) {
							//adjusts the dimensions of the image to fit the screen
							adjustImageSize($ac_bgimage);
							$ac_bgimage.fadeIn(1000, dfd.resolve);
						}
					).promise();
					},
					slideOutMenu		= function() {
						
						var new_w	= $(window).width() - $title.outerWidth(true);
						return $.Deferred(
						function(dfd) {
							//slides out the menu
							$menu.stop()
							.animate({
								width	: new_w + 'px'
							}, 700, dfd.resolve);
						}
					).promise();
					},
						
						toggleMenuItems		= function(dir) {
						return $.Deferred(
						function(dfd) {
							
							$menuItems.each(function(i) {
										var $el_title	= $(this).children('a:first'),
											marginTop, opacity, easing;
										if(dir === 'up'){
											marginTop	= '0px';
											opacity		= 1;
											easing		= 'easeOutBack';
										}
										else if(dir === 'down'){
											marginTop	= '60px';
											opacity		= 0;
											easing		= 'easeInBack';
						}
								$el_title.stop()
								.animate({
													marginTop	: marginTop,
													opacity		: opacity
												 }, 200 + i * 200 , easing, function(){
									if(i === totalItems - 1)
										dfd.resolve();
								});
							});
						}
					).promise();
					},
					initEventsSubMenu	= function() {
						$menuItems.each(function(i) {
							var $item		= $(this), // the <li>
							$el_title	= $item.children('a:first'),
							el_image	= $el_title.attr('href'),
							$sub_menu	= $item.find('.ac_subitem'),
							$ac_close	= $sub_menu.find('.ac_close');
							
													$el_title.bind('click.Menu', function(e) {
									$.when(toggleMenuItems('down')).done(function(){
									openSubMenu($item, $sub_menu, el_image);
								});
								return false;
							});
							
							$ac_close.bind('click.Menu', function(e) {
								closeSubMenu($sub_menu);
								return false;
							});
						});
					},
					openSubMenu			= function($item, $sub_menu, el_image) {
						$sub_menu.stop()
						.animate({
							height		: '400px',
							marginTop	: '-200px'
						}, 400, function() {
										//the bg image changes
							showItemImage(el_image);
						});
					},
						
					showItemImage		= function(source) {
							//if its the current one return
						if($ac_bgimage.attr('src') === source)
							return false;
								
						var $itemImage = $('<img src="'+source+'" alt="Background" class="ac_bgimage"/>');
						$itemImage.insertBefore($ac_bgimage);
						adjustImageSize($itemImage);
						$ac_bgimage.fadeOut(1500, function() {
							$(this).remove();
							$ac_bgimage = $itemImage;
						});
						$itemImage.fadeIn(1500);
					},
					closeSubMenu		= function($sub_menu) {
						$sub_menu.stop()
						.animate({
							height		: '0px',
							marginTop	: '0px'
						}, 400, function() {
							//show items
										toggleMenuItems('up');
						});
					},
						

					initWindowEvent		= function() {
						
						$(window).bind('resize.Menu' , function(e) {
							adjustImageSize($ac_bgimage);
							
							var new_w	= $(window).width() - $title.outerWidth(true);
							$menu.css('width', new_w + 'px');
						});
					},
						
					adjustImageSize		= function($img) {
						var w_w	= $(window).width(),
						w_h	= $(window).height(),
						r_w	= w_h / w_w,
						i_w	= $img.width(),
						i_h	= $img.height(),
						r_i	= i_h / i_w,
						new_w,new_h,
						new_left,new_top;
							
						if(r_w > r_i){
							new_h	= w_h;
							new_w	= w_h / r_i;
						}
						else{
							new_h	= w_w * r_i;
							new_w	= w_w;
						}
							
						$img.css({
							width	: new_w + 'px',
							height	: new_h + 'px',
							left	: (w_w - new_w) / 2 + 'px',
							top		: (w_h - new_h) / 2 + 'px'
						});
					},
						
					loadImages			= function() {
						return $.Deferred(
						function(dfd) {
							var total_images 	= $ItemImages.length,
							loaded			= 0;
							for(var i = 0; i < total_images; ++i){
								$('<img/>').load(function() {
									++loaded;
									if(loaded === total_images)
										dfd.resolve();
								}).attr('src' , $ItemImages[i]);
							}
						}
					).promise();
					};
						
					return {
						init : init
					};
				})();
			
				
				Menu.init();
			});
		</script>
</body>
</html>



Ti potrebbe interessare anche

commenta la notizia

C'č 1 commento
Pier Paolo
Condividi le tue opinioni su questo articolo!