Come posso rendere trascinabile un div dell'interfaccia utente jQuery per il touchscreen?


112

Ho un'interfaccia utente jQuery draggable()che funziona in Firefox e Chrome. Il concetto di interfaccia utente è fondamentalmente fare clic per creare un elemento di tipo "post-it".

Fondamentalmente, faccio clic o tocco div#everything(100% in alto e in largo) che ascolta i clic e viene visualizzata un'area di testo di input. Aggiungi del testo e poi quando hai finito lo salva. Puoi trascinare questo elemento in giro. Funziona su browser normali, ma su un iPad con cui posso testare non posso trascinare gli elementi in giro. Se tocco per selezionare (si attenua leggermente), non posso quindi trascinarlo. Non trascinerà affatto a sinistra oa destra. Io posso trascinare verso l'alto o verso il basso, ma non sto trascinando l'individuo div, sto trascinando l'intera pagina web.

Quindi ecco il codice che utilizzo per acquisire i clic:

$('#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);
});

Ed ecco il codice che uso per "salvare" la nota e trasformare il div di input in un div di visualizzazione:

$('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();
    }
});

E ho questo codice quando carico la pagina per le note salvate:

$('.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();
    }
});

Il mio STATEoggetto gestisce il salvataggio delle note.

Onload, questo è l'intero corpo html:

<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>

Quindi, la mia domanda è davvero: come posso farlo funzionare meglio su iPad?

Non sono impostato su jQuery UI, mi chiedo se questo sia qualcosa che sto facendo di sbagliato con jQuery UI, o jQuery, o se potrebbero esserci framework migliori per creare elementi trascinabili () compatibili multipiattaforma / all'indietro che lo faranno lavorare per le interfacce utente touchscreen.

Sarebbero graditi anche commenti più generali su come scrivere componenti dell'interfaccia utente come questo.

Grazie!


AGGIORNAMENTO: sono stato in grado di collegarlo semplicemente alla mia draggable()chiamata dell'interfaccia utente jQuery e ottenere la trascinabilità corretta su iPad!

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

Il plugin jQuery Touch ha fatto il trucco!


1
Mi incuriosisce una cosa: puoi trascinare il div in giro con due o tre dita? So che a volte devi usare più dita per scorrere i contenuti incorporati in Safari mobile, quindi potrebbe essere lo stesso per i contenuti "trascinabili".
Walter Mundt

Walter Mundt grazie! Non ho provato nessuna variazione delle dita, proverò quando lo avrò tra le mani!
artlung

1
due o tre dita in realtà impedivano lo scorrimento inavvertito della "pagina intera", ma non apportavano modifiche al trascinabile.
artlung

Questa tecnica non sembrava funzionare per me, sfortunatamente. :(
blaster

@blaster Avrai bisogno di guardare alcune delle altre risposte per altre possibili soluzioni
artlung

Risposte:


138

Dopo aver perso molte ore, mi sono imbattuto in questo!

jquery-ui-touch-punch

Traduce gli eventi di tocco come eventi di clic. Ricordati di caricare lo script dopo jquery.

Ho funzionato su iPad e iPhone

$('#movable').draggable({containment: "parent"});

2
Questa soluzione funziona alla grande, un'altra risposta mi stanco ero buggy e davvero non ha aiutato
musefan

Un piccolo consiglio: funziona benissimo, anche se se l'elemento trascinabile è coperto da livelli come un'immagine con una maschera sopra non viene attivato il trascinamento ma la soluzione sarà l'aggiunta di eventi-puntatore: nessuno; sugli strati superiori.
Adler

Questa è un'ottima e semplice soluzione, devi solo usare il plugin e continuare a lavorare con la funzione trascinabile di JQuery. Perfetto grazie!
quasi un principiante

Ciò impedirà elementi cliccabili all'interno del trascinabile.
Abdul Sadik Yalcin

61

Attenzione: questa risposta è stata scritta nel 2010 e la tecnologia si muove rapidamente. Per una soluzione più recente, vedere la risposta di @ ctrl-alt-dileep di seguito .


A seconda delle tue esigenze, potresti provare il plugin jQuery touch ; puoi provare un esempio qui . Funziona bene per trascinare sul mio iPhone, mentre jQuery UI Draggable no.

In alternativa, puoi provare questo plugin, anche se ciò potrebbe richiedere di scrivere effettivamente la tua funzione trascinabile.

Come nota a margine: che ci crediate o no, stiamo sentendo un crescente ronzio su come i dispositivi touch come l'iPad e l'iPhone stiano causando problemi sia per i siti Web che utilizzano: funzioni hover / onmouseover e contenuti trascinabili.

Se sei interessato alla soluzione sottostante per questo, utilizza tre nuovi eventi JavaScript; ontouchstart, ontouchmove e ontouchend. Apple ha effettivamente scritto un articolo sul loro utilizzo, che puoi trovare qui . Un esempio semplificato può essere trovato qui . Questi eventi vengono utilizzati in entrambi i plugin a cui mi sono collegato.


2
Super fantastico! Tutto quello che dovevo fare era collegare la .touch({ animate: false, sticky: false, dragx: true, dragy: true, rotate: false, resort: true, scale: false });mia draggable()chiamata esistente e funziona a meraviglia! Devo ancora elaborare tutti gli eventi che voglio affrontare per ottenere il flusso di lavoro giusto, ma il plugin jQuery touch ha fatto il trucco!
artlung

4
il plugin non sembra più essere disponibile su jquery.com. puoi ancora trovare il javascript qui manifestinteractive.com/iphone/touch/js/jquery.touch.js
bjelli

1
Eh, ora manca il plugin anche da manifestinteractive.com. Prova questo: plugins.jquery.com/files/jquery.touch.js.txt
Ian Hunter

5
questa risposta non è più valida. vedere la risposta di @ ctrl-alt-dileep di seguito (jquery-ui-touch-punch) per una risposta del 2012
bjelli

1
@bjelli Grazie per averlo fatto notare. Ho aggiornato la mia risposta con un avviso. :)
vonconrad


7

jQuery ui 1.9 si prenderà cura di questo per te. Ecco una demo del pre:

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

Prendi il jquery.mouse.ui.js, incollalo sotto il file jQuery ui che stai caricando, e questo è tutto ciò che dovresti fare! Funziona anche per ordinabili.

Questo codice funziona alla grande per me, ma se ricevi errori, una versione aggiornata di jquery.mouse.ui.js può essere trovata qui:

Jquery-ui ordinabile non funziona su dispositivi touch basati su Android o IOS


3
È fantastico che abbiano a che fare con questo 1.9. FWIW, ho scoperto che la versione del codice in quella demo conteneva dei bug e non funzionava bene. Qualcuno ha pubblicato una versione più corretta su questa domanda: stackoverflow.com/questions/6745098/… che funziona meglio per me.
asgeo1

Ho aggiornato la mia risposta per affrontare questo problema. Non ho ancora ricevuto errori nel mio caso d'uso con l'originale.
thatmiddleway

1
Il link Dropbox è inattivo.
BerggreenDK


2

Ieri stavo lottando con un problema simile. Avevo già una soluzione "funzionante" utilizzando jQuery UI trascinabile insieme a jQuery Touch Punch, che sono menzionati in altre risposte. Tuttavia, l'utilizzo di questo metodo stava causando strani bug in alcuni dispositivi Android per me, e quindi ho deciso di scrivere un piccolo plugin jQuery che può rendere gli elementi HTML trascinabili utilizzando eventi touch invece di utilizzare un metodo che emula eventi mouse falsi.

Il risultato di ciò è jQuery Draggable Touch che è un semplice plug-in jQuery per rendere gli elementi trascinabili, che ha dispositivi touch come obiettivo principale utilizzando eventi touch (come touchstart, touchmove, touchend, ecc.). Ha ancora un fallback che utilizza gli eventi del mouse se il browser / dispositivo non supporta gli eventi di tocco.


Ciao Heyman, è un bel lavoro. Grazie per averlo condiviso. Funzionerà anche per jQuery ridimensionabile?
Haris

1

Puoi provare a utilizzare jquery.pep.js :

jquery.pep.js è un plugin jQuery leggero che trasforma qualsiasi elemento DOM in un oggetto trascinabile. Funziona su quasi tutti i browser, dal vecchio al nuovo, dal tocco al clic. L'ho costruito per soddisfare un'esigenza in cui il trascinamento dell'interfaccia utente di jQuery non era soddisfacente, dal momento che non funzionava su dispositivi touch (senza alcuni hacker).

Sito Web , collegamento GitHub


1
Grazie @martynas, controllerò!
artlung
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.