以前「jQueryでマウス動作がストップした時を判別して処理する方法」と題して、jQueryでマウス動作がストップした時を判別して処理する方法を紹介しましたが、それを利用してドロップダウンメニューのロールオーバー動作をマウス動作がストップしたときに発動させるUI改善について紹介してみます。

jQueryでマウス動作が止まった時点で展開するドロップダウンメニューを実装する方法

「jQueryでマウス動作が止まった時点で展開するドロップダウンメニューを実装する方法」サンプルを別枠で表示

※上記のサンプルでは「WORKS」「PRODUCT」「RECRUIT」の3つのボタンのみにドロップダウンメニュー動作を実装しています。

ドロップダウンメニューのようなロールオーバーの状態を判別して処理するメニューUIでは、ボタンにロールオーバーをして表示されたメニューエリアにマウスカーソルを持って行く際に誤って隣のボタンに少しでも触れてしまうと表示されていたメニューエリアの内容が入れ替わってしまい、ユーザーが意図したボタン操作をするまでにストレスを与えてしまう場合があります。

そのようなストレスを軽減させるために、マウスカーソルが動いている間はドロップダウンの展開動作は実行させず、マウスカーソルが止まった時点の位置を判別して処理を実行することでユーザーに意図した操作をおこないやすくさせることができます。
※実際の動作感覚については上記のサンプル画面の「WORKS」「PRODUCT」「RECRUIT」の各ボタン操作にてご確認ください。

マウスカーソルが動いている間は処理を実行させないので、ボタンにロールオーバーをした後、誤って少しでも隣のボタンに触れてしまっても出現していたメニューエリアが切り替わることなく操作することが可能になります。

このマウスストップドロップダウンメニューの全体構成についてまずはHTMLから。

◆HTML
<nav id="mddNav">
<ul>
<li><a href="#">WORKS</a>
	<div class="mddWrap">
		<div class="mddInner">
			<p><strong>WORKS</strong>DESIGN・HTML/CSS・SYSTEM 制作について紹介します。</p>
			<div>
				<span>DESIGN</span>
				<ul>
					<li>><a href="#">コンセプトワーク</a></li>
					<li>><a href="#">受賞リスト</a></li>
					<li>><a href="#">実績紹介</a></li>
				</ul>
			</div>
			<div>
				<span>HTML/CSS</span>
				<ul>
					<li>><a href="#">W3C推奨マークアップ</a></li>
					<li>><a href="#">構築手順</a></li>
					<li>><a href="#">構築実績</a></li>
				</ul>
			</div>
			<div>
				<span>SYSTEM</span>
				<ul>
					<li>><a href="#">WEBシステム設計</a></li>
					<li>><a href="#">データ解析</a></li>
				</ul>
			</div>
		</div><!-- /.mddInner -->
	</div><!-- /.mddWrap -->
</li>
<li><a href="#">PRODUCT</a>
	<div class="mddWrap">
		<div class="mddInner">
			<p><strong>PRODUCT</strong>プロダクト・サービスについて紹介します。</p>
			<div>
				<span>WEB</span>
				<ul>
					<li>><a href="#">WEBサイト制作</a></li>
					<li>><a href="#">CMS設計</a></li>
					<li>><a href="#">制作の流れ</a></li>
				</ul>
			</div>
			<div>
				<span>MOBILE &amp; SMART PHONE</span>
				<ul>
					<li>><a href="#">レスポンシブ制作</a></li>
					<li>><a href="#">APP制作</a></li>
					<li>><a href="#">使用言語</a></li>
				</ul>
			</div>
			<div>
				<span>SERVER</span>
				<ul>
					<li>><a href="#">サーバ構築&運営</a></li>
					<li>><a href="#">サーバ移行</a></li>
					<li>><a href="#">DB設計</a></li>
				</ul>
			</div>
		</div><!-- /.mddInner -->
	</div><!-- /.mddWrap -->
</li>
<li><a href="#">RECRUIT</a>
	<div class="mddWrap">
		<div class="mddInner">
			<p><strong>RECRUIT</strong>新卒・キャリア採用についてはこちらから。</p>
			<div>
				<span>新卒採用</span>
				<ul>
					<li>><a href="#">募集職種</a></li>
					<li>><a href="#">募集要項</a></li>
					<li>><a href="#">応募フォーム</a></li>
				</ul>
			</div>
			<div>
				<span>キャリア採用</span>
				<ul>
					<li>><a href="#">募集職種</a></li>
					<li>><a href="#">募集要項</a></li>
					<li>><a href="#">応募フォーム</a></li>
				</ul>
			</div>
		</div><!-- /.mddInner -->
	</div><!-- /.mddWrap -->
</li>
<li><a href="#">BLOG</a></li>
<li><a href="#">CONTACT</a></li>
</ul>
</nav><!-- /#mddNav -->

各ボタンをリストで構成し、各リストの中にボタン要素となる<a>タグとロールオーバー後に表示するドロップダウンパネルの要素をクラス「.mddWrap」で囲んで組み込んであります。

「.mddWrap」の中はサンプル用の見た目を形成するものになり、動作自体にはとくに影響しない部分になります。

これらの要素に対してCSSは以下のように指定します。

◆CSS
/* ------------------------------
   #mddNav
------------------------------ */
#mddNav {
	width: 100%;
	height: 45px;
	background: #efefef;
	border-top: #aaa 1px solid;
	border-bottom: #aaa 1px solid;
	position: relative;
	box-sizing: border-box;
	z-index: 10;
}

#mddNav > ul {
	margin: 0 auto;
	width: 800px;
	height: 45px;
	text-align: left;
}

