monoの開発ブログ

JavaScriptで一時的にスクロールを無効化する

更新しました。

Lightbox的なものを表示しているときに、Lightboxの中身をスクロールさせると端に到達したときスクロールが親要素に伝搬してしまう問題があります。小さな点ですが、どこまで読んでいたのか見失ってしまうので結構鬱陶しいですね。

そこで、Lightbox的なものを表示している間一時的に親要素のスクロールを防止する方法を調べてみました。

何を言っているのか分からないと思うので、デモを用意しました。まずはこちらをご覧ください。

実現方法

スクロールを禁止させるときはこんな感じ。スクロールバーを残したまま画面に固定し、スクロールしていた量だけ表示位置をずらして辻褄を合わせています。例ではスタイルの設定はクラスの付け外しで済ませています。

var scrollTop;

scrollTop = $(window).scrollTop();
$('body').addClass('noscroll').css('top', (-scrollTop) + 'px');

CSSは以下のようにしておきます。bodyのwidthはpositionがfixedになったときに計算方法が変わって崩れるのを防ぐために100%に固定しておきます。

body {
  width: 100%;
}

body.noscroll {
  position: fixed;
  overflow-y: scroll;
}

戻すときはこんな感じ。設定したクラスを外してスクロールしていた分を戻すだけですね。

$('body').removeClass('noscroll');
$(window).scrollTop(scrollTop);

問題点

IE9だとスクロールバーが二重に表示されてしまい切り替えの瞬間にガタッとなってしまいます。IE9の場合はスクロールを禁止しないようにすれば閲覧に支障は無いので致命的ではないですが。

参考