【コピペ】モーダル表示で背景固定。スマホ時はエリア外・ボタン両方どちらタップでも動くスクリプト。
2019/10/31
モーダルウィンドって便利ですよね。大好きです。
スマホメニューをレスポンシブで組む時にモーダルやドロワーって超使うと思うんですが、背景の固定って意外とうまくいかないんですよね。
上手くいかないというのは
・固定はできるけどメニュー開閉時、ページの一番上にコンテンツが戻っちゃう(気持ち悪い)
・固定、開閉、fixedあたりのclass切り替えがうまく動作しない
あたりですね。なんとなくうまくいくんですが、ここができるとこちらができなくなる、みたいな沼から出られなくなったりします。
特に僕はjsをゼロから組めない人間なのでなおさらです。
ひとつテンプレとして残しておけば次も大丈夫!ってことで備忘録。
デモはこちら >
このページの概要
jsの書き方
jqueryは読み込んでいるものとして進めます。var state = false;
var scrollpos;
$('#menu_bt, #menu_nav').on('click', function(){
$('body').toggleClass('open');
if(state == false) {
scrollpos = $(window).scrollTop();
$('body').addClass('fixed').css({'top': -scrollpos});
state = true;
} else {
$('body').removeClass('fixed').css({'top': 0});
window.scrollTo( 0 , scrollpos );
state = false;
}
});
new function(){
var attr ="data-tor-smoothScroll";
var attrPatt = /noSmooth/;
var d = document;
function addEvent(elm,listener,fn){
try{ // IE
elm.addEventListener(listener,fn,false);
}catch(e){
elm.attachEvent(
"on"+listener
,function(){
fn.apply(elm,arguments)
}
);
}
}
addEvent(window,"load",function(){
var anchors = d.getElementsByTagName("a");
for(var i = 0 ,len=anchors.length; i<len ; i++){
if(!attrPatt.test(anchors[i].getAttribute(attr)) &&
anchors[i].href.replace(/\#[a-zA-Z0-9_]+/,"") == location.href.replace(/\#[a-zA-Z0-9_]+/,"")){
anchors[i].rel = anchors[i].href;
anchors[i].href = "javascript:void(0)";
anchors[i].onclick=function(){SmoothScroll(this)}
}
}
});
}
#menu_btというのがハンバーガーメニュー、#menu_navっていうのがモーダルエリアを指します。
いろいろ触ってみたんですが、Smooth scrollの記述がないと、モーダル解除時にどうしてもトップに戻ってしまいます。
もう少しスマートな方法ないですかね。。。
html側の記述
<div class="menu-btn" id="menu_bt">
<a class="nav-button" href="#">
<span></span>
<span></span>
<span></span>
</a>
</div>
<nav class="menu" id="menu_nav">
<ul>
<li><a href="#">〇〇〇</a></li>
<li><a href="#">〇〇〇</a></li>
<li><a href="#">〇〇〇</a></li>
</ul>
</nav>
html側はシンプルな記述です。
レスポンシブで、PCは通常メニュー、スマホはハンバーガーメニューのパターンです。PC時はモーダルもなし。
メニューの配置は適宜cssで調整をしてくださいね。
cssの書き方
.menu li {}
.menu li a {
position: relative;
display: inline-block;
text-decoration: none;
padding: 0.6em 0.5em;
color: #FFF;
overflow: visible;
}
.menu li a::after {
position: absolute;
bottom: 10px;
left: 0;
content: '';
width: 100%;
height: 1px;
background: #FFF;
transform: scale(0, 1);
transform-origin: right top;
transition: transform .3s;
}
.menu li a:hover::after {
transform-origin: left top;
transform: scale(1, 1);
}
@media screen and (max-width: 768px) {
.menu-btn {
position: fixed;
top: 2%;
right: 3%;
z-index: 999999;
background: rgba(0,0,0,0.5);
border-radius: 6px;
padding: 0.6em 0.5em 0;
}
.menu {
position: fixed;
display: table;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.8);
-webkit-transition: all .5s;
transition: all .5s;
visibility: hidden;
opacity: 0;
z-index: 9999;
}
.menu ul {
display: table-cell;
vertical-align: middle;
}
.menu li {
width: 300px;
height: 80px;
line-height: 80px;
margin: 0 auto;
text-align: center;
}
.menu li a {
display: block;
font-size: 18px;
color: #fff;
}
.menu li a:hover {
color: #999;
}
/* 開閉用ボタンがクリックされた時 */
.open .menu {
-webkit-transition: all .5s;
transition: all .5s;
visibility: visible;
opacity: 1;
}
.nav-button {
display: block;
cursor: pointer;
}
/*メニューボタン*/
.nav-button,
.nav-button span {
display: inline-block;
transition: all 0.4s;
box-sizing: border-box;
}
.nav-button {
z-index: 20;
position: relative;
width: 32px;
height: 30px;
}
.nav-button span {
position: absolute;
left: 0;
width: 100%;
height: 4px;
background-color: #fff;
border-radius: 4px;
}
.nav-button span:nth-of-type(1) {
top: 0;
}
.nav-button span:nth-of-type(2) {
top: 12px;
}
.nav-button span:nth-of-type(3) {
top: 24px;
}
body.open .nav-button span:nth-of-type(1) {
-webkit-transform: translateY(12px) rotate(-45deg);
transform: translateY(12px) rotate(-45deg);
}
body.open .nav-button span:nth-of-type(2) {
opacity: 0;
}
body.open .nav-button span:nth-of-type(3) {
-webkit-transform: translateY(-12px) rotate(45deg);
transform: translateY(-12px) rotate(45deg);
}
}
@media only screen and ( max-width : 768px ) {
.fixed {
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
overflow: visible;
}
}
ハンバーガーメニューがクリックされたときにハンバーガーからバツボタンにアニメーションします。
PC時はメニューにマウスオーバーするとラインがアニメーションして動きます。
デモはこちら >