Start · Sprachen · JavaScript · Referenz · PointerEvent

PointerEvent

Schnittstelle

Ein <code>PointerEvent</code> beschreibt eine Eingabe per Maus, Stift oder Touch mit Kontaktgeometrie, Gerätetyp, Druck, Neigung und eindeutiger Zeiger-ID.

seit JavaScript Pointer Events Level 2/3 – Baseline: alle modernen Kategorie: webapi

Signatur

interface PointerEvent extends MouseEvent

Beschreibung

PointerEvent fasst Maus-, Stift- und Touch-Eingaben in einem gemeinsamen Ereignismodell zusammen. Statt getrennte Handler für mouse* und touch* zu schreiben, reagiert man auf pointerdown, pointermove, pointerup, pointercancel, pointerover, pointerout, pointerenter, pointerleave, gotpointercapture und lostpointercapture. Ein PointerEvent erbt von MouseEvent, deshalb stehen auch clientX, clientY, button, buttons und die Modifikatortasten zur Verfügung.

Dazu kommen zeigerspezifische Eigenschaften: pointerId (eindeutige ID pro aktivem Zeiger, wichtig für Multitouch), pointerType ("mouse", "pen" oder "touch"), isPrimary, width/height (Kontaktfläche in CSS-Pixeln), pressure und tangentialPressure (0–1 bzw. −1–1), tiltX/tiltY, twist, altitudeAngle/azimuthAngle sowie die Methoden getCoalescedEvents() und getPredictedEvents().

Typische Einsatzfälle sind Zeichen-Apps (Druck- und Neigungsempfindlichkeit), Drag-and-Drop, Schieberegler, Gesten wie Pinch-Zoom und Spiele. Mit element.setPointerCapture(pointerId) leitet man alle weiteren Ereignisse eines Zeigers an ein Element um, selbst wenn der Zeiger es verlässt – ideal für Ziehbewegungen.

Wichtig: Bei Touch führt der Browser standardmäßig eigene Gesten (Scrollen, Zoomen) aus und feuert dann pointercancel. Über die CSS-Eigenschaft touch-action (z. B. touch-action: none) steuert man, welche Gesten der Browser übernimmt.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Ereignistyp für den Konstruktor new PointerEvent(type, options), z. B. "pointerdown".
$options PointerEventInit {} Optionales Objekt mit allen MouseEventInit-Feldern plus pointerId, width, height, pressure, tangentialPressure, tiltX, tiltY, twist, altitudeAngle, azimuthAngle, pointerType, isPrimary, coalescedEvents, predictedEvents.

Rückgabewert

Typ
PointerEvent
Beschreibung
Der Konstruktor liefert ein neues PointerEvent-Objekt, das mit dispatchEvent() ausgelöst werden kann (isTrusted ist dann false).

Beispiele

Gerätetyp und Druck auswerten

const canvas = document.querySelector('#zeichenflaeche');

canvas.addEventListener('pointerdown', (event) => {
  console.log(`Typ: ${event.pointerType}, ID: ${event.pointerId}`);
  console.log(`Druck: ${event.pressure.toFixed(2)}, primär: ${event.isPrimary}`);
});
Typ: pen, ID: 2 Druck: 0.47, primär: true

Ziehen mit Pointer Capture (inkl. Entfernen der Listener)

// CSS: #regler { touch-action: none; }
const knopf = document.querySelector('#regler');
let startX = 0;

const onMove = (e) => {
  knopf.style.transform = `translateX(${e.clientX - startX}px)`;
};

const onEnd = (e) => {
  knopf.releasePointerCapture(e.pointerId);
  knopf.removeEventListener('pointermove', onMove);
  knopf.removeEventListener('pointerup', onEnd);
  knopf.removeEventListener('pointercancel', onEnd);
};

knopf.onpointerdown = (e) => {
  startX = e.clientX;
  knopf.setPointerCapture(e.pointerId);
  knopf.addEventListener('pointermove', onMove);
  knopf.addEventListener('pointerup', onEnd);
  knopf.addEventListener('pointercancel', onEnd);
};

Flüssige Linien mit getCoalescedEvents()

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

canvas.addEventListener('pointermove', (event) => {
  if (event.buttons !== 1) return;
  // Alle zwischengespeicherten Zwischenpunkte zeichnen
  const punkte = event.getCoalescedEvents?.() ?? [event];
  for (const p of punkte) {
    const r = 1 + p.pressure * 6;
    ctx.beginPath();
    ctx.arc(p.offsetX, p.offsetY, r, 0, Math.PI * 2);
    ctx.fill();
  }
});

Multitouch: aktive Zeiger zählen und synthetisches Ereignis

const aktiv = new Map();
const flaeche = document.querySelector('#flaeche');

flaeche.addEventListener('pointerdown', (e) => {
  aktiv.set(e.pointerId, e);
  console.log('Aktive Zeiger:', aktiv.size);
});
['pointerup', 'pointercancel'].forEach((typ) =>
  flaeche.addEventListener(typ, (e) => aktiv.delete(e.pointerId))
);

// Synthetisches Ereignis, z. B. für Tests
flaeche.dispatchEvent(new PointerEvent('pointerdown', {
  pointerId: 42, pointerType: 'touch', isPrimary: true, bubbles: true
}));
Aktive Zeiger: 1

// Wichtig · Fallstricke

  • touch-action nicht vergessen: Ohne touch-action: none (oder pan-y o. ä.) übernimmt der Browser bei Touch das Scrollen und feuert pointercancel – Ziehgesten brechen dann ab.
  • pointercancel immer behandeln, sonst bleiben Zustände (z. B. „wird gezogen“) hängen.
  • Browser feuern nach Pointer-Events weiterhin kompatible mouse*-Ereignisse; preventDefault() in pointerdown unterdrückt diese, nicht aber click.
  • pressure ist bei Geräten ohne Drucksensor 0,5 bei gedrückter Taste und sonst 0. width/height sind bei der Maus 1.
  • getCoalescedEvents() fehlt in älteren Safari-Versionen und ist nur im sicheren Kontext verfügbar; getPredictedEvents(), altitudeAngle und azimuthAngle sind neuer und nicht überall vorhanden – per Feature-Erkennung prüfen.
  • pointermove kann sehr häufig feuern; aufwendige Arbeit per requestAnimationFrame bündeln und Listener mit { passive: true } registrieren, wenn kein preventDefault() nötig ist.
  • pointerId-Werte sind nur während der Lebensdauer eines Zeigers eindeutig und dürfen nicht als stabile Geräte-ID verwendet werden.