Preventing Scrolling
Preventing scrolling on the mouse wheel
react
DEMO
Preventing scrolling is a simple process by using overflow: hidden or overflowY to prevent scrolling on vertical direction. This is achieved by hidding the scroll bar and it's content in order to prevent user from scrolling. But this does not prevent mouse wheel scrolling.
It took me a while to fix this problem but instead of e.preventDefault(); using e.stopPropagation(); will fix this issue. Let have a look at simple example.
Preventing scrolling is a simple process by using overflow: hidden or overflowY to prevent scrolling on vertical direction. This is achieved by hidding the scroll bar and it's content in order to prevent user from scrolling. But this does not prevent mouse wheel scrolling.
It took me a while to fix this problem but instead of e.preventDefault(); using e.stopPropagation(); will fix this issue. Let have a look at simple example.
useEffect(() => { // Add event listeners with capture phase const options = { passive: false, capture: true }; window.addEventListener("wheel", handleScroll, options); window.addEventListener("touchmove", handleScroll, options); return () => { window.removeEventListener("wheel", handleScroll, options); window.removeEventListener("touchmove", handleScroll, options); }; }, []);
Here I have simple event listener inside useEffect that simply adds and remove mouse wheel and mouse move event.
The options passive: false explicity tells the browswer that the event listener might call preventDefault(), and it should not assume that scrolling should always happen without interruption. This is important for preventing scrolls. If you don't set this browser might ignore your call to preventDefault() in some situations, especially on touch screens.
The option capture: true refers to the capture phase of event propagation. An event propagate in two phase: the capture phase and bubbling phase. This ensures that wheel and touchmove event are caught before they are processed by any other elements that might allow scrolling.
Rest is just adding and cleanup function for event listeners.
// Unified scroll prevention handler const handleScroll = (e) => { if (isLocked.current) { e.preventDefault(); e.stopPropagation(); // Count wheel events only if (e.type === "wheel") { scrollCounter.current += 1; console.log("Scroll attempts:", scrollCounter.current); if (scrollCounter.current >= 5) { isLocked.current = false; } } } };
When user starts to scroll using mouse wheel, trackpad or swiping down on mobile devices event is captured. If isLocked.current ref is true then app will prevent from scrolling while scrollCounter is equal or greater than 5.
The key here is the stopPropagation() which stops event from propagting up and down the DOM hierarchy. The event dosen't "bubble" up the DOM tree, which prevents otherevent listeners on parent elements from firing.
This allow mouse wheel interaction, in this case user needs to scroll 5 times before you are able to scroll further down the page. This can be useful as you could display different content or trigger different action while user scrolls on your page without need of buttons and mouse click. Result is smooth interaction between the user and the contents.
DEMO