Wie kann ich eine jQuery-Benutzeroberfläche für den Touchscreen 'draggable ()' div draggable machen?

112

Ich habe eine jQuery-Benutzeroberfläche draggable(), die in Firefox und Chrome funktioniert. Das Konzept der Benutzeroberfläche besteht im Wesentlichen aus einem Klick, um ein Element vom Typ "Post-It" zu erstellen.

Grundsätzlich klicke oder tippe ich auf div#everything(100% hoch und breit), um auf Klicks zu warten, und ein Eingabetextbereich wird angezeigt. Sie fügen Text hinzu und speichern ihn dann, wenn Sie fertig sind. Sie können dieses Element verschieben. Das funktioniert in normalen Browsern, aber auf einem iPad, mit dem ich testen kann, kann ich die Elemente nicht verschieben. Wenn ich zum Auswählen berühre (es wird dann leicht gedimmt), kann ich es nicht ziehen. Es wird überhaupt nicht nach links oder rechts gezogen. Ich kann nach oben oder unten ziehen, aber ich ziehe nicht die Person, sondern divdie gesamte Webseite.

Hier ist der Code, den ich zum Erfassen von Klicks verwende:

$('#everything').bind('click', function(e){
    var elem = document.createElement('DIV');
    STATE.top = e.pageY;
    STATE.left = e.pageX;
    var e = $(elem).css({
        top: STATE.top,
        left: STATE.left
    }).html('<textarea></textarea>')
    .addClass('instance')
    .bind('click', function(event){
        return false;
    });
    $(this).append(e);
});

Und hier ist der Code, mit dem ich die Notiz "speichere" und das Eingabediv nur in ein Anzeigediv verwandle:

$('textarea').live('mouseleave', function(){
    var val = jQuery.trim($(this).val());
    STATE.content = val;
    if (val == '') {
        $(this).parent().remove();
    } else {
        var div  = $(this).parent();
        div.text(val).css({
            height: '30px'
        });
        STATE.height = 30;
        if ( div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight ) {
            while (div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight) {
                var h = div.height() + 10;
                STATE.height = h;
                div.css({
                    height: (h) + 'px'
                });     // element just got scrollbars
            }
        }
        STATE.guid = uniqueID()
        div.addClass('savedNote').attr('id', STATE.guid).draggable({
            stop: function() {
                var offset = $(this).offset();
                STATE.guid = $(this).attr('id');
                STATE.top = offset.top;
                STATE.left = offset.left;
                STATE.content = $(this).text();
                STATE.height = $(this).height();
                STATE.save();
            }
        });
        STATE.save();
        $(this).remove();
    }
});

Und ich habe diesen Code, wenn ich die Seite für gespeicherte Notizen lade:

$('.savedNote').draggable({
    stop: function() {
        STATE.guid = $(this).attr('id');
        var offset = $(this).offset();
        STATE.top = offset.top;
        STATE.left = offset.left;
        STATE.content = $(this).text();
        STATE.height = $(this).height();
        STATE.save();
    }
});

Mein STATEObjekt behandelt das Speichern der Notizen.

Onload, das ist der gesamte HTML-Body:

<body> 
    <div id="everything"></div> 
<div class="instance savedNote" id="iddd1b0969-c634-8876-75a9-b274ff87186b" style="top:134px;left:715px;height:30px;">Whatever dude</div> 
<div class="instance savedNote" id="id8a129f06-7d0c-3cb3-9212-0f38a8445700" style="top:131px;left:347px;height:30px;">Appointment 11:45am</div> 
<div class="instance savedNote" id="ide92e3d13-afe8-79d7-bc03-818d4c7a471f" style="top:144px;left:65px;height:80px;">What do you think of a board where you can add writing as much as possible?</div> 
<div class="instance savedNote" id="idef7fe420-4c19-cfec-36b6-272f1e9b5df5" style="top:301px;left:534px;height:30px;">This was submitted</div> 
<div class="instance savedNote" id="id93b3b56f-5e23-1bd1-ddc1-9be41f1efb44" style="top:390px;left:217px;height:30px;">Hello world from iPad.</div> 

</body>

Meine Frage lautet also wirklich: Wie kann ich diese Funktion auf dem iPad verbessern?

Ich bin nicht auf die jQuery-Benutzeroberfläche eingestellt. Ich frage mich, ob ich mit der jQuery-Benutzeroberfläche oder jQuery etwas falsch mache oder ob es möglicherweise bessere Frameworks für plattformübergreifende / abwärtskompatible draggable () -Elemente gibt Arbeit für Touchscreen-Benutzeroberflächen.

