ライトボックスを使用している間、親のhtml / bodyスクロールバーを無効にしようとしています。ここでの主な言葉はdisableです。で隠したくないoverflow: hidden;
。
これはoverflow: hidden
、サイトがジャンプして、スクロールがあった領域を占めるためです。
スクロールバーを表示したままスクロールバーを無効にできるかどうか知りたい。
ライトボックスを使用している間、親のhtml / bodyスクロールバーを無効にしようとしています。ここでの主な言葉はdisableです。で隠したくないoverflow: hidden;
。
これはoverflow: hidden
、サイトがジャンプして、スクロールがあった領域を占めるためです。
スクロールバーを表示したままスクロールバーを無効にできるかどうか知りたい。
回答:
オーバーレイヤーの下のページを上部で「固定」できる場合、オーバーレイを開いたときに設定できます
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');
$('body').css('top', -($('body').scrollTop()) + 'px').addClass('noscroll');
選択したソリューションへの4つの小さな追加:
ほとんどのブラウザで機能するように見える完全なソリューション:
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に感謝します。
afterLoad()
とafterClose
コールバックを無効にしました。この質問を検索する他の人に役立つかもしれません。
scrollTop
、「スクロールを無効にする」コードの2行目をとして表すことができます$( window ).scrollTop()
。
if (scrollTop < 0) { scrollTop = 0; }
。これは、gist.github.com/jayd3e/2eefbbc571cd1668544bを無効にするための完全なコードです。
$.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();
これは私にとって本当にうまくいきました...
// 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);
});
本体のスクロールバーを非表示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>
私は自分のライトボックス実装のためにこれを正確に行いました。これまでのところ、うまく機能しているようです。
これが私たちが行ったソリューションです。オーバーレイが開かれたときにスクロール位置を保存し、ユーザーがページをスクロールしようとしたときに保存位置までスクロールして戻り、オーバーレイが閉じられたときにリスナーをオフにします。
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>
z-index
のは.overlay-shown
、固定ヘッダよりも大きくなるように。(このコードは、固定ヘッダーのあるサイトで本番
body
タグのスクロールバーについて話していました。昨日あなたのコードを試してみましたが、ページの上部に固定ヘッダーがあります。body
タグを介してスクロールを処理する場合、スクロールバーは固定ヘッダーの下になります。
$("body")
、を使用しているようです$(window)
。z-index: -1
オーバーレイを非表示にする代わりに、などを使用できますvisibility: hidden
。動作するかどうかを確認する簡単なテストについては、jsfiddle.net / 8p2gfehaを参照してください。固定ヘッダーがスクロールバーの上に表示されなくなりました。私は最終的にこれらの変更を回答に組み込むようにします。
同様の問題が発生しました。左側のメニューが表示されたときに、それがスクロールを妨げます。高さが100vhに設定されるとすぐに、スクロールバーが消え、コンテンツが右に急に動きました。
したがって、スクロールバーを有効にしたままにしても構わない場合(ただし、ウィンドウを完全な高さに設定して、実際にはどこにもスクロールしないようにする)、別の可能性として、小さな下マージンを設定して、スクロールバーを表示し続けることができます。
body {
height: 100vh;
overflow: hidden;
margin: 0 0 1px;
}
overflow:hidden
マージンが効かないようにしていませんか?
粗雑ですが機能する方法は、スクロールを強制的に上に戻すことです。したがって、スクロールを事実上無効にします。
var _stopScroll = false;
window.onload = function(event) {
document.onscroll = function(ev) {
if (_stopScroll) {
document.body.scrollTop = "0px";
}
}
};
ライトボックスを開くときはフラグを立て、閉じるときはフラグを下げます。
私は「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の要素がある場合は、それらの要素にもパディングを追加する必要があることに注意してください。
<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%を超えないため、ライトボックス(および)をスクロールしても効果はありません。
すべてのモーダル/ライトボックスのJavaScriptベースのシステムは、HTMLタグまたは本文タグでモーダル/ライトボックスを表示するときにオーバーフローを使用します。
ライトボックスが表示されているとき、jsはhtmlまたはbodyタグに隠されたオーバーフローをプッシュします。ライトボックスが非表示の場合、一部は非表示を削除し、他はhtmlまたはbodyタグでオーバーフロー自動をプッシュします。
Macで作業する開発者には、スクロールバーの問題は見られません。
スクロールバーの削除のモーダルの下でコンテンツが滑らないようにするには、非表示を未設定で置き換えるだけです。
ライトボックスを開く/表示:
<html style="overflow: unset;"></html>
ライトボックスを閉じる/隠す:
<html style="overflow: auto;"></html>
オーバーレイヤーの下のページを上部で「固定」できる場合、オーバーレイを開いたときに設定できます
.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));
この方法を提案したのは、スクロールイベントを変更する必要がないためだけです。
これにより、スクロール位置を保存し、スクロールを有効にすると、ビューポートが一番上にジャンプするのを停止します。
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();
});
あなたはJavascriptでそれを行うことができます:
// Classic JS
window.onscroll = function(ev) {
ev.preventDefault();
}
// jQuery
$(window).scroll(function(ev) {
ev.preventDefault();
}
そして、ライトボックスが閉じているときにそれを無効にします。
ただし、ライトボックスにスクロールバーが含まれている場合、開いている間はスクロールできません。これはwindow
、body
との両方が含まれているため#lightbox
です。したがって、次のようなアーキテクチャを使用する必要があります。
<body>
<div id="global"></div>
<div id="lightbox"></div>
</body>
次に、にonscroll
のみイベントを適用します#global
。