【Javascript】ユーザーの window スクロールイベントを禁止/許可する

  • Javascript

特定の操作をした時に、スクロールを禁止したい時があります。そんな時にさっと使える関数を紹介します。

あくまでスクロールイベントを発生させなくするものなので、body を固定するとかそういうことはしません。

下記の stackoverflow の回答にあるコードを使っています。

https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily

コード

useScroll.js

/**
 * event preventDefault
 *
 * @param {Event} e
 */
const preventDefaultEvent = (e) => {
  e.preventDefault();
}

/**
 * スクロールを許可/禁止する
 */
export const useScroll = () => {

  // modern Chrome requires { passive: false } when adding event
  let supportsPassive = false;
  try {
    window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
      get() { supportsPassive = true; }
    }));
  } catch (e) { }
  const wheelEvent = 'onwheel' in window.document.createElement('div') ? 'wheel' : 'mousewheel';
  const wheelOpt = supportsPassive ? { passive: false } : false;

  /**
   * スクロールを禁止する
   */
  const disableScroll = () => {
    window.addEventListener(wheelEvent, preventDefaultEvent, wheelOpt); // modern desktop
    window.addEventListener('touchmove', preventDefaultEvent, wheelOpt); // mobile
  }

  /**
   * スクロールを許可する
   */
  const enableScroll = () => {
    window.removeEventListener(wheelEvent, preventDefaultEvent, wheelOpt);
    window.removeEventListener('touchmove', preventDefaultEvent, wheelOpt);
  }

  return { enableScroll, disableScroll }
}

参考サイトでは、

  • 古い Internet Explorer
  • キーボードによるスクロール

にも対応していますが、今回作成したものは省いています。もし必要なら参考サイトを確認しながら追加してみてください(正直、参考の丸コピで十分しっかり動きます)

使い方

使い方は簡単で、

  • 有効にしたいならenableScroll()
  • 無効にしたいならdisableScroll()

を実行するだけです。

先程のコードをuseScroll.jsにコピペしてから、ファイルを読み込んで使います(この use という命名がいいのかはよく分かってませんが、雰囲気でつけてます)。

HTML

<div>
  <button class="enable-scroll">有効!</button>
  <button class="disable-scroll">無効!</button>
</div>

Javascript

import { useScroll } from './useScroll';
const { enableScroll, disableScroll } = useScroll();

document.querySelector('.enable-button').addEventListener('click', () => {
  // ボタンを押したらスクロール禁止
  enableScroll();
});

document.querySelector('.disable-button').addEventListener('click', () => {
  // ボタンを押したらスクロール許可
  disableScroll();
});

import が使えない

もしimportが使えない場合は、exportを消して、普通に定義して使います。

export const useScroll = () => {
  ...
}

const useScroll = () => {
  ...
}

// 関数を定義
const { enableScroll, disableScroll } = useScroll();

他の選択肢

scroll lock 系は、npm でよさげなライブラリが公開されています。body-scroll-lock とかは、「モーダルが出た時にロックする」などもサクっとできて便利そうです。