JavaScript drag and drop und Doppelklick auf iPhone und Android
Eine Drag&Drop Funktion per JavaScript ist ja „relativ“ einfach mit mousedown, mousemove und mouseup zu lösen. Allerdings funktioniert diese Art des Drag&Drop auf dem iPhone (Ipod, IPad) und Android Handys nicht, da es dort keinen Mauszeiger gibt und somit natürlich nur move-Events ausgelöst werden können, wenn mit dem Finger über den Bildschirm gestrichen wird.
Ein weiteres Problem ist der Doppelklick, denn beim doppelten Antippen des Bildschirms wird (zumindest auf dem iPhone) das angetippte Element gezoomt. Für die oben genannten Geräte gibt es im Gegensatz zum normalen Browser auf dem PC weitere Events. Diese sind unter anderem touchstart wenn ein oder mehrere Finger das Display berühren, touchend wenn ein oder mehrere Finger wieder losgelassen werden, touchmove wenn mit dem Finger über das Display gestrichen wird.
Als Alternative für den Doppelklick bietet sich das Antippen des Multitouch-Displays mit zwei Fingern gleichzeitig an.
Natürlich könnte man nun die ganzen Aktionen für die Drag&Drop Funktion noch einmal für die touch-Events programmieren, doch es gibt eine viel simplere Lösung dafür.
Nach längerem Suchen bin ich hier fündig geworden.
Die dort vorgestellte Funktion simuliert die entsprechenden Mausevents, also ein mousedown für touchstart, ein mouseup für touchend und ein mousemove für touchmove.
Für meine Zwecke hat dies jedoch nicht ausgereicht, da ich zum einen auch den Doppelklick mit einem 2-Finger-Touch simulieren wollte und die Events nicht für alle DOM Elemente greifen sollten.
Zuerst erweitere ich das Skript um diesen Codeteil:
[pastacode lang=“javascript“ message=“JavaScript“ highlight=““ provider=“manual“]
if(event.touches && event.touches.length == 2) {
if(event.type != "touchstart") return;
type="dblclick";
} else {
// hier der bisherige switch Teil des Skripts
}
[/pastacode]
Dieser Code sorgt dafür, dass geprüft wird, mit wie vielen Fingern das Event ausgelöst wurde. Bei 2 Fingern und dem Event touchstart setze ich den Typ des zu simulierenden Mausevents auf dblclick. Nur in den sonstigen Fällen werden die anderen Events bearbeitet.
Als zweite Erweiterung möchte ich, dass das Event nur für bestimmte Elemente greift. Hierzu erweitere ich den Code unterhalb des Switch Blocks:
[pastacode lang=“javascript“ message=“JavaScript“ highlight=““ provider=“manual“]
if(!first.target) return; // nur wenn das Event ein Zielelement hatte
var tryNode = first.target; // Zielelement speichern
if(tryNode.nodeName != 'DIV' || !tryNode.id) return;
// nur auf elemente des Typs DIV anwenden und auch nur, wenn diese eine id haben
[/pastacode]
Die Einschränkungen könnte man natürlich mit Hilfe von jQuery noch viel umfangreicher gestalten, in dem man zum Beispiel $(tryNode).hasClass(‚meineTestklasse‘) statt des nodeNames überprüft.
Hier noch einmal der gesamte Code im Überblick:
[pastacode lang=“javascript“ message=“JavaScript“ highlight=““ provider=“manual“]
function touchHandler(event) {
var touches = event.changedTouches;
var first = touches[0];
var type = '';
if(event.touches && event.touches.length == 2) {
if(event.type != "touchstart") return;
type="dblclick";
} else {
switch(event.type) {
case "touchstart":
type = "mousedown";
break;
case "touchmove":
type="mousemove";
break;
case "touchend":
type="mouseup";
break;
default:
return;
}
}
if(!first.target) return;
var tryNode = first.target;
if(tryNode.nodeName != 'DIV' || !tryNode.id) return;
event.preventDefault();
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0, null);
tryNode.dispatchEvent(simulatedEvent);
}
document.addEventListener("touchstart", touchHandler, true);
document.addEventListener("touchmove", touchHandler, true);
document.addEventListener("touchend", touchHandler, true);
document.addEventListener("touchcancel", touchHandler, true);
[/pastacode]
Servus…
Ist ja alles schön und gut, aber wo soll ich das ganze denn hintippen in meinem iphone?
erxtra app oder direkt im safari?
Daniel
Hallo Daniel,
ich glaube du hast da etwas komplett missverstanden. Es handelt sich um einen Artikel für Seitenbetreiber, die auf ihren Seiten den Besuchern diese Funktion anbieten möchten.