Signatur
Beschreibung
Das Ereignis gesturestart ist eine proprietäre WebKit-Erweiterung. Es wird auf einem Element ausgelöst, sobald eine Mehrfinger-Geste beginnt, also typischerweise ein zweiter Finger den Bildschirm berührt (iOS) oder auf dem Trackpad eine Pinch- oder Drehbewegung startet (macOS Safari). Das übergebene Objekt ist ein GestureEvent mit den Eigenschaften scale (Anfangswert 1.0) und rotation (Anfangswert 0 Grad).
Der Ablauf einer Geste besteht aus drei Ereignissen: gesturestart zu Beginn, beliebig viele gesturechange während der Bewegung und gestureend, wenn weniger als zwei Finger übrig sind. In gesturestart merkt man sich üblicherweise den Ausgangszustand, etwa den aktuellen Zoomfaktor oder Drehwinkel eines Elements. Die folgenden gesturechange-Werte beziehen sich immer relativ auf diesen Beginn.
In der Praxis wird gesturestart vor allem für zwei Aufgaben genutzt: Pinch-Zoom und Drehen von Bildern, Karten oder Canvas-Inhalten in Safari umsetzen und mit event.preventDefault() das native Zoomen der Seite verhindern, zum Beispiel in Web-Apps mit eigener Gestensteuerung. Die Registrierung erfolgt per addEventListener("gesturestart", …) oder über die Eigenschaft element.ongesturestart, die es ebenfalls nur in Safari gibt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "gesturestart". |
|
| $handler Pflicht | (event: GestureEvent) => void | Callback, der ein GestureEvent erhält. Wichtige Eigenschaften: scale, rotation, clientX/clientY, target. |
|
| $options | boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal } | false | Übliche Listener-Optionen. Damit preventDefault() wirkt, darf passive nicht auf true stehen. |
Beispiele
Bild per Pinch zoomen und drehen (Safari)
const img = document.querySelector('#foto');
let startScale = 1;
let startRotation = 0;
let currentScale = 1;
let currentRotation = 0;
img.addEventListener('gesturestart', (event) => {
event.preventDefault(); // natives Seitenzoomen verhindern
startScale = currentScale;
startRotation = currentRotation;
console.log('Geste beginnt:', event.scale, event.rotation);
});
img.addEventListener('gesturechange', (event) => {
event.preventDefault();
currentScale = startScale * event.scale;
currentRotation = startRotation + event.rotation;
img.style.transform = `scale(${currentScale}) rotate(${currentRotation}deg)`;
});
img.addEventListener('gestureend', () => {
console.log('Geste beendet, Zoom:', currentScale.toFixed(2));
});
Seitenzoom in einer Web-App blockieren und wieder freigeben
const blockZoom = (event) => event.preventDefault();
// Blockieren (iOS ignoriert seit iOS 10 user-scalable=no im Viewport)
document.addEventListener('gesturestart', blockZoom, { passive: false });
// Später wieder freigeben, z. B. beim Verlassen des Vollbild-Editors
const leaveEditor = () => {
document.removeEventListener('gesturestart', blockZoom);
console.log('Seitenzoom wieder erlaubt');
};
leaveEditor();
on-Eigenschaft mit Funktionserkennung und Fallback
const karte = document.querySelector('#karte');
if ('ongesturestart' in window) {
// Safari: native Gesten-Ereignisse
karte.ongesturestart = (event) => {
event.preventDefault();
karte.dataset.gesture = 'aktiv';
console.log('Safari-Geste gestartet');
};
} else {
// Andere Browser: zwei aktive Pointer als Gestenbeginn werten
const pointers = new Set();
karte.style.touchAction = 'none';
karte.addEventListener('pointerdown', (event) => {
pointers.add(event.pointerId);
if (pointers.size === 2) console.log('Pointer-Geste gestartet');
});
const release = (event) => pointers.delete(event.pointerId);
karte.addEventListener('pointerup', release);
karte.addEventListener('pointercancel', release);
}
// Wichtig · Fallstricke
- Nicht standardisiert:
gesturestartgibt es nur in Safari auf iOS/iPadOS und in Safari unter macOS (dort über Trackpad-Gesten). Chrome, Firefox und Edge lösen es nicht aus, auch nicht auf Android. Wer plattformübergreifend arbeitet, sollte Pointer Events odertouchstart/touchmovemit zwei Berührungspunkten nutzen. - Funktion vorher prüfen: Vor der Nutzung mit
'ongesturestart' in windowtesten. Der TypGestureEventfehlt außerdem in den Standard-TypeScript-DOM-Typen. - Passive Listener: Mit
{ passive: true }wirdpreventDefault()ignoriert, das native Zoomen findet dann trotzdem statt. - Barrierefreiheit: Seit iOS 10 ignoriert Safari
user-scalable=noabsichtlich. Wer das Zoomen übergesturestartblockiert, nimmt sehbehinderten Menschen eine wichtige Hilfe. Das sollte man nur in eng begrenzten Bereichen tun, etwa auf einer Canvas mit eigener Zoomfunktion. - Werte sind relativ:
scaleundrotationbeziehen sich immer auf den Beginn der aktuellen Geste. Deshalb ingesturestartden Ausgangszustand speichern, sonst springt das Element bei jeder neuen Geste zurück. - Auf iOS laufen parallel dazu weiter
touchstart/touchmove-Ereignisse. Wer beide Arten auswertet, muss doppelte Verarbeitung vermeiden.