最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cancel wheel event with e.preventDefault in react event bubbling - Stack Overflow

programmeradmin4浏览0评论

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
Add a comment  | 

4 Answers 4

Reset to default 9

I 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

发布评论

评论列表(0)

  1. 暂无评论