How to programmatically disable page scrolling with jQuery

JqueryCssScroll

Jquery Problem Overview


Using jQuery, I would like to disable scrolling of the body:

My idea is to:

  1. Set body{ overflow: hidden;}
  2. Capture the current scrollTop();/scrollLeft()
  3. Bind to the body scroll event, set scrollTop/scrollLeft to the captured value.

Is there a better way?


Update:

Please see my example, and a reason why, at http://jsbin.com/ikuma4/2/edit

I am aware someone will be thinking "why does he not just use position: fixed on the panel?".

Please do not suggest this as I have other reasons.

Jquery Solutions


Solution 1 - Jquery

This will completely disable scrolling:

$('html, body').css({
    overflow: 'hidden',
    height: '100%'
});

To restore:

$('html, body').css({
    overflow: 'auto',
    height: 'auto'
});

Tested it on Firefox and Chrome.

Solution 2 - Jquery

The only way I've found to do this is similar to what you described:

  1. Grab current scroll position (don't forget horizontal axis!).
  2. Set overflow to hidden (probably want to retain previous overflow value).
  3. Scroll document to stored scroll position with scrollTo().

Then when you're ready to allow scrolling again, undo all that.

Edit: no reason I can't give you the code since I went to the trouble to dig it up...

// lock scroll position, but retain settings for later
var scrollPosition = [  self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,  self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);


// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])

Solution 3 - Jquery

try this

$('#element').on('scroll touchmove mousewheel', function(e){
  e.preventDefault();
  e.stopPropagation();
  return false;
})

Solution 4 - Jquery

I just provide a little tuning to the solution by tfe. In particular, I added some additional control to ensure that there is no shifting of the page content (aka page shift) when the scrollbar is set to hidden.

Two Javascript functions lockScroll() and unlockScroll() can be defined, respectively, to lock and unlock the page scroll.

function lockScroll(){
    $html = $('html'); 
    $body = $('body'); 
    var initWidth = $body.outerWidth();
    var initHeight = $body.outerHeight();

    var scrollPosition = [
        self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
        self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
    ];
    $html.data('scroll-position', scrollPosition);
    $html.data('previous-overflow', $html.css('overflow'));
    $html.css('overflow', 'hidden');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);   
    
    var marginR = $body.outerWidth()-initWidth;
    var marginB = $body.outerHeight()-initHeight; 
    $body.css({'margin-right': marginR,'margin-bottom': marginB});
} 
 
function unlockScroll(){
    $html = $('html');
    $body = $('body');
    $html.css('overflow', $html.data('previous-overflow'));
    var scrollPosition = $html.data('scroll-position');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);    

    $body.css({'margin-right': 0, 'margin-bottom': 0});
}

where I assumed that the <body> has no initial margin.

Notice that, while the above solution works in most of the practical cases, it is not definitive since it needs some further customization for pages that include, for instance, an header with position:fixed. Let's go into this special case with an example. Suppose to have

<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>

with

#header{position:fixed; padding:0; margin:0; width:100%}

Then, one should add the following in functions lockScroll() and unlockScroll():

function lockScroll(){
    //Omissis   
        

    $('#header').css('margin-right', marginR);
} 
 
function unlockScroll(){
    //Omissis   

    $('#header').css('margin-right', 0);
}

Finally, take care of some possible initial value for the margins or paddings.

Solution 5 - Jquery

you can use this code:

$("body").css("overflow", "hidden");

Solution 6 - Jquery

To turn OFF scrolling try this:

var current = $(window).scrollTop();
$(window).scroll(function() {
    $(window).scrollTop(current);
});

to reset:

$(window).off('scroll');

Solution 7 - Jquery

I've written a jQuery plugin to handle this: $.disablescroll.

It prevents scrolling from mousewheel, touchmove, and keypress events, such as Page Down.

There's a demo here.

Usage:

$(window).disablescroll();

// To re-enable scrolling:
$(window).disablescroll("undo");

Solution 8 - Jquery

One liner to disable scrolling including middle mouse button.

$(document).scroll(function () { $(document).scrollTop(0); });

edit: There's no need for jQuery anyway, below same as above in vanilla JS(that means no frameworks, just JavaScript):

document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })

this.documentElement.scrollTop - standard

this.body.scrollTop - IE compatibility

Solution 9 - Jquery

