%e3%82%a2%e3%82%b3%e3%83%bc%e3%83%87%e3%82%a3%e3%82%aa%e3%83%b3%e3%83%a1%e3%83%8b%e3%83%a5%e3%83%bc%e3%81%ae%e5%ae%9f%e8%a3%85%e6%96%b9%e6%b3%95

アコーディオンメニューの実装方法

レスポンシブ

先日、レスポンシブ対応のアコーディオンメニューの実装の依頼があり、思わぬところで躓いたので、備忘録として残しておきます。

jQueryを使用しますが、実装方法は簡単です。

サンプルはこちら

サンプルは分かりやすくするために、余計な装飾は省いています。
あくまで構造だけ。

HTMLの「head」内に記述

1行目は、jqueryの読込です。
8~16行目までは、画面サイズに応じて、ul#menuの表示・非表示の切り替えをしています。
10行目の「var p = 480;」は横幅480pxになった時の、メニューの表示・非表示設定をしています。この記述があると、横幅を可変した時にメニューの切り替えがスムーズになります。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js?ver=3.8.1"></script>
<script type='text/javascript'>
$(function(){
  $("#toggle").click(function(){
    $("#menu").slideToggle();
    return false;
  });
  $(window).resize(function(){
    var win = $(window).width();
    var p = 480;
    if(win > p){
      $("#menu").show();
    } else {
      $("#menu").hide();
    }
  });
});
</script>

HTMLにメニュー部分を記述

	<div id="nav">
		<div id="toggle">
			<a href="#">menu</a>
		</div>
		<ul id="menu">
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
			<li><a href="#"><img src="sample.png" alt="" /></a></li>
		</ul>
	</div>

id、class名などは適宜変更してください。

CSS記述。レスポンシブ記載あり。

/* ==========================================================================
   メニュー
   ========================================================================== */
div#nav{
	margin: 100px 0;
	padding: 0;
	height: 40px;
	clear: both;
}
div#nav ul:after{
	height: 0;
	visibility: hidden;
	display: block;
	font-size: 0;
	content: " ";
	clear: both;
}
div#nav ul li{
	margin: 0;
	padding: 0 35px;
	float: left;	/* メニュー横並び */
	list-style-type: none;
}
div#nav ul li img{
	height: auto;
}
#toggle{
	display: none;
}

/* ==========================================================================
   480px以下のデバイス向け設定
   ========================================================================== */
/* 全体 */
@media only screen and (max-width: 480px) {
	body{
		margin: 0;
		padding: 0;
		width: 480px;
		min-width: 480px;
		max-width: 480px;
	}
	div#nav{
		margin: 0;
		width: 100%;
	}
	div#nav ul{
		height: auto;
		display: none;
		text-align: center;
	}
	div#nav ul li{
		margin: 10px auto;
		padding: 0;
		width: 480px;
		clear: left;
	}
	div#toggle{
		margin: 100px auto 10px;
		width: 100%;
		display: block;
	}
	div#toggle a{
		padding: 0;
		display: block;
		text-align: center;
	}
	div#nav ul li a:link,
	div#nav ul li a:visited{
		display: block;
	}
}

CSSは画像を使わないのであれば、もう少しシンプルに記述できます。

メニュースライドの表示速度を変更する

HTMLに組み込んだJSに直接書き込むだけ。

<script type='text/javascript'>
$(function(){
  $("#toggle").click(function(){
    $("#menu").slideToggle(1000);
    return false;
  });
  $(window).resize(function(){
    var win = $(window).width();
    var p = 480;
    if(win > p){
      $("#menu").show();
    } else {
      $("#menu").hide();
    }
  });
});
</script>

4行目の「.slideToggle()」に数値を入れるか、「”fast”」「#normal”」「”slow”」を記述するだけ。

注意点

今回、陥ったミスは、メニューを画像にしたため、「height」で高さ指定をしたことでした。
別に高さ指定をしても動作には問題がないのですが、上下にスライドする時に表示速度が変わるように見え、一律の速さにしてほしいとの指摘を受けました。
レスポンシブ時にメニューの「ul」に「height:auto」を指定するだけのことなんですが、まさかこの記述だけで動作がおかしくなるとは思わず、かなり時間を使ってしまいました。
もしお困りの方がいらっしゃったら、お試しください。

@media only screen and (max-width: 480px) {
	div#nav ul{
		height: auto;
		display: none;
	}
}