body-scroll-lock.jsとは
body-scroll-lock.jsを使うと特定の要素以外のスクロールをロックできる。
例えばモーダルを表示する際はモーダル内のスクロールする部分の要素以外はスクロールしないようにロックする必要がある。
body-scroll-lock.jsを使用すればスクロールをロックするための処理を簡単に実装できる。
これを見て「bodyにoverflow: hiddenを付ければ良いのでは?」と思う人もいるかも知れないが、bodyにoverflow: hiddenを付けるだけだとiOS (iPhoneなど)ではスクロールのロックが効かないので注意が必要。
bodyにoverflow:hiddenでスクロールロックしたサンプル
body-scroll-lock.jsの特徴
GitHubに書かれているbody-scroll-lock.jsの特徴は以下の通り。
各環境でこれらの対応をするのは手間がかかるが、body-scroll-lock.jsなら簡単に実装できる。
- bodyのスクロールを無効化し、対象要素のスクロールを無効化しない。
- iOSのモバイル/タブレットで動作します。
- Androidで動作します。
- デスクトップ版Safariで動作します。
- Chrome/Firefoxで動作します。
- React, Angular, VueJSで動作します。
- ネストされたターゲット要素に対応。
- スクロールバーの幅を確保できる。
- -webkit-overflow-scrolling: タッチでも動作します。
GitHub - willmcpo/body-scroll-lock
body-scroll-lock.jsの使い方
まず以下のコマンドでインストールする。
npm i -D body-scroll-lock
@typesが必要な場合はnpm i -D @types/body-scroll-lockも実行する
インストールしたらbody-scroll-lockからdisableBodyScrollとenableBodyScrollをimportして、以下のようにスクロールをロックする際にロックしない要素(target)を指定するだけで実装できる。
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
const target = document.getElementById('t');
const button = document.getElementById('b');
const modal = document.getElementById('m');
const modalBg = document.getElementById('mbg');
target.addEventListener('click', (e) => {
e.stopPropagation();
});
button.addEventListener('click', () => {
modal.style.display = 'flex';
modalBg.style.display = 'block';
disableBodyScroll(target);
});
modal.addEventListener('click', () => {
modal.style.display = 'none';
modalBg.style.display = 'none';
enableBodyScroll(target);
});
body-scroll-lock.jsで特定の要素以外のスクロールをロックするサンプル