このページの本文へ

前へ 1 2 次へ

  • twitterでつぶやく
  • はてなブックマークに登録
  • del.icio.usに登録
  • livedoorクリップに登録
  • Buzzurlに登録
  • StumbleUponに登録
  • Google Bookmarksに登録
  • Facebookでシェア
  • Yahoo!ブックマークに登録
  • お気に入りに登録
  • 本文印刷

Web制作の現場で使えるjQuery UIデザイン入門 ― 第19回

jQueryで作る多階層ドロップダウンメニュー

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

文● 西畑一馬/to-R


多階層対応のドロップダウンメニューへ改造する

 サンプル01では1階層までのサブメニューを展開するメニューバーを作成しました。今度はより複雑な構造のサイトでも利用できるように、多階層対応のドロップダウンメニューへ改造します。

多階層対応版のドロップダウンメニュー。2回層目からは横にサブメニューを展開する

 HTMLは次のようになります。サンプル01と同じようにul/li要素の入れ子で記述していきます。このサンプルでは、メニューA、Cは1階層目(子カテゴリー)までのサブメニューを、メニューBは2階層目(孫カテゴリー)までのサブメニューを記述しています。

サンプル02(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>
                <ul class="sub">
                    <li><a href="#">サブメニューA2</a></li>
                    <li><a href="#">サブメニューA2</a></li>
                    <li><a href="#">サブメニューA2</a></li>
                </ul>
            </li>
        </ul>
    </li>
    <li><a href="#">メニューB</a>
        <ul class="sub">
            <li><a href="#">サブメニューB</a></li>
            <li><a href="#">サブメニューB</a>
                <ul class="sub">
                    <li><a href="#">サブメニューB2</a></li>
                    <li><a href="#">サブメニューB2</a></li>
                    <li><a href="#">サブメニューB2</a>
                        <ul class="sub">
                            <li><a href="#">サブメニューB3</a></li>
                            <li><a href="#">サブメニューB3</a></li>
                            <li><a href="#">サブメニューB3</a></li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><a href="#">サブメニューB</a></li>
        </ul>
    </li>
    <li><a href="#">メニューC</a>
        <ul class="sub">
            <li><a href="#">サブメニューB</a>
                <ul class="sub">
                    <li><a href="#">サブメニューC2</a></li>
                    <li><a href="#">サブメニューC2</a></li>
                    <li><a href="#">サブメニューC2</a></li>
                </ul>
            </li>
            <li><a href="#">サブメニューB</a></li>
            <li><a href="#">サブメニューB</a></li>
        </ul>
    </li>
</ul>


 CSSは次のようになります。2階層目以降のサブメニューはpositionで表示位置をずらすため、a要素にposition:relative;を設定して表示を位置を合わせるようにしています。サブメニュー内のli要素は(ul.sub li)はfloat:none;を適用して回り込みを解除し、横並びにならないようにしています。

 2階層目以降のサブメニュー(ul.sub li ul.sub)はposition:absolute;を指定しています。position:absoluteは、親要素のpositionプロパティにstatic以外の値が設定されている場合、親要素の左上が座標の基準になりますので、top:0;とleft:179px;と設定することで親要素のli要素と横並びに配置できます。この方法なら、階層がいくら増えてもサブメニューがきちんと表示されます。

サンプル02(CSS部分)


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


 以上でCSSは完成ですが、残念ながらIE6/IE7にはレイアウト機能にバグがあり、他のブラウザーと表示結果が異なるため、対策用に以下のCSSを追加します。

 サブメニュー(ul.sub)にdisplay:none;を設定しているのは、IE6の場合、dispay:noneの要素内の子要素のdisplayプロパティをjQueryで変更できないためです。サンプル01ではスクリプト側で非表示にしていましたが、今回はCSSで非表示しています。

 セレクターの冒頭に* htmlを付けているのはIE6用、*+htmlはIE7用のCSSです。IE6/7それぞれのli要素にdisplay:inline;とzoom:1;、サブメニューのul要素に対してposition:relative;とzoom:1;を設定しています。


ul.sub{
    display:none;
}
* html ul.menu li{
    display:inline;
    zoom:1;
}
*+html ul.menu li{
    display:inline;
    zoom:1;
}
* html ul.sub{
    zoom:1;
    position:relative;
}
*+html ul.sub{
    zoom:1;
    position:relative;
}


 スクリプト部分は次のようになります。

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


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


 初期設定はCSSで済ませたので、マウスオーバー/アウトイベントの処理のみ記述しています。サンプル01とほとんど同じですが、子セレクター(関連記事)を利用して、マウスカーソルが重なったli要素の直下のul要素だけ(つまり、子孫カテゴリーが存在する場合だけ)サブメニューの表示/非表示を切り替えるように変更しています。

 以上で、多階層型メニューバーが完成しました。slideUp()/slideDownをfadeIn()/fadeOut()(関連記事)に変更するとふわっと表示されるメニューになります。また、背景画像を変更するだけでも簡単にデザインをカスタマイズできます。好みに合わせて動きやデザインを変えてみてください。


著者:西畑一馬(にしはた かずま)

著者写真

to-R代表、Webクリエイター。PHPによるシステム開発や、CMSを利用したWebサイト制作、SEO対策などのマーケティング、コンサルティング、Webクリエイター向けの講座などを業務で行なっている。また、ブログto-RではJavaScriptやSEO対策、CSS、Movable TypeなどのWeb制作にかかわるさまざまな情報を発信している。
主な著書に「現場のプロから学ぶXHTML+CSS」(共著、毎日コミュニケーションズ刊)がある。

前へ 1 2 次へ

カテゴリートップへ

この連載の記事

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く

みんなが買ってる最新アイテムはコレだ!

Microsoft Windows 7 Home Premium 通常版 Service Pack 1 適用済み

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

マイクロソリューション Micro Solution Inc.

83人が購入

BenQ 24型 LCDワイドモニタ XL2420T

BenQ 24型 LCDワイドモニタ XL2420T

ベンキュージャパン

37,238円〜

3人が購入

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

アスキー・メディアワークス

2,499円〜

20人が購入

メモリーカード 32GB (PCH-Z321J)

メモリーカード 32GB (PCH-Z321J)

ソニー・コンピュータエンタテインメント

7,772円〜

6人が購入

Amazon.co.jp