Start · Sprachen · JavaScript · Referenz · Element: pointermove

Element: pointermove

Ereignis

Wird ausgelöst, wenn ein Zeiger (Maus, Stift, Finger) seine Koordinaten, seinen Druck, seine Neigung oder seinen Tastenstatus ändert.

seit JavaScript Baseline: alle modernen Browser (seit 2020, Pointe Kategorie: webapi

Signatur

element.addEventListener("pointermove", handler)

Beschreibung

Das Ereignis pointermove ist Teil der Pointer Events API und fasst Maus-, Stift- und Touch-Eingaben in einem einheitlichen Modell zusammen. Es wird ausgelöst, sobald ein aktiver Zeiger seine Position ändert. Es feuert auch dann, wenn sich Eigenschaften wie pressure, tiltX/tiltY, width/height oder der Tastenzustand ändern und dafür kein anderes Pointer-Ereignis zuständig ist. Die Handler-Funktion erhält ein PointerEvent, das von MouseEvent erbt.

Registrieren lässt sich das Ereignis mit element.addEventListener("pointermove", handler) oder über die Eigenschaft element.onpointermove = handler. Das Ereignis steigt im DOM auf (Bubbling), ist abbrechbar (cancelable) und passiert Shadow-DOM-Grenzen (composed).

Typische Einsatzfälle sind Drag-and-Drop, Zeichen-Anwendungen, eigene Schieberegler, Hover-Effekte und Gesten. Zusammen mit setPointerCapture() bekommt das Element alle weiteren Bewegungen eines Zeigers, auch wenn dieser das Element verlässt.

Bei Touch-Eingaben bricht der Browser den Zeiger mit pointercancel ab, sobald er selbst scrollt oder zoomt. Danach kommen keine pointermove-Ereignisse mehr an. Mit der CSS-Eigenschaft touch-action (z. B. touch-action: none) legst du fest, welche Browser-Gesten erlaubt bleiben.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "pointermove".
$handler Pflicht (event: PointerEvent) => void Callback, der bei jeder Zeigerbewegung aufgerufen wird. Wichtige Eigenschaften: clientX/clientY, offsetX/offsetY, pointerId, pointerType ("mouse", "pen", "touch"), pressure, buttons, isPrimary.
$options boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal } false Optionen für addEventListener. Mit passive: true kann der Browser flüssiger rendern, wenn du preventDefault() nicht brauchst. Mit signal lässt sich der Listener gezielt entfernen.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt undefined zurück. Der Handler erhält ein PointerEvent-Objekt.

Beispiele

Zeigerposition live anzeigen (addEventListener)

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

box.addEventListener('pointermove', (event) => {
  info.textContent = `${event.pointerType}: x=${event.offsetX}, y=${event.offsetY}, Druck=${event.pressure.toFixed(2)}`;
});
mouse: x=120, y=48, Druck=0.00

Element ziehen mit Pointer Capture

const knob = document.querySelector('#knob');
knob.style.touchAction = 'none'; // Browser soll bei Touch nicht scrollen
let start = null;

knob.addEventListener('pointerdown', (e) => {
  knob.setPointerCapture(e.pointerId);
  start = { x: e.clientX - knob.offsetLeft, y: e.clientY - knob.offsetTop };
});

knob.addEventListener('pointermove', (e) => {
  if (!knob.hasPointerCapture(e.pointerId)) return;
  knob.style.left = `${e.clientX - start.x}px`;
  knob.style.top = `${e.clientY - start.y}px`;
});

knob.addEventListener('pointerup', (e) => {
  knob.releasePointerCapture(e.pointerId);
});

on-Property und Entfernen per removeEventListener

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const zeichnen = (e) => {
  if (e.buttons !== 1) return; // nur bei gedrückter Haupttaste
  ctx.fillRect(e.offsetX, e.offsetY, 2, 2);
};

canvas.addEventListener('pointermove', zeichnen);

// Nach 10 Sekunden Zeichnen deaktivieren
setTimeout(() => canvas.removeEventListener('pointermove', zeichnen), 10_000);

// Alternative: Einzel-Handler per on-Property
canvas.onpointermove = (e) => console.log('Bewegung', e.pointerId);
// canvas.onpointermove = null; // wieder entfernen
Bewegung 1

Hochauflösende Stift-Eingabe mit getCoalescedEvents()

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

canvas.addEventListener('pointermove', (e) => {
  if (e.buttons !== 1) return;
  // Zwischenpunkte, die der Browser zu einem Ereignis zusammengefasst hat
  const punkte = e.getCoalescedEvents?.() ?? [e];
  for (const p of punkte) {
    ctx.fillRect(p.offsetX, p.offsetY, 1 + p.pressure * 4, 1 + p.pressure * 4);
  }
});

// Wichtig · Fallstricke

  • Hohe Frequenz: pointermove feuert sehr oft. Aufwendige Arbeit (Layout, DOM-Änderungen) gehört gebündelt in requestAnimationFrame(). Browser fassen Ereignisse oft pro Frame zusammen. Die einzelnen Zwischenpunkte liefert getCoalescedEvents(), Safari unterstützt das erst seit Version 18.
  • Touch und touch-action: Ohne passendes touch-action im CSS übernimmt der Browser bei Touch das Scrollen. Er sendet dann pointercancel, und weitere pointermove-Ereignisse bleiben aus.
  • Mehrere Zeiger: Beim Multitouch kommt jedes Ereignis mit einer eigenen pointerId. Prüfe isPrimary oder verwalte die Zeiger in einer Map.
  • Maus ohne Taste: Bei der Maus feuert pointermove auch ohne gedrückte Taste. Für Drag-Logik solltest du buttons oder hasPointerCapture() prüfen.
  • preventDefault() in pointermove verhindert kein Scrollen. Dafür ist touch-action zuständig.
  • Kompatibilität: Alle aktuellen Browser unterstützen das Ereignis. Safari kann es seit Version 13, der Internet Explorer 10 nur mit Präfix (MSPointerMove).