ulリスト + jQueryで作る、開閉するアコーディオンメニュー

ulリスト + jQueryで作る、開閉するアコーディオンメニュー

連動開閉するアコーディオンメニューというものを作ったので、自分の備忘録として。ページ遷移時に該当部分は開いておく機能(WPの条件分岐にて)もおまけで。


サンプル

三角のアイコン部分が開閉します。閉じている時は右向き、開いている時は下向きになります。他を開くと今開いていた所は一緒に閉じます。

参考サイト

こちらを参考にさせていただきました。ありがとうございます!

三角アイコン素材

右向き三角 下向き三角

デモで使ってる画像です。よかったらお使い下さい。簡単な画像ですのでどこにでも使っていただいて構いません。スマホ対応のため、CSSで1/2サイズで表示します。

コード

html

<ul class="accordion">
	<li class="current"><a href="#">リスト1</a></li>
	<li><a href="#">リスト2</a></li>
	<li class="sub">
		<p><span>リスト3</span></p>
		<ul>
			<li><a href="#">サブリスト3-1</a></li>
			<li><a href="#">サブリスト3-2</a></li>
			<li><a href="#">サブリスト3-3</a></li>
		</ul>
	</li>
	<li class="sub">
		<p><span>リスト4</span></p>
		<ul>
			<li><a href="#">サブリスト4-1</a></li>
			<li><a href="#">サブリスト4-2</a></li>
			<li><a href="#">サブリスト4-3</a></li>
		</ul>
	</li>
	<li><a href="#demo">リスト5</a></li>
	<li class="sub">
		<p><span>リスト6</span></p>
		<ul>
			<li><a href="#">サブリスト6-1</a></li>
			<li><a href="#">サブリスト6-2</a></li>
			<li><a href="#">サブリスト6-3</a></li>
		</ul>
	</li>	
</ul>

css

ul.accordion{ /* アコーディオンを含むリスト */
	width: 150px;
	margin: 20px 0;
	}
ul.accordion ul{
	margin: 2px 0 10px 14px;
	display: none; /* アコーディオン非表示 */
	}
ul.accordion li{ /* 見出し */
	list-style: none;
	line-height: 20px;
	border-left: 3px #6cf solid;
	padding-left:5px;
	margin: 5px 0;
	color: #333;
	}
ul.accordion li a{
	color: #333;
	text-decoration: none;
	}
ul.accordion li a:hover, .over{
	color: #666;
	text-decoration: underline;
	}
ul.accordion li.current{
	font-weight: bold;
	background-color: #dffcff;
	}
ul.accordion li.sub{ /* サブメニュー */
	border: none;
	padding: 0;
	}
ul.accordion li p span{ /* サブメニューの三角アイコン */
	background:url(accordion-list1.gif) no-repeat 0 6px;
	background-size: 4px 7px;
	padding-left: 9px;
	}
ul.accordion li p span.open{ /* サブメニューが開いてるとき */
	background:url(accordion-list2.gif) no-repeat 0 7px;
	background-size: 7px 4px;
	padding-left: 12px;
	}

マウスホバーしたときに下線が出るようにしています。aタグだけでなく開閉部分のホバーにも下線が出たほうが「押せる」感があるかなと思って.overというクラスを作っています。(21行目)

p:hoverでいけると思ってたらIEでバージョンによってぐぬぬ…!クラス作ってjQuery側で付与してあげる形にしました。

jQuery

<script type="text/javascript">
jQuery(function($) {
	$('.accordion p').mouseover(function(){
		$(this).addClass('over');   
	});
	$('.accordion p').mouseout(function(){
		$(this).removeClass('over');   
	});
	$('.accordion p').click(function(){
		if($(this).next('ul').is(':visible')) { //既に開いている場所なら
			$(this).next('ul').slideUp(300); //閉じる
			$(this).children('span').removeClass('open'); //.openを削除
		} else { //閉じている場所なら
			$('.accordion ul').slideUp(); //全部閉じる
			$('.accordion').find('span').removeClass('open'); //.open全削除
			$(this).next('ul').slideDown(300); //開く
			$(this).children('span').addClass('open'); //.open付加
		}
	});
})(jQuery);
</script>

