Signatur
Beschreibung
Die Eigenschaft changedTouches eines TouchEvent liefert eine TouchList. Sie enthält nur die Touch-Objekte, die mit dem aktuellen Ereignis zu tun haben. Welche das sind, hängt vom Ereignistyp ab:
touchstart: die Berührungspunkte, die mit diesem Ereignis neu dazugekommen sind.touchmove: die Berührungspunkte, die sich seit dem letzten Ereignis bewegt haben.touchendundtouchcancel: die Berührungspunkte, die gerade von der Oberfläche entfernt oder abgebrochen wurden.
Bei touchend ist changedTouches besonders wichtig. Ein Finger, der losgelassen wurde, steht dann nicht mehr in touches und auch nicht mehr in targetTouches. Die Endposition einer Geste (etwa für Wischgesten oder Tipp-Erkennung) findet man nur in changedTouches.
Jedes Touch-Objekt hat eine eindeutige identifier. Damit lassen sich mehrere Finger über touchstart, touchmove und touchend hinweg verfolgen. Das ist die Grundlage für Multitouch-Zeichenflächen, Pinch-Gesten und Spielsteuerungen.
Rückgabewert
Touch-Objekten. Zugriff über length, item(index) oder den Index-Operator [i]. Die Liste ist durchlaufbar (Iterable), for...of und Array.from() funktionieren also.Beispiele
Endposition eines Fingers bei touchend auslesen
const area = document.querySelector('#area');
area.addEventListener('touchend', (event) => {
// touches ist hier bereits leer – nur changedTouches kennt den gelösten Finger
const touch = event.changedTouches[0];
console.log(`Losgelassen bei x=${touch.clientX}, y=${touch.clientY}`);
console.log('Verbleibende Finger:', event.touches.length);
});
Wischgeste (Swipe) erkennen
const el = document.querySelector('.carousel');
let startX = 0;
let startY = 0;
el.addEventListener('touchstart', (e) => {
const t = e.changedTouches[0];
startX = t.clientX;
startY = t.clientY;
}, { passive: true });
el.addEventListener('touchend', (e) => {
const t = e.changedTouches[0];
const dx = t.clientX - startX;
const dy = t.clientY - startY;
if (Math.abs(dx) > 50 && Math.abs(dx) > Math.abs(dy)) {
console.log(dx < 0 ? 'Wisch nach links' : 'Wisch nach rechts');
}
});
Multitouch-Zeichnen mit identifier
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const active = new Map(); // identifier -> letzte Position
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
for (const t of e.changedTouches) {
active.set(t.identifier, { x: t.clientX, y: t.clientY });
}
}, { passive: false });
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
for (const t of e.changedTouches) {
const prev = active.get(t.identifier);
if (!prev) continue;
ctx.beginPath();
ctx.moveTo(prev.x - rect.left, prev.y - rect.top);
ctx.lineTo(t.clientX - rect.left, t.clientY - rect.top);
ctx.stroke();
active.set(t.identifier, { x: t.clientX, y: t.clientY });
}
}, { passive: false });
const endTouch = (e) => {
for (const t of e.changedTouches) active.delete(t.identifier);
};
canvas.addEventListener('touchend', endTouch);
canvas.addEventListener('touchcancel', endTouch);
// Wichtig · Fallstricke
- Häufigster Fehler: Bei
touchenddie Position ausevent.touches[0]lesen. Diese Liste enthält den gelösten Finger nicht mehr und ist oft leer, sodassundefinedherauskommt. Hier immerchangedTouchesverwenden. changedToucheskann mehrere Einträge enthalten, wenn mehrere Finger gleichzeitig aufsetzen oder sich bewegen. Die Liste deshalb durchlaufen, statt nur auf[0]zuzugreifen.- Die Reihenfolge der Einträge ist nicht garantiert. Finger über
identifierzuordnen, nie über den Index. TouchListist kein echtes Array.mapoderfiltergehen erst nachArray.from(e.changedTouches).touchcancelimmer mitbehandeln, sonst bleiben Einträge in der eigenen Zustandsverwaltung liegen (z. B. wenn das System die Geste übernimmt).- Kompatibilität: Touch Events werden in allen mobilen Browsern unterstützt. Auf dem Desktop gibt es sie nur mit Touch-Hardware (Desktop-Safari erst ab Version 18.2). Für eingabeunabhängigen Code (Maus, Stift, Touch) eignen sich
PointerEvents meist besser. - Soll
preventDefault()das Scrollen verhindern, muss der Listener mit{ passive: false }registriert werden. Chrome behandelttouchstart/touchmoveaufwindow,documentundbodystandardmäßig als passiv.