jQueryを使ったアコーディオンメニューには様々なアイデアがあるが、どれも一長一短な感じがしていたので、ネット上で公開されているスクリプトを参考にしてカスタマイズしてみた。
まずはサンプルページを見てもらおう。なお、コードをできるだけわかりやすくするため、スタイルシートの記述は必要最低限に留めた。実際に使用する際は各自で装飾して欲しい。
アコーディオンメニューのサンプルページ
navigation menuと書かれた部分が親カテゴリーとなっているので、クリックすると以下のサブカテゴリーが表示させるようになっている。
サンプル1の記述
<<< JavaScript >>>
<script type="text/javascript">
$(function(){
$(".accordion1 span").click(function(){
$(".accordion1 ul").slideToggle("slow");
});
});
</script>
<<< HTML >>>
<div class="accordion1">
<span>navigation menu | ▼</span>
<ul>
<li><a href="#">menu #1</a></li>
<li><a href="#">menu #2</a></li>
<li><a href="#">menu #3</a></li>
<li><a href="#">menu #4</a></li>
<li><a href="#">menu #5</a></li>
<li><a href="#">menu #6</a></li>
<li><a href="#">menu #7</a></li>
</ul>
</div>
<<< CSS >>>
.accordion1 {
width:160px;
border:1px solid #000;
}
.accordion1 span {
display:block; /*ブロック要素として表示*/
margin:0;
padding:0;
width:160px;
height:30px;
text-align: center;
}
.accordion1 ul {
margin:5px 0 0 0;
margin:0;
padding:0;
display:none; /*閉じた状態で読み込む*/
height: 210px; /*開いたときの全体の高さ*/
}
.accordion1 li {
list-style:none;
margin:0;
padding:0;
height: 20px; /*項目の高さ*/
display:block;
}
.accordion1 li a {
margin:0;
padding:5px 10px;
display:block;
height: 20px; /*項目の高さ*/
}
ポイントは<span>をdisplay:blockでブロック要素としている点と、CSSの.accordion1 ulに記述したdisplay:noneでページ読み込み時にサブカテゴリーを隠していることだ。
シンプルで使いやすいが、ひとつ欠点があって複数の項目を使うためにはIDを変えたJSが親カテゴリー分だけ必要となる。カテゴリーが多いページには向かないだろう。
サンプル2はひとつのJSで複数の親カテゴリーを表示させるタイプで、上記のサンプル1の欠点をカバーしている。ただし、こちらにも使い勝手の悪い部分があって、クリックしてもらえばわかるが一旦開くと別の親カテゴリーを開かない限り、閉じることができないのだ。つまり、初期のすべて閉じた状態に戻すにはページを再読み込みするしかない。
サンプル2の記述
<<< JavaScript >>>
<script type="text/javascript">
$(function() {
$('.accordion2 dd').hide();
$('.accordion2 dt a').click(function(){
$('.accordion2 dd').slideUp();
$(this).parent().next().slideDown();
return false;
});
});
</script>
<<< HTML >>>
<dl class="accordion2">
<dt><a href="#">navigation menu1 | ▼</a></dt>
<dd>
<a href="#">menu #1</a><br>
<a href="#">menu #2</a><br>
<a href="#">menu #3</a><br>
<a href="#">menu #4</a><br>
<a href="#">menu #5</a><br>
<a href="#">menu #6</a><br>
<a href="#">menu #7</a><br>
</dd>
<dt><a href="#">navigation menu2 | ▼</a></dt>
<dd>
<a href="#">menu #1</a><br>
<a href="#">menu #2</a><br>
<a href="#">menu #3</a><br>
<a href="#">menu #4</a><br>
<a href="#">menu #5</a><br>
<a href="#">menu #6</a><br>
<a href="#">menu #7</a><br>
</dd>
<dt><a href="#">navigation menu3 | ▼</a></dt>
<dd>
<a href="#">menu #1</a><br>
<a href="#">menu #2</a><br>
<a href="#">menu #3</a><br>
<a href="#">menu #4</a><br>
<a href="#">menu #5</a><br>
<a href="#">menu #6</a><br>
<a href="#">menu #7</a><br>
</dd>
</dl>
<<< CSS >>>
.accordion2 {
width:160px;
}
.accordion2 dt {
background: #ddd;
padding: 10px;
border-top: 1px #ccc solid;
}
.accordion2 dt a {
color: #000;
text-decoration:none;
display:block;
}
.accordion2 dd {
padding: 10px;
}
これらの欠点を補うために作ったのがサンプル3のスクリプト。ひとつのJSで複数の親カテゴリーを個別に操作でき、クリックするたびにそれぞれ開閉が可能となっている。
サンプル3の記述
<<< JavaScript >>>
<script type="text/javascript">
$(function(){
$(".accordion3 ul").hide();
$(".accordion3 span").click(function(){
$(this).next("ul").slideToggle()
.siblings("ul:visible").slideUp();
$(this).toggleClass("active");
$(this).siblings("span").removeClass("active");
});
});
</script>
<<< HTML >>>
<div class="accordion3">
<span class="accordion3_title">navigation menu1 | ▼</span>
<ul class="accordion3_ul">
<li><a href="#">menu #1</a></li>
<li><a href="#">menu #2</a></li>
<li><a href="#">menu #3</a></li>
<li><a href="#">menu #4</a></li>
<li><a href="#">menu #5</a></li>
<li><a href="#">menu #6</a></li>
<li><a href="#">menu #7</a></li>
</ul>
</div>
<div class="accordion3">
<span class="accordion3_title">navigation menu2 | ▼</span>
<ul class="accordion3_ul">
<li><a href="#">menu #1</a></li>
<li><a href="#">menu #2</a></li>
<li><a href="#">menu #3</a></li>
<li><a href="#">menu #4</a></li>
<li><a href="#">menu #5</a></li>
<li><a href="#">menu #6</a></li>
<li><a href="#">menu #7</a></li>
</ul>
</div>
<div class="accordion3">
<span class="accordion3_title">navigation menu2 | ▼</span>
<ul class="accordion3_ul">
<li><a href="#">menu #1</a></li>
<li><a href="#">menu #2</a></li>
<li><a href="#">menu #3</a></li>
<li><a href="#">menu #4</a></li>
<li><a href="#">menu #5</a></li>
<li><a href="#">menu #6</a></li>
<li><a href="#">menu #7</a></li>
</ul>
</div>
なお、スタイルシートの適用はしていない。つまり、JSですべてを制御しているのでサンプル1のようにCSS側にdisplay:noneなどの記述をする必要はない。ようやく納得できるアコーディオンメニューとなった。