How to prevent background scrolling when Bootstrap

2019-01-08 10:33发布

How to prevent background scrolling when Bootstrap 3 modal open on mobile platforms? On desktop browsers the background is prevented from scrolling and works as it should.

On mobile browsers (Safari ios, Chrome ios, etc), when a modal is opened and using your finger to scroll it, the background also scrolls as does the modal. How do I prevent that?

20条回答
来,给爷笑一个
2楼-- · 2019-01-08 11:19

No scripts needed.

BS 3 sets a .modal-open class on body that you can use to set the position and overflow values (made with 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; 
            }
        }
    }   
}
查看更多
forever°为你锁心
3楼-- · 2019-01-08 11:22

The chosen solution works, however they also snap the background to the top scrolling position. I extended the code above to fix that 'jump'.

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

The css is pretty simple:

// 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;
}
查看更多
孤傲高冷的网名
4楼-- · 2019-01-08 11:23

Try this,

 body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}
查看更多
beautiful°
5楼-- · 2019-01-08 11:23

I thought you might forget to add attribute data-toggle="modal" to the link or button that triggers the modal popup event. Firstly, I also got the same problem but, after adding the attribute above it works well for me.

查看更多
等我变得足够好
6楼-- · 2019-01-08 11:23

This might be a bit like beating a dead horse here.. but, my currently implemented solution on DIY modals via vanilla JS:

On modal show:

if (document.body.style.position !== 'fixed') {
    document.body.style.top = -window.scrollY + 'px';
    document.body.style.position = 'fixed';
}

On modal hide:

document.body.style.position = '';
window.scrollTo(0, -parseInt(document.body.style.top, 10));
document.body.style.top = '';
查看更多
Evening l夕情丶
7楼-- · 2019-01-08 11:23

Using position:fixed has the side effect of scrolling the body to the top.

If you do not your body to scroll to the top, DO NOTE use position:fixed. Just disable touchmove on the body if the modal is open. Note: The modal itself is still able to scroll on touch (if larger than the screen).

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: Note, for very small modals, you might have to add the following line to your CSS:

.modal-dialog{
    height: 100%;
}
查看更多
登录 后发表回答