Signatur
Beschreibung
Das Ereignis touchcancel signalisiert, dass eine laufende Touch-Interaktion nicht regulär beendet wurde. Anders als bei touchend hat der Nutzer den Finger nicht bewusst angehoben. Der Browser oder das Betriebssystem hat die Berührung abgebrochen. Typische Auslöser sind ein eingeblendeter Systemdialog oder ein eingehender Anruf, das Verlassen des Dokuments (z. B. wenn der Finger über die Browser-Oberfläche gleitet), mehr gleichzeitige Berührungspunkte als das Gerät verarbeiten kann oder das Übernehmen der Geste durch den Browser, z. B. zum Scrollen oder Zoomen.
Der Handler erhält ein TouchEvent. In event.changedTouches stehen die abgebrochenen Berührungspunkte. event.touches enthält nur noch die Punkte, die weiterhin aktiv sind. Das Ereignis steigt im DOM auf (Bubbling), lässt sich aber nicht abbrechen: cancelable ist false.
In der Praxis nutzt man touchcancel zum Aufräumen. Zustände, die bei touchstart aufgebaut wurden, sollten hier genauso zurückgesetzt werden wie bei touchend. Dazu gehören laufende Drag-Operationen, Zeichenpfade, Timer für langes Drücken und visuelle Hervorhebungen. Wer touchcancel ignoriert, riskiert „hängende“ Zustände, etwa ein Element, das nach einem Anruf weiter am Finger klebt.
Registrieren kann man den Handler mit addEventListener("touchcancel", handler) oder über die Eigenschaft element.ontouchcancel = handler.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "touchcancel". |
|
| $handler Pflicht | (event: TouchEvent) => void | Callback, der ein TouchEvent erhält. Wichtige Eigenschaften: changedTouches (abgebrochene Punkte), touches, targetTouches. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { passive: true }, once, capture oder signal (AbortSignal). |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein TouchEvent.Beispiele
Drag-Zustand bei Abbruch zurücksetzen
const box = document.querySelector('#box');
let dragging = false;
let startX = 0;
let startY = 0;
box.addEventListener('touchstart', (e) => {
const t = e.changedTouches[0];
dragging = true;
startX = t.clientX;
startY = t.clientY;
box.classList.add('dragging');
}, { passive: true });
box.addEventListener('touchmove', (e) => {
if (!dragging) return;
const t = e.changedTouches[0];
box.style.transform = `translate(${t.clientX - startX}px, ${t.clientY - startY}px)`;
}, { passive: true });
// Gemeinsame Aufräumlogik für reguläres Ende und Abbruch
const resetDrag = (e) => {
dragging = false;
box.classList.remove('dragging');
if (e.type === 'touchcancel') {
box.style.transform = ''; // Position zurücksetzen
console.log('Drag abgebrochen');
}
};
box.addEventListener('touchend', resetDrag);
box.addEventListener('touchcancel', resetDrag);
Mehrere Finger verfolgen und abgebrochene Punkte entfernen
const canvas = document.querySelector('canvas');
const activeTouches = new Map();
canvas.addEventListener('touchstart', (e) => {
for (const t of e.changedTouches) {
activeTouches.set(t.identifier, { x: t.clientX, y: t.clientY });
}
}, { passive: true });
canvas.addEventListener('touchcancel', (e) => {
for (const t of e.changedTouches) {
activeTouches.delete(t.identifier);
console.log(`Touch ${t.identifier} abgebrochen`);
}
console.log('Noch aktiv:', e.touches.length);
});
Timer für langes Drücken über ontouchcancel abbrechen
const button = document.querySelector('#hold');
let timer = null;
button.ontouchstart = () => {
timer = setTimeout(() => console.log('Langes Drücken erkannt'), 800);
};
const clear = () => {
clearTimeout(timer);
timer = null;
};
button.ontouchend = clear;
button.ontouchcancel = clear; // z. B. wenn der Browser zu scrollen beginnt
Listener mit AbortController wieder entfernen
const controller = new AbortController();
const area = document.querySelector('#area');
const onCancel = (e) => console.log('Abgebrochen:', e.changedTouches.length);
area.addEventListener('touchcancel', onCancel, { signal: controller.signal });
// Später: alle Listener mit diesem Signal entfernen
controller.abort();
// Alternativ: area.removeEventListener('touchcancel', onCancel);
// Wichtig · Fallstricke
- Nicht abbrechbar:
preventDefault()hat intouchcancelkeine Wirkung. Das Ereignis ist bereits die Folge einer Entscheidung des Browsers. - Kein
touchenddanach: Wurde ein Berührungspunkt abgebrochen, folgt für ihn keintouchendmehr. Die Aufräumlogik gehört deshalb immer in beide Handler. - Implementierungsspezifisch: Wann genau
touchcancelausgelöst wird, ist je nach Browser und Betriebssystem verschieden. Besonders häufig passiert es, wenn der Browser eine Geste für natives Scrollen oder Zoomen übernimmt. Mit der CSS-Eigenschafttouch-action(z. B.touch-action: none) lässt sich das oft verhindern. - Kompatibilität: Touch Events stehen nur auf touchfähigen Geräten zur Verfügung. In Desktop-Browsern ohne Touchscreen existiert
ontouchcancelteilweise gar nicht (Feature-Erkennung:'ontouchstart' in window). Für Maus, Stift und Touch zusammen empfehlen sich Pointer Events, hier istpointercanceldas Gegenstück. - Für die Zuordnung mehrerer Finger immer
Touch.identifierverwenden, nicht die Position in der Liste.