Подтвердить что ты не робот

Как предотвратить фоновые прокрутки, когда Bootstrap 3 модально открыт в мобильных браузерах?

Как предотвратить прокрутку фона при запуске Bootstrap 3 на мобильных платформах? В настольных браузерах фон не может прокручиваться и работает так, как должен.

В мобильных браузерах (Safari ios, Chrome ios и т.д.), когда модален открыт и с помощью пальца, чтобы прокрутить его, фон также прокручивается так же, как и модальный. Как это предотвратить?

4b9b3361

Ответ 1

Смотрите здесь: https://github.com/twbs/bootstrap/issues/7501

Итак, попробуйте:

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

v3.0.0. должен был устранить эту проблему. Используете ли вы последнюю версию? Если это так, отправьте сообщение о проблеме https://github.com/twbs/bootstrap/

Ответ 2

Попробуйте это,

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

Ответ 3

Я попробовал принятый ответ, который мешал телу прокручиваться, но имел проблему прокрутки вверх. Это должно решить обе проблемы.

Как побочная заметка, она выглядит переполнена: скрытый не работает на теле для iOS Safari только в том случае, если iOS Chrome работает нормально.

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);
    });

Ответ 4

$('.modal') 
.on('shown', function(){ 
  console.log('show'); 
  $('body').css({overflow: 'hidden'}); 
}) 
.on('hidden', function(){ 
  $('body').css({overflow: ''}); 
}); 

используйте этот

Ответ 5

Никаких сценариев не требуется.

BS 3 задает класс .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; 
            }
        }
    }   
}

Ответ 6

Если вы используете jQuery, вы можете сделать это с помощью scrollTop

  • Сохранить положение вертикальной прокрутки тела;
  • Отключить прокрутку по телу;
  • Показать модальный;
  • Закрыть модальный;
  • Повторяющийся прокрутка по телу;
  • Установить сохраненную позицию прокрутки.

#modal {
    bottom: 0;
    position: fixed;
    overflow-y: scroll;
    overflow-x: hidden;
    top: 0;
    width: 100%;
}

Ответ 7

Выбранное решение работает, однако они также привязывают фон к верхней позиции прокрутки. Я продлил код выше, чтобы исправить этот "прыжок".

//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;
}

Ответ 8

У вас была проблема с этим, iPhone + Safari, где нужно было добавить:

position: fixed;

Как уже упоминалось в другом месте, это создало проблему с прокруткой. Исправление, которое сработало для меня, заключалось в том, чтобы зафиксировать позицию сверху на модальном открытии, а затем оживить эту позицию в модальном закрытии

после модального открытия:

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

при модальном закрытии

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

Ответ 9

Я думал, что вы можете забыть добавить атрибут data-toggle="modal" к ссылке или кнопке, которая запускает модальное всплывающее событие. Во-первых, у меня также была та же проблема, но после добавления вышеприведенного атрибута она работает хорошо для меня.

Ответ 10

В дополнение к @Karthick Kumar answer от загрузочные документы

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

Ответ 11

Эй, ребята, поэтому я думаю, что нашел исправление. Это работает для меня на iphone и Android в настоящий момент. Его разброс часов в часы поиска, чтения и тестирования. Так что, если вы видите части своего кода, здесь вы получаете кредит lol.

@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;
}

Причина, по которой носитель информации находится на рабочем столе, у меня возникли проблемы с тем, когда модальный будет открывать весь контент на странице, будет перемещаться с центра налево. Похоже, дерьмо. Таким образом, это нацелено на устройства с размерами планшета, где вам нужно будет прокручивать. На мобильном телефоне и планшете все еще есть небольшая смена, но на самом деле это немного. Дайте мне знать, если это сработает для вас, ребята. Надеюсь, это поставит гвоздь в гроб

Ответ 12

Я нашел простое решение javascript/jquery, которое использует модальные события bootstrap.

Мое решение также устраняет проблему position:fixed, где она прокручивает фоновую страницу до конца, вместо того, чтобы оставаться на месте, когда модальное окно открыто/закрыто.

Подробнее здесь

Ответ 13

