私のウェブサイトのモーダル( http://Twitter.github.com/bootstrap から)を開いている間、マウスホイールを使用すると、体がスクロールしなくなります。
モーダルが開かれたときに以下のjavascriptを呼び出そうとしましたが、成功しませんでした
$(window).scroll(function() { return false; });
AND
$(window).live('scroll', function() { return false; });
私達のウェブサイトがIE6のサポートをやめたことに注意してください、しかしIE7 +は互換性がある必要があります。
ブートストラップのmodal
は、モーダルダイアログが表示されると自動的にクラスにmodal-open
をボディに追加し、ダイアログが非表示になるとそれを削除します。したがって、CSSに以下を追加することができます。
body.modal-open {
overflow: hidden;
}
あなたは上記のコードがBootstrap CSSコードベースに属すると主張するかもしれません、しかしこれはあなたのサイトにそれを追加するための簡単な修正です。
2013年8月8日更新
これはTwitter Boostrap v。2.3.0で機能しなくなりました - 彼らはもはやmodal-open
クラスをボディに追加しません。
回避策は、モーダルが表示されようとしているときに本体にクラスを追加し、モーダルが閉じられたときにそれを削除することです。
$("#myModal").on("show", function () {
$("body").addClass("modal-open");
}).on("hidden", function () {
$("body").removeClass("modal-open")
});
2013年3月11日の更新 Bootstrap 3.0ではmodal-open
クラスがスクロールを防ぐ目的で明示的に返されるように見えます。
体に.modal-openを再導入します(そこでスクロールを無効にできます)。
これを見なさい: https://github.com/Twitter/bootstrap/pull/6342 - モーダル セクションを見なさい。
受け入れられた答えはモバイル(少なくともiOS 7 w/Safari 7)では機能せず、CSSが機能するときに私のサイトでMOAR JavaScriptを実行したくない。
このCSSは、背景ページがモーダルの下でスクロールするのを防ぎます。
body.modal-open {
overflow: hidden;
position: fixed;
}
しかし、それはまた本質的に一番上にスクロールするというわずかな副作用もあります。 position:absolute
はこれを解決しますが、モバイルでスクロールする機能を再導入します。
あなたのビューポートを知っていれば( ビューポートを<body>
に追加するための私のプラグイン)、position
にCSSトグルを追加することができます。
body.modal-open {
// block scroll for mobile;
// causes underlying page to jump to top;
// prevents scrolling on all screens
overflow: hidden;
position: fixed;
}
body.viewport-lg {
// block scroll for desktop;
// will not jump to top;
// will not prevent scroll on mobile
position: absolute;
}
モーダルの表示/非表示の際に、基礎となるページが左右にジャンプしないようにするためにもこれを追加します。
body {
// STOP MOVING AROUND!
overflow-x: hidden;
overflow-y: scroll !important;
}
ボディオーバーフローを隠すだけで、ボディがスクロールしなくなります。モーダルを非表示にしたら、それを自動に戻します。
これがコードです:
$('#adminModal').modal().on('shown', function(){
$('body').css('overflow', 'hidden');
}).on('hidden', function(){
$('body').css('overflow', 'auto');
})
あなたはオーバーフローでボディサイズをウィンドウサイズに設定することを試みることができました:モーダルが開いているとき隠される
警告: 以下のオプションはBootstrap v3.0.xには関係ありません。これらのバージョンでのスクロールはモーダル自体に限定されているためです。ビューポートの高さよりも高い高さを持つモーダルでコンテンツを表示することはできません。
scroll イベントはキャンセルできません。ただし、 マウスホイール および wheel イベントをキャンセルすることは可能です。大きな注意点は、すべてのレガシーブラウザがそれらをサポートしているわけではないということです。Mozillaはつい最近Gecko 17.0で後者のサポートを追加しました。私は本格的な普及を知らないが、IE6 +とChromeはそれらをサポートしている。
これらを活用する方法は次のとおりです。
$('#myModal')
.on('shown', function () {
$('body').on('wheel.modal mousewheel.modal', function () {
return false;
});
})
.on('hidden', function () {
$('body').off('wheel.modal mousewheel.modal');
});
@ charlietflの答えを超えてスクロールバーを考慮する必要があります。そうしないと、文書がリフローすることがあります。
body
の幅を記録するbody
のオーバーフローをhidden
に設定します明示的に本体の幅を手順1の幅に設定します。
var $body = $(document.body);
var oldWidth = $body.innerWidth();
$body.css("overflow", "hidden");
$body.width(oldWidth);
body
のオーバーフローをauto
に設定しますbody
の幅をauto
に設定します
var $body = $(document.body);
$body.css("overflow", "auto");
$body.width("auto");
に触発: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
これを試してください:
.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
height: 100%;
}
それは私のために働きました。 (IE 8をサポート)
/* =============================
* Disable / Enable Page Scroll
* when Bootstrap Modals are
* shown / hidden
* ============================= */
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function theMouseWheel(e) {
preventDefault(e);
}
function disable_scroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = theMouseWheel;
}
function enable_scroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = null;
}
$(function () {
// disable page scrolling when modal is shown
$(".modal").on('show', function () { disable_scroll(); });
// enable page scrolling when modal is hidden
$(".modal").on('hide', function () { enable_scroll(); });
});
CSSを変更しただけではChrome上で機能させることができませんでした。ページを上にスクロールしたくないからです。これはうまくいきました:
$("#myModal").on("show.bs.modal", function () {
var top = $("body").scrollTop(); $("body").css('position','fixed').css('overflow','hidden').css('top',-top).css('width','100%').css('height',top+5000);
}).on("hide.bs.modal", function () {
var top = $("body").position().top; $("body").css('position','relative').css('overflow','auto').css('top',0).scrollTop(-top);
});
このコードについてはよくわかりませんが、一撃の価値があります。
JQueryでは:
$(document).ready(function() {
$(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
$("#Modal").css("overflow", "hidden");
});
});
私が前に言ったように、私は100%確実ではありませんがとにかく試してください。
クラス 'is-modal-open'を追加したり、javascriptでbodyタグのスタイルを変更したりしても問題ありません。しかし、私たちが直面する問題は、本体がオーバーフローしたときです。これは後で使い勝手の問題になるでしょう。
この問題の解決策として、bodyタグのオーバーフローを変更するのではなく、隠しhtmlタグで変更します。
$('#myModal').on('shown.bs.modal', function () {
$('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
$('html').css('overflow','auto');
});
Bootstrap の場合は、これを試すことができます(
Firefox
、Chrome
、およびMicrosoft Edge
に取り組んでいます)。
body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}
お役に立てれば...
最善の解決策は、これらの回答のほとんどで使用されているCSS専用のbody{overflow:hidden}
解決策です。一部の回答では、スクロールバーが消えることによって引き起こされる「ジャンプ」を防ぐ修正も提供されています。しかし、どれもエレガントすぎませんでした。だから、私はこれら二つの関数を書いた、そしてそれらはかなりうまくいくように思われる。
var $body = $(window.document.body);
function bodyFreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('overflow', 'hidden');
$body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}
function bodyUnfreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
$body.css('overflow', 'auto');
}
this jsFiddle をチェックしてください。
あなたは次のロジックを使うことができます、私はそれをテストしました、そしてそれは(IEの中でさえ)働きます
<html>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}
$(function(){
$('#locker').click(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);
})
$('#unlocker').click(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll');
})
})
</script>
<div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="locker">lock</button>
<button id="unlocker">unlock</button>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
チェックボックスハックによって生成されたサイドバーがありました。しかし主な考え方は、文書scrollTopを保存し、ウィンドウのスクロール中に変更しないことです。
私はただ、bodyが 'overflow:hidden'になったときにページがジャンプするのを好まなかった。
window.addEventListener('load', function() {
let prevScrollTop = 0;
let isSidebarVisible = false;
document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
isSidebarVisible = event.target.checked;
window.addEventListener('scroll', (event) => {
if (isSidebarVisible) {
window.scrollTo(0, prevScrollTop);
}
});
})
});
悲しいことに、上記の答えのどれも私の問題を直しませんでした。
私の状況では、Webページにもともとスクロールバーがあります。モーダルをクリックするたびに、スクロールバーは消えず、ヘッダーは少し右に移動します。
それから私は.modal-open{overflow:auto;}
を追加しようとしました(ほとんどの人がこれをお勧めします)。それは確かに問題を解決した:私はモーダルを開いた後にスクロールバーが表示されます。しかし、もう1つの副作用が出てきます。「ヘッダーの下の背景は、モーダルの後ろの別の長いバーと一緒に、少し左に移動します」ということです。
幸いなことに、{padding-right: 0 !important;}
を追加した後、すべてが完全に修正されました。ヘッダとボディの両方の背景は動かず、モーダルはまだスクロールバーを保持します。
これがまだこの問題に立ち往生している人々を助けることを願っています。がんばろう!
2017年11月現在、Chromeに新しいcssプロパティが導入されました
overscroll-behavior: contain;
執筆時点ではクロスブラウザのサポートが制限されていますが、これはこの問題を解決します。
詳細およびブラウザサポートについては、下記のリンクを参照してください。
多くの人が "オーバーフロー:隠し"をボディに提案していますが、これはうまくいきません(少なくとも私の場合はそうではありません)。
これは、jQueryを使用して(携帯電話とコンピューターの両方で)私にとって有効な解決策です。
$('.yourModalDiv').bind('mouseenter touchstart', function(e) {
var current = $(window).scrollTop();
$(window).scroll(function(event) {
$(window).scrollTop(current);
});
});
$('.yourModalDiv').bind('mouseleave touchend', function(e) {
$(window).off('scroll');
});
これにより、モーダルのスクロールが機能し、Webサイトが同時にスクロールするのを防ぎます。
このフィドルに基づく: http://jsfiddle.net/dh834zgw/1/ /
次のスニペット(jqueryを使用)はウィンドウスクロールを無効にします。
var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');
そしてあなたのCSSでは:
html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}
モーダルを削除するときは、htmlタグのnoscrollクラスを削除することを忘れないでください。
$('html').toggleClass('noscroll');
モーダルが100%の高さ/幅の場合、 "mouseenter/leave"はスクロールを簡単に有効/無効にするように働きます。これは私にとって本当にうまくいきました:
var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}
$("#myModal").mouseenter(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);
}).mouseleave(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll',lockscroll);
});
Bootstrap 3のための私の解決策:
.modal {
overflow-y: hidden;
}
body.modal-open {
margin-right: 0;
}
私にとってoverflow: hidden
クラスの唯一のbody.modal-open
は、元のmargin-right: 15px
のためにページが左に移動するのを妨げませんでした。
ほとんどの作品はここにありますが、すべてをまとめた答えはありません。
問題は3つあります。
(1)基礎ページのスクロールを防止する
$('body').css('overflow', 'hidden')
(2)スクロールバーを外します
var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)
(3)モーダルが解任されたときに片付ける
$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')
モーダルがフルスクリーンではない場合は、.modalバインディングをフルスクリーンオーバーレイに適用します。
これがBootstrapでうまくいくかどうかは100%確信できませんが、試してみる価値があります - githubにあるRemodal.jsでうまくいきました: http://vodkabears.github.io/remodal/ メソッドがかなり似ていることには意味があります。
ページの先頭へのジャンプを止め、コンテンツの右への移動を防ぐには、モーダルが起動されたときにクラスをbody
に追加し、次のCSSルールを設定します。
body.with-modal {
position: static;
height: auto;
overflow-y: hidden;
}
position:static
とheight:auto
が組み合わさってコンテンツの右側へのジャンプを止めます。 overflow-y:hidden;
は、ページがモーダルの後ろにスクロール可能になるのを防ぎます。
私はちょうどそれをこうやった….
$('body').css('overflow', 'hidden');
しかしスクローラが消えたときそれはすべて正しい20pxを動かした、それで私は加えた
$('body').css('margin-right', '20px');
その直後.
私のために働きます。
私のために働いた
$('#myModal').on({'mousewheel': function(e)
{
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
});
オーバーフローを隠して位置を固定することはトリックを行いますが、私の流動的な設計ではブラウザの幅を超えてそれを固定するので、幅:100%はそれを修正しました。
body.modal-open{overflow:hidden;position:fixed;width:100%}
このVanillaのjs関数を使って、 "modal-open"クラスを本体に追加しています。 (smhmicの回答に基づく)
function freezeScroll(show, new_width)
{
var innerWidth = window.innerWidth,
clientWidth = document.documentElement.clientWidth,
new_margin = ((show) ? (new_width + innerWidth - clientWidth) : new_width) + "px";
document.body.style.marginRight = new_margin;
document.body.className = (show) ? "modal-open" : "";
};
これは私にとって最良の解決策です。
Css:
.modal {
overflow-y: auto !important;
}
そしてJs:
modalShown = function () {
$('body').css('overflow', 'hidden');
},
modalHidden = function () {
$('body').css('overflow', 'auto');
}
body-scroll-lock
を使用
とても軽く、とてもきれいで人気がある
このコードを試してください:
$('.entry_details').dialog({
width:800,
height:500,
draggable: true,
title: entry.short_description,
closeText: "Zamknij",
open: function(){
// blokowanie scrolla dla body
var body_scroll = $(window).scrollTop();
$(window).on('scroll', function(){
$(document).scrollTop(body_scroll);
});
},
close: function(){
$(window).off('scroll');
}
});
$('.modal').on('shown.bs.modal', function (e) {
$('body').css('overflow-y', 'hidden');
});
$('.modal').on('hidden.bs.modal', function (e) {
$('body').css('overflow-y', '');
});
SharePoint 2013のユーザー向けの小さなメモです。本文には既にoverflow: hidden
があります。あなたが探しているのは、id overflow: hidden
を持つdiv要素にs4-workspace
を設定することです。
var body = document.getElementById('s4-workspace');
body.className = body.className+" modal-open";
他のモーダル内でモーダルを使用すると、上記が発生します。別のモーダルの内側でモーダルを開くと、後者を閉じるとbody
からクラスmodal-open
が削除されます。問題の修正は、後者のモーダルをどのように閉じるかによって異なります。
Htmlのようにモーダルを閉じると、
<button type="button" class="btn" data-dismiss="modal">Close</button>
それならこのようなリスナーを追加しなければなりません、
$(modalSelector).on("hidden.bs.modal", function (event) {
event.stopPropagation();
$("body").addClass("modal-open");
return false;
});
Javascriptを使ってモーダルを閉じると、
$(modalSelector).modal("hide");
その後、このようにしてしばらくしてからコマンドを実行する必要があります。
setInterval(function(){$("body").addClass("modal-open");}, 300);
ブートストラップ3モーダルのscrollイベントを取得する方法について疑問に思っている人のために:
$(".modal").scroll(function() {
console.log("scrolling!);
});
私のために最後にこれを直したのは 本体スクロールロック でした。
他の解決策はiOSのスクロールを無効にしません。
これは私のために働いた:
$("#mymodal").mouseenter(function(){
$("body").css("overflow", "hidden");
}).mouseleave(function(){
$("body").css("overflow", "visible");
});
クロスプラットフォームでのパフォーマンスを向上させるには、HTMLにoverflow: hidden
を追加してください。
私は使うだろう
html.no-scroll {
overflow: hidden;
}
私にとっては、この問題は主にiOSで発生していたので、それを修正するためのコードをiOSでのみ提供します。
if(!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) {
var $modalRep = $('#modal-id'),
startScrollY = null,
moveDiv;
$modalRep.on('touchmove', function(ev) {
ev.preventDefault();
moveDiv = startScrollY - ev.touches[0].clientY;
startScrollY = ev.touches[0].clientY;
var el = $(ev.target).parents('#div-that-scrolls');
// #div-that-scrolls is a child of #modal-id
el.scrollTop(el.scrollTop() + moveDiv);
});
$modalRep.on('touchstart', function(ev) {
startScrollY = ev.touches[0].clientY;
});
}
Bulmaのようにそれをしないのはなぜですか?モーダルがアクティブなときは、HTMLにそれらのクラスを追加します。以上です。
編集:オーケー、ブルマはこのバグを抱えているので、他のものも追加しなければならない
html.is-modal-active {
overflow: hidden !important;
position: fixed;
width: 100%;
}