問題
スマートフォンのメニューでモーダルウィンドウをプラグインなしで実現させるには?
解決策
コンテンツ・ナビゲーション表示用ボタン、ナビゲーションの3つのブロックに分け、css、jqueryで操作する。
モーダルウィンドウをプラグインなしで実装します。
スマートフォンのナビゲーションには、様々なタイプがあります。
- ハンバーガー
- ドロップダウン
- スライド
- アイコン
その中でもモーダルウィンドウタイプをプラグインなしで実装します。
プラグインを使わないことで、
- プラグインの設定による拘束がなくなる。
- カスタマイズが自由に行えて、機能や挙動の拡張が容易。
などのメリットがあります。
3つのブロックに分けます。
まず、モーダルウィンドウを実装するために、HTMLのbodyタグ内を3つのブロックに分ける必要があります。
- メニューボタン
- ナビゲーション
- コンテンツ
これらを「コンテンツ」、「ナビゲーション」、「メニューボタン」の順に、上から重ねて表示させる必要があります。
メニューボタンの作成
まず、メニューボタンの構築です。
HTMLの構築
Ulでメニューボタンを構築します。
<ul class="menu-icon clearfix sp">
<li class="menu">
<a href="#">
<span class="icon"></span>
<span class="text">MENU</span>
</a>
</li>
</ul>
CSSの構築
CSSで「position: fixed;」に設定します。
そして一番手前に表示させるため、「z-index: 9999;」を設定します。
※メニューボタンの設定に関しては、過去の記事をご覧ください。
バツマーク(×)に切り替わるメニューアイコンの作り方
.menu-icon{
position: fixed;
top: 0;
right: 0;
z-index: 9999;
}
ナビゲーションの作成
次に、ナビゲーションの構築です。
HTMLの構築
id「mdl-nav」と設定した要素で囲い、メニューのリスト「クラス:nav-list」を構築します。
<div id="mdl-nav" class="sp">
<div class="inner-wrapper">
<ul class="nav-list clearfix">
<li>
<a href="#">メニュー1</a>
</li>
<li>
<a href="#">メニュー2</a>
</li>
<li>
<a href="#">メニュー3</a>
</li>
</ul>
</div><!-- inner-wrapper -->
</div><!-- /mdl-nav -->
CSSの構築
CSSでid「mdl-nav」に「position: fixed;」「display: none;」に設定します。
さらにメニューボタンの次に表示されるように、「z-index」で1~9998の数値を設定します。
そしてリストのクラス「nav-list」に、適宜cssを設定します。
#mdl-nav {
position:fixed;
top:65px;
right:0;
bottom:0;
left:0;
overflow:auto;
margin:auto;
padding: 30px 30px 60px;
z-index:2000;
display:none;
background-color:rgba(252,236,232,0.8);
z-index: 5000;
}
.nav-list {
margin-bottom: 20px ;
}
.nav-list > li{
margin-bottom: 5px;
}
.nav-list > li a{
display: block;
padding: 5px 10px 5px;
color: #000000;
font-weight: bold;
letter-spacing: 0.5pt;
}
コンテンツの作成
最後に、コンテンツの構築です。
HTMLの構築
id「mdl-contents」と設定し、メニューボタンの「menu-list」とナビゲーションの「mdl-nav」の間に設置します。
<div class="menu-icon sp">
...
</div>
<div id="mdl-contents">
...(ヘッダー・フッターなど、コンテンツ一通り)
</div>
<div id="mdl-nav" class="sp">
...
</div>
jQueryの構築
仕上げにjQueryのコード例です。
$(function() {
var mdl_nav = $('#mdl-nav');
var toggle = $('.menu-icon .menu a');
var mdl_site = $('#mdl-contents');
//開閉用ボタンをクリックでクラスの切替え
toggle.on({
'touchstart': function(event) {
this.isTouch = true;
},
'touchmove': function(event) {
this.isTouch = false;
},
"touchend click": function (event) {
if(this.isTouch == true){
event.preventDefault();
mdl_nav.fadeToggle();
toggle.toggleClass("close");
if(toggle.hasClass("close")){
toggle.children(".text").html("CLOSE");
mdl_site.addClass('blur');
}else{
toggle.children(".text").html("MENU");
mdl_site.removeClass('blur');
}
};
}
});
mdl_nav.on({
'touchstart': function(event) {
this.isTouch = true;
},
'touchmove': function(event) {
this.isTouch = false;
},
"touchend click": function (event) {
if(this.isTouch == true){
if(!$(event.target).closest('a').length) {
event.preventDefault();
}
if(!$(event.target).closest('.inner-wrapper').length) {
mdl_nav.fadeOut();
toggle.removeClass("close");
toggle.children(".text").html("MENU");
mdl_site.removeClass('blur');
};
};
}
});
$(window).resize(function(){
if($(window).width() > 640){
mdl_nav.fadeOut();
mdl_site.removeClass('blur');
if(toggle.hasClass("close")){
toggle.removeClass("close");
toggle.children(".text").html("MENU");
}
}
});
});
- メニューアイコンを囲うaタグにクリックイベントを設定します。
- クリックイベントの処理内で、toggleClass(“close”); でaタグに「close」クラスの追加⇔取り消しを交互に行うようにします。
- もしaタグに「close」クラスを持っていればナビゲーションを表示させ、そうでなければ非表示にさせるようにしています。
- もしaタグに「close」クラスを持っていれば、メニューアイコン下のテキストを「CLOSE」に切り替えて、そうでなければ「MENU」に切り替えるようにしています。
このサイト自体がモーダルウィンドウを起用しており、ほとんど同じ設定を行っているので、ぜひスマホの実機でご覧ください。
コメント