web-dev-qa-db-ja.com

非表示にしないでスクロールを無効にするだけですか?

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

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

スクロールバーを表示したままスクロールバーを無効にすることが可能かどうかを知りたいです。

171
Dejan.S

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

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

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

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

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

更新

また、少し改善することもできます。レイヤーを開く直前にJavaScriptを介してdocument.documentElement.scrollTopプロパティを取得する場合は、body要素のtopプロパティとしてその値を動的に割り当てることができます。上にいるか、すでにスクロールしている場合.

Css

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

JS

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

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

  1. 'noscroll'をbodyの代わりに[html]に適用して、IEで二重スクロールバーが表示されないようにします。
  2. 'noscroll'クラスを追加する前に実際にスクロールバーがあるかどうかをチェックをすること。そうでなければ、サイトは新しいスクロールしないスクロールバーによってプッシュプッシュされます。
  3. 可能な限り保持するにはscrollTopページ全体が先頭に戻らないようにします(Fabrizioの更新と同様ですが、 'noscroll'クラスを追加する前に値を取得する必要があります)。
  4. すべてのブラウザがscrollTopを http://help.dottoro.com/ljnvjiow.php に記載されているのと同じ方法で処理するわけではありません。

ほとんどのブラウザで動作すると思われる完全な解決策:

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さん、私を正しい方向に導いてくれたBrodoと、ダブルスクロールバーの解決方法 に感謝します

74
Mike Garcia

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();
31
ceed

これは私にとって本当にうまくいった…。

// 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);
});
8
dmackenz

Scrollイベントを無効にすることはできませんが、mousewheelやtouchmoveのように、スクロールにつながる関連アクションを無効にすることができます。

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

私はOPです

Fcalderanからの回答の助けを借りて、私は解決策を形成することができました。使い方を明確にし、非常に重要な詳細width: 100%;を追加するので、私はここに私の解決策を残します。

このクラスを追加します

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

これは私のために働いたと私はFancyappを使用していました。

6
Dejan.S

あるいは、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>

私は自分自身のライトボックスの実装のためにまさにこれをしました。これまでのところうまくいっているようです。

3
mpen

これが私たちが行った解決策です。オーバーレイを開いたときにスクロール位置を保存し、ユーザーがページをスクロールしようとしたときはいつでも保存位置にスクロールバックし、オーバーレイを閉じたときにリスナーをオフにします。

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>
2
0b10011

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

スクロールバーを有効にしたままにしておけば(しかし実際にはどこにもスクロールされないようにウィンドウをフルハイトに設定して)、もう1つの可能性は小さな下余白を設定することです。

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

基本的ではあるがうまくいく方法はスクロールを強制的に上に戻すことで、スクロールを事実上無効にすることです。

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

ライトボックスを開くとフラグが上がり、閉じるとフラグが下がります。

ライブテストケース

0
Shadow Wizard

<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
Marek C

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

.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
Bhuvan Arora

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

ライトボックスが表示されているとき、jsはhtmlまたはbodyタグに隠されたオーバーフローをプッシュします。ライトボックスが隠れているときは、隠れているものを削除するものもありますhtmlまたはbodyタグにオーバーフローオートをプッシュします。

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

スクロールバーの削除のモーダルでコンテンツがスリップしないように、hiddenをunsetに置き換えます。

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

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

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

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

私は "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;
}

オーバーレイを表示するときは、htmlに "noscroll"クラスを追加し、bodyにpadding-rightを追加します。

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

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

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

Noscrollスタイルはちょうどこれです:

.noscroll { overflow: hidden; }

Position:fixedの要素がある場合は、それらの要素にもパディングを追加する必要があります。

0
Janne Annala

あなたはオーバーフローを保つことができます:隠されているが手動でスクロール位置を管理します:

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

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

うまくいくはずです

0
malko