Я знаю, что это ответ, но ни одно из этих решений не сработало для меня. Мне нужен был другой подход. Я использую 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);

});

Ответ 14

Использование position:fixed имеет побочный эффект прокрутки тела вверху.

Если вы не хотите, чтобы ваше тело прокручивалось вверх, DO NOTE используйте 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');
})

EDIT: Обратите внимание, что для очень маленьких модалов вам может понадобиться добавить следующую строку в ваш CSS:

.modal-dialog{
    height: 100%;
}

Ответ 15

Предоставлено 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. */

В отличие от других решений, которые мы пробовали, он не прокручивает фон до вершины после закрытия всплывающего мода.

Ответ 16

Я открываю модальный после модального и факта ошибку на модальной прокрутке, и этот css решил мою проблему:

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

Ответ 17

Вышеупомянутые ответы не помогли, так что я сделал:

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

Моя особая проблема заключалась в том, что после загрузки я увеличил размер модальности.

Это известная проблема iOS, см. здесь. Поскольку это ничего не нарушает, вышеупомянутое решение было достаточно для моих нужд.

Ответ 18

Это может быть немного похоже на избиение мертвой лошади здесь.. но, мое в настоящее время реализовано решение на моделях DIY через vanilla JS:

В модальном шоу:

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

Ответ 19

Мое решение...

Ver en jsfiddle

//Fix modal mobile Boostrap 3
function Show(id){
    //Fix CSS
    $(".modal-footer").css({"padding":"19px 20px 20px","margin-top":"15px","text-align":"right","border-top":"1px solid #e5e5e5"});
    $(".modal-body").css("overflow-y","auto");
    //Fix .modal-body height
    $('#'+id).on('shown.bs.modal',function(){
        $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
        h1=$("#"+id+">.modal-dialog").height();
        h2=$(window).height();
        h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
        h4=h2-(h1-h3);      
        if($(window).width()>=768){
            if(h1>h2){
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            }
            $("#"+id+">.modal-dialog").css("margin","30px auto");
            $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
            if($("#"+id+">.modal-dialog").height()+30>h2){
                $("#"+id+">.modal-dialog").css("margin-top","0px");
                $("#"+id+">.modal-dialog").css("margin-bottom","0px");
            }
        }
        else{
            //Fix full-screen in mobiles
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
            $("#"+id+">.modal-dialog").css("margin",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border",0);
            $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
        }
        //Aply changes on screen resize (example: mobile orientation)
        window.onresize=function(){
            $("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
            h1=$("#"+id+">.modal-dialog").height();
            h2=$(window).height();
            h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
            h4=h2-(h1-h3);
            if($(window).width()>=768){
                if(h1>h2){
                    $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                }
                $("#"+id+">.modal-dialog").css("margin","30px auto");
                $("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);               
                if($("#"+id+">.modal-dialog").height()+30>h2){
                    $("#"+id+">.modal-dialog").css("margin-top","0px");
                    $("#"+id+">.modal-dialog").css("margin-bottom","0px");
                }
            }
            else{
                //Fix full-screen in mobiles
                $("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
                $("#"+id+">.modal-dialog").css("margin",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border",0);
                $("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);   
            }
        };
    });  
    //Free event listener
    $('#'+id).on('hide.bs.modal',function(){
        window.onresize=function(){};
    });  
    //Mobile haven't scrollbar, so this is touch event scrollbar implementation
    var y1=0;
    var y2=0;
    var div=$("#"+id+">.modal-dialog>.modal-content>.modal-body")[0];
    div.addEventListener("touchstart",function(event){
        y1=event.touches[0].clientY;
    });
    div.addEventListener("touchmove",function(event){
        event.preventDefault();
        y2=event.touches[0].clientY;
        var limite=div.scrollHeight-div.clientHeight;
        var diff=div.scrollTop+y1-y2;
        if(diff<0)diff=0;
        if(diff>limite)diff=limite;
        div.scrollTop=diff;
        y1=y2;
    });
    //Fix position modal, scroll to top.    
    $('html, body').scrollTop(0);
    //Show
    $("#"+id).modal('show');
}