How to prevent background scrolling when Bootstrap 3 modal open on mobile browsers?

后端 未结 20 1347
抹茶落季
抹茶落季 2020-12-01 01:45

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

相关标签:
20条回答
  • 2020-12-01 01:57

    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; 
                }
            }
        }   
    }
    
    0 讨论(0)
  • 2020-12-01 01:58

    As additional to @Karthick Kumar answer from bootstrap docs

    show is triggered at the start of an event

    shown is triggered on the completion of an action

    ... so it should be:

    $('.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 讨论(0)
  • 2020-12-01 01:59
    $('.modal') 
    .on('shown', function(){ 
      console.log('show'); 
      $('body').css({overflow: 'hidden'}); 
    }) 
    .on('hidden', function(){ 
      $('body').css({overflow: ''}); 
    }); 
    

    use this one

    0 讨论(0)
  • 2020-12-01 01:59

    My solution...

    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');
    }
    
    0 讨论(0)
  • 2020-12-01 02:01

    Hey guys so i think i found a fix. This is working for me on iphone and android at the moment. Its a mash up of hours upon hours of searching, reading and testing. So if you see parts of your code in here credit goes to you 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;
    }
    

    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. Let me know if this works for you guys. Hopefully this puts the nail in the coffin

    0 讨论(0)
  • 2020-12-01 02:02

    Had an issue with this as well, iPhone + Safari where needed to add:

    position: fixed;
    

    As mentioned elsewhere, this created a scroll-to-top issue. Fix that worked for me was to capture the position to top upon modal open, and then animate to that position on modal close

    upon modal open:

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

    upon modal close

    $('body').css("position", "static");
    $('body').animate({scrollTop: scrollTo}, 0);
    
    0 讨论(0)
提交回复
热议问题