WPでない場合は2行目と20行目は必要ありません。

3~8行までが前述の開閉部分のマウスホバー・アウトで.overというクラスを付けたり消したりしてるところ。

9から19行目がクリック時に開閉するところ。詳しくはコメントアウトに解説を書いておきました。

WordPressでページ遷移時に該当部分を開いておく

141107-1

デフォルトだと全部閉じていますが、このようにページ遷移した時にカレントのあるところは開いておきたい、という内容。

WPじゃない場合も頑張れば出来そうですが、今回自分で実装したのがWPだったのでメモがてら。固定ページの条件分岐を使います。リスト1, 2, 3…のリンク先が、それぞれ p1, p2, p3… というスラッグの固定ページだとします。

php

<?php $ad = ' class="current"'; ?>
<ul class="accordion">
	<li<?php if(is_page('p1')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p1">リスト1</a></li>
	<li<?php if(is_page('p2')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p2">リスト2</a></li>
	<li class="sub">
<?php if(is_page(array('p3-1','p3-2','p3-3'))): //このページのどれかなら ?>
		<p><span class="open">リスト3</span></p>
		<ul>
<?php else: //それ以外 ?>
		<p><span>リスト3</span></p>
		<ul class="hide">
<?php endif; //if終了 ?>
			<li<?php if(is_page('p3-1')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p3-1">サブリスト3-1</a></li>
			<li<?php if(is_page('p3-2')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p3-2">サブリスト3-2</a></li>
			<li<?php if(is_page('p3-3')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p3-3">サブリスト3-3</a></li>
		</ul>
	</li>
	<li class="sub">
<?php if(is_page(array('p4-1','p4-2','p4-3'))): ?>
		<p><span class="open">リスト4</span></p>
		<ul>
<?php else: ?>
		<p><span>リスト4</span></p>
		<ul class="hide">
<?php endif; ?>
			<li<?php if(is_page('p4-1')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p4-1">サブリスト4-1</a></li>
			<li<?php if(is_page('p4-2')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p4-3">サブリスト4-2</a></li>
			<li<?php if(is_page('p4-3')){ echo $ad; } ?>><a href="<?php echo home_url('/'); ?>p4-3">サブリスト4-3</a></li>
		</ul>
	</li>
</ul>

長くなるのでリスト5以降は省略。

まず1行目で$adという変数に class="current"という文字列(頭に空白有)を入れておいて、各リスト部分でis_page('スラッグ名')の判別を行い、該当のページなら$adを出力することで、カレント表示させます。

全部にecho ' class="current"';って書いてもいいんですけどちょっとでも短くなるかなーと思って(;´Д`)

そして、6行目で該当のサブリストのページを全て指定して、これに含まれる場合は

<p><span class="open">リスト3</span></p>
<ul>

.openをつけたspanにしておいて、それ意外は

<p><span>リスト3</span></p>
<ul class="hide">

.openの無いspanと、ulに.hideというクラスがついたもの。

条件によって、このどちらかが出力されるようにしておきます。

css

先ほど書いたcssでは、

ul.accordion ul{
	margin: 2px 0 10px 14px;
	display: none; /* アコーディオン非表示 */
	}

と、サブリストは特に指定無しで全て非表示になっていたところを、

ul.accordion ul{
	margin: 2px 0 10px 14px;
	}
ul.accordion ul.hide{
	display: none; /* アコーディオン非表示 */
	}

.hideというクラスがついたところを非表示にする、というふうに分けておきます。

こうすれば、phpによって出し分けされたhtmlで、あらかじめ非表示にしておくところ、そうでないところを指定することができる、という感じです。

いかがでしたでしょうか。どなたかの参考になれたら幸いですー!

このメニューを使ったこんな記事も書きました。

公開日:2014/11/07

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)

YouTubeでQ&Aコンテンツを企画しています

運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。