ドロワーメニューを開いた時に背面のページのスクロールを止めたい

概要

SPサイズでドロワーメニューを開いた時に、ヘッダの高さ分のエリアで背面のページがスクロールして邪魔になるときがあります。その時に停止する方法です

対策

ドロワーメニューを開いた時にJavascriptでhtmlとbodyの要素にクラス(例:no-scroll)を追加します。
そして、cssでoverflow: hidden;を適用します。
ネット上ではbody要素だけに適用している例が多かったですが、何故かそれだけではスクロールを停止できませんでした。html要素にも適用すると確実だと思います。

コード例は以下です。

■html
<div class="drawer-contents" id="js-drawer-contents">
  <ul class="drawer-nav__list">
    <li><a href="#reason" class="drawer-menu__item-link">●●が選ばれる理由</a></li>
    <li><a href="#case" class="drawer-menu__item-link">企業研修</a></li>
    <li><a href="#overview" class="drawer-menu__item-link">会社概要</a></li>
  </ul>
</div>

■javascript
////// drawer-menu//////
 
const InitializeDrawer = () => {
  const drawerIcon = document.querySelector("#js-drawer-icon");
  const drawerContent = document.querySelector("#js-drawer-contents");
  const drawerContentLinks = document.querySelectorAll(".drawer-menu__item-link");

  // ボタンまたはドロワーが存在しない場合は処理を終了
  if (!drawerIcon || !drawerContent) return;

  // ボタンをクリックしたらドロワーを開く
  if (drawerIcon) {
    drawerIcon.addEventListener("click", function (e) {
      e.preventDefault();
      drawerIcon.classList.toggle("is-checked");
      drawerContent.classList.toggle("is-checked");
      document.body.classList.toggle("no-scroll");
      document.documentElement.classList.toggle("no-scroll");
    });
  }

  // クリックしたらドロワーを閉じる
  drawerContentLinks.forEach((link) => {
    link.addEventListener("click", function (e) {
      e.preventDefault();
      const targetUrl = this.getAttribute("href"); // クリックされたリンクのURLを取得

      drawerIcon.classList.remove("is-checked");
      drawerContent.classList.remove("is-checked");
      document.body.classList.remove("no-scroll");
      document.documentElement.classList.remove("no-scroll");

      // 少し遅らせてページ遷移(アニメーション後に遷移)
      setTimeout(() => {
        window.location.href = targetUrl;
      }, 300); // 300ms 待って遷移(アニメーションの時間と合わせる)
    });
  });
};

InitializeDrawer();

■scss
/* スクロール禁止用 */

html.no-scroll,
body.no-scroll {
  overflow: hidden;
  height: 100%;     /* モバイルでの慣性スクロール防止 */
  touch-action: none; /* iOSのスクロール抑止 */
}

以上