Start · Sprachen · JavaScript · Referenz · Element: wheel

Element: wheel

Ereignis

Wird ausgelöst, wenn der Benutzer ein Mausrad dreht oder eine vergleichbare Eingabe macht (z. B. Zwei-Finger-Wischen auf dem Touchpad). Der Handler erhält ein <code>WheelEvent</code>.

seit JavaScript Baseline: alle modernen Browser (seit 2017) Kategorie: webapi

Signatur

element.addEventListener("wheel", handler, options)

Beschreibung

Das wheel-Ereignis wird an einem Element ausgelöst, wenn der Benutzer das Rad eines Zeigegeräts dreht. Das kann ein Mausrad sein, aber auch ein Touchpad mit Zwei-Finger-Geste oder ein Trackball. Der Handler erhält ein WheelEvent mit den Eigenschaften deltaX, deltaY, deltaZ und deltaMode. Dazu kommen alle Eigenschaften von MouseEvent, also z. B. clientX, ctrlKey und shiftKey.

Registrieren kannst du den Handler auf zwei Wegen: mit element.addEventListener("wheel", handler) oder über die Eigenschaft element.onwheel = handler. Das Ereignis steigt im DOM nach oben (bubbles) und lässt sich abbrechen (cancelable). Mit event.preventDefault() unterdrückst du also das Standardverhalten, etwa das Scrollen der Seite oder das Zoomen mit Strg + Rad.

Typische Einsatzfälle sind:

  • eigene Zoom-Steuerung, z. B. für Karten, Bildbetrachter oder Canvas
  • horizontales Scrollen einer Leiste mit dem vertikalen Mausrad
  • das Durchblättern von Werten, z. B. Zahlen, Folien oder Galeriebilder

Wichtig: wheel ist nicht dasselbe wie scroll. wheel meldet die Eingabe des Geräts, auch wenn dadurch gar nichts scrollt. scroll feuert erst, wenn sich die Scroll-Position tatsächlich geändert hat. Wenn du nur auf Scrollen reagieren willst, ist scroll meist die bessere Wahl.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, hier immer "wheel".
$handler Pflicht (event: WheelEvent) => void Callback-Funktion, die ein WheelEvent erhält. Wichtige Eigenschaften: deltaX, deltaY, deltaZ und deltaMode. deltaMode gibt die Einheit an: 0 = Pixel, 1 = Zeilen, 2 = Seiten.
$options boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal } { passive: false } (auf window/document/body in Chrome/Firefox: passive: true) Optionen für den Listener. passive: false ist nötig, wenn du preventDefault() aufrufen willst. signal erlaubt das Entfernen des Listeners über einen AbortController.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Den Rückgabewert des Handlers wertet der Browser ebenfalls nicht aus. Um das Standardverhalten zu verhindern, rufst du event.preventDefault() auf.

Beispiele

Zoom mit dem Mausrad auf einem Bild

const img = document.querySelector('#bild');
let scale = 1;

const onWheel = (event) => {
  event.preventDefault(); // Seitenscroll unterdrücken
  // Negatives deltaY = Rad nach oben = hineinzoomen
  scale += event.deltaY * -0.001;
  scale = Math.min(Math.max(0.25, scale), 4); // auf 0,25–4 begrenzen
  img.style.transform = `scale(${scale})`;
  console.log('Zoom:', scale.toFixed(2));
};

// passive: false ist nötig, damit preventDefault() wirkt
img.addEventListener('wheel', onWheel, { passive: false });
Zoom: 0.90 Zoom: 0.80 Zoom: 0.90

Horizontales Scrollen einer Leiste mit dem vertikalen Mausrad

const leiste = document.querySelector('.thumbnail-leiste');

leiste.addEventListener('wheel', (event) => {
  // Nur eingreifen, wenn überwiegend vertikal gescrollt wird
  if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) return;
  event.preventDefault();
  // deltaMode 1 = Zeilen (z. B. Firefox) → grob in Pixel umrechnen
  const faktor = event.deltaMode === 1 ? 16 : 1;
  leiste.scrollLeft += event.deltaY * faktor;
}, { passive: false });

Handler per onwheel setzen und Listener wieder entfernen

const box = document.querySelector('#box');

// Variante 1: on-Property (nur ein Handler möglich)
box.onwheel = (event) => {
  console.log(`deltaY: ${event.deltaY}, Strg: ${event.ctrlKey}`);
};

// Variante 2: addEventListener + removeEventListener
const logRichtung = (event) => {
  console.log(event.deltaY > 0 ? 'runter' : 'hoch');
};
box.addEventListener('wheel', logRichtung);

// Nach 5 Sekunden beide Handler entfernen
setTimeout(() => {
  box.removeEventListener('wheel', logRichtung);
  box.onwheel = null;
  console.log('wheel-Handler entfernt');
}, 5000);
deltaY: 100, Strg: false runter wheel-Handler entfernt

Seitenweises Blättern mit Drosselung über AbortController

const folien = document.querySelectorAll('.folie');
let index = 0;
let gesperrt = false;
const controller = new AbortController();

document.querySelector('#praesentation').addEventListener('wheel', (event) => {
  event.preventDefault();
  if (gesperrt) return; // Touchpads liefern viele Events pro Geste
  gesperrt = true;
  index = Math.max(0, Math.min(folien.length - 1, index + Math.sign(event.deltaY)));
  folien[index].scrollIntoView({ behavior: 'smooth' });
  console.log('Folie', index + 1);
  setTimeout(() => { gesperrt = false; }, 600);
}, { passive: false, signal: controller.signal });

// Später: controller.abort() entfernt den Listener
Folie 2 Folie 3

// Wichtig · Fallstricke

  • Passive Listener: In Chrome, Edge und Firefox sind wheel-Listener auf window, document und document.body standardmäßig passive: true. Dort bleibt preventDefault() ohne Wirkung, und die Konsole zeigt eine Warnung. Wenn du das Scrollen verhindern willst, gib { passive: false } ausdrücklich an. Blockiere das Scrollen aber nur, wenn es nötig ist, denn nicht-passive Listener können das Scrollen ruckelig machen.
  • Richtung und Größe der Deltas sind nicht einheitlich: Die Werte unterscheiden sich je nach Browser, Betriebssystem und Gerät. Firefox liefert zum Teil deltaMode = 1 (Zeilen), andere Browser liefern Pixel. Touchpads erzeugen viele kleine Events hintereinander, oft mit Trägheit (Nachlauf). Verlass dich deshalb nicht auf feste Werte wie 100. Nutze besser Math.sign(deltaY) und drossle die Verarbeitung.
  • Pinch-Zoom: Die Zwei-Finger-Zoomgeste auf Touchpads kommt in Chromium-Browsern und Firefox als wheel-Event mit ctrlKey === true an.
  • Veraltete Ereignisse: mousewheel und DOMMouseScroll sind nicht standardisiert und veraltet. Nutze nur noch wheel.
  • Barrierefreiheit: Wenn du das Scrollen komplett abfängst, bekommen Tastatur- und Screenreader-Nutzer davon nichts mit. Biete deshalb zusätzlich eine Bedienung per Tastatur oder über Schaltflächen an.
  • Kein Ersatz für scroll: Scrollen per Tastatur, Scrollleiste oder Touch-Wischen löst kein wheel-Ereignis aus.