在反应事件冒泡中使用 e.preventDefault 取消轮子事件

Fem*_*Oni 7 scrollbar mousewheel dom-events reactjs

我试图在e.preventDefault()触发轮事件时阻止窗口滚动,但无论如何浏览器都会滚动。

<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>

Run Code Online (Sandbox Code Playgroud)

js

handleWheelEvent = e => {
    e.preventDefault();
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
    // those 3 should prevent browser from scrolling but they don't
}
Run Code Online (Sandbox Code Playgroud)

小智 9

我找不到一种方法来防止在 React 事件中滚动,但可以使用 refs 达到相同的效果

在构造函数中:

this.divRef = React.createRef()
this.preventDefault = e => e.preventDefault()
Run Code Online (Sandbox Code Playgroud)

在渲染中:

<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>
Run Code Online (Sandbox Code Playgroud)

添加和删​​除 PreventDefault 事件侦听器:

componentDidMount () {
    this.divRef.current.addEventListener('wheel', this.preventDefault)
}

componentWillUnmount () {
    this.divRef.current.removeEventListener('wheel', this.preventDefault)
}
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 5

React 在根元素(不是document)处绑定所有事件,并且wheel事件是使用true option内部绑定的,我引用 MDN:

一个布尔值,如果为 true,则表示侦听器指定的函数永远不会调用 PreventDefault()。如果被动侦听器确实调用了 PreventDefault(),则用户代理除了生成控制台警告之外不会执行任何操作

这就是我在使用滚轮影响输入字段时阻止页面滚动的方法:

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)
}, [])
Run Code Online (Sandbox Code Playgroud)

参考讨论: