モバイルプラットフォームでBootstrap 3モーダルを開いたときにバックグラウンドスクロールを防ぐ方法デスクトップブラウザーでは、背景のスクロールが防止され、正常に機能します。
モバイルブラウザ(Safari ios、Chrome iosなど)では、モーダルを開いて指でスクロールすると、モーダルと同様に背景もスクロールします。どうすればそれを防ぐことができますか?
こちらをご覧ください: https://github.com/twbs/bootstrap/issues/7501
だから試してください:
$('body').css('overflow','hidden');
$('body').css('position','fixed');
V3.0.0。この問題を修正する必要がありました。最新バージョンを使用していますか?その場合は https://github.com/twbs/bootstrap/ に問題を投稿してください
これを試して、
body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}
私は容認された答えを試してみましたが、これは体がスクロールするのを防ぎましたが、上にスクロールする問題がありました。これで両方の問題が解決するはずです。
サイドノートとして、オーバーフローが表示されます:iOS Chromeが正常に機能するため、hiddenはiOS Safariのボディでは機能しません。
var scrollPos = 0;
$('.modal')
.on('show.bs.modal', function (){
scrollPos = $('body').scrollTop();
$('body').css({
overflow: 'hidden',
position: 'fixed',
top : -scrollPos
});
})
.on('hide.bs.modal', function (){
$('body').css({
overflow: '',
position: '',
top: ''
}).scrollTop(scrollPos);
});
$('.modal')
.on('shown', function(){
console.log('show');
$('body').css({overflow: 'hidden'});
})
.on('hidden', function(){
$('body').css({overflow: ''});
});
これを使う
スクリプトは必要ありません。
BS 3は、bodyに.modal-openクラスを設定します。このクラスを使用して、位置およびオーバーフロー値(LESSで作成)を設定できます。
body {
font-family:'Open Sans';
margin:0;
&.modal-open {
position:fixed;
overflow:hidden;
.modal {
overflow: scroll;
@media only screen and (min-resolution:150dpi) and (max-width: @screen-sm),
only screen and (-webkit-min-device-pixel-ratio:1.5) {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
}
}
}
JQueryを使用する場合は、 scrollTop でこれを行うことができます
#modal {
bottom: 0;
position: fixed;
overflow-y: scroll;
overflow-x: hidden;
top: 0;
width: 100%;
}
$('.open-modal').click(function (e) {
e.preventDefault();
$('#modal').toggle();
scrollTo = $('body').scrollTop();
$('body').css("position", "fixed");
});
$('.close-modal').click(function (e) {
e.preventDefault();
$('#modal').toggle();
$('body').css("position", "static");
$('body').animate({scrollTop: scrollTo}, 0);
});
選択したソリューションは機能しますが、背景を上部のスクロール位置にスナップします。上記のコードを拡張して、その「ジャンプ」を修正しました。
//Set 2 global variables
var scrollTopPosition = 0;
var lastKnownScrollTopPosition = 0;
//when the document loads
$(document).ready(function(){
//this only runs on the right platform -- this step is not necessary, it should work on all platforms
if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
//There is some css below that applies here
$('body').addClass('platform-ios');
//As you scroll, record the scrolltop position in global variable
$(window).scroll(function () {
scrollTopPosition = $(document).scrollTop();
});
//when the modal displays, set the top of the (now fixed position) body to force it to the stay in the same place
$('.modal').on('show.bs.modal', function () {
//scroll position is position, but top is negative
$('body').css('top', (scrollTopPosition * -1));
//save this number for later
lastKnownScrollTopPosition = scrollTopPosition;
});
//on modal hide
$('.modal').on('hidden.bs.modal', function () {
//force scroll the body back down to the right spot (you cannot just use scrollTopPosition, because it gets set to zero when the position of the body is changed by bootstrap
$('body').scrollTop(lastKnownScrollTopPosition);
});
}
});
CSSは非常に簡単です。
// You probably already have this, but just in case you don't
body.modal-open {
overflow: hidden;
width: 100%;
height: 100%;
}
//only on this platform does it need to be fixed as well
body.platform-ios.modal-open {
position: fixed;
}
上記の答えは役に立たなかったので、私がしたことは:
.modal {
-webkit-overflow-scrolling: touch;
}
私の特定の問題は、ロード後にモーダルサイズを大きくしたときでした。
これはiOSの既知の問題です こちらを参照 。それは他に何も壊さないので、上記の解決策は私のニーズに十分でした。
これにも問題があり、iPhone + Safariを追加する必要がある場合:
position: fixed;
他の場所で述べたように、これはスクロールしてトップへの問題を引き起こしました。私のために働いた修正は、モーダルオープン時にトップに位置をキャプチャし、モーダルクローズ時にその位置にアニメーション化することでした
モーダルオープン時:
scrollTo = $('body').scrollTop();
$('body').css("position", "fixed");
モーダルクローズ時
$('body').css("position", "static");
$('body').animate({scrollTop: scrollTo}, 0);
モーダルポップアップイベントをトリガーするリンクまたはボタンに属性data-toggle="modal"
を追加するのを忘れるかもしれないと思った。第一に、私も同じ問題を抱えていましたが、上記の属性を追加した後はうまく機能します。
これは、ここで死んだ馬を打つようなものかもしれません。
モーダルショーの場合:
if (document.body.style.position !== 'fixed') {
document.body.style.top = -window.scrollY + 'px';
document.body.style.position = 'fixed';
}
モーダル非表示:
document.body.style.position = '';
window.scrollTo(0, -parseInt(document.body.style.top, 10));
document.body.style.top = '';
やあみんな、私は修正を見つけたと思う。これは現在、iphoneとAndroidで機能しています。数時間にわたる検索、読書、テストの時間のマッシュアップです。あなたがここであなたのコードの一部を見るならば、信用はあなたに行きます笑。
@media only screen and (max-device-width:768px){
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 {
overflow-x: hidden;
overflow-y: scroll !important;
}
メディア固有が存在する理由は、デスクトップ上で、モーダルがページ上のすべてのコンテンツを開くときに問題が発生していたため、中央から左にシフトします。がらくたのように見えた。そのため、これは、スクロールする必要があるタブレットサイズのデバイスまでを対象としています。モバイルとタブレットではまだわずかな変化がありますが、実際にはそれほどではありません。これがあなたのために働くかどうか私に知らせてください。うまくいけば、これは爪をcoに入れる
JDiApice のおかげで iOS 8.xモーダルスクロールの問題#14839 で他の貢献者の作業を合成および拡張した人
@media only screen and (max-device-width:768px) {
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 {
overflow-x: hidden;
overflow-y: scroll !important;
}
/* The reason the media specific is on there is
on a desktop i was having issues with when the modal would open
all content on the page would shift from centered to left.
Looked like crap. So this targets up to tablet size devices
where you would need to scroll. There is still a slight shift
on mobile and tablet but its really not much. */
試した他のソリューションとは異なり、ポップアップモーダルを閉じた後、背景を上部にスクロールしません。
position:fixed
を使用すると、本文が上部にスクロールされるという副作用があります。
体を上にスクロールしない場合は、position:fixed
を使用してください。モーダルが開いている場合は、本体のtouchmoveを無効にします。注:モーダル自体は、タッチでスクロールできます(画面よりも大きい場合)。
CSS:
body.modal-open {
overflow: hidden;
width: 100%;
/* NO position:fixed here*/
}
JS:
$('.modal').on('show.bs.modal', function (ev) { // prevent body from scrolling when modal opens
$('body').bind('touchmove', function(e){
if (!$(e.target).parents().hasClass( '.modal' )){ //only prevent touch move if it is not the modal
e.preventDefault()
}
})
})
$('.modal').on('hide.bs.modal', function (e) { //unbind the touchmove restrictions from body when modal closes
$('body').unbind('touchmove');
})
編集:非常に小さなモーダルの場合、CSSに次の行を追加する必要がある場合があります。
.modal-dialog{
height: 100%;
}
モーダルの後にモーダルを開き、実際にはモーダルスクロールのエラーが発生し、このCSSは私の問題を解決しました:
.modal {
overflow-y: auto;
padding-right: 15px;
}
@ Karthick Kumar answer from bootstrap docs に追加
showはイベントの開始時にトリガーされます
示されたはアクションの完了時にトリガーされます
...したがって、次のようになります。
$('.modal')
.on('show.bs.modal', function (){
$('body').css('overflow', 'hidden');
})
.on('hide.bs.modal', function (){
// Also if you are using multiple modals (cascade) - additional check
if ($('.modal.in').length == 1) {
$('body').css('overflow', 'auto');
}
});
bootstrapモーダルイベントを利用する簡単なjavascript/jqueryソリューションを見つけました。
私の解決策は、モーダルウィンドウが開いた/閉じたときに所定の位置に留まるのではなく、背景ページを一番上までスクロールするposition:fixed
問題も修正します。
詳細を見る こちら
私はこれが答えられたことを知っていますが、これらの解決策のどれも私のために働きませんでした。私は別のアプローチを取る必要がありました。 PhoneGapを使用しており、コードをネイティブにコンパイルしているため、背景を本文に移動する必要がありました。これが他の人の助けになることを願っています。または、これを行うためのよりクリーンな方法がある場合は、気軽にコメントしてください...
$(document).on('shown.bs.modal', '.modal', function (e) {
$("#" + e.target.id).find(".modal-backdrop").css("z-index", $("#" + e.target.id).css("z-index")).insertBefore("#" + e.target.id);
});