You can attach a function to scroll events and prevent its default behaviour.

var $window = $(window);

$window.on("mousewheel DOMMouseScroll", onMouseWheel);

function onMouseWheel(e) {
	e.preventDefault();
}

https://jsfiddle.net/22cLw9em/

Solution 10 - Jquery

  • To Hide Scroll: $("body").css("overflow", "hidden");
  • To Restore Scroll: $("body").css("overflow", "initial");

Solution 11 - Jquery

Can't you just set the body height to 100% and overflow hidden? See http://jsbin.com/ikuma4/13/edit

Solution 12 - Jquery

Somebody posted this code, which has the problem of not retaining the scroll position when restored. The reason is that people tend to apply it to html and body or just the body but it should be applied to html only. This way when restored the scroll position will be kept:

$('html').css({
    'overflow': 'hidden',
    'height': '100%'
});

To restore:

$('html').css({
    'overflow': 'auto',
    'height': 'auto'
});

Solution 13 - Jquery

This may or may not work for your purposes, but you can extend jScrollPane to fire other functionality before it does its scrolling. I've only just tested this a little bit, but I can confirm that you can jump in and prevent the scrolling entirely. All I did was:

  • Download the demo zip: http://github.com/vitch/jScrollPane/archives/master
  • Open the "Events" demo (events.html)
  • Edit it to use the non-minified script source: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • Within jquery.jscrollpane.js, insert a "return;" at line 666 (auspicious line number! but in case your version differs slightly, this is the first line of the positionDragY(destY, animate) function

Fire up events.html, and you'll see a normally scrolling box which due to your coding intervention won't scroll.

You can control the entire browser's scrollbars this way (see fullpage_scroll.html).

So, presumably the next step is to add a call to some other function that goes off and does your anchoring magic, then decides whether to continue with the scroll or not. You've also got API calls to set scrollTop and scrollLeft.

If you want more help, post where you get up to!

Hope this has helped.

Solution 14 - Jquery

I put an answer that might help here: https://stackoverflow.com/questions/5485244/jquery-simplemodal-disable-scrolling/6403909#6403909

It shows how to turn off the scroll bars without shifting the text around. You can ignore the parts about simplemodal.

Solution 15 - Jquery

If you just want to disable scrolling with keyboard navigation, you can override keydown event.

$(document).on('keydown', function(e){
    e.preventDefault();
    e.stopPropagation();
});

Solution 16 - Jquery

Try this code:

    $(function() { 
        // ...

   	    var $body = $(document);
        $body.bind('scroll', function() {
            if ($body.scrollLeft() !== 0) {
                $body.scrollLeft(0);
            }
        });

        // ...
    });

Solution 17 - Jquery

I am using the following code to disable scrolling and it works fine

    $('html').css({
      'overflow': 'hidden',
      'height': '100%'
    });

except that on my android tablet, url address bar and top window tags remain visible, and when users scroll up and down, the window also scrolls for about 40px up and down, and shows/hides the url bar and the tags. Is there a way to prevent that and have scrolling fully disabled ?

Solution 18 - Jquery

You can cover-up the window with a scrollable div for preventing scrolling of the content on a page. And, by hiding and showing, you can lock/unlock your scroll.

Do something like this:

#scrollLock {
    width: 100%;
    height: 100%;
    position: fixed;
    overflow: scroll;
    opacity: 0;
    display:none
}

#scrollLock > div {
    height: 99999px;
}

function scrollLock(){
	$('#scrollLock').scrollTop('10000').show();
}

function scrollUnlock(){
	$('#scrollLock').hide();
}

Solution 19 - Jquery

For folks who have centered layouts (via margin:0 auto;), here's a mash-up of the position:fixed solution along with @tfe's proposed solution.

Use this solution if you're experiencing page-snapping (due to the scrollbar showing/hiding).

