Active or Passive Event Listeners

How can I add an event listener and select whether it is active or passive? I need to use preventDefault on a mousewheel event and update the scrollPosition of several elements manually instead, but chrome does not let me do that, firing this error:
“[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive”

How exactly do you add event listeners? Can you provide a code example?

This is the way I’m adding event listeners. I can of course add event listeners in some other way, like through a reference, if that is necessary to get this to work.

[@react.component]

let make = () => {
  let onWheelHandler = event => {
    ReactEvent.Wheel.preventDefault(event);
  };
  <div onWheel=onWheelHandler />
}

Which React version do you use by the way? Apparently, React 16 only attached an actual even listener to document and then dispatched a synthetic event to the intended target, and since Chrome 73, wheel event listener attached to a root target is passive by default.

React 17 doesn’t attach its single listener to document anymore, so it shouldn’t have this problem (but I guess it means you can have worse scroll performance, and scroll performance is why passive event listeners were added to browsers in the first place). There was actually a discussion on what to do with passive/active event listeners in v17. I don’t know what the resolution is, but most likely they’ve decided to “do nothing”, so onWheel even listeners shouldn’t be passive there anymore.

Anyway, if you still use React 16, or if onWheel is still passive by default in React 17, and you’re sure your scroll performance won’t be affected, I guess the way out is to use a ref and addEventListener.

Thank you for the help hoichi. I managed to get around the problem without using preventDefault in the end. The underlying problem was bi-directional syncing of scrollStatus for multiple sources of scrolling, which broke when smooth scrolling was turned on.

1 Like