How to disable scrolling temporarily?

JavascriptJqueryScroll

Javascript Problem Overview


I'm using the scrollTo jQuery plugin and would like to know if it is somehow possible to temporarily disable scrolling on the window element through Javascript? The reason I'd like to disable scrolling is that when you scroll while scrollTo is animating, it gets really ugly ;)

Of course, I could do a $("body").css("overflow", "hidden"); and then put it back to auto when the animation stops, but it would be better if the scrollbar was still visible but inactive.

Javascript Solutions


Solution 1 - Javascript

The scroll event cannot be canceled. But you can do it by canceling these interaction events:
Mouse & Touch scroll and Buttons associated with scrolling.

[Working demo]

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

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

function preventDefaultForScrollKeys(e) {
  if (keys[e.keyCode]) {
    preventDefault(e);
    return false;
  }
}

// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () { supportsPassive = true; } 
  }));
} catch(e) {}

var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

// call this to Disable
function disableScroll() {
  window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
  window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
  window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}

// call this to Enable
function enableScroll() {
  window.removeEventListener('DOMMouseScroll', preventDefault, false);
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 
  window.removeEventListener('touchmove', preventDefault, wheelOpt);
  window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

UPDATE: fixed Chrome desktop and modern mobile browsers with passive listeners

Solution 2 - Javascript

Do it simply by adding a class to the body:

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

Add the class then remove when you want to re-enable scrolling, tested in IE, FF, Safari and Chrome.

$('body').addClass('stop-scrolling')

For mobile devices, you'll need to handle the touchmove event:

$('body').bind('touchmove', function(e){e.preventDefault()})

And unbind to re-enable scrolling. Tested in iOS6 and Android 2.3.3

$('body').unbind('touchmove')

Solution 3 - Javascript

Here's a really basic way to do it:

window.onscroll = function () { window.scrollTo(0, 0); };

It's kind of jumpy in IE6.

Solution 4 - Javascript

The following solution is basic but pure JavaScript (no jQuery):

function disableScrolling(){
    var x=window.scrollX;
	var y=window.scrollY;
	window.onscroll=function(){window.scrollTo(x, y);};
}

function enableScrolling(){
	window.onscroll=function(){};
}

Solution 5 - Javascript

This solution will maintain the current scroll position whilst scrolling is disabled, unlike some which jump the user back to the top.

It's based on galambalazs' answer, but with support for touch devices, and refactored as a single object with jquery plugin wrapper.

Demo here.

On github here.

/**
 * $.disablescroll
 * Author: Josh Harrison - aloof.co
 *
 * Disables scroll events from mousewheels, touchmoves and keypresses.
 * Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
 */

;(function($) {

    "use strict";

    var instance, proto;

    function UserScrollDisabler($container, options) {
        // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
        // left: 37, up: 38, right: 39, down: 40
        this.opts = $.extend({
            handleKeys : true,
            scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
        }, options);
        
        this.$container = $container;
        this.$document = $(document);
        this.lockToScrollPos = [0, 0];

        this.disable();
    }

    proto = UserScrollDisabler.prototype;

    proto.disable = function() {
        var t = this;

        t.lockToScrollPos = [
            t.$container.scrollLeft(),
            t.$container.scrollTop()
        ];

        t.$container.on(
            "mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
            t._handleWheel
        );
        
        t.$container.on("scroll.disablescroll", function() {
            t._handleScrollbar.call(t);
        });

        if(t.opts.handleKeys) {
            t.$document.on("keydown.disablescroll", function(event) {
                t._handleKeydown.call(t, event);
            });
        }
    };
        
    proto.undo = function() {
        var t = this;
        t.$container.off(".disablescroll");
        if(t.opts.handleKeys) {
            t.$document.off(".disablescroll");
        }
    };
    
    proto._handleWheel = function(event) {
        event.preventDefault();
    };
    
    proto._handleScrollbar = function() {
        this.$container.scrollLeft(this.lockToScrollPos[0]);
        this.$container.scrollTop(this.lockToScrollPos[1]);
    };
    
    proto._handleKeydown = function(event) {
        for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
            if (event.keyCode === this.opts.scrollEventKeys[i]) {
                event.preventDefault();
                return;
            }
        }
    };
        

    // Plugin wrapper for object
    $.fn.disablescroll = function(method) {

        // If calling for the first time, instantiate the object and save
        // reference. The plugin can therefore only be instantiated once per
        // page. You can pass options object in through the method parameter.
        if( ! instance && (typeof method === "object" || ! method)) {
            instance = new UserScrollDisabler(this, method);
        }

        // Instance already created, and a method is being explicitly called,
        // e.g. .disablescroll('undo');
        else if(instance && instance[method]) {
            instance[method].call(instance);
        }

    };

    // Global access
    window.UserScrollDisabler = UserScrollDisabler;

})(jQuery);

