Vanilla Javascript Swipe – Wischen und Ziehen
Swipe oder Wischen ist eine Geste auf Touchscreens, bei der ein Finger auf dem Touchscreen bewegt wird. Die Maus auf dem Desktop setzt Swipes durch das Mausrad (wheel-Event) um. Swipes mittels touch-Event oder wheel-Event blättern horizontal durch Slideshows, Angebote und Galerien.
Swipe mit Touch-Geste und Scrollrad der Maus
Ein Swipe von Rechts nach Links oder Links nach Rechts holt den Screen einer zuvor oder danach besuchten Seite auf den Screen, in Apps wie iTunes scrollt ein Fingerwisch durch die aktuellen Charts, Ein swipe-Event gibt es nicht, sondern Swipe wird durch touchstart und touchend entdeckt, wenn der Finger über eine Distanz hinweg nicht angehoben wird. Auch wenn immer häufiger pointer-Events eingesetzt werden, um Gesten sowohl auf dem Touchscreen als auch mit Maus oder Stift auszuwerten, sind hier touch-Events angebracht, denn das Wischen mit der Maus wird durch das Mausrad umgesetzt - mit wheel-Events.
| Event | Beschreibung |
|---|---|
touchstart |
Finger berührt den Bildschirm. |
touchmove |
Finger wird auf dem Bildschirm bewegt. |
touchend |
Finger verlässt den Bildschirm. |
touchcancel |
Touch-Geste wird abgebrochen (z. B. wenn ein Anruf eingeht). |
| Event | Beschreibung |
|---|---|
| pointerdown | Der Finger wird aufgesetzt oder die Maus klickt |
| pointermove | Benutzer bewegt den Finger, die Maus der den Pen ohne hochzuheben |
| pointerup | Zeigegerät oder Finger werden angehoben |
| pointercancel | Eingabe abgebrochen |
| pointercapture, lostpointercapture | Ein Element hält den Pointer exklusiv fest |
Für ein einfaches Swipe von rechts nach links oder von links nach rechts braucht Javascript nur wenige Zeilen. Hinter "Swipe" steckt ein einfaches Pointer-Event sowie das Auslesen, auf welchen Koordinaten der Finger die Touchfläche verläßt. Mit der Maus auf dem Desktop-Rechner wird Swipe als Bewegung mit dem Scrollrad umgesetzt.
<div class="result"></div> <div class="swipeDetector lock-screen"></div>
1️⃣ Auf dem Touchscreen entscheiden zwei Events durch ihre jeweiligen Positionen, in welche Richtung der Swipe führt: touchstart und touchend.
const el = document.querySelector(".swipeDetector");
const result = document.querySelector(".result");
// Einstellungen
const BASE_THRESHOLD = 50;
const FAST_THRESHOLD = 20;
const FLICK_TIME = 200; // ms
// ==========================
// 1️⃣ TOUCH (Finger)
// ==========================
let touchStartX = 0;
let touchStartTime = 0;
el.addEventListener("touchstart", (evt) => {
const t = evt.touches[0];
touchStartX = t.clientX;
touchStartTime = Date.now();
}, { passive: true });
el.addEventListener("touchend", (evt) => {
const t = evt.changedTouches[0];
const diff = t.clientX - touchStartX;
const duration = Date.now() - touchStartTime;
handleSwipe(diff, duration);
});
2️⃣ Das Scrollrad entscheidet über die Richtung des Wischens oder Swipe: wheel-Event.
// ==========================
// 2️⃣ WHEEL (Maus / Trackpad)
// ==========================
let wheelAccum = 0;
let wheelStartTime = 0;
let wheelTimeout;
let lastTrigger = 0;
const COOLDOWN = 200; // ms zwischen Swipes
el.addEventListener("wheel", (evt) => {
evt.preventDefault();
const now = Date.now();
if (now - lastTrigger < COOLDOWN) return;
const delta = evt.deltaX || evt.deltaY;
// 👉 sofort reagieren bei ausreichend starkem Impuls
if (Math.abs(delta) > 15) {
handleSwipe(delta, 50); // kurze Dauer = schneller Swipe
lastTrigger = now;
}
}, { passive: false });
3️⃣Sowohl touch-Events als auch wheel liefern die Differenz in der horizontalen Richtung des Swipes.
// 3️⃣ zentrale Swipe-Auswertung
function handleSwipe(diff, duration = 300) {
const threshold = duration < FLICK_TIME ? FAST_THRESHOLD : BASE_THRESHOLD;
if (Math.abs(diff) < threshold) return;
if (diff < 0) {
result.textContent = "Swipe nach Links";
el.style.backgroundColor = "cornflowerblue";
} else {
result.textContent = "Swipe nach Rechts";
el.style.backgroundColor = "salmon";
}
}
Swipe mit scroll-snap und etwas Javascript
Dank CSS Scroll-Snap entsteht die sauberste Lösung: Echtes Swipe-Verhalten ohne Drag-Simulation, weil der Browser das Scrollen übernimmt. Javascript reagiert nur für die Anzeigen-Buttons. Das Ergebnis ist ein weiches Swipe, das sowohl auf dem Touchscreen als auch auf dem Monitor funktioniert (Drag, Scrollrad, Trackpad).
function initGallery() {
const gallery = document.getElementById("gallery");
const dotsContainer = document.getElementById("dots");
if (!gallery || !dotsContainer) {
console.error("Gallery oder Dots nicht gefunden!");
return;
}
const slides = gallery.querySelectorAll("img");
if (slides.length === 0) {
console.error("Keine Bilder gefunden!");
return;
}
let currentIndex = 0;
// =========================
// 1️⃣ DOTS ERZEUGEN
// =========================
slides.forEach((_, index) => {
const dot = document.createElement("button");
dot.addEventListener("click", () => {
goToSlide(index);
});
dotsContainer.appendChild(dot);
});
// =========================
// 2️⃣ DOT AKTUALISIEREN
// =========================
function setActiveDot(index) {
const dots = dotsContainer.querySelectorAll("button");
dots.forEach(dot => dot.classList.remove("active"));
if (dots[index]) dots[index].classList.add("active");
}
// =========================
// 3️⃣ ZU SLIDE SPRINGEN
// =========================
function goToSlide(index) {
gallery.scrollTo({
left: index * gallery.clientWidth,
behavior: "smooth"
});
}
// =========================
// 4️⃣ SCROLL → INDEX
// =========================
gallery.addEventListener("scroll", () => {
const index = Math.round(gallery.scrollLeft / gallery.clientWidth);
if (index !== currentIndex) {
currentIndex = index;
setActiveDot(currentIndex);
}
});
// =========================
// 5️⃣ DESKTOP DRAG
// =========================
let isDown = false;
let startX;
let scrollLeft;
gallery.addEventListener("mousedown", (e) => {
isDown = true;
gallery.classList.add("dragging");
startX = e.pageX - gallery.offsetLeft;
scrollLeft = gallery.scrollLeft;
});
gallery.addEventListener("mouseleave", () => {
isDown = false;
gallery.classList.remove("dragging");
});
gallery.addEventListener("mouseup", () => {
isDown = false;
gallery.classList.remove("dragging");
});
gallery.addEventListener("mousemove", (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - gallery.offsetLeft;
const walk = (x - startX) * 1.5;
gallery.scrollLeft = scrollLeft - walk;
});
// =========================
// 6️⃣ INIT
// =========================
setActiveDot(0);
}
/* START */
document.addEventListener("DOMContentLoaded", initGallery);