web-dev-qa-db-fra.com

Javascript drag and drop pour les appareils tactiles

Je recherche un plugin drag & DROP qui fonctionne sur les appareils tactiles.

Je voudrais une fonctionnalité similaire à celle de plugin jQuery UI qui autorise les éléments "droppable".

Le plugin jqtouch supporte le glisser, mais pas le déposer.

Ici est un glisser/déposer compatible uniquement avec iPhone/iPad.

Quelqu'un peut-il m'indiquer un plugin glisser-déposer qui fonctionne sous Android/iOS?

... ou il est peut-être possible de mettre à jour le plug-in jqtouch afin de le rendre utilisable, il tourne déjà sur Andriod et IOS.

Merci!

115
joe

Vous pouvez utiliser l'interface utilisateur de Jquery pour le glisser-déposer avec une bibliothèque supplémentaire qui traduit les événements de la souris en contact, ce dont vous avez besoin. La bibliothèque que je recommande est https://github.com/furf/jquery-ui-touch -punch , avec cela votre glisser-déposer de Jquery UI devrait fonctionner sur les appareils tactiles

ou vous pouvez utiliser ce code que j'utilise, il convertit également les événements de la souris en contact et fonctionne comme par magie.

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);
}

Et dans votre document, appelez simplement la fonction init ()

code trouvé à partir de Ici

254
ryuutatsuo

Pour ceux qui cherchent à utiliser ceci et à garder la fonctionnalité 'click' (comme John Landheer le mentionne dans son commentaire), vous pouvez le faire avec juste quelques modifications:

Ajoutez quelques globals:

var clickms = 100;
var lastTouchDown = -1;

Puis modifiez l'instruction switch de l'original en ceci:

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

Vous voudrez peut-être ajuster les "clics" à vos goûts. Fondamentalement, il s’agit simplement de rechercher un "touchstart" suivi rapidement d’un "touchend" pour simuler un clic.

21
E.Z. Hart

Merci pour les codes ci-dessus! - J'ai essayé plusieurs options et c'était le billet. J'avais des problèmes avec preventDefault qui empêchait le défilement sur l'ipad - je teste maintenant les éléments pouvant être déplacés et cela fonctionne très bien jusqu'à présent.

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

J'avais la même solution que gregpress answer , mais mes éléments déplaçables utilisaient une classe au lieu d'un identifiant. Cela semble fonctionner.

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

Vieux fil je sais .......

Le problème avec la réponse de @ryuutatsuo est qu'il bloque également toute entrée ou tout autre élément devant réagir sur des "clics" (par exemple des entrées), c'est pourquoi j'ai écrit cette solution. Cette solution a rendu possible l’utilisation de toute bibliothèque existante de glisser-déposer basée sur les événements mousedown, mousemove et mouseup sur n’importe quel périphérique tactile (ou cumputer). C'est aussi une solution multi-navigateur.

J'ai testé plusieurs appareils et cela fonctionne rapidement (en combinaison avec la fonction glisser-déposer de ThreeDubMedia (voir aussi http://threedubmedia.com/code/event/drag )). C'est une solution jQuery, vous ne pouvez donc l'utiliser qu'avec des bibliothèques jQuery. J'ai utilisé jQuery 1.5.1 parce que certaines fonctions plus récentes ne fonctionnent pas correctement avec IE9 et les versions ultérieures (non testé avec les versions les plus récentes de jQuery).

Avant vous ajoutez une opération par glisser/déposer à un événement vous devez d'abord appeler cette fonction :

simulateTouchEvents(<object>);

Vous pouvez également bloquer tous les composants/enfants pour la saisie ou accélérer la gestion des événements en utilisant la syntaxe suivante:

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

Voici le code que j'ai écrit. J'ai utilisé quelques astuces de Nice pour accélérer l'évaluation (voir code).

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

Ce qu'il fait: Au début, il traduit les événements tactiles en événements de souris. Il vérifie si un événement est causé par un élément sur/dans l'élément qui doit être déplacé. S'il s'agit d'un élément d'entrée tel que input, textarea, etc., la traduction est ignorée ou, si un événement de souris standard y est associé, une traduction est également ignorée.

Résultat: chaque élément d'un élément déplaçable fonctionne toujours.

Codage heureux, greetz, Erwin Haantjes

8
Codebeat