DEMO
デモはこちら。Chrome、Firefox、Opera、Safariの新しめのやつと、一応IE6でも動きます。
※2012.01.28 – Firefox9/IE9で表示が乱れていた部分を修正
やってること
サブナビゲーションは普通に「#nav ul li」にマウスオーバーして開きます。
「#navbg」は「#nav」からは独立していて、「#nav ul」にマウスオーバーすると「#nav ul li」の位置までスライドして開きます。
html+css
htmlはリストの中にリストが入ってます。サブナビゲーションがある場合はだいたいこんな感じですよね。
html
<div id="nav"> <ul class="clearfix"> <li><a href="#">HOME</a></li> <li> <a href="#">ABOUT</a> <ul> <li><a href="#">ABOUT01</a></li> <li><a href="#">ABOUT02</a></li> <li><a href="#">ABOUT03</a></li> <li><a href="#">ABOUT04</a></li> </ul> </li> <li> <a href="#">BLOG</a> <ul> <li><a href="#">BLOG01</a></li> <li><a href="#">BLOG02</a></li> <li><a href="#">BLOG03</a></li> </ul> </li> ・・・・ </ul> <!-- /#nav--></div>
cssはムダなところが多いかもしれませんが、こんな感じにするとナビゲーションが横並びになります。
css
#nav { padding: 0 10px; font-size: 116%; color: #2C342D; border-bottom: solid 1px #2C342D; background: #EFF1EF; } #nav ul li { list-style: none; float: left; cursor: pointer; } #nav ul li a { font-weight: bold; text-decoration: none; color: #424F44; display: block; padding: 8px 20px; } #nav ul li a.over { background: #D1D8D1; } #nav ul li ul { position: absolute; z-index: 1; } #nav ul li ul li { position: absolute; width: auto; cursor: pointer; font-size: 80%; } #nav ul li ul li a { padding: 11px 16px; background: transparent; white-space: nowrap; color: #fff; } #nav ul li ul li a:hover { background: #373C37; } #navbg { background: #6B726B; position: absolute; width: 0px; }
「#navbg」はhtmlにはないですが、サブナビゲーションのバックの部分で、あまり意味のない部分ですのでjQueryで配置します。
jQueryの部分
最初にメイン・サブナビゲーションの配置の設定を行います。
var nav = $('#nav'); //(メインメニュー)ulをliの合計のwidthにする var ulWidth = 0; $('>ul>li', nav).each(function (i) { ulWidth += $(this).outerWidth(true); }); $('>ul', nav).css('width', ulWidth+'px'); //サブメニューのwidth取得とUIの設定 var subWidthArray = new Array(); $('>ul>li', nav).each(function (i) { var tempNum = 0; if($('>ul',this).length == 1) { $('>ul>li',this).each(function () { $(this).css('left', tempNum + 'px'); tempNum += $(this).outerWidth(true); }); $('>ul',this).css('width', tempNum + 'px'); } else { subWidthArray[i] = 0; } subWidthArray[i] = tempNum; });
- 2~7行目
-
サブナビゲーションのwidthを一つ一つ取得して、メインナビゲーション全体のwidthに割り当ててます。
ulはブロック要素なのでそのままだと横画面一杯に広がってますので、マウスオーバーしたときにあまりよろしくありません。
ただ、横型のナビゲーションだとボタンを画像にすることが多いので、その場合はcssで指定した方が早いですね。 - 9~21行目
-
サブナビゲーションでも同じようにwidthを取得してます。
サブメニューは絶対配置なのでwidthを取得した分だけleftで右にずらします。
(2012.01修正)
その他初期設定とかです。
//サブナビゲーションに追尾するやつを配置 nav.append('<div id="navbg"></div>'); var navbg = $('#navbg'); //navbgの初期位置 var homeLeft = nav.position().left; //サブナビゲーションがマウスオーバー状態か var subNavFlug = false; //#navbgの高さをサブナビゲーションと同じにする navbg .height($('ul li ul li', nav).height()) .css({ 'top': $('ul li ul', nav).position().top, 'left': $(nav).position().left }); //サブナビゲーションを非表示 $('ul ul', nav).css('display', 'none');
メインulにマウスオーバーしたら
ここからマウスオーバーの処理です。
メインのulのマウスインの設定はありませんが、アウトしたときかつ「subNavFlug」が「false」のときに初期地点に戻り、横幅を0にします。
$('ul', nav).hover( function() {}, function() { if (subNavFlug == false) { navbg.animate({ 'left' : homeLeft, 'width': 0 }, 300); } });
メインliにマウスオーバーしたら
サブナビゲーションの開閉はliのマウスオーバーで設定します。
//メインナビゲーションマウスオーバーでサブナビゲーション開く $('>ul>li',nav).hover( function() { $('>a',this).addClass('over'); var currntNum = $(this).index(); var currentUl = $('ul', this); currentUl .show() .css('opacity', 0); //X座標取得 var posX = $(this).position().left; currentUl.css('left', posX); //navbgをサブナビゲーションの位置に移動 if(subWidthArray[currntNum]) { navbg.animate({'left' : posX, 'width': subWidthArray[currntNum]}, 300, function(){ currentUl.css({'opacity': 1}); }); } else { navbg.animate({'left' : homeLeft, 'width': subWidthArray[currntNum]}, 300); } }, function() { $('>a',this).removeClass('over'); $('ul', this).hide(); });
サブナビゲーション(currentUl)はマウスオーバー後すぐに表示(show)すると「#bgnav」がない状態で表示されてしまいますので、すぐに透明度(opacity)を0にしてアニメーション後に透明度を1にします。
サブナビゲーションのマウスオーバーでフラグON
最後にフラグ(subNavFlug)の切り替えを行ってます。
//サブナビゲーションマウスオーバーでフラグON $('>ul>li>ul',nav).hover( function() { subNavFlug = true; }, function() { subNavFlug = false; });
最終的なコードです。
ソースコード