2 Reaktionen

JavaScript drag and drop und Doppelklick auf iPhone und Android

Geschätzte Lesedauer:

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]

Dieser Artikel wurde von Marius Burkard verfasst.

Marius Burkard ist Diplom-Wirtschaftsinformatiker und arbeitet seit 2006 als selbstständiger Software-Entwickler und Linux-Server-Administrator mit der Firma pixcept KG. Er ist unter anderem mitverantwortlich für die Projekte Was-lese-ich.de und ISPProtect.

2 Kommentare - bis jetzt!

Eigenen Kommentar verfassen
  1. Daniel
    schrieb am :

    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

  2. schrieb am :

    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.

Und jetzt du! Deine Meinung?

Erforderliche Felder sind mit einem Asterisk (*) gekennzeichnet. Die E-Mail-Adresse wird nicht veröffentlicht.
  1. Nach Absenden des Kommentar-Formulars erfolgt eine Verarbeitung der von Ihnen eingegebenen personenbezogenen Daten durch den datenschutzrechtlich Verantwortlichen zum Zweck der Bearbeitung Ihrer Anfrage auf Grundlage Ihrer durch das Absenden des Formulars erteilten Einwilligung.
    Weitere Informationen