メニューの子カテゴリをjqueryでフワッと表示する

子カテゴリをフワッっと表示する

前回メニューに配置したカテゴリから、子カテゴリを取得するところまで解説しました。

今回は、前回出力したソースからマウスホバーで子カテゴリを表示を行います。
CSSでも同じ様な動きができますが、今回はjqueryでシンプルにやってみます。

HTML・CSSの記述

まず前提になるPHPで出力されるソースはこんな感じ。

HTML

<div class="menu">
	<ul>
		<li class="menu-item">
			<a href="">親メニュー1</a>
			<ul class="sub-menu">
				<li class="sub-menu-item"><a href="">子メニュー1</a></li>
				<li class="sub-menu-item"><a href="">子メニュー2</a></li>
				<li class="sub-menu-item"><a href="">子メニュー3</a></li>
				<li class="sub-menu-item"><a href="">子メニュー4</a></li>
			</ul>
		</li>
		<li class="menu-item">
			<a href="">親メニュー2</a>
		</li>
		<li class="menu-item">
			<a href="">親メニュー3</a>
			<ul class="sub-menu">
				<li class="sub-menu-item"><a href="">子メニュー1</a></li>
				<li class="sub-menu-item"><a href="">子メニュー2</a></li>
				<li class="sub-menu-item"><a href="">子メニュー3</a></li>
				<li class="sub-menu-item"><a href="">子メニュー4</a></li>
			</ul>
		</li>
		<li class="menu-item">
			<a href="">親メニュー4</a>
		</li>
	</ul>
</div>

CSS

<style>
ul{
	margin:0;
	padding:0;
}
.menu{
	width:800px;
	margin:0 auto;
}

.menu ul li.menu-item{
	width:25%;
	height: 30px;
	font-size:14px;
	line-height: 30px;
	text-align: center;
	background: #418bd8;
	border-left:1px solid #fff;
	list-style-type: none;
	display: block;
	box-sizing: border-box;
	float:left;
	position: relative;
}

a{
	text-decoration: none;
	color: #fff;
	display: block;
}

a:hover{
	background:#95b6d8;
}

.sub-menu{
	width:100%;
	display:none;
	position: absolute;
	top:50px;
}

.sub-menu-item{
	width:100%;
	height: 30px;
	font-size:14px;
	line-height: 30px;
	text-align: center;
	background: #72a4d8;
	list-style-type: none;
	border-top:1px solid #fff;
	box-sizing: border-box;
}
</style>

CSSのポイントは2点

・sub-menuを初期にdisplay:noneで消しておく。
・フワッと上げるのでtop:50pxで少し下げておく。

jqueryの記述

jquery

<script>
	$(function(){
		$(".menu ul li").has("ul").on({
			'mouseenter' : function(){
				$(this).children('ul').show().animate({opacity:'1',top:'30px'},200);
			},
			'mouseleave' : function(){
				$(this).children('ul').animate({opacity:'0',top:'50px'},500).hide();
			}
		})
	});
</script>

処理を簡単に解説していきます。

$(“.menu-item”).has(“ul”)

今回のポイントその1はこの.has()メソッド。
()内の子孫要素を持った親要素に対して処理を行うようにするメソッドです。

.on()

ポイントその2は.on()メソッド。
.onを使うことで一つのセレクタに複数のイベントタイプを定義できます。

mouseenterとmouseleave

同じような使い方ではmouseoverとmouseoutもあるのですが、内包要素にフォーカスされた時に挙動がおかしくなるようなので今回はmouseenterとmouseleaveを使いました。

.children(‘ul’)

マウスホバー時のセレクタは親メニューですが、実行するセレクタは子メニューなので.children(‘ul’)で子要素にあるulを指定してやります。

show()とhidden()

それぞれdisplay:blockとdisplay:noneと同義の処理になります。

アニメーション内でopacityを使った透明化はしていますが、それだけだと透明になっただけなので、その辺りにマウスを当てると子メニューが出現しちゃいます。
ですので、チェーンメソッドでそれぞれのアニメーション処理前後にかませて出現・消去を行っています。

まとめ

非常にシンプルですがjqueryの挙動を知るには良いソースじゃないでしょうか。

ちなみに上記の例ですと、アニメーション処理中に素早くフォーカスを繰り返した場合、表示・非表示を繰り返す挙動が発生します。
それが気になる方は子メニューのセレクタに下記を追加してください。

.children("ul:not(:animated)")

アニメーション処理中は処理を行わない指定なんですが、この場合素早くフォーカスを繰り返すとマウスホバーに反応しなくなるケースがあります。(外でクリックした後だと正常に作動する。)

どちらも一長一短な感じで、もっと良い方法がないかと模索中です。

2件のコメント

ありがとうございます。とても良い記事に感謝です。参考にさせて頂きました。
あと、post-typeではなくて、post_typeかもしれません。

コメントありがとうございます。
参考にになったようで何よりです!

あと、ご指摘ありがとうござます。
post_typeでしたね…早速修正しておきました。

コメントを残す

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

CAPTCHA