Signatur
Beschreibung
Das Ereignis mousemove feuert immer wieder, solange der Mauszeiger über einem Element bewegt wird. Der Handler erhält ein MouseEvent mit den aktuellen Koordinaten (clientX/clientY, pageX/pageY, offsetX/offsetY, screenX/screenY), der Bewegung seit dem letzten Ereignis (movementX/movementY) und dem Zustand der Maustasten (buttons) und Zusatztasten (shiftKey, ctrlKey, altKey, metaKey).
Typische Einsatzfälle sind Drag-&-Drop-Eigenbauten, Zeichenflächen auf <canvas>, Tooltips, die dem Cursor folgen, Parallax-Effekte und Hover-Vorschauen. Registriert wird der Handler mit addEventListener("mousemove", handler) oder über die Eigenschaft element.onmousemove = handler. Das Ereignis steigt im DOM auf (bubbles) und lässt sich abbrechen (cancelable).
Da mousemove sehr häufig ausgelöst wird (oft mehr als 60 Mal pro Sekunde), sollte der Handler schlank sein. Aufwendige Arbeit wie DOM-Änderungen oder Layout-Abfragen bündelt man am besten mit requestAnimationFrame() oder drosselt sie (Throttling).
Für moderne Anwendungen, die auch Touch und Stift unterstützen sollen, ist das gleichwertige pointermove-Ereignis meist die bessere Wahl.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "mousemove". |
|
| $handler Pflicht | (event: MouseEvent) => void | Callback, der bei jeder Bewegung ein MouseEvent erhält. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { passive: true }, { once: true }, { signal } oder capture. |
Rückgabewert
addEventListener() gibt undefined zurück. Der Handler erhält ein MouseEvent-Objekt.Beispiele
Koordinaten relativ zum Element anzeigen
const box = document.querySelector('#box');
const anzeige = document.querySelector('#koordinaten');
box.addEventListener('mousemove', (event) => {
const rect = box.getBoundingClientRect();
const x = Math.round(event.clientX - rect.left);
const y = Math.round(event.clientY - rect.top);
anzeige.textContent = `x: ${x}, y: ${y}`;
});
Zeichnen auf einem Canvas mit gedrückter Maustaste
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.lineWidth = 2;
canvas.addEventListener('mousedown', (e) => {
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
});
canvas.addEventListener('mousemove', (e) => {
// buttons & 1 = linke Maustaste gedrückt
if ((e.buttons & 1) === 0) return;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
});
Tooltip folgt dem Cursor – gedrosselt per requestAnimationFrame
const tooltip = document.querySelector('.tooltip');
let letztesEvent = null;
let geplant = false;
const onMove = (e) => {
letztesEvent = e;
if (geplant) return;
geplant = true;
requestAnimationFrame(() => {
tooltip.style.transform = `translate(${letztesEvent.clientX + 12}px, ${letztesEvent.clientY + 12}px)`;
geplant = false;
});
};
document.addEventListener('mousemove', onMove, { passive: true });
// Später wieder entfernen – gleiche Funktionsreferenz nötig
document.querySelector('#aus').addEventListener('click', () => {
document.removeEventListener('mousemove', onMove);
tooltip.hidden = true;
});
Alternative über die on-Eigenschaft
const flaeche = document.querySelector('#flaeche');
flaeche.onmousemove = (e) => {
console.log(`Bewegung: ${e.movementX}, ${e.movementY}`);
};
// Handler entfernen
setTimeout(() => { flaeche.onmousemove = null; }, 5000);
// Wichtig · Fallstricke
- Performance:
mousemovefeuert sehr häufig. Keine teuren Berechnungen oder erzwungenen Layout-Neuberechnungen (z. B. wiederholtesgetBoundingClientRect()mit Schreibzugriffen gemischt) direkt im Handler – mitrequestAnimationFrame()bündeln oder drosseln. - Außerhalb des Elements: Verlässt der Cursor das Element beim Ziehen, kommen keine Ereignisse mehr an. Für Drag-Logik den Listener deshalb auf
documentregistrieren odersetPointerCapture()mit Pointer Events verwenden. - Touch-Geräte: Auf Touchscreens wird
mousemovenicht zuverlässig bzw. nur emuliert ausgelöst. Für geräteübergreifende Eingabepointermoveverwenden. buttons(Bitmaske aller gedrückten Tasten) ist fürmousemoveaussagekräftig,buttondagegen nicht – es ist hier meist0.offsetX/offsetYbeziehen sich auf das Ziel-Element (event.target), das bei verschachtelten Kindelementen ein anderes sein kann als das Element mit dem Listener.removeEventListener()funktioniert nur mit derselben Funktionsreferenz; anonyme Pfeilfunktionen lassen sich nicht entfernen – alternativAbortControllermit der Optionsignalnutzen.- Browser-Kompatibilität: in allen Browsern unterstützt;
movementX/movementYsind in allen modernen Browsern verfügbar.