Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent page scrolling to top upon adding fixed position

I'm facing a problem where the page is scrolling to the top whenever I add my .noscroll class to the body. This way the scrollbar is still visible but greyed out whenever the overlay appears.

I know that it's the addClass() function that is the cause of this because when I comment out that line, it doesn't scroll to the top when my overlay appears.

jQuery

$('a').click(function(e) {
    //reset default anchor behavior
    e.preventDefault();

    //add noscroll class to body
    $("body").addClass("noscroll"); 

    //open overlay box
    openOverlayBox(); 
});

The openOverlayBox() function is simply a full browser screen overlay with a black tint.

CSS

body.noscroll{
    position: fixed;
    width: 100%;
    overflow-y: scroll;
}

Body HTML

<a href="#">Test</a>

How can I make the scroll position stay the same after the .noscroll class has been added to the body?

EDIT 1: I'm trying to achieve the same as on Facebook. If you view a picture or video, the overlay appears, the scrollbar is greyed out but the scrolled position is maintained.

EDIT 2: I found a very close solution to my issue, but the only thing is that this does not grey the scrollbar out, but just removes it. Also when the content is centered in the middle, it still makes the content jump a little to the right because the scrollbar from the body is hidden.

EDIT 3: After Cuberto's answer and some research of myself I found out what needs to be done to get it working I want. However I don't have a clue how I would start doing it. But this is what should solve it. I when opening the overlay I need to set my main div on position: fixed and a negative top value of the scroll position. When exiting the overlay, the position: fixed; and top attribute should be removed and the same scroll position set as when the overlay was opened.

like image 983
Kid Diamond Avatar asked Nov 26 '13 23:11

Kid Diamond


2 Answers

I believe this is what you are looking for.

Hope you enjoy this fiddle. I took the one you referenced at the end of your question and re-worked it the way you wanted.

I happened to have done something similar to this on my site but I never restricted the scrolling underneath until now.


Javascript + jQuery:

$(document).ready(function () {
    var offsetY = window.pageYOffset,
        $body = $('body'),
        $win = $(window),
        $close = $('.close'),
        $open = $('.open'),
        $holder = $('#popupholder'),
        $stuff = $('#stuff');
    // Close with 'esc' key
    $(document).keyup(function (e) {
        if (e.keyCode == 27) $close.trigger('click');
    });
    $open.click(function () {
        offsetY = window.pageYOffset;
        // Block scrolling
        $body.css({
            'position': 'fixed',
                'color': '#FFFF00',
                'backgroundColor': '#00D',
                'top': -offsetY + 'px'
        });
        // Show popup
        $holder.css('display', 'block');
    });

    $close.click(function () {
        // Allow scrolling again
        $body.css({
            'position': 'static',
                'color': '',
                'backgroundColor': ''
        });
        /**
         * Remove the following scrollTop()'s if you want.
         * just a UI tweak that the user would expect.
         **/
        // Make the page stay at the position it was at before the overlay
        $win.scrollTop(offsetY);
        // Reset the overlay scroll position to the top
        $stuff.scrollTop(0);
        // Hide popup
        $holder.css('display', 'none');
    });
});

CSS:

#popupholder {
    max-height: none;
    position: fixed;
    background-color: rgba(0, 0, 0, 0.75);
    display: none;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: hidden;
}
#wrap {
    max-height: none;
    position: fixed;
    overflow: hidden;
    top: 60px;
    right: 60px;
    left: 60px;
    bottom: 60px;
    background-color: rgba(155, 155, 134, 0.5);
    display: block;
}
#stuff {
    max-height: 100%;
    position: absolute;
    overflow-y: scroll;
    top: 0;
    /* If you want the scrollbar inside the overlay to show up, set right: 0; */
    right: -20px;
    left: 0;
    bottom: 0;
    padding: 10px;
}

HTML:

(abridged version)

<div id="popupholder">
    <div id="wrap">
        <div id="stuff">
            <button class="close">Close me</button>
            <p> Inside information </p>
            <button class="close">Close me</button>
        </div>
    </div>
<button class="open">Popup</button>

Original code credit goes to this answer. Code was highly altered but credit given where credit is due.

like image 166
Deryck Avatar answered Oct 18 '22 19:10

Deryck


Taking a quick look at how facebook does it, it's something like this:

<body>
  <div class="main" style="position: fixed; top: -400px"></div>
  <div class="overlay" style="position: absolute; width: 100%; height: 100%"></div>
</body>

Sorry for the inline styles. You need to programmatically set the main div's top style to your scroll position.

like image 44
sbking Avatar answered Oct 18 '22 21:10

sbking