jQuery:hoverしたらメニューがぬるっと横に開いて中身のテキストがフェードインするやつを作る

だま
だま

タイトルを見てなんぞ?と思った方は、とりあえずデモページを見てもらえればと思います。

デモページ

※ブラウザの横幅を1024px以下にすると、メニューが縦方向に開くようになります。

こんな感じの動きを実装できるjQueryの紹介です。

html

今回はhoverしたli要素の横幅を伸ばし、その中に入っているdd要素がフェードインするようにしました。

<ul class="menu-list">
	<li>
		<dl>
			<dt>サンプルタイトル</dt>
			<dd>フェードインする部分</dd>
		</dl>
	</li>
	<li>
		<dl>
			<dt>サンプルタイトル</dt>
			<dd>フェードインする部分</dd>
		</dl>
	</li>
	<li>
		<dl>
			<dt>サンプルタイトル</dt>
			<dd>フェードインする部分</dd>
		</dl>
	</li>
	<li>
		<dl>
			<dt>サンプルタイトル</dt>
			<dd>フェードインする部分</dd>
		</dl>
	</li>
</ul>

css

ul要素にdisplay:flex;を設定して中身を横並びにし、ぬるっとさせる為にli要素へtransitionを設定。

li要素に「open」のclassが付与された時にメニューの横幅が広がるようにします。

フェードインしたい要素はdisplay: none;で予め非表示にしておきます。

ul{ display: flex; }
ul li{
	width: calc(100% / 4);
	height: 350px;
	padding: 30px 0;
	transition: .4s;
}
/* メニューが開いた時の幅 */
ul li.open{ width: 460px; }
/* フェードインする要素を非表示にしておく */
ul li dl dd{ display: none; }

jQuery

こんな感じで書きます。

<script>
	$(function(){
		$('.menu-list li').hover(function() {
			$(this).addClass('open');//hoverしたメニューにopenを付与
			hoverEasing = setTimeout(function(){//時間差でテキストをフェードイン
				$('.open dd').fadeIn();
			},400);
		},
		function() {
			$('.menu-list li dd').hide();//中身のテキストをすべて非表示に
			$('.menu-list li').removeClass('open');//すべてのメニューを閉じる
			clearTimeout(hoverEasing);//setTimeoutをリセット
		});
	});
</script>

setTimeoutを使用してフェードインを少し遅らせる事で、テキストを自然に表示できます。

遅らせないとメニューの横幅に連動してテキストの幅もヌルヌルヌル~っと可変してしまうのでちょっと気持ち悪いです。

テキストがフェードインした瞬間にカーソルを外すとメニューを閉じた後に再度setTimeoutの処理が実行されてテキストが残ったままになってしまう現象が起きたので、clearTimeoutを入れて意図せぬタイミングでイベントが発火するのを防いでいます。

clickイベントでやりたい人向けのおまけ

いやhoverじゃなくてclickイベントでやりたいんだけど?やっぱスマホ対応とかあるし?って人もいると思います。

そんな場合は、こんな感じにします。開いているメニューをもう一度クリックすると閉じるようにしています。

<script>
	$(function(){
		$('.menu-list li').on('click',function() {
			if($(this).hasClass('open')){//クリックしたメニューにopenが付与されていたら
				$('.menu-list li dd').hide();//中身のテキストをすべて非表示に
				$('.menu-list li').removeClass('open');//すべてのメニューを閉じる
			} else {//クリックした要素にopenが付与されていなかったら
				$('.menu-list li dd').hide();//中身のテキストをすべて非表示に
				$('.menu-list li').removeClass('open');//すべてのメニューを閉じる
				$(this).addClass('open');//クリックしたメニューを開く
				setTimeout(function(){//時間差でテキストをフェードイン
					$('.open dd').fadeIn();
				},400);
			}
		});
	});
</script>

関連記事