Trascinamento della selezione JavaScript per dispositivi touch [chiuso]


120

Sto cercando un plug-in drag & DROP che funzioni su dispositivi touch.

Vorrei funzionalità simili al plugin jQuery UI che consente elementi "droppabili".

Il plugin jqtouch supporta il trascinamento, ma non il rilascio.

Ecco il drag & drop che supporta solo iPhone / iPad.

Qualcuno può indicarmi la direzione di un plug-in drag & drop che funziona su Android / ios?

... Oppure potrebbe essere possibile aggiornare il plugin jqtouch per la droppabilità, funziona già su Andriod e IOS.

Grazie!


1
È in corso, ma non so quali dispositivi lo supportano: questo plugins.jquery.com/project/mobiledraganddrop ... hai controllato le librerie jQuerymobile.com? Ho trovato anche questa domanda SO duplicato: stackoverflow.com/questions/3172100/...
iivel

Grazie. Sì, mobiledraganddrop supporta solo il click and drop sui dispositivi mobili. Non sono riuscito a trovare nulla su jQuerymobile.com. L'altra domanda ha una risposta già contrassegnata come corretta che fa riferimento a sencha.com/products/touch che ha una licenza di origine limitata.
joe

Sono curioso di vederne uno che funzioni su browser mobili e desktop.
Lime

Risposte:


258

Puoi utilizzare l'interfaccia utente di Jquery per il trascinamento della selezione con una libreria aggiuntiva che traduce gli eventi del mouse in tocco, che è ciò di cui hai bisogno, la libreria che consiglio è https://github.com/furf/jquery-ui-touch-punch , con questo il tuo drag and drop dall'interfaccia utente di Jquery dovrebbe funzionare su dispositivi touch

oppure puoi usare questo codice che sto usando, converte anche gli eventi del mouse in tocco e funziona come per magia.

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({
        touchstart: "mousedown",
        touchmove: "mousemove",
        touchend: "mouseup"
    }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() {
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);
}

E nel tuo document.ready chiama semplicemente la funzione init ()

codice trovato da qui


11
Grazie, sul mio dispositivo Android è ora possibile trascinare le cose. Tuttavia, l'evento clic non viene più attivato quando si fa clic su di esso. Qualche idea su come risolverlo?
John Landheer

9
Nota: poiché l'ascoltatore di eventi è registrato per l'intero documento, questa soluzione disabilita anche lo scorrimento sul mio Nexus S ...
Ethan Leroy

29
Grazie per aver condiviso questo. Tuttavia, dovresti dare credito all'autore originale del codice che hai pubblicato. ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
undefined

2
@JohnLandheer Ho risolto il problema allegando i listener di eventi solo agli oggetti che volevo trascinabili,document.getElementById('draggableContainer').addEventListener(...
chiliNUT

1
Il tocco è fantastico. Una di quelle cose "funziona e basta". Purtroppo, non supporta il dual-touch ... cosa che mi piacerebbe vedere.
DA.

21

Per chiunque desideri utilizzarlo e mantenere la funzionalità 'clic' (come menziona John Landheer nel suo commento), puoi farlo con solo un paio di modifiche:

Aggiungi un paio di globali:

var clickms = 100;
var lastTouchDown = -1;

Quindi modifica l'istruzione switch dall'originale a questa:

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}

Potresti voler adattare i "clic" ai tuoi gusti. Fondamentalmente sta solo cercando un "touchstart" seguito rapidamente da un "touchend" per simulare un clic.


@EZ Hart - potresti farmi sapere dove mettere il tuo codice nel codice sopra indicato per abilitare l'evento click ???
Valay

1
@ ChakoDesai - Il codice nella risposta è stato modificato pesantemente da quando ho scritto la mia risposta. Scopri stackoverflow.com/posts/6362527/revisions e un'occhiata al codice dal 30 giugno 2011; la mia risposta avrà molto più senso sulla base di quella versione.
EZ Hart

@EZ Hart - Ho aggiornato il mio codice dall'URL fornito. Ma perché a volte clickfunziona ea volte no ???
Valay

@ ChakoDesai - Senza vedere il tuo codice non posso esserne sicuro. Potresti voler aprire una nuova domanda per questo.
EZ Hart

Una risposta aggiornata per far funzionare il codice di cui sopra con gli eventi click può essere trovato qui: stackoverflow.com/questions/28218888/...
Blunderfest

12

Grazie per i codici sopra! - Ho provato diverse opzioni e questo era il biglietto. Ho avuto problemi in quanto preventDefault impediva lo scorrimento sull'ipad - Ora sto testando gli elementi trascinabili e finora funziona alla grande.

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}

Hai provato questo in Windows Phone? O qualcosa di diverso dall'iPhone? Dall'esperienza passata, sembra funzionare perfettamente su iPhone / iPad, ma non funziona bene su altri dispositivi, specialmente su Windows Phone.
quasi un principiante il

10

Avevo la stessa soluzione della risposta di gregpress , ma i miei elementi trascinabili utilizzavano una classe invece di un ID. Sembra funzionare.

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}

4
Il fatto che tu abbia semplicemente utilizzato un selettore diverso non garantisce che sia una risposta separata, ma invece avresti dovuto commentare la risposta di @ gregpress.
bPratik

2
@bPratik a meno che non volesse la formattazione più piacevole fornita da una risposta e il fatto che abbia fornito un intero esempio di codice garantisce una risposta separata. Avrebbe dovuto lasciare un commento che si collega alla sua risposta però ...
drzaus

8

Vecchio thread lo so .......

Il problema con la risposta di @ryuutatsuo è che blocca anche qualsiasi input o altro elemento che deve reagire ai "clic" (ad esempio gli input), quindi ho scritto questa soluzione. Questa soluzione ha reso possibile utilizzare qualsiasi libreria drag and drop esistente basata su eventi mousedown, mousemove e mouseup su qualsiasi dispositivo touch (o cumputer). Questa è anche una soluzione cross-browser.

Ho provato su diversi dispositivi e funziona velocemente (in combinazione con la funzione di trascinamento della selezione di ThreeDubMedia (vedi anche http://threedubmedia.com/code/event/drag )). È una soluzione jQuery quindi puoi usarla solo con le librerie jQuery. Ho usato jQuery 1.5.1 perché alcune funzioni più recenti non funzionano correttamente con IE9 e versioni successive (non testate con le versioni più recenti di jQuery).

Prima di aggiungere qualsiasi operazione di trascinamento della selezione a un evento, devi prima chiamare questa funzione :

simulateTouchEvents(<object>);

È inoltre possibile bloccare tutti i componenti / figli per l'input o per accelerare la gestione degli eventi utilizzando la seguente sintassi:

simulateTouchEvents(<object>, true); // ignore events on childs

Ecco il codice che ho scritto. Ho usato dei simpatici trucchi per velocizzare la valutazione (vedi codice).

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

Che cosa fa: inizialmente traduce gli eventi di tocco singolo in eventi del mouse. Controlla se un evento è causato da un elemento su / nell'elemento che deve essere trascinato. Se è un elemento di input come input, textarea ecc., Salta la traduzione, o se ad esso è collegato un evento del mouse standard, salterà anche una traduzione.

Risultato: ogni elemento su un elemento trascinabile funziona ancora.

Buona programmazione, saluti, Erwin Haantjes


quale oggetto devo passare simulateTouchEvents(<object>, true);???
Valay

Ad esempio: simulateTouchEvents ($ ('# yourid;), true); o simulateTouchEvents (document.getElementById ('yourid'), true); ecc
Codebeat

potresti per favore guardare il mio link a un'altra domanda ???
Valay

Usa threedubmedia.com/code/event/drag e disabilita lo spostamento xoy dell'elemento. Quando utilizzi il codice in questo articolo puoi "scorrere" le barre di scorrimento. Ma sappi perché vuoi farlo perché una pagina sul cellulare ha già le barre di scorrimento. Non capisci cosa vuoi farci. Successo!
Codebeat

Devo aggiungere il drag-n-drop delle colonne e lo scorrimento di entrambi. Quando attivo gli toucheventi chrome, non riesco a scorrere la tabella. Nemmeno sul cellulare.
Valay
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.