🔒

body-scroll-lockというライブラリを使ってドロワーメニュー、モーダルの背景スクロールを固定する

2022/07/25に公開

ScrollTriggerを使っていたら意図しない挙動になった

これまで背景スクロール固定はZennで紹介されていたこちらの方法を導入していました。
https://zenn.dev/tak_dcxi/articles/bbdb6cd9305ba4
しかし某案件でGSAPScrollTriggerを使って、pinを使ったスクロールジャックがあるアニメーションを実装していたのですが、ドロワーメニューを開く瞬間にスクロールジャックした要素が謎の挙動で出現しまう現象にぶつかりました。

救世主「body-scroll-lock」

色々検索していたところ「body-scroll-lock」(以後BSL)というライブラリに出会ったので導入してみたところ、上記の現象が起こらずに無事実装できました。
https://github.com/willmcpo/body-scroll-lock

BSLの特徴

公式のGitHubのFeaturesでは次のように書かれています。

  • disables body scroll WITHOUT disabling scroll of a target element
  • works on iOS mobile/tablet (!!)
  • works on Android
  • works on Safari desktop
  • works on Chrome/Firefox
  • works with vanilla JS and frameworks such as React / Angular / VueJS
  • supports nested target elements (eg. a modal that appears on top of a flyout)
  • can reserve scrollbar width
  • -webkit-overflow-scrolling: touch still works

そうなんです、スクロール関係で悪さを起こしがちなiOS Safariにも対応しているのです!素晴らしい👏

またドキュメントにはVanilla.jsだけでなく流行りのReactでの導入の仕方も書かれているので、様々な場面で導入できそうです。

デモ

使い方

特に難しいことはなく、ライブラリを読み込んで実行するだけです。

main.js
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;

// この要素以外のスクロールをロックする(ここにドロワーメニューやモーダルを指定する)
const targetElement = document.querySelector('#someElementId');

// スクロールをロックする
disableBodyScroll(targetElement);
// ロックを解除する
enableBodyScroll(targetElement);

オプション

オプションにはスクロールロックで必要になりがちなスクロールバー分の余白の追加もできます。(bodypadding-rightを追加)

main.js
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;
// オプション
const options = {
  reserveScrollBarGap: true, // bodyにスクロールバー分のpadding-rightを追加するかどうか(デフォルト値:false)
};

// この要素以外のスクロールをロックする(ここにドロワーメニューやモーダルを指定する)
const targetElement = document.querySelector('#someElementId');

// スクロールをロックする(オプション追加)
disableBodyScroll(targetElement,options);
// ロックを解除する
enableBodyScroll(targetElement);//解除するときはoptionsつけなくても大丈夫です。多分。

あとallowTouchMoveというオプションもあるみたいです。
気になる方はGitHubをご確認ください。

参考サイト

https://pon-web.info/web/121

Discussion