#mddNav > ul > li {
	width: 160px;
	height: 45px;
	float: left;
	border-left: #aaa 1px solid;
	box-sizing: border-box;
}

#mddNav > ul > li:last-child {
	border-right: #aaa 1px solid;
}

#mddNav > ul > li > a {
	height: 45px;
	font-size: 14px;
	font-weight: bold;
	line-height: 45px;
	display: block;
	text-align: center;
	border: #fff 1px solid;
	transition: all 0.2s linear;
}

#mddNav > ul > li:hover > a {
	background: #fff;
}

#mddNav > ul > li.mddActive > a {
	background: #fff!important;
}

#mddNav .mddWrap {
	top: 45px;
	left: 0;
	width: 100%;
	height: 0;
	text-align: center;
	background: #fff;
	background: linear-gradient(to bottom,  #fff 0%,#efefef 100%);
	border-bottom: #aaa 1px solid;
	position: absolute;
	z-index: 10;
	overflow: hidden;
	display: none;
	box-shadow: 0 2px 2px #eee;
}

#mddNav .mddWrap .mddInner {
	margin: 0 auto;
	padding-top: 45px;
	width: 800px;
	height: 250px;
	line-height: 1.6;
	text-align: left;
}

#mddNav .mddWrap .mddInner > div {
	margin-right: 20px;
	width: 250px;
	font-size: 14px;
	line-height: 1.6;
	float: left;
	border-right: #aaa 1px solid;
}

#mddNav .mddWrap .mddInner > div:last-child {
	margin-right: 0;
	border-right: none;
}

#mddNav .mddWrap .mddInner > div > ul > li {
	font-size: 14px;
	line-height: 1.6;
}

#mddNav .mddWrap .mddInner > div > ul > li a:link {
	text-decoration: underline;
}

#mddNav .mddWrap .mddInner > div > ul > li a:hover {
	text-decoration: none;
}

#mddNav .mddWrap .mddInner p {
	margin-bottom: 25px;
	padding-left: 10px;
	font-size: 14px;
	line-height: 1.6;
	border-left: #000 5px solid;
}

#mddNav .mddWrap .mddInner p strong {
	font-size: 1.1em;
	display: block;
}

#mddNav .mddWrap .mddInner > div span {
	margin-bottom: 5px;
	font-weight: bold;
}

#contents {
	margin: 0 auto;
	padding: 40px 0;
	width: 800px;
	text-align: left;
}

#contents p {
	padding-bottom: 2em;
	font-size: 1.2em;
	line-height: 2em;
}

/* ------------------------------
   Clearfix Elements
------------------------------ */
#mddNav > ul:after {
	content: " ";
	display: block;
	clear: both;
}

ドロップダウンメニュー全体を囲う要素をID「#mddNav」として、中に入るメニューボタン要素とロールオーバーで表示させるドロップダウンパネル部分のレイアウトを調整しています。

ドロップダウンパネル要素となる「.mddWrap」はCSS側では「display:none」をつけて非表示状態にしておきます。

そして実際のマウス動作スクリプトは以下の様になります。

◆SCRIPT
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(function(){
	var moveElm = $('#mddNav > ul > li');
	moveTimer = 0;
	hideTimer = 0;

	moveElm.hover(function(){
		var self = $(this),
		selfMdd = self.find('.mddWrap');

		self.on('mousemove', function(){

			clearTimeout(moveTimer);
			clearTimeout(hideTimer);

			moveTimer = setTimeout(function(){
				self.addClass('mddActive');
				selfMdd.css({display:'block'}).stop().animate({height:'250px',opacity:'1'},200,'swing');

				self.siblings('li').removeClass('mddActive');
				self.siblings('li').find('.mddWrap').stop().animate({height:'0',opacity:'0'},function(){
					$(this).css({display:'none'});
				});
			}, 200);
		});
	},function(){
		var self = $(this),
		selfMdd = self.find('.mddWrap');

		clearTimeout(moveTimer);

		hideTimer = setTimeout(function(){
			self.removeClass('mddActive');
			selfMdd.css({display:'none'});
		}, 200);
	});

	$('#mddNav > ul').hover(function(e){
		e.preventDefault();
	},function(){
		$('#mddNav > ul > li').removeClass('mddActive').find('.mddWrap').stop().animate({height:'0',opacity:'0'});
	});
});
</script>

スクリプト開始部分にある設定値の内容は以下の様になっています。

btnElm = $(‘#mddNav > ul > li’) ドロップダウンを表示させる対象となるボタン要素
mddSpeed = 300 ドロップダウンが展開する際のスピード

以前の記事のマウスストップ動作の紹介では「mousemove」と「mouseout」のみを使っての処理で実装していましたが、ドロップダウンメニューの場合は子要素もロールオーバーの対象とする必要があるため、全体を「hover()」メソッドを使って制御しています。

ボタン要素にロールオーバーした後に「mousemove」にてマウスが動いている間は処理を実行させず、マウス動作が止まった時点でドロップダウンパネルを展開する処理を実行させています。

ドロップダウンパネルと大元のボタンからマウスが外れた状態でマウス動作が止まった際には「hover()」メソッドの処理にてドロップダウンパネルを非表示にする処理を実行させます。

以上がjQueryを使ってマウス動作が止まった時点でドロップダウンメニューを動作させる方法でした。

ドロップダウンのメニュー展開後に、ほかのボタンに触れてしまってメニュー内容が切り替わってしまうのはユーザーのメニュー操作によるストレスにも大きくつながるので、この様な仕組みにすることで使い勝手のよいドロップダウンメニューを実装できるかと思います。

マウスが止まった時点で展開するドロップダウンメニューを実装する際にぜひ。

サンプルファイルをダウンロードしたい方はこちらから