今回はJavaScript(Vanilla JS)とちょっとのCSSを使って、メニューを開いている間は背景スクロールを禁止にする実装方法を紹介します。
Contents
サンプル
See the Pen Restrict scrolling while we open menu by POSIPAN (@posipan) on CodePen.
リンク
仕様
- メニューボタンをクリックした時に、メニューが表示される。
- 同時に、html要素にスクロールを禁止にするためのクラスを追加する。
- メニューを閉じた時、スクロール禁止を解除する。(クラスの削除)
コード解説
SCSS
CodePenには色々書いていますが、ポイントとなる記述は下記です。
メニューボタンをクリックした時に、html要素に.fixed
を追加します。overflow: hidden;
により、スクロールができなくなるようにしています。
html {
&.fixed {
height: 100%;
overflow: hidden;
}
}
【2022.05.31追記】JavaScriptのコードを簡略化したため、.navのSCSSを変更しました。
JavaScriptでフェイドアニメーションさせていましたが、今回の変更ではCSSのtransitionでアニメーションさせています。
ここで大事なのはpointer-eventsプロパティです。
opacity: 0;
は透明度の影響で要素は見えなくなりますが、display: none;
非表示になるわけではありません。
ゆえにリンクがあればクリックできてしまうので、これをpointer-events: none;よってクリックを無効にし、非表示を擬似的に表現しています。
.nav {
opacity: 0;
pointer-events: none; // クリックを無効にする
transition: 0.3s ease transform, 0.3s ease opacity;
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
height: 100%;
&.active {
opacity: 1;
pointer-events: auto; // クリックを有効にする
}
}
JavaScript
基本的には、.menu-btn
をクリックした際に
クラスの追加・削除の切り替えを行なっているだけです。
コード内のthis
はmenuBtn
を指しています。
詳細はコード内のコメントに記載しています。
// 要素の取得
const html = document.documentElement;
const menuBtn = document.querySelector('.menu-btn');
const nav = document.querySelector('.nav');
// .menu-btnをクリックした時、
menuBtn.addEventListener('click', function() {
// .menu-btnに.activeがなかったら、
// .activeを追加し、html要素に.fixed、.navに.activeを追加する。
if (!this.classList.contains('active')) {
this.classList.add('active');
html.classList.add('fixed');
nav.classList.add('active');
} else {
// .menu-btnに.activeがすでに追加されていれば、
// .activeを削除し、html要素の.fixed、.navの.activeを削除する。
this.classList.remove('active');
html.classList.remove('fixed');
nav.classList.remove('active');
}
});
完成です!