このページの本文へ

jQueryで作る多階層ドロップダウンメニュー (1/2)

2009年11月19日 22時26分更新

文●西畑一馬/to-R

  • この記事をはてなブックマークに追加
本文印刷

※この記事は「Web制作の現場で使えるjQuery UIデザイン入門」の第19回です。過去の記事もご覧ください。


 「ドロップダウン型メニューバー」は、メニューにマウスカーソルを重ねるとサブメニューが下または右方向に展開するUIです。グローバルメニューとして設置すれば、サイト内のどのページからでもサブカテゴリーや孫カテゴリーにワンクリックで直接移動できる、使い勝手のいいナビゲーションを実現できます。今回は、jQueryでドロップダウン型メニューバーを作成する方法を解説します。

今回制作するサンプル

サンプル画面
ドロップダウン型のメニューバーのサンプル。マウスカーソルを重ねるとサブメニューが展開する(画像クリックでサンプルページを表示します)


基本のドロップダウンメニュー

 メインメニューにマウスカーソルを重ねると、すぐ下にサブメニューを表示するドロップダウン型メニューから作りましょう。サブメニューの1回層目までの表示に対応したメニューです。

サンプル01完成図

メインメニューのすぐ下にサブメニューを表示する

 メニューバーのHTML/XHTML(以下、HTML)は以下のように記述します。メインメニューをul/li要素で記述し、メインメニューに対応するサブメニューをli要素の中にul/li要素で入れ子に記述していきます。メインメニューのul要素にはclass属性「menu」を、子カテゴリーのul要素にはclass属性「sub」を付けて親子関係を分かりやすくしておきます。


サンプル01(HTML部分)


<ul class="menu">
    <li><a href="#">メニューA</a>
        <ul class="sub">
            <li><a href="#">サブメニューA</a></li>
            <li><a href="#">サブメニューA</a></li>
            <li><a href="#">サブメニューA</a></li>
        </ul>
    </li>
    <li><a href="#">メニューB</a>
        <ul class="sub">
            <li><a href="#">サブメニューB</a></li>
            <li><a href="#">サブメニューB</a></li>
            <li><a href="#">サブメニューB</a></li>
        </ul>
    </li>
    <li><a href="#">メニューC</a>
        <ul class="sub">
            <li><a href="#">サブメニューC</a></li>
            <li><a href="#">サブメニューC</a></li>
            <li><a href="#">サブメニューC</a></li>
        </ul>
    </li>
</ul>

 CSSでは、メインメニューのすぐ下、縦方向にサブメニューが並ぶようレイアウトします。このCSSをjQueryで操作し、メインメニューがマウスオーバーされたときにサブメニューの表示/非表示を切り替えるわけです。

作例サンプル

CSSでは上記画面のようにレイアウトする

 メインメニューのli要素(ul.menu li)はfloatプロパティで横並びにします。a要素はクリック領域をli要素と同じサイズに拡大するため、display:block;でブロックレベル要素に変換し、widthとheightに100%を指定します。a:hoverにはマウスオーバー時の背景を設定して簡単なロールオーバー効果を付けておきましょう。

 サブメニューのli要素(ul.menu li ul.sub)にposition:absolute;を設定しているのは、サブメニューを開いた際にマウスイベントが動作しなくなる現象を防ぐためです。最後に、メインメニューの回り込み(float:left;)を解除するためclearfixを設定します。clearfixについてはコラムで詳しく解説していますので参照してください。

サンプル01(CSS部分)


ul.menu li{
    float:left;
    width:179px;
    height:48px;
    background:url("images/btn.png");
}
ul.menu li a{
    display:block;
    width:100%;
    height:100%;
    line-height:48px;
    text-indent:30px;
    font-weight:bold;
    color:#CFDFB5;
    text-decoration:none;
}
ul.menu li a:hover{
    background:url("images/btn_over.png");
}
ul.menu li ul.sub{
    position:absolute;
}
ul.menu{
    zoom:1;
}
ul.menu:after {
    height:0;
    visibility:hidden;
    content:".";
    display:block;
    clear:both;
}


 スクリプト部分は次のようになります。今回は非常にシンプルです。

サンプル01(スクリプト部分)


$(function(){
    $("ul.sub").hide();
    $("ul.menu li").hover(function(){
            $("ul:not(:animated)",this).slideDown("fast")
        },
        function(){
            $("ul",this).slideUp("fast");
    })
})


 初期設定では、サブメニューのul要素を非表示にします。次にjQueryのhover()イベントでマウスオーバーイベントとマウスアウトイベントを設定します。hover()は以下のように記述します。


$(セレクター).hover(function(){
    マウスオーバー時のイベント
},function(){
    マウスアウト時のイベント
})


 hover()はmouseover() /mouseout()とよく似ていますが(関連記事)、少しだけ挙動が異なります。mouseover()/mouseout()はセレクターで指定した要素内に子要素が存在する場合、子要素にマウスカーソルが移動した際にもイベントの処理が実行されます。たとえばドロップダウンメニューの場合、メインメニューからサブメニューへのマウスカーソルの移動でも処理が実行されます。一方、hover()の場合は、セレクターで指定した要素にマウスカーソルが重なったか、外れたかだけを感知し、子要素への移動は感知しません。

 メインメニューにマウスカーソルが重なると、slideUp()/slideDown()(関連記事)を利用してサブメニューを表示します。このとき、アニメーションが何度も実行されることを防ぐため、:not(:animated)セレクターを忘れずに追加しておきましょう(関連記事)。

 以上でドロップダウン型メニューバーが完成しました。


【CSSワンポイントレッスン 】

floatによる回り込みを解除するclearfix

 floatを利用して回り込みをする場合、後続する要素でclear:bothを指定すると回り込みを解除できます。ただし、サンプル1のように後続する要素が存在しない場合など、clear:bothで回り込みを解除できないこともあります。そんなときに役立つのが「clearfix」と呼ばれるCSSのテクニックです。


ul.menu:after {
    content:".";
    display:block;
    clear:both;
    height:0;
    visibility:hidden;
}


 floatで回り込みを設定した要素(ul menu li)を包んでいる要素(ul.menu)を指定し、after擬似要素とcontentプロパティで要素を擬似的に作って挿入します。作成した擬似要素のdisplayプロパティをblockに変換し、clear:bothを指定することでfloatの回り込みを解除します。このままだとブラウザー上に擬似要素が表示される(表示領域が確保される)ため、最後にvisibility:hidden;やheight:0;を利用して擬似要素を不可視の状態に変更します。

 ただし、この方法はafter擬似要素に対応していないInternet Explorer 6(IE6)やIE7では利用できません。IE6やIE7では以下のように独自のzoomプロパティを設定することで回り込みを解除できます。


ul.menu{
    zoom:1;
}




次ページ:

前へ 1 2 次へ

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています