スクロールを無効にして非表示にしませんか?


198

ライトボックスを使用している間、親のhtml / bodyスクロールバーを無効にしようとしています。ここでの主な言葉はdisableです。で隠したくないoverflow: hidden;

これはoverflow: hidden、サイトがジャンプして、スクロールがあった領域を占めるためです。

スクロールバーを表示したままスクロールバーを無効にできるかどうか知りたい。


1
スクロールは可能でしょうか?(ライトボックスにスクロールバーはありますか?)
ŠimeVidas 2012

サイトはスクロールしましたが、ライトボックスが開いている間は無効にしたいだけです。スクロールバーを表示しているときに無効にできるかどうか知りたいだけです。ライトボックスなどでそれを行う方法のように、他には何も必要ありません。
Dejan.S 2012年

スクロールバー付きのライトボックスを使用する問題は何ですか?
マニー

1
私は無効にする方法を知っているので@Dejan すべての主要なスクロールバーを無効にするだろうが、またライトボックスに1 ... -スクロール
サイムVIDAS

1
この投稿に回答を編集しないでください。以下の回答セクションは回答です。以下の回答とは異なる質問への回答がある場合は、回答の選択に独自のソリューションを追加できます。
intcreator 2016

回答:


173

オーバーレイヤーの下のページを上部で「固定」できる場合、オーバーレイを開いたときに設定できます

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

右のスクロールバーは表示されますが、コンテンツはスクロールできません。オーバーレイを閉じるときは、これらのプロパティを

body { position: static; overflow-y:auto }

この方法を提案したのは、スクロールイベントを変更する必要がないためだけです。

更新

少し改善することもできます:document.documentElement.scrollTopレイヤーが開く直前にJavaScript経由でプロパティを取得する場合、その値を次のように動的に割り当てることができます:top body要素のプロパティ。このアプローチでは、ページがその場所に配置されます上に戻るか、すでにスクロールしている場合。

CSS

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

JS

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

2
それは私のレイアウトを混乱させますが、いくつかの変更を加えるとうまくいくかもしれません。私はこのように私はそれをもっと試します
Dejan.S

4
少し変更を加えると、これは機能します。幅を追加しました:100%; 私は私の質問をソリューションで更新しましたが、あなたは幅であなたを変更することができます:100%;? 提案をありがとう
Dejan.S

3
私はなぜ知らないが、これは私のためにうまく機能: $('body').css('top', -($('body').scrollTop()) + 'px').addClass('noscroll');
PDXIIIを

4
@whitesiroi、あなたは正しい。フィドルを更新しました:jsfiddle.net/evpozdniakov/2m8km9wgありがとうございます!
evpozdniakov

1
ソリューションのコメントを読んでいる人のために、最後のフィドルは、両方のケースでスクロールバーの位置を維持しながら、スクロールバーを無効にして再度有効にするソリューションを提供します。ありがとう!
user1063287

78

選択したソリューションへの4つの小さな追加:

  1. IEでのダブルスクロールバーを防ぐために、本文ではなくhtmlに「noscroll」を適用します。
  2. 実際にスクロールバーがあるかどうか確認するには「noscroll」クラスを追加する前ます。それ以外の場合、サイトは新しい非スクロールスクロールバーによってジャンププッシュされます。
  3. ページ全体が先頭に戻らないようにすべてのscrollTopを保持するには(Fabrizioの更新のように、 'noscroll'クラスを追加する前に値を取得する必要があります)
  4. すべてのブラウザーがhttp://help.dottoro.com/ljnvjiow.phpに記載されているのと同じ方法でscrollTopを処理するわけではありません

ほとんどのブラウザで機能するように見える完全なソリューション:

CSS

html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

スクロールを無効にする

if ($(document).height() > $(window).height()) {
     var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
     $('html').addClass('noscroll').css('top',-scrollTop);         
}

スクロールを有効にする

var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);

私を正しい軌道に乗せてくれたFabrizioとDejanに感謝し、ダブルスクロールバーの解決のためにBrodingoに感謝します。


1
これはデスクトップでうまくテストされましたが、iPhoneでは、読者がページをスクロールしようとするまで、空白の白い画面が作成されました。読者がページを操作しようとすると、意図した画面がスクロールがロックされた状態で表示されます。
Michael Khalili

これは、iPadのFancyboxと完全に連携し、ライトボックスイメージのスクロールafterLoad()afterCloseコールバックを無効にしました。この質問を検索する他の人に役立つかもしれません。
Tomanow 2013

「スクロールを有効にする」の部分では、「スクロールを無効にする」の呼び出しの後にhtml要素に配置されたスタイル属性を削除することができます。ね?
ベン

3
jQueryは、ネイティブDOMを標準化してscrollTop、「スクロールを無効にする」コードの2行目をとして表すことができます$( window ).scrollTop()
Barney

これにもう1つ追加する必要があると思います。OSXのChromeでは、ブラウザが「オーバースクロール」して、スクロールに弾力性を与えることができます。このコードを使用すると、ページの上または下の灰色の領域にいて、スクロールを無効にする場所にカーソルを合わせます。ブラウザウィンドウの上/下のスポットに固定されます。このため、負のスクロール値のチェックを追加する必要があります:if (scrollTop < 0) { scrollTop = 0; }。これは、gist.github.com/jayd3e/2eefbbc571cd1668544bを無効にするための完全なコードです。
JayD3e 2014

34

jQueryが含まれる場合:


無効にする

$.fn.disableScroll = function() {
    window.oldScrollPos = $(window).scrollTop();

    $(window).on('scroll.scrolldisabler',function ( event ) {
       $(window).scrollTop( window.oldScrollPos );
       event.preventDefault();
    });
};

可能にする

$.fn.enableScroll = function() {
    $(window).off('scroll.scrolldisabler');
};

使用法

//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();

1
これは私にとっては完璧でした、前の答えは私のページをバウンスさせました、これはそうではありません
ボグダン・トミ

嬉しい私は、あなたがモバイルデバイスのために、あまりにも「touchmove」をチェックする必要があるかもしれません、歓声を助けることができる
Ceedで

まあ、これはほとんど私のために働いた。Windows(Firefox、Chrome)とFirefoxのMacOSでは不思議に機能しましたが、それからChromeとSafariのMacOSと共にWindows IEとEdgeに行きました。問題はページが左右にジャンプすることではなくなりましたが、スクロールバーが上から現在の位置にジャンプするか、ページが上にちらついていました。男、これはとてもとても近かった。多分私達はまだそれを働かせることができます。
Steven Ventimiglia 2017年

これは完璧に機能しました。ありがとうございます。オーバーレイメニューもページの下部にあるWebサイトでの理想的なtuの使用!
SauriolJf 2017

12

私はOPです

fcalderanからの回答を利用して、ソリューションを形成することができました。ソリューションを使用する方法を明確にし、非常に重要な詳細を追加するため、ここにソリューションを残します。width: 100%;

このクラスを追加します

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

これは私にとってはうまくいき、私はFancyappを使用していました。


11

これは私にとって本当にうまくいきました...

// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);

// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);


// lock window scrolling
function lockScroll(e) {
    e.preventDefault();
}

この2行のコードを、スクロールをロックするタイミングを決定するものでラップするだけです。

例えば

$('button').on('click', function() {
     $('body').bind('mousewheel touchmove', lockScroll);
});

これがすべての中で最良の答えです
Jafo

7

スクロールイベントを無効にすることはできませんが、マウスホイールやタッチムーブなど、スクロールにつながる関連アクションを無効にすることができます。

$('body').on('mousewheel touchmove', function(e) {
      e.preventDefault();
});

4

本体のスクロールバーを非表示overflow: hiddenにすると同時にマージンを設定して、コンテンツがジャンプしないようにすることができます。

let marginRightPx = 0;
if(window.getComputedStyle) {
    let bodyStyle = window.getComputedStyle(document.body);
    if(bodyStyle) {
        marginRightPx = parseInt(bodyStyle.marginRight, 10);
    }
}

let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
    overflow: 'hidden',
    marginRight: `${marginRightPx + scrollbarWidthPx}px`
});

次に、無効なスクロールバーをページに追加して、ギャップを埋めます。

textarea {
  overflow-y: scroll;
  overflow-x: hidden;
  width: 11px;
  outline: none;
  resize: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  border: 0;
}
<textarea></textarea>

私は自分のライトボックス実装のためにこれを正確に行いました。これまでのところ、うまく機能しているようです。


1
私はこの方法が一番好きです。非常にシンプルで機能します。ありがとう!
dericcain 2017年

2

これが私たちが行ったソリューションです。オーバーレイが開かれたときにスクロール位置を保存し、ユーザーがページをスクロールしようとしたときに保存位置までスクロールして戻り、オーバーレイが閉じられたときにリスナーをオフにします。

IEでは少しびくびくしますが、Firefox / Chromeでは魅力のように機能します。

var body = $("body"),
  overlay = $("#overlay"),
  overlayShown = false,
  overlayScrollListener = null,
  overlaySavedScrollTop = 0,
  overlaySavedScrollLeft = 0;

function showOverlay() {
  overlayShown = true;

  // Show overlay
  overlay.addClass("overlay-shown");

  // Save scroll position
  overlaySavedScrollTop = body.scrollTop();
  overlaySavedScrollLeft = body.scrollLeft();

  // Listen for scroll event
  overlayScrollListener = body.scroll(function() {
    // Scroll back to saved position
    body.scrollTop(overlaySavedScrollTop);
    body.scrollLeft(overlaySavedScrollLeft);
  });
}

function hideOverlay() {
  overlayShown = false;

  // Hide overlay
  overlay.removeClass("overlay-shown");

  // Turn scroll listener off
  if (overlayScrollListener) {
    overlayScrollListener.off();
    overlayScrollListener = null;
  }
}

// Click toggles overlay
$(window).click(function() {
  if (!overlayShown) {
    showOverlay();
  } else {
    hideOverlay();
  }
});
/* Required */
html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
html { overflow: hidden; }
body { overflow-y: scroll; }

/* Just for looks */
.spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); }
.overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; }
.overlay .spacer { background: linear-gradient(#88f, #0ff); }
.overlay-shown { z-index: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<h1>Top of page</h1>
<p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p>
<div class="spacer"></div>
<h1>Bottom of page</h1>
<div id="overlay" class="overlay">
  <h1>Top of overlay</h1>
  <p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p>
  <div class="spacer"></div>
  <h1>Bottom of overlay</h1>
</div>


確かに機能しますが、固定ヘッダーの場合はスクロールバーがその下に潜るので、デザインが汚染されます。
Leon Willens

@LeonWillensどういう意味かわかりません。あなたは、固定ヘッダの下に表示されるオーバーレイを心配している場合は、調整する必要がありますz-indexのは.overlay-shown、固定ヘッダよりも大きくなるように。(このコードは、固定ヘッダーのあるサイトで本番
環境で

いいえ、bodyタグのスクロールバーについて話していました。昨日あなたのコードを試してみましたが、ページの上部に固定ヘッダーがあります。bodyタグを介してスクロールを処理する場合、スクロールバーは固定ヘッダーの下になります。
Leon Willens

1
@LeonWillensおっと、本番環境でこれを修正し、更新するのを忘れたようです。ではなく$("body")、を使用しているようです$(window)z-index: -1オーバーレイを非表示にする代わりに、などを使用できますvisibility: hidden。動作するかどうかを確認する簡単なテストについては、jsfiddle.net / 8p2gfehaを参照してください。固定ヘッダーがスクロールバーの上に表示されなくなりました。私は最終的にこれらの変更を回答に組み込むようにします。
0b10011

魅力的な作品!ありがとうございました:)
Leon Willens

1

同様の問題が発生しました。左側のメニューが表示されたときに、それがスクロールを妨げます。高さが100vhに設定されるとすぐに、スクロールバーが消え、コンテンツが右に急に動きました。

したがって、スクロールバーを有効にしたままにしても構わない場合(ただし、ウィンドウを完全な高さに設定して、実際にはどこにもスクロールしないようにする)、別の可能性として、小さな下マージンを設定して、スクロールバーを表示し続けることができます。

body {
    height: 100vh;
    overflow: hidden;
    margin: 0 0 1px;
}

overflow:hiddenマージンが効かないようにしていませんか?
Koja

0

あなたはoverflow:hiddenを維持できますが、手動でスクロール位置を管理します:

実際のスクロール位置の追跡を表示する前に:

var scroll = [$(document).scrollTop(),$(document).scrollLeft()];
//show your lightbox and then reapply scroll position
$(document).scrollTop(scroll[0]).scrollLeft(scroll[1]);

それはうまくいくはずです


0

粗雑ですが機能する方法は、スクロールを強制的に上に戻すことです。したがって、スクロールを事実上無効にします。

var _stopScroll = false;
window.onload = function(event) {
    document.onscroll = function(ev) {
        if (_stopScroll) {
            document.body.scrollTop = "0px";
        }
    }
};

ライトボックスを開くときはフラグを立て、閉じるときはフラグを下げます。

ライブテストケース


0

私は「overflow:hidden」メソッドに固執し、スクロールバーの幅と同じpadding-rightを追加するのが好きです。

lostsourceによるスクロールバー幅関数を取得します

function getScrollbarWidth() {
    var outer = document.createElement("div");
    outer.style.visibility = "hidden";
    outer.style.width = "100px";
    outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps

    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    // force scrollbars
    outer.style.overflow = "scroll";

    // add innerdiv
    var inner = document.createElement("div");
    inner.style.width = "100%";
    outer.appendChild(inner);        

    var widthWithScroll = inner.offsetWidth;

    // remove divs
    outer.parentNode.removeChild(outer);

    return widthNoScroll - widthWithScroll;
}

オーバーレイを表示するときに、「noscroll」クラスをhtmlに追加し、パディング権を本文に追加します。

$(html).addClass("noscroll");
$(body).css("paddingRight", getScrollbarWidth() + "px");

非表示にするときは、クラスとパディングを削除します。

$(html).removeClass("noscroll");
$(body).css("paddingRight", 0);

noscrollスタイルはこれだけです:

.noscroll { overflow: hidden; }

position:fixedの要素がある場合は、それらの要素にもパディングを追加する必要があることに注意してください。


このソリューションを使用しました。それは私が二重のスクロールバーを回避するのに役立ちました(1つは本体用、もう1つはオーバーレイのコンテンツ用)。また、スクロールバーがまったく表示されない場合があるOSXでも非常にうまく機能します。
Novazembla 2017

0

<div id="lightbox"><body>要素内にあるため、ライトボックスをスクロールすると、本体もスクロールします。解決策は、<body>要素を100%を超えて拡張せず、長いコンテンツを別のdiv要素内に配置し、必要に応じてでこのdiv要素にスクロールバーを追加することoverflow: autoです。

html {
  height: 100%
}
body {
  margin: 0;
  height: 100%
}
#content {
  height: 100%;
  overflow: auto;
}
#lightbox {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<html>
  <body>
    <div id="content">much content</div>
    <div id="lightbox">lightbox<div>
  </body>
</html>

body本体が画面の高さの100%を超えないため、ライトボックス(および)をスクロールしても効果はありません。


0

すべてのモーダル/ライトボックスのJavaScriptベースのシステムは、HTMLタグまたは本文タグでモーダル/ライトボックスを表示するときにオーバーフローを使用します。

ライトボックスが表示されているとき、jsはhtmlまたはbodyタグに隠されたオーバーフローをプッシュします。ライトボックスが非表示の場合、一部は非表示を削除し、他はhtmlまたはbodyタグでオーバーフロー自動をプッシュします。

Macで作業する開発者には、スクロールバーの問題は見られません。

スクロールバーの削除のモーダルの下でコンテンツが滑らないようにするには、非表示を未設定で置き換えるだけです。

ライトボックスを開く/表示:

<html style="overflow: unset;"></html>

ライトボックスを閉じる/隠す:

<html style="overflow: auto;"></html>

0

オーバーレイヤーの下のページを上部で「固定」できる場合、オーバーレイを開いたときに設定できます

.disableScroll { position: fixed; overflow-y:scroll }

このクラスをスクロール可能な本体に提供すると、右側のスクロールバーが表示されますが、コンテンツはスクロールできません。

ページの位置を維持するには、jqueryでこれを実行します

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

オーバーレイを閉じるときは、これらのプロパティを

var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));

この方法を提案したのは、スクロールイベントを変更する必要がないためだけです。


0

これにより、スクロール位置を保存し、スクロールを有効にすると、ビューポートが一番上にジャンプするのを停止します。

CSS

.no-scroll{
  position: fixed; 
  width:100%;
  min-height:100vh;
  top:0;
  left:0;
  overflow-y:scroll!important;
}

JS

var scrollTopPostion = 0;

function scroll_pause(){
  scrollTopPostion = $(window).scrollTop();
  $("body").addClass("no-scroll").css({"top":-1*scrollTopPostion+"px"});
}

function scroll_resume(){
  $("body").removeClass("no-scroll").removeAttr("style");
  $(window).scrollTop(scrollTopPostion);
}

あとは、関数を呼び出すだけです

$(document).on("click","#DISABLEelementID",function(){
   scroll_pause();
});

$(document).on("click","#ENABLEelementID",function(){
   scroll_resume();
});

-1

あなたはJavascriptでそれを行うことができます:

// Classic JS
window.onscroll = function(ev) {
  ev.preventDefault();
}

// jQuery
$(window).scroll(function(ev) {
  ev.preventDefault();
}

そして、ライトボックスが閉じているときにそれを無効にします。

ただし、ライトボックスにスクロールバーが含まれている場合、開いている間はスクロールできません。これはwindowbodyとの両方が含まれているため#lightboxです。したがって、次のようなアーキテクチャを使用する必要があります。

<body>
  <div id="global"></div>
  <div id="lightbox"></div>
</body>

次に、にonscrollのみイベントを適用します#global

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.