I am trying to prevent window scrolling with e.preventDefault()
when a wheel event is fired but browser scrolls no matter what.
<div onWheel={this.handleWheelEvent} >
<div className='yellow fullpage'>Yellow Page</div>
<div className='green fullpage'>Green Page</div>
<div className='blue fullpage'>Yellow Page</div>
</div>
js
handleWheelEvent = e => {
e.preventDefault();
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
// those 3 should prevent browser from scrolling but they don't
}
I am trying to prevent window scrolling with e.preventDefault()
when a wheel event is fired but browser scrolls no matter what.
<div onWheel={this.handleWheelEvent} >
<div className='yellow fullpage'>Yellow Page</div>
<div className='green fullpage'>Green Page</div>
<div className='blue fullpage'>Yellow Page</div>
</div>
js
handleWheelEvent = e => {
e.preventDefault();
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
// those 3 should prevent browser from scrolling but they don't
}
Share
Improve this question
edited Jul 27, 2023 at 21:39
Femi Oni
asked Aug 5, 2019 at 12:29
Femi OniFemi Oni
8242 gold badges10 silver badges26 bronze badges
1
- Sorry, didn't realize it was ReactJS not JS. This link should help. stackoverflow.com/questions/34790949/… – dar Commented Aug 5, 2019 at 13:06
4 Answers
Reset to default 9I couldn't find a way to prevent scrolling in React events but it's possible to achieve same effect using refs
In constructor:
this.divRef = React.createRef()
this.preventDefault = e => e.preventDefault()
In render:
<div ref={this.divRef} >
<div className='yellow fullpage'>Yellow Page</div>
<div className='green fullpage'>Green Page</div>
<div className='blue fullpage'>Yellow Page</div>
</div>
Adding and removing preventDefault event listener:
componentDidMount () {
this.divRef.current.addEventListener('wheel', this.preventDefault)
}
componentWillUnmount () {
this.divRef.current.removeEventListener('wheel', this.preventDefault)
}
React binds all events at the root element (not the document
), and the wheel
event is binded internally using true
option, and I quote MDN:
A Boolean that, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning
This is how I did blocked the page from scrolling while using the wheel to affect an input field:
const wheelTimeout = useRef()
const onWheel = e => {
// ... some code I needed ...
// while wheel is moving, do not release the lock
clearTimeout(wheelTimeout.current)
// flag indicating to lock page scrolling (setTimeout returns a number)
wheelTimeout.current = setTimeout(() => {
wheelTimeout.current = false
}, 300)
}
// block the body from scrolling (or any other element)
useEffect(() => {
const cancelWheel = e => wheelTimeout.current && e.preventDefault()
document.body.addEventListener('wheel', cancelWheel, {passive:false})
return () => document.body.removeEventListener('wheel', cancelWheel)
}, [])
Reference discussions:
- https://github.com/facebook/react/issues/14856
You can't use event.preventDefault()
inside event onScroll, because preventDefault apply after page scrolled. But you can use prevetDefault on the following events:
- onWheel
- onKeydown
- onPageUp
- onPageDown
<div onWheel={e => e.stopPropagation()}></div>
try this