Search code examples
javascriptjqueryhtmlpreventdefault

Disable mousewheel with preventDefault but can not enable it?


I have 2 button to enable/disable mousewheel as below. I have disabled it, but I can not re-enable

function disableScroll() {
  document.addEventListener("mousewheel", function(event) {
    event.preventDefault();
  }, {
    passive: false
  });
}

function enableScroll() {
  document.removeEventListener("mousewheel", function(event) {
    event.preventDefault();
  }, {
    passive: false
  });
}
<button onclick="disableScroll()">Disable</button>
<button onclick="enableScroll()">Enale</button>


Solution

  • The issue with your current logic is because the event handler you add and the event handler you remove are not the same reference. To address this put the event handler in its own named function and reference it.

    let disabledScrollHandler = (e) => {
      e.preventDefault();
    }
    
    document.querySelector('#disable').addEventListener('click', () => 
      document.addEventListener('mousewheel', disabledScrollHandler, { passive: false }));
    
    document.querySelector('#enable').addEventListener('click', () => 
      document.removeEventListener('mousewheel', disabledScrollHandler, { passive: false }));
    html,
    body {
      height: 1000px;
    }
    <button id="disable">Disable</button>
    <button id="enable">Enable</button>

    That said, you can achieve this without nested and dynamic event handlers by adding a class to the body. This class sets the overflow state of the element which in turn prevents the scroll behaviour. Try this:

    document.querySelector('#disable').addEventListener('click', function() {
      document.body.classList.add('disable-scroll');
    });
    
    document.querySelector('#enable').addEventListener('click', function() {
      document.body.classList.remove('disable-scroll');
    });
    html, body { height: 1000px; }
    body.disable-scroll { overflow: hidden; }
    <button id="disable">Disable</button>
    <button id="enable">Enable</button>

    Note that the latter approach also prevents scrolling via the keyboard, if that's a requirement.