How to disable scrolling temporarily?
Asked Answered
H

47

543

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.

Hosey answered 22/1, 2011 at 19:23 Comment(2)
If it is still showing, then the user is trained to think that it must be functioning. If the dose not move or dose not respond, then it will break the users mental model of how you page works and result in confusion. I would just find a better way of dealing with scrolling whilst animating, like for instance stopping the animation.Dinner
Another solution: #9280758Commemorate
D
895

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

Damn answered 22/1, 2011 at 19:55 Comment(38)
How would I disable mouse scroll?Hosey
Call disable_scroll() from the code above, then enable_scroll() after the animation ended.Damn
Tip for other devs stuck in this trap: Do make sure you remove any and all 'e.stopPropagation()' calls from other jQuery attempts to stop scrolling, because not only does it not work, it prevents the event from bubbling to THIS code that DOES work. Hopefully my wasted 30 mins will help save someone else time :)Deaver
If using jQuery UI Dialog, I would advise renaming preventDefault() method to anything else, like scrollPreventDefault(). It was making my modal dialog not centered on the page. Maybe a naming conflict in jQuery or jQuery UI?Pavo
I know the post is quite old but it was what i needed. Just one problem, its working for Safari but not for Google Chrome. Can anybody help me out with this?Divine
It works in all browsers. The problem is in your code somewhere. See the working demo. jsbin.com/disable-scrolling/1Damn
There is a little error that allows scrolling even when disabled. You can move the horizontal/vertical bar without problems. Any idea on how to fix it?Leghorn
I answer myself, with the second answer, the one from hallodom, it works PERFECT and it's very simple and uses less code.Leghorn
Yes, it does. Do you happen to use any smooth scrolling extension?Damn
Demo from the link is scrollable by Space/Shift+Space on Mac in Chrome, Firefox, Safari, Opera.Symphony
You can add 32 (space) to the disabled keys array (show in the code comments).Damn
Made an edit that now includes space blocking, just waiting for somebody to review the edit.Seek
just returning false prevents the event...thanks to many answers like these and like 13+ more around internet i have made something jsfiddle.net/techsin/CLTfS/13/embedded/resultHenni
I can scroll this like I always do: using middle button press and moving the mouse... Therefore this trick will not affect such users as me ;)Luetic
I've refactored your helpful code into a single, self-contained object: https://mcmap.net/q/55698/-how-to-disable-scrolling-temporarily :)Octane
...and here's a jQuery plugin based on your answer.Octane
I'd like to second Denis' comment about using the middle button to scrollPyralid
middle mouse button and selecting text both cause scrolling...you could disable selection but that is bad ui practiceHenni
The scrollbar is not disabled.Hindustan
It works on browser emulator but not on an actual mobile deviceValerio
I can still make it scroll by dragging a file over the top/bottom of the page. This also works by selecting text on the page and doing the same dragover the top/bottom.Delibes
Is there a way to use this solution for just the html/body and not overflow containers within the page?Niveous
Best solution so far for preventing scroll by showing modal. Thanks a lotMissive
Be careful!! This method may not fit for the case where you have scroll inside your modal!Animalism
The demo doesn’t work as expected in the mobile emulator of Chrome in the developer toolbar. The scrolling continues to work despite being disabled in the demo.Cordon
"mousedown" for middle button is missing. It's used for scrollingWhopper
It is old and still works. ;) Spacebar keyCode (32) is listed in the comments. You can add it to your keys var.Damn
In latest chrome you'll need to bind via addEventListener and explicitly specify the event handler as non-passive.Bounce
The demo doesn't work for me on Mac Chrome -- but does work on Mac Safari. I'm using a touchpad.Tot
If you open side menu/bar in Youtube (any video page - not home page, bcz we already have side bar open in homepage.) it disables scrolling and hides scrollbar, i checked in Firefox and chrome, in both this same behaviour is observed. I wonder how they did it. What JS code..Indeciduous
on Chrome I make it work again using window.addEventListener and removing the lines with onwheel and onmousewheelSomatology
Why pass "wheel event" to the mobile listener?Mcadams
Working mostly for me, but MacOS's fn+up and fn+down (which are the equivalent of home and end) still get throughValer
Can somebody please explain the part with the test EventListener? I cannot understand it, it looks pretty weird...Deron
This is a good solution and my guess is that the best existing implementation (solving edge cases like text selection, allowing selected element scroll etc.) exists in Web Components which can be used in vanilla code https://mcmap.net/q/56554/-how-to-disable-scroll-without-hiding-itLeslileslie
I can scroll with scrollbar, it will not work for all conditions.Intransigence
Using react. Had to attach it on document. Works fine. Thanks!Gerladina
HTML5 breaks this answer. Adding `draggable="true"' to any element allows the page to be scrolled via edge scrolling while dragging.Batten
C
502

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')
Careworn answered 23/8, 2012 at 10:58 Comment(22)
This worked well for me in Chrome 21.0.1180.89, IE9, FF15 & Safari 5.1.7Hitormiss
quick note, this appears to not work in iOS6 (presumably 5 as well). Anyone know of a workaround?Bomar
Got it! You have to handle the touchmove event, as with $('body').bind('touchmove', function(e){e.preventDefault()}). Edited this answer to include this mobile solution.Bomar
Cool, just have to make sure any inner scrolling can work in the modal for the touch device. Could do an overlay just underneath the modal and prevent the default touchmove on the overlay instead of body.Careworn
While this solution does work, it has the (potentially) undesirable effect of scrolling back to the top of the page.Capacitor
@Capacitor this technique doesn't scroll to the top on our implementation on capsulecrm.com. A problem we've found recently is the modal overflows the height of the body height at 100% and controls aren't visible. We've had to have an inner scroll area on content.Careworn
Chrome bug allows scrolling when overflow is set to hidden.Seek
Is that with height set to 100% on the body also?Careworn
This didn't work for me unless my selector was $('body,html')Wail
Used @Bomar solution for disabling mobile viewport scrolling while keeping it enabled on a child element with overflow: scroll. You can do this with $('.child').bind("touchmove", function(e){e.stopPropagation()})Midyear
This solution works but the scroll bar disappear and create a 'bump' effect (under window os) when you apply this class to the body (for example)Memorialize
It should be noted that, as @Wail pointed out, this solution is a lot more effective using $('body, html') as the selector, since in many cases the height of the body does not determine the content or if the page is scrollable. Not to mention that height: 100% on the body element usually doesn't do anything if there's nothing for the 100% to reference to.Doroteya
This is great. I love how clever and simple it is. What gets me past the other issues people are having is to have html initially set to position: absolute; width: 100%; height: 100%; overflow-y: scroll. (I always add overflow-y: scroll to html, can't recommend it enough). Then in .stop-scrolling, which is toggled only on html, all you need is overflow-y: hidden. Voila, no more content jumping around. (Works in Chrome 43.0.2357.132 (64-bit) OS X Yosemite)Leandraleandre
This also stops the scroll event from firing. Just sayin'Displacement
@matt any workarounds for the jump-to-top issue? Been struggling with that on: doubledutch.me/product/spring-release-2016Bereave
@yagudaev I did not find a solution to this issue I was happy with. Sorry :(Capacitor
I tried your solution for mobile but it´s not working and css is not helping. Can you help me here #41525657 ?Threadgill
On the jump-to-top issue, I only encountered it if the position: fixed property was added to the .stop-scrolling class. Otherwise, I don't encounter that problem as well.Georgie
Nice solution. Unfortunately it naturally prevents any pinch-to-zoom-gestures. I want to use this in the context of a fullscreen image overlay and pinch-to-zoom is quite usefull here. I think it's hard to fix this without digging quite deep right?Dramaturgy
A fix for the jumping issue https://mcmap.net/q/55698/-how-to-disable-scrolling-temporarilyUpanchor
It doesn't work if you have draggable elementsCaliber
overflow: hidden really is the best and simplest solution for this. This prevents any weird stuttering in beetween. Simply effective. Can also just set and unset it via js instead of using classes.Morey
L
77

Here's a really basic way to do it:

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

It's kind of jumpy in IE6.

Lecythus answered 22/1, 2011 at 19:29 Comment(10)
Not really a disabling, more like a snap to default when the scroll is attempted.Dinner
@Marcus As good as it's going to get with an event that isn't cancelable.Lecythus
It may interfere with jQuery scrollTo plugin.Damn
Even though it doesn't disable it for real, it simulates it and that's good enough for me.Dispirited
I used this approach but triggering it with jquery $(document).scroll(, it was way to slow and made the page flicker in internet explorerLissettelissi
what i have to write when i want to enable the window scroll?Defensive
IMHO - best answer here. Plus, you don't have to lock it to (0, 0), just use the current scroll position.Idyll
But how do we reenable it?Girlish
Fails with not just the jQuery scrollTo plugin, but also css scroll-behavior: smooth and many other things. Basically, it's not realtime, and thus is super jankyValer
this is the best for popupsExceptional
E
73

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(){};
}
Eyot answered 3/10, 2014 at 21:21 Comment(9)
Jumpy in Safari 7.1 and IE 11. Newest Chrome, Firefox, Opera ok.Coupler
Still a tiny bit jumpy on newest ChromeAdsorb
Working fine, In safari, chrome, but flickered in IEChassidychassin
If this solution not works for some browser, then that is browsers problemSuperorganic
As mentioned on another answer, scroll-behavior: smooth borks this. Also, I disagree with Oto saying that it's the browser's fault. You're basically assuming that something will happen instantly when in reality it is asynchronousValer
You can set window.onscroll=null instead of adding an empty anonymous function, null is the initial value of window.onloadBatholomew
This suited me the best! Thanks.Polyurethane
@Batholomew Nice idea but sadly doesn't work in my testsMorey
@LuckyLukeSkywalker Then addEventListener and removeEventListener can be used, check this tutorial: (w3schools.com/jsref/met_element_removeeventlistener.asp)Batholomew
S
28

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.

Strychnine answered 29/2, 2012 at 4:12 Comment(1)
100% neat and simple trick, minimal JS no scroll events. Just target the element we need to disable scroll and set overflow to hidden. Been writing JS and CSS for almost 10 years and I did not thought of this! Then to re-enable scroll just toggle overflow to auto!Pudgy
O
25

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);
Octane answered 3/2, 2014 at 17:25 Comment(15)
Glad it's useful. NB I've edited with a link to this in jQuery plugin format.Octane
Might help if the disable scroll button actually workedMorganatic
@user1672694, it works here in Chrome. What's your browser and which demo page have you found the bug on? Any JS errors in the console?Octane
On Chrome (38, Windows 7), I can still scroll by clicking and holding the middle-button down, then dragging.Motivate
On first glance it looks like that behaviour can't be disabled. You'd have to disable middle-clicking altogether, which probably isn't a good idea.Octane
The scrollbar is not disabled.Hindustan
@Hindustan Did you click the 'toggle scrolling' button?? If you did it would be helpful to know your browser/version.Octane
@ZougenMoriver Yes, I toggled it. I can verify the behaviour in Firefox 33.0.3. Granted the arrow keys etc don't work, but the scrollbar does. I also tested on Chrome (at work - I forget which version) with the same outcome.Hindustan
@Hindustan Thanks for highlighting. Just updated to prevent this too. Can't believe I didn't spot this before!Octane
Also - FWIW - I tested in IE on Windows with reasonable results. IE9+ all worked, (unable to test lower versions) but with flicker: the div rapidly alternated between intended scroll position and position 0.Hindustan
@Hindustan Thanks. I've just managed to successfully test IE7-11 and I have to say I didn't see any flickering. Worth knowing that it could occur though.Octane
@ZougenMoriver it introduces a problem on the mobile though, both mobile FF and Chrome are unable to zoom when the fingers are placed inside of the scroll-blocked div.Aimee
If the scroll-disabled element is body, spacebar and arrow keys are not functional in input elements.Coupler
Awesome plugin! Just wondering if it is at all possible to check if the scroll wheel has been triggered while scrolling is disabled? I ask because I wish to disable scroll at the start and then smooth scroll down if they use scroll wheel down. Thanks!Keratose
Please disregard, I found that binding it mousewheel worked a charmKeratose
O
22
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;
}
Outcurve answered 14/8, 2019 at 5:6 Comment(1)
for the type safety, I'd recommend to use negative numbers instead of nullNodular
B
8

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);
}
Being answered 9/11, 2014 at 8:46 Comment(1)
I found this worked for me if I added overflow-y: scroll to the .scrollDisabled style. Otherwise, there was a little jump as the scrollbar hid each time. Of course, that only works for me because my page it long enough to need a scrollbar even on the largest displays.Abshier
A
8

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.

Agrimony answered 4/7, 2021 at 21:54 Comment(0)
U
7

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 });
}
Urethroscope answered 26/9, 2017 at 10:9 Comment(0)
I
7

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.

Impressionable answered 26/2, 2019 at 17:59 Comment(1)
I just had vertical scrolling on a table body (TBODY). stop: this.table.body.style.overflowY = 'hidden'; restart: this.table.body.style.overflowY = 'auto'Fret
K
6

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; 
   }
}
Kyser answered 23/8, 2013 at 13:33 Comment(1)
Are you sure that it is an answer not just a comment of other answer?Nester
W
5

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)
});
Wharfage answered 15/8, 2013 at 11:42 Comment(0)
H
5

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>
Hazem answered 21/10, 2021 at 14:55 Comment(0)
G
4

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.

Gasoline answered 26/9, 2013 at 11:43 Comment(1)
This worked for me and the problem of scrolling to the top after using position:fixed. Thank u!Northeasterly
A
4

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();
});
About answered 5/3, 2016 at 14:10 Comment(1)
This worked for me in React where jQuery is non existent and where React does not have access to manage the state of the body tag.Inquietude
S
4

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.

Scarabaeoid answered 13/9, 2018 at 18:16 Comment(0)
F
4

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/

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

Farra answered 23/9, 2021 at 19:35 Comment(1)
Implemented on react application successfully! Thanks.Supremacist
P
3

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() });
    }
};
Pruitt answered 23/4, 2013 at 7:25 Comment(1)
a bit jumpy, but this works for IE 7 (client uses it). other solutions do not.Saddlebacked
I
3

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.

Intoxicant answered 10/6, 2016 at 19:45 Comment(0)
I
3

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.

Isolationist answered 20/2, 2018 at 22:23 Comment(5)
that will reset the scroll positionSepticidal
@AngelDavidCalderaroPacciott No, the scroll position will remain the same height/distance.Isolationist
@Isolationist it does reset the scroll position on ChromeFluoric
@Fluoric I just checked it, it only does it on some occassions (when the body height isn't relative to its children). Please try changing body to html instead.Isolationist
I bet you didn't check your solution in Iphone cause overflow:hidden doesn't work in thereRestitution
H
3

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.

Husain answered 7/3, 2018 at 1:39 Comment(0)
U
3

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;
}

Upanchor answered 14/1, 2020 at 11:36 Comment(0)
E
3

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.

Eurythmics answered 11/6, 2021 at 0:56 Comment(0)
O
2

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.

Oneidaoneil answered 2/10, 2014 at 18:56 Comment(0)
V
2

Building on Cheyenne Forbes' answer, and one I found here via fcalderan: 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.

Violette answered 13/8, 2017 at 19:27 Comment(0)
V
2

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.

Voluntaryism answered 18/12, 2017 at 3:55 Comment(0)
M
2

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

Malraux answered 28/5, 2018 at 19:2 Comment(0)
W
2

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
  }
}
Wesla answered 10/7, 2019 at 18:21 Comment(0)
S
2

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

Sowder answered 14/3, 2021 at 13:43 Comment(0)
M
1

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);
}
Multifold answered 31/10, 2018 at 2:58 Comment(0)
C
0

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");
}
});
Convulsive answered 25/4, 2013 at 23:38 Comment(3)
That only seems to stop touch scrolling, but the mouse scrolling, arrow keys, page up and down keys, etc will still work. -1Seek
These 'events' are for touch scrolling, just substitute whatever events you need.Convulsive
also, this seems to be used in some other very specific situation. popupbeforeposition? What is that supposed to be for? What does this have to do with temporarily disabling scrolling? At least make it relevant to this situation. It looks like you copied this directly from a website.Seek
P
0

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';
Paternity answered 4/7, 2014 at 21:51 Comment(1)
Disabling space bar key is really a no-go solutionYaroslavl
W
0

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; };
}
Wandy answered 23/12, 2014 at 14:43 Comment(0)
G
0

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;
}
Grodin answered 1/8, 2015 at 11:56 Comment(1)
So an answer based on mine got upvotes but mine got only downvotes? Why does stackoverflow hate me?Grodin
S
0

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() {};
});
Savagery answered 3/10, 2015 at 14:53 Comment(0)
R
0

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';
});
Rousseau answered 19/2, 2016 at 21:21 Comment(0)
T
0

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');
Thankless answered 1/3, 2016 at 6:46 Comment(0)
S
0

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>
Sennacherib answered 20/2, 2017 at 17:16 Comment(0)
S
0

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

Seibert answered 26/10, 2020 at 10:33 Comment(0)
H
0

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
    }
);
Hanna answered 30/10, 2020 at 14:52 Comment(0)
U
0

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() {}; 
} 
Udele answered 10/11, 2020 at 23:32 Comment(0)
K
0

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%;
}
Kennethkennett answered 16/5, 2021 at 14:31 Comment(0)
E
0

this.style.overflowX = 'hidden'; you can use this code line inside your function and works on the specific element it's being clicked.

Endor answered 15/12, 2022 at 19:2 Comment(2)
Welcome to SO! Please take a look at the other answers that were given before. Your approach is mentioned there already. In order to keep the site clear and make it easy to find answers, we try to avoid double answers.Maitund
it's not the same approachEndor
A
0

Setting pointer-events: none can also be a solution if the content inside doesn't has to clickable. Disables scrolling, wheeling and arrow keys.

Adept answered 14/10, 2023 at 0:21 Comment(0)
P
-1

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.

Pentastich answered 22/12, 2021 at 21:1 Comment(1)
This seems more like a comment than an answer. It is unclear which listener you are referring to, how sharing the event throughout functions is necessary, and where preventDefault is supposed to be applied.Tallith
C
-5

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.

Coolie answered 7/7, 2012 at 0:27 Comment(1)
You need to store the old values of window.scrollX and window.scrollY outside the function to freeze the scrolling, otherwise it is useless!Eyot

© 2022 - 2024 — McMap. All rights reserved.