リスト要素をドロップダウンメニューに変換する jQuery プラグインを作ってみた
更新履歴
- 2011-09-29
- Ver 0.1.3 に更新
垂直方向へのスクロール状態でのメニュー表示位置ずれ不具合を修正しました。 - 2010-12-01
- Ver 0.1.2 に更新
ドロップダウンメニューの保持を示すマーカー(»)の表示位置の調整処理を補正しました。 - 2010-11-17
- Ver 0.1.1 に更新
メニューが画面の端で展開された際に、ウィンドウの表示枠からはみ出て隠れてしまわないように、表示位置を補正をするようにしました。Demo
先日、イントラの WEB ページで 10 年以上使用してる Java アプレット製のドロップダウンメニューを JavaScript でリニューアルしたいという相談を受けました。jQuery のプラグイン使えば簡単かなと思い安請け合いしたのですが、なかなかしっくりくるプラグインを見つけることができませんでした。具体的には水平/垂直の両方向に対応したドロップダウン、メニューの表示/非表示のタイミングの使用感といった点で Java アプレット版より劣ってしまいます。
そんな訳で Java アプレット版と同等レベルの使用感を実現させるべく自前で作成することになった jQuery プラグインを紹介します。
機能概要
ul 要素の入れ子で定義したリストをドロップダウンメニューに変換することができます。
ul 要素の入れ子でリストを定義し、
<ul class="example"> <li>API <ul> <li>Core <ul> <li>Object <ul> <li><a href="each.html">each(callback)</a></li> <li><a href="size.html">size()</a></li> <li><a href="length.html">length</a></li> </ul> </li> <li>Plugin <ul> <li><a href="fn.extend.html">$.fn.extend()</a></li> <li><a href="extend.html">$.extend()</a></li> </ul> </li> /* 省略 */ </li> </ul>
ルート要素となる ul に対しプラグインを適用します。以下のようなドロップダウンメニューが生成されます。
使い方
jquery.js 、 jquery.exdropdown.js 、exdropdown.css を読み込みます。
<link rel="stylesheet" type="text/css" href="exdropdown.css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.exdropdown.js"></script>
適用したい ul の先祖要素に対し、exDropDown() メソッドを適用します。
$('ul.example').exDropDown();
ルートメニューを水平方向に配置にする
horizonRootMenu パラメータを指定するとルートメニューを水平方向に配置にする事ができます。
$('ul.example').exListMenu({ horizonRootMenu : true });
ルートメニューのリスト項目を幅を均一にする
horizonListWidth パラメータを使用すると水平配置したルートメニューのリスト項目の幅を均一にすることができます。
$('ul.example').exDropDown({ horizonRootMenu : true, horizonListWidth : 100 });
デザインを CSS で変更する
ドロップダウンメニューのマークアップ
ul 要素の入れ子構成のマークアップに対しプラグインを適用しますが、プラグインを適用すると下記のように ul 要素の入れ子が無くなり、替わりに div 要素で階層を持つようなマークアップに変換されます。
/* ルートメニュー */ <ul class="ex-drop-down ex-dr-root ex-dr"> /* ドロップダウンメニューを保有してる場合 */ <li class="ex-dr-folder ex-dr"> /* list-A */ <a> <span class="ex-dr-label">text</span> <span class="ex-dr-arrow">text</span> </a> </li> <li class="ex-dr-folder ex-dr"> /* list-B */ <a> <span class="ex-dr-label">text</span> <span class="ex-dr-arrow">text</span> </a> </li> /* ドロップダウンメニューを保有しない場合 */ <li class="ex-dr"> <a>text</a> </li> </ul> /* ドロップダウンメニュー */ <div class="ex-dr-pack"> <div class="ex-dr-pack"> /* list-A に対応 */ <ul class="ex-dr-context ex-dr"> <li class="ex-dr-folder ex-dr"> /* list-C */ <a> <span class="ex-dr-label">text</span> <span class="ex-dr-arrow">text</span> </a> </li> </ul> <div class="ex-dr-pack"> /* list-C に対応 */ <ul class="ex-dr-context ex-dr"> <li><a>link</a></li> </ul> </div> </div> <div class="ex-dr-pack"> /* list-B に対応 */ /* 省略 */ </div> </div>
開発当初は ul 要素の入れ子状態を保持したままドロップダウンメニューを生成する実装にしてましたが、
- IE6 と IE8 の互換性
- ドロップダウンメニューの表示幅の自動調整
- CSS によるデザインのカスタマイズ性
等を考慮した結果、上記のようなマークアップを生成するようにしました。
デフォルトデザインの配色を変更する
以下の記述を追加すると、デフォルトのデザインの配色をブルー系に変更できます。
ul.ex-dr-root, ul.ex-dr-context{ border-top:solid 1px #0077bb; border-left:solid 1px #0077bb; } ul.ex-dr-context{ padding:0; border-bottom:#335577; border-right:#335577; } ul.ex-dr-root li a, ul.ex-dr-root li a:visited, ul.ex-dr-context li a, ul.ex-dr-context li a:visited{ padding:4px; text-decoration:none; background:#3399dd ; color:#fff; border:solid 1px #55bbff; border-right:solid 1px #0077bb; border-bottom:solid 1px #0077bb; } ul.ex-dr-root li a:hover, ul.ex-dr-context li a:hover{ background:#44aaee ; color:#ffff55; }
独自のクラス名でルートメニューのデザインのみを変更する
独自のクラス名でルートメニューのデザインのみを変更する場合は、rootStyle パラメータにそのクラス名を指定します。一画面に複数のドロップダウンメニューを置き、一方にのみ独自のスタイルを当てる場合に有効です。(ドロップダウン部分のスタイルを変更する場合は contextStyle パラメータを使います)
<ul class="menu1"> <li><a href="menu.html">menu</a></li> ... </ul> <ul class="menu2"> <li><a href="menu.html">menu</a></li> ... </ul>
ul.top-menu{ margin:0; padding:0; } ul.top-menu li a, ul.top-menu li a:visited{ padding:0 4px; margin-right:1px; text-decoration:none; background:#333; color:#fff; } ul.top-menu li a:hover{ color:#ffaacc; background:#000; }
$('#menu2').exDropDown(); $('#menu1').exDropDown({ horizonRootMenu : true, horizonListWidth : 129, rootStyle : 'top-menu' });
特定のリスト項目のみデザインを変更する
li 要素にクラス名を付与し、以下のような CSS を定義しするとアイコンを表示したり、配色を変更することができます。
<ul> <li class="section"><a href="menu.html">menu</a></li> <li class="icon"><a href="menu.html">menu</a></li> ... </ul>
ul.ex-dr-root li.section a, ul.ex-dr-root li.section a:visited{ background-color:#444; color:#ff5577; } ul.ex-dr-root li.section a:hover{ background-color:#222; color:#ff7799; } ul.ex-dr-root li.icon a, ul.ex-dr-root li.icon a:visited{ padding-left:20px; background-image:url(icon.gif); background-repeat:no-repeat; background-position-y:4px; }
Ver 0.1.1 の追加機能
表示位置の補正機能
メニューが画面の端で展開された際に、ウィンドウの表示枠からはみ出て隠れてしまわないように、表示位置を補正をするようにしました。
Demo
パラメータ
下記パラメータがあります。
- api
- 初期値:false
true にすると api オブジェクトを返します。 - marginLeft
- 初期値:-4
ドロップダウンメニューの水平位置を補正します。 - marginTop
- 初期値:-4
ドロップダウンメニューの垂直位置を補正します。 - horizonRootMenu
- 初期値:false
true にするとルートメニューが水平配置されます。 - horizonListWidth
- 初期値:auto
ルートメニューのリスト項目の幅を統一したい場合は、その幅を指定します。 - showDelay
- 初期値:500
リスト項目を mouseover した際のドロップダウンメニューが表示されるまでの時間を指定します。 - hideDelay
- 初期値:1500
リスト項目を mouseout した際のドロップダウンメニューが非表示にされるまでの時間を指定します。
false を指定することで自動非表示を抑止することができます。 - rootStyle
- 初期値:ex-dr-root
ルートメニューに適用するクラス名を指定します。 - contextStyle
- 初期値:ex-dr-context
ドロップダウンメニューに適用するクラス名を指定します。 - minWidth
- 初期値:100
リスト項目の幅の最小値を指定します。 - arrowText
- 初期値:&raquo;
ドロップダウンメニューの保持を示すマークとなる文字列を指定します。
API
下記メソッドがあります。
- showContext( li 要素 )
- 指定した li 要素配下のドロップダウンメニューを表示し true を返します
li 要素がドロップダウンメニューを保持してない場合は false を返します。 - hideContext( li 要素 )
- 指定した li 要素配下のドロップダウンメニューを非表示にし true を返します
li 要素がドロップダウンメニューを保持してない場合は false を返します。