Wheel events
Wheel events report wheel-like input through `WheelEvent`, including deltas and their unit mode. They are distinct from scroll notifications, so use them for input handling and observe scroll positions when you need the actual movement.
A `wheel` event represents input from a mouse wheel, trackpad, or another device that emulates wheel actions. Its `WheelEvent` object provides `deltaX`, `deltaY`, and `deltaZ`, plus `deltaMode`, which identifies the unit of those values: pixels, lines, or pages.
Do not treat a wheel delta as a guaranteed content scroll distance. A line has no universal pixel size, and a page depends on the relevant scrolling context. If an application needs a pixel-equivalent estimate, it must choose and document its own assumptions; otherwise, preserve the raw value and its mode.
`wheel` and `scroll` describe different stages. Wheel input may be received by an element that cannot scroll, while scrolling can result from a keyboard, scrollbar drag, script, or other input. Even when both occur, wheel deltas are not a reliable way to infer the final direction or amount of content movement; observe `scrollTop` or `scrollLeft` in a `scroll` handler when that is the requirement.
The event is cancelable when the browser's default action can be prevented, but cancelability can vary across a burst of wheel events. Use `{ passive: true }` when the handler only observes input. Use `{ passive: false }` when custom behavior must call `preventDefault()`, and keep that handler efficient because it can delay scrolling or zooming.
Wheel input can also represent zooming, commonly signaled by `ctrlKey`. If implementing custom zoom or scroll behavior, clamp state, account for modifier keys, and test mouse wheels, trackpads, different writing directions, and the target's scrolling behavior.
Key points
- Read `deltaMode` before interpreting any `delta*` value.
- Line and page deltas do not have a universal pixel conversion.
- Use `scroll` and scroll-position changes to measure actual content movement.
- Choose passive listeners for observation; choose non-passive listeners only when cancellation is required.
- Wheel input may indicate zooming, including modifier-key gestures.
Interview questions
What is the difference between a `wheel` event and a `scroll` event?
`wheel` is an input event describing wheel-like pointing-device activity, whereas `scroll` indicates that a scroll position changed. A wheel event can occur on an unscrollable target, so it does not imply scrolling. Conversely, keyboard navigation, a scrollbar drag, or JavaScript can cause scrolling without wheel input. I use `scrollTop` or `scrollLeft` observed during `scroll` when I need the actual movement.
How do you interpret `deltaMode` and convert wheel deltas to pixels?
`deltaMode` tells me how to interpret each delta: pixel units, line units, or page units. A pixel delta can be used as a pixel-sized input value, but line and page values should not be blindly multiplied by a universal constant. If the UI requires pixel-like motion, I choose explicit application-specific scales and describe the result as an estimate. For exact scrolling behavior, I generally use the browser's scrolling APIs or observe the resulting scroll position instead.
When should a wheel listener be passive?
I use a passive listener when I only need to observe or record wheel input. It tells the browser that the handler will not cancel the default action, which can reduce input latency. If I need to implement custom zooming or prevent native scrolling, I register with `{ passive: false }` and call `preventDefault()` where appropriate. The handler should remain short because a non-passive path may make the browser wait before scrolling.
How would you implement custom zooming with wheel input?
I first distinguish ordinary scrolling from zoom intent, including modifier keys such as `ctrlKey`. For custom behavior, I prevent the browser default only with a non-passive listener, update state from the deltas, and clamp the resulting scale or position. I would not assume that the sign of `deltaY` alone proves the document moved in a particular direction. For scrolling direction, I compare scroll-position changes in a `scroll` handler.
What issues would you consider when supporting both mouse wheels and trackpads?
I would avoid assuming that one event equals one user gesture or that all devices emit the same magnitude. Trackpads may produce many small, fractional events, while mouse wheels may produce larger steps, and the unit can vary through `deltaMode`. I would normalize only for a clearly defined UI purpose, preserve sign and precision, and test across devices. I would also decide whether the handler should prevent native behavior and measure performance under rapid input.