// lock scroll position, but retain settings for later
var scrollPosition = [
    window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
    window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var $html = $('html'); // bow to the demon known as MSIE(v7)
$html.addClass('modal-noscroll');
$html.data('scroll-position', scrollPosition);
$html.data('margin-top', $html.css('margin-top'));
$html.css('margin-top', -1 * scrollPosition[1]);

…combined with…

// un-lock scroll position
var $html = $('html').removeClass('modal-noscroll');
var scrollPosition = $html.data('scroll-position');
var marginTop = $html.data('margin-top');
$html.css('margin-top', marginTop);
window.scrollTo(scrollPosition[0], scrollPosition[1])

…and finally, the CSS for .modal-noscroll

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

I would venture to say this is more of a proper fix than any of the other solutions out there, but I haven't tested it that thoroughly yet… :P


Edit: please note that I have no clue how badly this might perform (read: blow up) on a touch device.

Solution 20 - Jquery

You can also use DOM to do so. Say you have a function you call like this:

function disable_scroll() {
document.body.style.overflow="hidden";
}

And that's all there is to it! Hope this helps in addition to all the other answers!

Solution 21 - Jquery

This is what I ended up doing:

CoffeeScript:

	$("input").focus ->
		$("html, body").css "overflow-y","hidden"
		$(document).on "scroll.stopped touchmove.stopped mousewheel.stopped", (event) ->
			event.preventDefault()

	$("input").blur ->
		$("html, body").css "overflow-y","auto"
		$(document).off "scroll.stopped touchmove.stopped mousewheel.stopped"

Javascript:

$("input").focus(function() {
 $("html, body").css("overflow-y", "hidden");
 $(document).on("scroll.stopped touchmove.stopped mousewheel.stopped", function(event) {
   return event.preventDefault();
 });
});

$("input").blur(function() {
 $("html, body").css("overflow-y", "auto");
 $(document).off("scroll.stopped touchmove.stopped mousewheel.stopped");
});

Solution 22 - Jquery

Not sure if anybody has tried out my solution. This one works on the whole body/html but no doubt it can be applied to any element that fires a scroll event.

Just set and unset scrollLock as you need.

var scrollLock = false;
var scrollMem = {left: 0, top: 0};

$(window).scroll(function(){
    if (scrollLock) {
        window.scrollTo(scrollMem.left, scrollMem.top);
    } else {
        scrollMem = {
            left: self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
            top: self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
        };
    }
});

Here's the example JSFiddle

Hope this one helps somebody.

Solution 23 - Jquery

I think the best and clean solution is:

window.addEventListener('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y);
});

And with jQuery:

$(window).on('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y)
})

Those event listener should block scrolling. Just remove them to re enable scrolling

Solution 24 - Jquery

If want to programmatically disable scrolling you can use:

overflow: clip;

If you wanted to disable scrolling for the user you can use:

overflow: hidden;

https://developer.mozilla.org/en-US/docs/Web/CSS/overflow

The browser support for the overflow property varies:

https://caniuse.com/?search=overflow

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHailwoodView Question on Stackoverflow
Solution 1 - JquerygitaarikView Answer on Stackoverflow
Solution 2 - JquerytfeView Answer on Stackoverflow
Solution 3 - JquerycubbiuView Answer on Stackoverflow
Solution 4 - JqueryJeanValjeanView Answer on Stackoverflow
Solution 5 - Jquerymr.soroushView Answer on Stackoverflow
Solution 6 - JqueryPatrick DaVaderView Answer on Stackoverflow
Solution 7 - JqueryJosh HarrisonView Answer on Stackoverflow
Solution 8 - JqueryPawelView Answer on Stackoverflow
Solution 9 - JquerydzimiView Answer on Stackoverflow
Solution 10 - JqueryJoan Alberto Aguilar PeñaView Answer on Stackoverflow
Solution 11 - JqueryAdrian SchmidtView Answer on Stackoverflow
Solution 12 - JqueryMescalinaView Answer on Stackoverflow
Solution 13 - JqueryJeremy WarneView Answer on Stackoverflow
Solution 14 - Jquerymhenry1384View Answer on Stackoverflow
Solution 15 - JqueryseanView Answer on Stackoverflow
Solution 16 - JqueryJopieView Answer on Stackoverflow
Solution 17 - Jqueryuser3102556View Answer on Stackoverflow
Solution 18 - JqueryAppexView Answer on Stackoverflow
Solution 19 - JqueryMatthematticsView Answer on Stackoverflow
Solution 20 - JqueryBrendanView Answer on Stackoverflow
Solution 21 - JqueryMarzView Answer on Stackoverflow
Solution 22 - JqueryFossilMFCView Answer on Stackoverflow
Solution 23 - JqueryTizianoView Answer on Stackoverflow
Solution 24 - JqueryKonkretView Answer on Stackoverflow