Start · Sprachen · JavaScript · Referenz · Element: touchmove

Element: touchmove

Ereignis

Wird ausgelöst, wenn ein oder mehrere Berührungspunkte auf der Touch-Oberfläche bewegt werden, und liefert ein <code>TouchEvent</code> mit den aktuellen Positionen.

seit JavaScript Baseline: alle modernen Browser (auf Desktop nur m Kategorie: webapi

Signatur

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

Beschreibung

Das touchmove-Ereignis gehört zur Touch Events API und feuert wiederholt, solange ein Finger (oder Stift) nach einem touchstart über die Oberfläche bewegt wird. Das Ereignis wird immer an das Element geschickt, auf dem die Berührung begonnen hat, auch wenn der Finger dieses Element längst verlassen hat.

Der Handler bekommt ein TouchEvent. Die wichtigsten Eigenschaften sind:

  • touches: alle Berührungspunkte, die gerade auf der Oberfläche liegen
  • targetTouches: die Punkte, die auf dem Ziel-Element begonnen haben
  • changedTouches: die Punkte, die sich seit dem letzten Ereignis bewegt haben

Jedes Touch-Objekt hat eine eindeutige identifier sowie die Koordinaten clientX/Y, pageX/Y und screenX/Y.

Typische Anwendungen sind Wisch-Gesten, Drag-and-Drop auf Mobilgeräten, Zeichenflächen, Slider und Pinch-Zoom. Du kannst den Handler per addEventListener("touchmove", …) oder über die Eigenschaft element.ontouchmove registrieren. Für neuen Code, der Maus, Stift und Touch gleich behandeln soll, sind die Pointer Events (pointermove) meist die bessere Wahl.

Das Ereignis ist abbrechbar (cancelable), bubbelt und kann mit event.preventDefault() das native Scrollen oder Zoomen verhindern. Das klappt aber nur, wenn der Listener nicht passiv ist.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier "touchmove".
$handler Pflicht (event: TouchEvent) => void Callback-Funktion. Sie bekommt ein TouchEvent mit touches, targetTouches und changedTouches.
$options boolean | { passive?: boolean, capture?: boolean, once?: boolean, signal?: AbortSignal } { passive: true } auf window/document/body in Chrome und Firefox Optionen für den Listener. Mit passive: false darf der Handler preventDefault() aufrufen. Mit signal lässt sich der Listener über einen AbortController wieder entfernen.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt undefined zurück. Der Handler bekommt ein TouchEvent.

Beispiele

Fingerposition verfolgen (addEventListener)

const area = document.querySelector('#touch-area');

area.addEventListener('touchmove', (event) => {
  // changedTouches enthält nur die Punkte, die sich bewegt haben
  for (const touch of event.changedTouches) {
    console.log(`Finger ${touch.identifier}: x=${Math.round(touch.clientX)}, y=${Math.round(touch.clientY)}`);
  }
}, { passive: true });
Finger 0: x=142, y=318 Finger 0: x=145, y=322 …

Element per Touch verschieben und Scrollen verhindern

const box = document.querySelector('.draggable');
let offsetX = 0;
let offsetY = 0;

box.addEventListener('touchstart', (e) => {
  const t = e.targetTouches[0];
  const rect = box.getBoundingClientRect();
  offsetX = t.clientX - rect.left;
  offsetY = t.clientY - rect.top;
}, { passive: true });

// passive: false, damit preventDefault() das Scrollen der Seite unterbindet
box.addEventListener('touchmove', (e) => {
  e.preventDefault();
  const t = e.targetTouches[0];
  box.style.transform = `translate(${t.clientX - offsetX}px, ${t.clientY - offsetY}px)`;
}, { passive: false });

Wischrichtung erkennen und Listener wieder entfernen

const slider = document.querySelector('.slider');
let startX = 0;

const onMove = (e) => {
  const deltaX = e.touches[0].clientX - startX;
  if (Math.abs(deltaX) > 50) {
    console.log(deltaX > 0 ? 'Wisch nach rechts' : 'Wisch nach links');
    // Nach erkannter Geste Listener entfernen
    slider.removeEventListener('touchmove', onMove);
  }
};

slider.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX;
  slider.addEventListener('touchmove', onMove, { passive: true });
}, { passive: true });
Wisch nach links

Pinch-Abstand über die on-Property messen

const img = document.querySelector('#zoom-image');

img.ontouchmove = (e) => {
  if (e.touches.length !== 2) return;
  const [a, b] = e.touches;
  const distance = Math.hypot(b.clientX - a.clientX, b.clientY - a.clientY);
  console.log(`Abstand: ${distance.toFixed(0)} px`);
};

// Handler wieder entfernen:
// img.ontouchmove = null;
Abstand: 184 px Abstand: 201 px

// Wichtig · Fallstricke

  • Passive Listener: Chrome, Edge und Firefox behandeln touchmove-Listener auf window, document und document.body standardmäßig als passive: true. Ein Aufruf von preventDefault() wird dort ignoriert und erzeugt eine Konsolenwarnung. Wenn du Scrollen gezielt unterbinden willst, gib { passive: false } ausdrücklich an. Oft ist die CSS-Eigenschaft touch-action: none die schnellere und sauberere Lösung.
  • Performance: touchmove kann sehr oft feuern, bis zur Bildwiederholrate und darüber. Aufwendige DOM-Änderungen solltest du per requestAnimationFrame bündeln. Nicht-passive Listener können das Scrollen spürbar verzögern.
  • Ziel-Element: event.target bleibt das Element, auf dem die Berührung begonnen hat, auch wenn der Finger es verlässt. Das Element unter dem Finger findest du mit document.elementFromPoint(touch.clientX, touch.clientY).
  • Entfernte Elemente: Wird das Start-Element während der Geste aus dem DOM entfernt, kommen die weiteren touchmove-Ereignisse nicht mehr beim übergeordneten Element an. Das Element sollte daher bis touchend im DOM bleiben.
  • Kompatibilität: Alle mobilen Browser unterstützen das Ereignis. Auf Desktop-Browsern feuert es nur mit Touch-Hardware; Safari auf macOS unterstützt Touch Events nicht. Wenn du Maus, Stift und Touch einheitlich behandeln willst, nimm pointermove. Prüfe die Unterstützung mit 'ontouchstart' in window.
  • Nach touchcancel (zum Beispiel bei einem Systemdialog) kommen keine weiteren touchmove-Ereignisse. Setze deinen Gesten-Zustand dort zurück.