js/css : disable scrollbar but keep scroll position

后端 未结 6 433
情深已故
情深已故 2020-12-31 01:40

I\'m using the Jquery dialog to open a popup box window on top of a page. When I open the dialog box, I want the general page scrolling to be disabled. To do so, I am doing

相关标签:
6条回答
  • 2020-12-31 01:58

    you can calculate the difference between the body width, before and after the overflow hidden, and apply it as padding-right to the body

    var bodyStartW = $("body").width();
    $("body").css("overflow-y" , "hidden");
    var bodyEndW = $("body").width();
    var bodyMarginL = bodyEndW - bodyStartW;
    $("body").css("padding-right" , bodyMarginL);
    

    In Safari you had the same trick for the "html" tag, and margin-right instead of padding-right

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

    I use these two functions for the same purpose:

    function enableBodyScroll() {
      if (document.readyState === 'complete') {
        document.body.style.position = '';
        document.body.style.overflowY = '';
    
        if (document.body.style.marginTop) {
          const scrollTop = -parseInt(document.body.style.marginTop, 10);
          document.body.style.marginTop = '';
          window.scrollTo(window.pageXOffset, scrollTop);
        }
      } else {
        window.addEventListener('load', enableBodyScroll);
      }
    }
    
    function disableBodyScroll({ savePosition = false } = {}) {
      if (document.readyState === 'complete') {
        if (document.body.scrollHeight > window.innerHeight) {
          if (savePosition) document.body.style.marginTop = `-${window.pageYOffset}px`;
          document.body.style.position = 'fixed';
          document.body.style.overflowY = 'scroll';
        }
      } else {
        window.addEventListener('load', () => disableBodyScroll({ savePosition }));
      }
    }
    

    How it works:

    1. When you want to disable the scroll with saving the current position, you run disableBodyScroll({ savePosition: true }).

    2. The function check whether the page loaded or not (because user may trigger dialog opening during the loading).

    3. If the page is loaded, it saves current scroll position by setting margin-top on body, then it sets position: fixed; overflow-y: scroll on it to remove scrollbar.

    4. If the page isn't loaded, it adds event listener to run (3.) when the page loads.

    For enabling scroll everything is the same, but the function remove styles instead of setting them.

    Source of the code: https://github.com/funbox/diamonds/blob/master/lib/body-scroll.ts

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

    I have made a pretty simple example of my solution.

    http://jsfiddle.net/6eyJm/1/

    Your popup should be in a box

    <div id="shadow">
    <div id="popup">
        <a id='close' href="#">Close</a>
    </div>
    

    Then put those CSS on de root div

    #shadow{
        display: none;
        position: fixed;
        top:0;
        bottom: 0;
        width: 100%;
        height:100%;
        background-color: rgba(0,0,0,0.6);
    }
    

    Position fixed is really important since you dont want to see the white border, it will take full window width and not body.

    Then there's the little JS trick

    $('#open').click(function(e){
        e.preventDefault()
        $('body').width($('body').width());
        $('body').css('overflow', 'hidden');
        $('#shadow').css('display', 'block');
    })
    $('#close').click(function(e){
        e.preventDefault()
        $('body, #shadow').removeAttr('style')
    })
    

    The goal here is to take the body width before removing the scroll bar. Your content will not move.

    Hope it help!

    Sorry for my english, not my native langage.

    0 讨论(0)
  • 2020-12-31 02:14

    Remembering the offset should keep your popup at bay;

    JSfiddle

    HTML

    <div id="popupholder">
        <button id="close">Close me</button>
    </div>
    
    
    asd <br />asd <br />asd <br />asd <br />asd <br />
    <button class="open">Popup</button>
    <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd<br />
    <button class="open">Popup</button>
    <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />
    <button class="open">Popup</button>
    <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd<br />
    <button class="open">Popup</button>
    <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />asd <br />
    

    CSS

    html, body {
        margin: 0px;
    }
    
    #popupholder {
        width: 100%;
        height: 100%;
        position: absolute;
        display: box;
        display: -webkit-box;
        display: -moz-box;
        background-color: rgba(0,0,0,0.75);
        display: none;
    }
    
    #close {
        display: block;
        height: 20px;
        margin: 75px auto 0px auto;
    }
    

    JavaScript

    $(document).ready(function() {
        $('.open').click(function() {
            // Block scrolling
            $('body').css('overflow', 'hidden');
    
            // Show popup
            var offset = window.pageYOffset;
            //console.log(offset);
            $('#popupholder').css({
                'display': 'block',
                'top': offset + 'px'
            });
        });
    
        $('#close').click(function() {
            // Enable scrolling
            $('body').css('overflow', 'auto');
    
            // Hide popup
            $('#popupholder').css('display', 'none');
        });
    });
    

    For safety-reasons you could add a very high z-index to your #popupholder, but that's not really relevant to the question.

    0 讨论(0)
  • 2020-12-31 02:15

    This is the best solution I got so far. And believe me I tried all the others and this is the best and the simplest solution I came up with. It works great on Windows devices, which pushes the page from the right to have room for the system scrollbar and IOS devices which don't require space for their scrollbars in the browsers. So by using this you wont need to add padding on the right so the page doesn't flicker when you hide the overflow of the body or html with css.

    The solution is pretty simple if you think about it. The idea is to give the window.scrollTop() the same exact position at the moment that a popup is opened. Also change that position when the window resizes ( as the scroll position changes once that happens ).

    So here we go...

    First lets create the variable that will let you know that the popup is open and call it stopWindowScroll. If we don't do this then you'll get an error of an undefined variable on your page and set it to 0 - as not active.

    $(document).ready(function(){
        stopWindowScroll = 0;
    });
    

    Now lets make the open popup function witch can be any function in your code that triggers whatever popup you are using as a plugin or custom. In this case it will be a simple custom popup with a simple document on click function.

    $(document).on('click','.open-popup', function(){
        // Saving the scroll position once opening the popup.
        stopWindowScrollPosition = $(window).scrollTop();
        // Setting the stopWindowScroll to 1 to know the popup is open.
        stopWindowScroll = 1;
        // Displaying your popup.
        $('.your-popup').fadeIn(300);
    });
    

    So the next thing we do is create the close popup function, which I repeat again can be any function you already have created or are using in a plugin. The important thing is that we need those 2 functions to set the stopWindowScroll variable to 1 or 0 to know when it's open or closed.

    $(document).on('click','.open-popup', function(){
        // Setting the stopWindowScroll to 0 to know the popup is closed.
        stopWindowScroll = 0;
        // Hiding your popup
        $('.your-popup').fadeOut(300);
    });
    

    Then lets create the window.scroll function so we can prevent the scrolling once the stopWindowScroll mentioned above is set to 1 - as active.

    $(window).scroll(function(){
        if(stopWindowScroll == 1) {
             // Giving the window scrollTop() function the position on which
             // the popup was opened, this way it will stay in its place.
             $(window).scrollTop(stopWindowScrollPosition);
        }
    });
    

    Thats it. No CSS required for this to work except your own styles for the page. This worked like a charm for me and I hope it helps you and others.

    Here is a working example on JSFiddle:

    JS Fiddle Example

    Let me know if this helped. Regards.

    0 讨论(0)
  • 2020-12-31 02:16

    I had the same problem this repository helped me no-scroll

    0 讨论(0)
提交回复
热议问题