Solution 6 - Javascript

I'm sorry to answer an old post but I was looking for a solution and came across this question.

There are many workarounds for this issue to still display the scrollbar, like giving the container a 100% height and an overflow-y: scroll styling.

In my case I just created a div with a scrollbar which I display while adding overflow: hidden to the body:

function disableScroll() {
	document.getElementById('scrollbar').style.display = 'block';
	document.body.style.overflow = 'hidden';
}

The element scrollbar must have this styles:

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

This shows a grey scrollbar, hope it helps future visitors.

Solution 7 - Javascript

var winX = null;
var winY = null;

window.addEventListener('scroll', function () {
    if (winX !== null && winY !== null) {
        window.scrollTo(winX, winY);
    }
});

function disableWindowScroll() {
    winX = window.scrollX;
    winY = window.scrollY;
}

function enableWindowScroll() {
    winX = null;
    winY = null;
}

Solution 8 - Javascript

I was looking out for a solution to this problem but was not satisfied with the any of the above solutions (as of writing this answer), so I came up with this solution..

CSS

.scrollDisabled {   
    position: fixed;
    margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
    width: 100%;
}

JS

var y_offsetWhenScrollDisabled=0;

function disableScrollOnBody(){
    y_offsetWhenScrollDisabled= $(window).scrollTop();
    $('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
    $('body').removeClass('scrollDisabled').css('margin-top', 0);
    $(window).scrollTop(y_offsetWhenScrollDisabled);
}

Solution 9 - Javascript

As of Chrome 56 and other modern browsers, you have to add passive:false to the addEventListener call to make preventDefault work. So I use this to stop scrolling on mobile:

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

function disableScroll(){
	document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
	document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}

Solution 10 - Javascript

No, I wouldn't go with event handling because:

  • not all events are guaranteed to reach body,

  • selecting text and moving downwards actually scrolls the document,

  • if at the phase of event detaching sth goes wrong you are doomed.

I've bitten by this by making a copy-paste action with a hidden textarea and guess what, the page scroll whenever I make copy because internally I have to select the textarea before I call document.execCommand('copy').

Anyway that's the way I go, notice the setTimeout():

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

A momentum flashing exists as the scrollbars disappear momentarily but it's acceptable I thing.

Solution 11 - Javascript

According to the galambalazs post I would add support for touch devices, allowing us to touch but no scroll up or down:

function disable_scroll() {
   ...
   document.ontouchmove = function(e){ 
        e.preventDefault(); 
   }
}

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}

Solution 12 - Javascript

Depending on what you want to achieve with the removed scroll you could just fix the element that you want to remove scroll from (on click, or whatever other trigger you'd like to temporarily deactivate scroll)

I was searching around for a "temp no scroll" solution and for my needs, this solved it

make a class

.fixed{
    position: fixed;
}

then with Jquery

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from

contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class

//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){
    
    if(contentContainer.hasClass('notfixed')){
        contentContainer.removeClass('notfixed').addClass('fixed');
    
    }else if(contentContainer.hasClass('fixed')){
        contentContainer.removeClass('fixed').addClass('notfixed');
    };
});

I found that this was a simple enough solution that works well on all browsers, and also makes for simple use on portable devices (i.e. iPhones, tablets etc). Since the element is temporarily fixed, there is no scroll :)

NOTE! Depending on the placement of your "contentContainer" element you might need to adjust it from the left. Which can easily be done by adding a css left value to that element when the fixed class is active

contentContainer.css({
    'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});

Solution 13 - Javascript

Another solution:

body {
    overflow-y: scroll;
    width: 100%;
    margin: 0 auto;
}

This way you always have a vertical scrollbar, but as most of my content is longer than the viewport, this is ok for me. Content is centered with a separate div, but without setting margin again in body my content would stay at the left.

These are the two function I use to show my popup/modal:

var popup_bodyTop = 0;
var popup_bodyLeft = 0;

function popupShow(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');

    // remember current scroll-position
    // because when setting/unsetting position: fixed to body
    // the body would scroll to 0,0
    popup_bodyLeft = $(document).scrollLeft();
    popup_bodyTop  = $(document).scrollTop();

    // invert position
    var x = - popup_bodyLeft;
    var y = - popup_bodyTop;

    $('body').css('position', 'fixed');
    $('body').css('top', y.toString() +'px');
    $('body').css('left', x.toString() +'px');
}

function popupHide(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');
    $('body').css('position', '');
    $('html, body').scrollTop(popup_bodyTop);
    $('html, body').scrollLeft(popup_bodyLeft);
}

Result: non scrollable background and no re-positioning of the content because of the left scrollbar. Tested with current FF, Chrome and IE 10.

Solution 14 - Javascript

I'm using showModalDialog, for showing secondary page as modal dialog.

to hide main window scrollbars:

document.body.style.overflow = "hidden";

and when closing modal dialog, showing main window scrollbars:

document.body.style.overflow = "scroll";

to access elements in main window from dialog:

parent.document.getElementById('dialog-close').click();

just for anybody searching about showModalDialog:(after line 29 of original code)

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
    e.preventDefault();
    document.body.style.overflow = "scroll";//****
    dialog.close();
});

Solution 15 - Javascript

This is the simplest solution I got so far. And believe me I tried all the others and this is the easiest one. 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.

Solution 16 - Javascript

How about this? (If you're using jQuery)

var $window = $(window);
var $body = $(window.document.body);

window.onscroll = function() {
	var overlay = $body.children(".ui-widget-overlay").first();
		
	// Check if the overlay is visible and restore the previous scroll state
	if (overlay.is(":visible")) {
		var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
		window.scrollTo(scrollPos.x, scrollPos.y);
	}
	else {
		// Just store the scroll state
		$body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
	}
};

Solution 17 - Javascript

Cancelling the event's as in the accepted answer is a horrible method in my opinion :/

Instead I used position: fixed; top: -scrollTop(); below.

Demo: https://jsfiddle.net/w9w9hthy/5/

From my jQuery popup project: https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
    if($("html").css("position") != "fixed") {
        var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
        if(window.innerWidth > $("html").width()) {
            $("html").css("overflow-y", "scroll");
        }
        $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
    }
}

//Unfreeze page content scrolling
function unfreeze() {
    if($("html").css("position") == "fixed") {
        $("html").css("position", "static");
        $("html, body").scrollTop(-parseInt($("html").css("top")));
        $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
    }
}

This code takes, width, height, scrollbar and pagejump issues into consideration.

Possible issues resolved with above code:

  • width, when setting position fixed the html element width can be smaller then 100%
  • height, same as above
  • scrollbar, when setting position fixed the page content no longer has a scrollbar even when it had a scrollbar before resulting in a horizontal pagejump
  • pagejump, when setting position fixed the page scrollTop is no longer effective resulting in a vertical pagejump

If anyone has any improvements to above page freeze/unfreeze code let me know so I can add those improvements to my project.

Solution 18 - Javascript

The simplest method is:

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

To undo it:

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

Easy to implement, but the only downside is:

  • The page will jump a bit to the left if it is center-aligned (horizontally).

This is due to the scroll bar being removed, and the viewport becoming a bit wider.

Solution 19 - Javascript

Here is my solution to stop the scroll (no jQuery). I use it to disable the scroll when the side menu appears.

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
  if(noscroll_var){
    document.getElementsByTagName("html")[0].style.overflowY = "";
    document.body.style.paddingRight = "0";
    noscroll_var = false
  }else{
    document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
    document.body.style.paddingRight = "17px";
    noscroll_var = true
  }
}/*noscroll()*/
</script>

<!-- Just to fill the page -->
<script>
  for(var i=0; i <= 80; i++){
    document.write(i + "<hr>")
  }
</script>

I put 17px of padding-right to compensate for the disappearance of the scroll bar. But this is also problematic, mostly for mobile browsers. Solved by getting the bar width according to this.

All together in this Pen.

Solution 20 - Javascript

To prevent the jump, this is what I used

export function toggleBodyScroll(disable) {
  if (!window.tempScrollTop) {
    window.tempScrollTop = window.pageYOffset; 
    // save the current position in a global variable so I can access again later

  }
  if (disable) {
    document.body.classList.add('disable-scroll');
    document.body.style.top = `-${window.tempScrollTop}px`;
  } else {
    document.body.classList.remove('disable-scroll');
    document.body.style.top = `0px`;
    window.scrollTo({top: window.tempScrollTop});
    window.tempScrollTop = 0;
  }
}

and in my css

.disable-scroll {
  height: 100%;
  overflow: hidden;
  width: 100%;
  position: fixed;
}

Solution 21 - Javascript

This answer suggests a solution for removing the "bump" that happens when overflow: hidden suggested in this solution is applied. Since an edit was declined, here it is:


To remove the "bump" that happens when overflow: hidden is applied, you could calculate the width of the scrollbar and substitute it with margin. Here's an example for the body element:

const bodyScrollControls = {
  scrollBarWidth: window.innerWidth - document.body.clientWidth,

  disable() {
    document.body.style.marginRight = `${this.scrollBarWidth}px`;
    document.body.style.overflowY = 'hidden';
  },
  enable() {
    document.body.style.marginRight = null;
    document.body.style.overflowY = null;
  },
};

If an element already has margin-right, getting existing one and adding scrollbar width to it shouldn't be a problem.

Solution 22 - Javascript

You can do like this:

This way you save 'insignificant' memory and the elements that are with Position: fixed didn't move and thus don't road your design itself.

CSS (Using CSS makes your life and memory easier)

html[DisableScroll] {
    overflow-y: scroll;
}

html[DisableScroll] body {
    overflow-y: hidden;
    height: 100vh;
}

JS

var enableScroll = function () {
   document.documentElement
     .removeAttribute('DisableScroll');
}

e.g

//When you want to enable escroll just call this function;

var enableScroll = function () {
   document.documentElement
   .removeAttribute('DisableScroll');
}
 
 setTimeout(() => {
    enableScroll();
}, 2000);

*{
  margin: 0px;
  padding: 0px
}
body{
  height: 4000px;
  background: #141417
}

html[DisableScroll] {
    overflow-y: scroll
}

html[DisableScroll] body {
    overflow-y: hidden;
    height: 100vh;
}
body>p{
color: #FBFBFD
}

div{
  position: fixed;
  left: 0;
  right: 0;
  margin: auto;
  width: 270px;
  background: #FBFBFD;
  color: #141417;
  text-align: center
} 

<!DOCTYPE html>
 <html lang="en" DisableScroll>
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
 </head>
 <body> 
    <div>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    </div>
     <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
    <p>@@@@</p><br>
 </body>
 </html>

Solution 23 - Javascript

I know this is an old question, but I had to do something very similar, and after some time looking for an answer and trying different approaches, I ended up using a very easy solution.

My problem was very similar, almost identical, the only difference is I didn't have to actually show the scroll bar - I just had to make sure its width would still be used, so the page's width would not change while my overlay was displayed.

When I start sliding my overlay into the screen, I do:

$('body').addClass('stop-scrolling').css('margin-right', 8);

and after I slide my overlay off the screen I do:

$('body').removeClass('stop-scrolling').css('margin-right', 0);

IMPORTANT: this works perfectly because my overlay is positioned absolute, right: 0px when visible.

Solution 24 - Javascript

Building on Cheyenne Forbes' answer, and one I found here via fcalderan: https://stackoverflow.com/questions/8701754/just-disable-scroll-not-hide-it and to fix Hallodom's issue of the scrollbar disappearing

CSS:

.preventscroll{
	position: fixed;
	overflow-y:scroll;
}

JS:

whatever.onclick = function(){
    $('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
    $('body').removeClass('preventscroll');
}

This code does jump you to the top of the page, but I think that fcalderan's code has a workaround.

Solution 25 - Javascript

I have the same problem, below is the way I handle it.

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");

/* file.css */
.no-scroll{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

hope this help.

Solution 26 - Javascript

This code will work on Chrome 56 and further (original answer doesn't work on Chrome anymore).

Use DomUtils.enableScroll() to enable scrolling.

Use DomUtils.disableScroll() to disable scrolling.

class DomUtils {
  // left: 37, up: 38, right: 39, down: 40,
  // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
  static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };

  static preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;
  }

  static preventDefaultForScrollKeys(e) {
    if (DomUtils.keys[e.keyCode]) {
      DomUtils.preventDefault(e);
      return false;
    }
  }

  static disableScroll() {
    document.addEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Disable scrolling in Chrome
    document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
      passive: false,
    });
  }

  static enableScroll() {
    document.removeEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Enable scrolling in Chrome
    document.removeEventListener(
      'keydown',
      DomUtils.preventDefaultForScrollKeys,
      {
        passive: false,
      }
    ); // Enable scrolling in Chrome
  }
}

Solution 27 - Javascript

i use this simple trick here:

.no-scroll{
  overflow: hidden;
}

let toggle_scrolling_state = () => {
   element.classList.toggle("no-scroll");
}

and then call the function when you want to stop scrolling on a event or ...

Solution 28 - Javascript

I have similar issue on touch devices. Adding "touch-action: none" to the element resolved the issue.

For more information. Check this out:-

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

Solution 29 - Javascript

> Store scroll length in a global variable and restore it when needed!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}

Solution 30 - Javascript

I found this answer on another site:

Disable scroll:

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

After close popup release scroll:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});

Solution 31 - Javascript

You can block the spacebar scroll and hide the browser scrollbar:

$(document).keydown(function(event) {
    if (event.keyCode == 32) {
        return false;

    }
});

document.documentElement.style.overflow = 'hidden';
document.body.scroll = 'no';

Solution 32 - Javascript

galambalazs's solution is great! It worked perfectly for me in both Chrome and Firefox. And it also may be extended to prevent any default event from the browser window. Let's say you are doing an app on the canvas. You could do this:

var events = {
  preventDefault: function(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;  
  },

  //spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
  //left: 37, up: 38, right: 39, down: 40
  keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
  keydown: function(e) {
    for (var i = events.keys.length; i--;) {
      if (e.keyCode === events.keys[i]) {
        events.preventDefault(e);
        return;
      }
    }
  },

  wheel: function(e) {
    events.preventDefault(e);
  },

  disable: function() {
    if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = events.wheel;
    document.onkeydown = helpers.events.keydown;
  },

  enable: function() {
    if (window.removeEventListener) {
      window.removeEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
  }
}

And then on your app let's say you're going to process your own events, like mouse, keyboard, touch events and so on... You could disable default events when the mouse goes inside the canvas and re-enable them when the mouse goes out:

function setMouseEvents(canvas) {
  var useCapture = false;

  //Mouse enter event
  canvas.addEventListener('mouseenter', function(event) {
    events.disable();
  }, useCapture);

  //Mouse leave event
  canvas.addEventListener('mouseleave', function(event) {
    events.enable();
  }, useCapture);
}

You could even disable right click menu with this hack:

function disableRightClickMenu(canvas) {
  var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
  my_gradient.addColorStop(0, "white");
  my_gradient.addColorStop(1, "white");
  canvas.context.fillStyle = my_gradient;
  canvas.context.fillRect(0, 0, canvas.width, canvas.height);
  canvas.oncontextmenu = function() { return false; };
}

Solution 33 - Javascript

Enabling the following CSS with JavaScript will help. I'm not as good as the others here but this worked for me.

body {
    position: fixed;
    overflow-y: scroll;
}

Solution 34 - Javascript

I had a similar animation problem on mobile screens but not on laptops, when trying to animate a div using jquery's animate command. So I decided to use a timer that restored the window's scroll position so frequently that to a naked eye the document would appear static. This solution worked perfectly on a small screen mobile device like Samsung Galaxy-2 or iphone-5.

Main Logic of this approach: The timer to set window's scroll position to original scroll position should be started before the jquery animate command, and then when animation is completed we need to clear this timer (original scroll position is the position just before animation starts).

I found to my pleasant surprise that the document actually appeared static during the animation duration if the timer interval was 1 millisecond, which is what I was aiming for.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

ANOTHER SOLUTION that worked: Based on the answer by Mohammad Anini under this post to enable/disable scrolling, I also found that a modified version of code as below worked.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});

Solution 35 - Javascript

My take on this issue also includes a concern with the body width, as the page seems to dance a little when we hide the scroll bar with overflow = "hidden". The following code works perfectly for me, and is based on an Angular approach.

element.bind('mouseenter', function() {
    var w = document.body.offsetWidth;
    document.body.style.overflow = 'hidden';
    document.body.style.width = w + 'px';
});

element.bind('mouseleave', function() {
    document.body.style.overflow = 'initial';
    document.body.style.width = 'auto';
});

Solution 36 - Javascript

A simple solution that worked for me (disabling window scrolling temporarily).

Based on this fiddle: http://jsfiddle.net/dh834zgw/1/

the following snippet (using jquery) will disable the window scroll:

 var curScrollTop = $(window).scrollTop();
 $('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

And in your css:

html.noscroll{
    position: fixed;
    width: 100%;
    top:0;
    left: 0;
    height: 100%;
    overflow-y: scroll !important;
    z-index: 10;
 }

Now when you remove the modal, don't forget to remove the noscroll class on the html tag:

$('html').toggleClass('noscroll');

Solution 37 - Javascript

Something I've just put together:

jsfiddle

document.onwheel = function(e) {
  // get the target element
  target = e.target;
  // the target element might be the children of the scrollable element
  // e.g., "li"s inside an "ul", "p"s inside a "div" etc.
  // we need to get the parent element and check if it is scrollable
  // if the parent isn't scrollable, we move up to the next parent
  while (target.scrollHeight <= target.clientHeight) {
    // while looping parents, we'll eventually reach document.body
    // since body doesn't have a parent, we need to exit the while loop
    if (target == document.body) {
      break;
    }
    target = target.parentElement;
  }
  // we want this behaviour on elements other than the body
  if (target != document.body) {
    // if the scrollbar is at the top and yet if it still tries to scroll up
    // we prevent the scrolling
    if (target.scrollTop <= 0 && e.deltaY < 0) {
      e.preventDefault();
    }
    // similarly, if the scrollbar is at the bottom and it still tries to scroll down
    // we prevent it
    else if (target.clientHeight + target.scrollTop >= target.scrollHeight && e.deltaY > 0) {
      e.preventDefault();
    }
  }
};

body {
  background: gainsboro;
}

#box {
  width: 300px;
  height: 600px;
  padding: 5px;
  border: 1px solid silver;
  margin: 50px auto;
  background: white;
  overflow: auto;
}

<div id="box">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

Solution 38 - Javascript

CSS

  overflow-y: hidden
}

Javascript
``let body = document.querySelector('body');
if(condition)  {
 //disable scroll on the entire body
 body?.classList.add("disable-scroll");
} 
else {
 //to remove the class attrib
 body?.removeAttribute("class");
 //or to remove the disable-scroll class only
 body?.classList.remove("dissble-scroll");
}

This is way better than long code. easy to understand

Solution 39 - Javascript

I found solution in this post. In my context I wish deactivate vertical scroll when I'm scrolling horizontally inside a

Like this =>

let scrollContainer = document.getElementById('scroll-container');
document.getElementById('scroll-container').addEventListener(
    "wheel",
    (event) => {
        event.preventDefault();
        scrollContainer.scrollLeft += event.deltaY;
    },
    {
        // allow preventDefault()
        passive: false
    }
);

Solution 40 - Javascript

Site I have inherited, had a scroll on links. To disable this scroll on click on specific button temporary, this worked for me:

$(document).ready(function() {		
	$('button.class-name').click(function(event) {
		disableScroll();
		setTimeout(enableScroll, 500);	
	});
});


function disableScroll() {
	scrollTop =  window.pageYOffset || document.documentElement.scrollTop; 
	scrollLeft =  window.pageXOffset || document.documentElement.scrollLeft, 

 	window.onscroll = function() { 
			window.scrollTo(scrollLeft, scrollTop); 
	};
}

function enableScroll() { 
	window.onscroll = function() {}; 
} 

Solution 41 - Javascript

For me this gives no content jump whatsoever.

To disabled scrolling:

this.htmlBody = $('body')
this.scrollPos = document.documentElement.scrollTop
this.htmlBody.css('top', -this.scrollPos + 'px').addClass('disable-scroll')

To re-enable scrolling:

this.htmlBody.removeClass('disable-scroll')
$(window).scrollTop(this.scrollPos)

And the CSS:

body.disable-scroll {
  position: fixed;
  width: 100%;
}

Solution 42 - Javascript

Toggle the overflowY with a Javascript function at the same time you toggle your mobile menu's visibility. Like this for example:

function handleClickMobileMenu() {
  document.body.style.overflowY = isMobileMenuOpen ? "hidden" : "scroll";
  //...
}

Call the function when you toggle the mobile menu on and off. Best use case is when your mobile menu is taking full viewport area.

Solution 43 - Javascript

I found that changing the style of body was not necessary.

The only thing we need is to prevent the whole document (html element) from having a y scrolling.

We can create and destroy a style sheet with Javascript to do that. Here's how I do it:

https://jsfiddle.net/3os72ryk/

var scroll_style_element;

function disable_scrolling(){
	
  // Create a style sheet we will only use to disable scrolling :
  scroll_style_element = document.createElement('style');
  document.head.appendChild(scroll_style_element);
  const scroll_style_sheet = scroll_style_element.sheet;
	
  scroll_style_sheet.insertRule('html{height:100%;overflow-y:hidden;}', scroll_style_sheet.cssRules.length);
}

function enable_scrolling(){
  if( scroll_style_element ) document.head.removeChild(scroll_style_element);
}

Very interested to know if anyone finds something wrong with this approach, so please comment below if you do.

Solution 44 - Javascript

There is another solution!

Instead of use multiple event listeners and add, stop and off them hardly, you can add listener just once with callback, in which you can share event throughout your functions, call preventDefault only where and when it needed and so on, even implement own event priority system.

Solution 45 - Javascript