Allgemeinere Kommentare zum Schreiben solcher UI-Komponenten sind ebenfalls willkommen.

Vielen Dank!


UPDATE: Ich konnte dies einfach mit meinem jQuery UI- draggable()Aufruf verketten und die richtige Draggability auf dem iPad erhalten!

.touch({
    animate: false,
    sticky: false,
    dragx: true,
    dragy: true,
    rotate: false,
    resort: true,
    scale: false
});

Das jQuery Touch Plugin hat es geschafft!

artlung
quelle
1
Ich bin neugierig auf etwas: Kannst du das Div mit zwei oder drei Fingern herumziehen? Ich weiß, dass Sie manchmal mehrere Finger verwenden müssen, um eingebettete Inhalte in Mobile Safari zu scrollen, sodass dies für "ziehbare" Inhalte möglicherweise dasselbe ist.
Walter Mundt
Walter Mundt danke! Ich habe keine Variationen von Fingern ausprobiert, ich werde es versuchen, wenn ich es in meine Hände bekomme!
Artlung
1
Zwei oder drei Finger verhinderten tatsächlich, dass die "ganze Seite" versehentlich gescrollt wurde, nahmen jedoch keine Änderung für das Dragable vor.
Artlung
Diese Technik schien bei mir leider nicht zu funktionieren. :(
Blaster
@blaster Sie müssen einige der anderen Antworten für andere mögliche Lösungen
suchen

Antworten:

138

Nachdem ich viele Stunden verschwendet hatte, stieß ich darauf!

jquery-ui-touch-punsch

Tap-Ereignisse werden als Klickereignisse übersetzt. Denken Sie daran, das Skript nach jquery zu laden.

Ich habe das auf dem iPad und iPhone zum Laufen gebracht

$('#movable').draggable({containment: "parent"});
Strg-Alt-Dileep
quelle
2
Diese Lösung funktioniert großartig, eine andere Antwort, die ich müde war, war
fehlerhaft
Ein kleiner Tipp: Funktioniert hervorragend, obwohl, wenn das ziehbare Element mit Ebenen wie ein Bild mit einer Maske darüber bedeckt ist, kein Ziehen aktiviert ist, sondern die Lösung darin besteht, Zeigerereignisse hinzuzufügen: keine; auf den obersten Schichten.
Adler
Dies ist eine großartige und einfache Lösung. Verwenden Sie einfach das Plugin und arbeiten Sie weiter mit der JQuery-Draggable-Funktion. Perfekt danke!
Fast ein Anfänger
Dadurch werden anklickbare Elemente in der ziehbaren Datei verhindert.
Abdul Sadik Yalcin
61

Achtung: Diese Antwort wurde 2010 geschrieben und die Technologie bewegt sich schnell. Eine neuere Lösung finden Sie in der Antwort von @ ctrl-alt-dileep unten .


Abhängig von Ihren Anforderungen möchten Sie möglicherweise das jQuery Touch-Plugin ausprobieren . Sie können ein Beispiel versuchen hier . Das Ziehen auf meinem iPhone funktioniert einwandfrei, während das Ziehen von jQuery UI nicht funktioniert.

Alternativ können Sie dieses Plugin ausprobieren. Möglicherweise müssen Sie jedoch Ihre eigene ziehbare Funktion schreiben.

Als Nebenbemerkung: Ob Sie es glauben oder nicht, wir hören immer mehr Gerüchte darüber, wie Touch-Geräte wie das iPad und das iPhone Probleme sowohl für Websites verursachen, die Hover- / Onmouseover-Funktionen als auch ziehbare Inhalte verwenden.

Wenn Sie an der zugrunde liegenden Lösung dafür interessiert sind, müssen Sie drei neue JavaScript-Ereignisse verwenden. ontouchstart, ontouchmove und ontouchend. Apple hat tatsächlich einen Artikel über ihre Verwendung geschrieben, den Sie hier finden . Ein vereinfachtes Beispiel finden Sie hier . Diese Ereignisse werden in beiden Plugins verwendet, mit denen ich verlinkt habe.

vonconrad
quelle
2
Sehr toll! Alles was ich tun musste war .touch({ animate: false, sticky: false, dragx: true, dragy: true, rotate: false, resort: true, scale: false });mich an meinen bestehenden draggable()Anruf zu binden und es funktioniert ein Vergnügen! Ich muss noch alle Ereignisse ausarbeiten, mit denen ich mich befassen möchte, um den Workflow richtig zu machen, aber das jQuery-Touch-Plugin hat es geschafft!
Artlung
4
Das Plugin scheint auf jquery.com nicht mehr verfügbar zu sein. Sie finden das Javascript immer noch hier manifestinteractive.com/iphone/touch/js/jquery.touch.js
bjelli
1
Heh, jetzt fehlt das Plugin auch auf manifestinteractive.com. Versuchen Sie dies: plugins.jquery.com/files/jquery.touch.js.txt
Ian Hunter
5
Diese Antwort ist nicht mehr gültig. Eine Antwort für 2012 finden Sie in der Antwort von @ ctrl-alt-dileep unten (jquery-ui-touch-punsch)
bjelli
1
@bjelli Danke, dass du darauf hingewiesen hast. Ich habe meine Antwort mit einer Warnung aktualisiert. :)
vonconrad
24

Dieses Projekt sollte hilfreich sein - ordnet Berührungsereignisse so zu, dass sie auf Ereignisse klicken, sodass die jQuery-Benutzeroberfläche ohne Änderungen auf iPad und iPhone funktioniert. Fügen Sie einfach das JS zu einem vorhandenen Projekt hinzu.

http://code.google.com/p/jquery-ui-for-ipad-and-iphone/

Steve
quelle
7

jQuery ui 1.9 wird dies für Sie erledigen. Hier ist eine Demo des Pre:

https://dl.dropbox.com/u/3872624/lab/touch/index.html

Nehmen Sie einfach die Datei jquery.mouse.ui.js heraus, stecken Sie sie unter die jQuery-UI-Datei, die Sie laden, und das ist alles, was Sie tun müssen! Funktioniert auch zum Sortieren.

Dieser Code funktioniert hervorragend für mich, aber wenn Sie Fehler erhalten, finden Sie hier eine aktualisierte Version von jquery.mouse.ui.js:

Jquery-ui sortable funktioniert nicht auf Touch-Geräten, die auf Android oder IOS basieren

das Mittelweg
quelle
3
Das ist großartig, sie haben es mit dieser 1.9 zu tun. FWIW, ich habe festgestellt, dass die Version des Codes in dieser Demo Fehler enthält und nicht so gut funktioniert. Jemand hat eine korrektere Version zu dieser Frage gepostet: stackoverflow.com/questions/6745098/… , die für mich besser funktioniert.
Asgeo1
Ich habe meine Antwort aktualisiert, um dies zu beheben. Ich habe noch keine Fehler in meinem Anwendungsfall mit dem Original erhalten.
Thatmiddleway
1
Dropbox-Link ist ausgefallen.
BerggreenDK
2

Ich hatte gestern mit einem ähnlichen Problem zu kämpfen. Ich hatte bereits eine "funktionierende" Lösung mit jQuery UI's Draggable zusammen mit jQuery Touch Punch, die in anderen Antworten erwähnt werden. Die Verwendung dieser Methode verursachte jedoch bei einigen Android-Geräten seltsame Fehler. Daher habe ich beschlossen, ein kleines jQuery-Plugin zu schreiben, mit dem HTML-Elemente mithilfe von Berührungsereignissen ziehbar gemacht werden können, anstatt eine Methode zu verwenden, die gefälschte Mausereignisse emuliert.

Das Ergebnis ist jQuery Draggable Touch , ein einfaches jQuery-Plugin zum Ziehen von Elementen, dessen Hauptziel Touch-Geräte sind, indem Touch-Ereignisse (wie Touchstart, Touchmove, Touchend usw.) verwendet werden. Es gibt immer noch einen Fallback, der Mausereignisse verwendet, wenn der Browser / das Gerät keine Berührungsereignisse unterstützt.

hey Mann
quelle
Hallo Heyman, das ist gute Arbeit. Danke, dass du es geteilt hast. Funktioniert es auch für jQuery, dessen Größe geändert werden kann?
Haris
1

Sie können versuchen, jquery.pep.js zu verwenden :

jquery.pep.js ist ein leichtes jQuery-Plugin, das jedes DOM-Element in ein ziehbares Objekt verwandelt. Es funktioniert in fast allen Browsern, von alt bis neu, von Touch bis Klick. Ich habe es entwickelt, um einem Bedarf gerecht zu werden, bei dem das Draggable von jQuery UI nicht erfüllt wurde, da es auf Touch-Geräten (ohne Hackery) nicht funktioniert hat.

Website , GitHub Link

Martynas
quelle
1
Danke @martynas, ich werde es überprüfen!
Artlung