Search code examples
javascriptjqueryscroll

How to disable scrolling temporarily?


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.


Solution

  • 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