React onWheel 处理程序无法阻止Default,因为它是被动事件侦听器

问题描述 投票:0回答:2

我正在尝试覆盖组件上的 Ctrl+滚动行为,但它无法处理错误

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See <URL>
。我认为我可以使用主动侦听器,那么有没有办法通过 React 来指定它?请注意,我需要访问和修改
onWheel
内的状态。

  const onWheel = (e: React.WheelEvent): void => {
    if (e.altKey) {
      e.preventDefault();
      // Error
    } else if (e.ctrlKey) {
      e.preventDefault();
      // Error
    }
  };

...

  return (<div className={styles["workspace"]} onWheel={onWheel}>
    stuff
  </div>);
javascript reactjs dom dom-events
2个回答
18
投票

有点晚了,但也许对其他人有帮助。

问题在于 React 默认使用被动事件处理程序,其中包含 Wheel、touchstart 和 touchmove 事件 - 换句话说,您无法在其中调用

stopPropagation

如果你想使用非被动事件处理程序,你需要使用 refs 并手动添加/删除事件处理程序,如下所示:

class MyComponent extends React.Component {
  myRef = React.createRef();

  componentDidMount() {
    // IMPORTANT: notice the `passive: false` option
    this.myRef.current.addEventListener('wheel', this.handleWheel, { passive: false });
  }

  componentWillUnmount() {
    this.myRef.current.removeEventListener('wheel', this.handleWheel, { passive: false });
  }

  handleWheel = (e) => {
    e.stopPropagation();
    // ...
  }

  // ...
}

应该和钩子类似。


0
投票

对于任何使用功能组件的人来说,这里有一个解决方案,灵感来自@johndodo

function MyComponent {
  const onWheel = useCallback(
    (e) => {
      console.log(e);
      e.preventDefault();
    },
    [],
  );

  const divRef = useCallback(
    (node) => {
      console.log(node);
      node.addEventListener('wheel', onWheel, { passive: false });
    },
    [onWheel],
  );

  return <div ref={divRef}>...</div>;
}

使用

useCallback
代替
divRef
+
useRef
的原因是
this

© www.soinside.com 2019 - 2024. All rights reserved.