[JS]これFlashじゃないの?ってなるナビゲーションを実装するjQueryのチュートリアル
Post on:2011年3月28日
sponsorsr
軽快なアニメーションが心地よいナビゲーションを実装するjQueryのチュートリアルを紹介します。
タイトルにある通り、Flashは使わないで実装されてます。

Animated Content Menu with jQuery
デモページ
[ad#ad-2]
まずは、デモページを堪能ください。
ナビゲーションの各ラベルをクリックすると、それに対応したパネルがアニメーションを伴って開くようになっています。

実装
HTMLの構造は、背景画像、グリッドのオーバーレイ、ローディングのアイコン、メインメニューの4つから構成されています。
HTML:背景
背景は、背景画像とオーバーレイとローディングをdiv要素で内包します。
<div id="ac_background" class="ac_background"> <img class="ac_bgimage" src="images/Default.jpg" alt="Background"/> <div class="ac_overlay"></div> <div class="ac_loading"></div> </div>
HTML:メインメニュー
各アイテムはリスト要素で管理されており、パネルはdiv要素(ac_subitem)内に配置されています。
パネル内にはデモではリスト要素が配置されていますが、あらゆる要素を自由に配置することができます。
<div id="ac_content" class="ac_content"> <h1><span>Cafe + Bar</span>Dhalia</h1> <div class="ac_menu"> <ul> <li> <a href="images/Appetizers.jpg">Appetizers</a> <div class="ac_subitem"> <span class="ac_close"></span> <h2>Appetizers</h2> <ul> <li>A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart.</li> <li>Lobster Bisque</li> <li>Smoked Salmon Terrine</li> <li>Tuna Ceviche</li> <li>Wild Mushroom Flan</li> <li>Almond Bruschetta</li> <li>Green Chilli Canapee</li> <li>Artichoke Rucula Salad</li> </ul> </div> </li> <li>...</li> <li>...</li> </ul> </div> </div>
[ad#ad-2]
JavaScript
「jquery.js」と「jquery.easing.1.3.js」を外部ファイルとし、下記のスクリプトを記述します。
$(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();
/*
for this menu, we will preload all the images.
let's add all the image sources to an array,
including the bg image
*/
$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() {
/*
1- loads the bg image and all the item images;
2- shows the bg image;
3- shows / slides out the menu;
4- shows the menu items;
5- initializes the menu items events
*/
$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() {
/* calculate new width for the menu */
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();
},
/* shows / hides the menu items */
toggleMenuItems = function(dir) {
return $.Deferred(
function(dfd) {
/*
slides in / out the items.
different animation time for each one.
*/
$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');
/* user clicks one item : appetizers | main course | desserts | wines | specials */
$el_title.bind('click.Menu', function(e) {
$.when(toggleMenuItems('down')).done(function(){
openSubMenu($item, $sub_menu, el_image);
});
return false;
});
/* closes the submenu */
$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);
});
},
/* changes the background 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');
});
},
/*
on window resize, ajust the bg image dimentions,
and recalculate the menus width
*/
initWindowEvent = function() {
/* on window resize set the width for the menu */
$(window).bind('resize.Menu' , function(e) {
adjustImageSize($ac_bgimage);
/* calculate new width for the menu */
var new_w = $(window).width() - $title.outerWidth(true);
$menu.css('width', new_w + 'px');
});
},
/* makes an image "fullscreen" and centered */
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'
});
},
/* preloads a set of images */
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
};
})();
/*
call the init method of Menu
*/
Menu.init();
});
CSS
デモのスタイルシートは「reset.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(../images/pattern.png) repeat top left;
}
.ac_loading{
position:fixed;
top:10px;
right:10px;
background:#000 url(../images/loader.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(../images/bg_menu.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(../images/bg_menu.png) 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; /* animate to 400px */
top:50%;
right:0px;
margin-top:0px; /* animate to -200px */
position:fixed;
z-index:99;
overflow:hidden;
background:transparent url(../images/bg_menu.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(../images/close.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;
}
sponsors