I found a better, but buggy way, combining sdleihssirhc's idea:

window.onscroll = function() {
    window.scrollTo(window.scrollX, window.scrollY);
    //Or
    //window.scroll(window.scrollX, window.scrollY);
    //Or Fallback
    //window.scrollX=window.scrollX;
    //window.scrollY=window.scrollY;
};

I didn't test it, but I'll edit later and let you all know. I'm 85% sure it works on major browsers.

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
QuestionOlivier LalondeView Question on Stackoverflow
Solution 1 - JavascriptgblazexView Answer on Stackoverflow
Solution 2 - JavascripthallodomView Answer on Stackoverflow
Solution 3 - JavascriptsdleihssirhcView Answer on Stackoverflow
Solution 4 - JavascriptMohammad AniniView Answer on Stackoverflow
Solution 5 - JavascriptJosh HarrisonView Answer on Stackoverflow
Solution 6 - JavascriptlisovaccaroView Answer on Stackoverflow
Solution 7 - JavascriptVăn QuyếtView Answer on Stackoverflow
Solution 8 - JavascriptRajat GuptaView Answer on Stackoverflow
Solution 9 - JavascriptHokaschaView Answer on Stackoverflow
Solution 10 - JavascriptcenturianView Answer on Stackoverflow
Solution 11 - JavascriptjvalenView Answer on Stackoverflow
Solution 12 - Javascriptaxelra82View Answer on Stackoverflow
Solution 13 - JavascriptMarcoView Answer on Stackoverflow
Solution 14 - JavascriptZolfaghariView Answer on Stackoverflow
Solution 15 - JavascriptArchitectView Answer on Stackoverflow
Solution 16 - JavascriptDanView Answer on Stackoverflow
Solution 17 - JavascriptseahorsepipView Answer on Stackoverflow
Solution 18 - JavascriptDaanView Answer on Stackoverflow
Solution 19 - JavascriptJosep81View Answer on Stackoverflow
Solution 20 - JavascriptMiladView Answer on Stackoverflow
Solution 21 - JavascriptcotneitView Answer on Stackoverflow
Solution 22 - JavascriptPreviellView Answer on Stackoverflow
Solution 23 - Javascriptuser2430829View Answer on Stackoverflow
Solution 24 - JavascriptQuibbleView Answer on Stackoverflow
Solution 25 - JavascriptRobertView Answer on Stackoverflow
Solution 26 - JavascriptPerrierCitrorView Answer on Stackoverflow
Solution 27 - Javascriptmodex98View Answer on Stackoverflow
Solution 28 - JavascriptGurpreetView Answer on Stackoverflow
Solution 29 - JavascriptKareemView Answer on Stackoverflow
Solution 30 - JavascriptpennstumpView Answer on Stackoverflow
Solution 31 - JavascriptsantyasView Answer on Stackoverflow
Solution 32 - JavascriptRafaelView Answer on Stackoverflow
Solution 33 - JavascriptCheyenne ForbesView Answer on Stackoverflow
Solution 34 - JavascriptSunilView Answer on Stackoverflow
Solution 35 - JavascriptFabio NolascoView Answer on Stackoverflow
Solution 36 - JavascriptlingView Answer on Stackoverflow
Solution 37 - JavascriptakinuriView Answer on Stackoverflow
Solution 38 - JavascriptKolaView Answer on Stackoverflow
Solution 39 - JavascriptYannick DurdenView Answer on Stackoverflow
Solution 40 - JavascriptatazminView Answer on Stackoverflow
Solution 41 - Javascriptdanday74View Answer on Stackoverflow
Solution 42 - JavascriptAlexandre DesrochesView Answer on Stackoverflow
Solution 43 - JavascriptFlorianBView Answer on Stackoverflow
Solution 44 - JavascriptKonstantin ChemshirovView Answer on Stackoverflow
Solution 45 - JavascriptdsrdakotaView Answer on Stackoverflow