web-dev-qa-db-ja.com

モバイルブラウザでBootstrap 3モーダルを開いたときにバックグラウンドスクロールを防ぐ方法

モバイルプラットフォームでBootstrap 3モーダルを開いたときにバックグラウンドスクロールを防ぐ方法デスクトップブラウザーでは、背景のスクロールが防止され、正常に機能します。

モバイルブラウザ(Safari ios、Chrome iosなど)では、モーダルを開いて指でスクロールすると、モーダルと同様に背景もスクロールします。どうすればそれを防ぐことができますか?

40
fat fantasma

こちらをご覧ください: https://github.com/twbs/bootstrap/issues/7501

だから試してください:

$('body').css('overflow','hidden');
$('body').css('position','fixed');

V3.0.0。この問題を修正する必要がありました。最新バージョンを使用していますか?その場合は https://github.com/twbs/bootstrap/ に問題を投稿してください

36
Bass Jobsen

これを試して、

 body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}
24
Sivakumar

私は容認された答えを試してみましたが、これは体がスクロールするのを防ぎましたが、上にスクロールする問題がありました。これで両方の問題が解決するはずです。

サイドノートとして、オーバーフローが表示されます: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);
    });
19
Joe
$('.modal') 
.on('shown', function(){ 
  console.log('show'); 
  $('body').css({overflow: 'hidden'}); 
}) 
.on('hidden', function(){ 
  $('body').css({overflow: ''}); 
}); 

これを使う

9
Karthick Kumar

スクリプトは必要ありません。

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; 
            }
        }
    }   
}
5
Martin

JQueryを使用する場合は、 scrollTop でこれを行うことができます

  1. ボディの垂直スクロール位置を保存します。
  2. 本体のスクロールを無効にします。
  3. モーダルを表示します。
  4. モーダルを閉じます。
  5. 本体のスクロールを再度有効にします。
  6. 保存されたスクロール位置を設定します。
#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);
});
3
Tonijn

選択したソリューションは機能しますが、背景を上部のスクロール位置にスナップします。上記のコードを拡張して、その「ジャンプ」を修正しました。

//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;
}
3
Mark Pruce

上記の答えは役に立たなかったので、私がしたことは:

.modal {
  -webkit-overflow-scrolling: touch; 
}

私の特定の問題は、ロード後にモーダルサイズを大きくしたときでした。

これはiOSの既知の問題です こちらを参照 。それは他に何も壊さないので、上記の解決策は私のニーズに十分でした。

2

これにも問題があり、iPhone + Safariを追加する必要がある場合:

position: fixed;

他の場所で述べたように、これはスクロールしてトップへの問題を引き起こしました。私のために働いた修正は、モーダルオープン時にトップに位置をキャプチャし、モーダルクローズ時にその位置にアニメーション化することでした

モーダルオープン時:

scrollTo = $('body').scrollTop();
$('body').css("position", "fixed");

モーダルクローズ時

$('body').css("position", "static");
$('body').animate({scrollTop: scrollTo}, 0);
1
Ryan Charmley

モーダルポップアップイベントをトリガーするリンクまたはボタンに属性data-toggle="modal"を追加するのを忘れるかもしれないと思った。第一に、私も同じ問題を抱えていましたが、上記の属性を追加した後はうまく機能します。

1
Micheal

これは、ここで死んだ馬を打つようなものかもしれません。

モーダルショーの場合:

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 = '';
1
Lucas

やあみんな、私は修正を見つけたと思う。これは現在、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に入れる

0
JoeyD

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. */

試した他のソリューションとは異なり、ポップアップモーダルを閉じた後、背景を上部にスクロールしません。

0
CAK2

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%;
}
0
Kito

モーダルの後にモーダルを開き、実際にはモーダルスクロールのエラーが発生し、このCSSは私の問題を解決しました:

.modal {
    overflow-y: auto;
    padding-right: 15px;
}
0
sokphea chea

@ 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');
            }
        });
0
madzohan

bootstrapモーダルイベントを利用する簡単なjavascript/jqueryソリューションを見つけました。

私の解決策は、モーダルウィンドウが開いた/閉じたときに所定の位置に留まるのではなく、背景ページを一番上までスクロールするposition:fixed問題も修正します。

詳細を見る こちら

0
Truchainz

私はこれが答えられたことを知っていますが、これらの解決策のどれも私のために働きませんでした。私は別のアプローチを取る必要がありました。 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);

});
0
Paul