2013-03-11 5 views
19

J'essaye de construire un site web où l'utilisateur peut faire glisser des éléments (un élément sur div) vers d'autres divs sur la page. Ce n'est pas une table ou autre, juste divs quelque part sur la page. Avec html5 glisser & laisser tomber ça fonctionne bien, maintenant j'essaye de le faire pour les appareils mobiles. Je peux faire glisser des objets vers des divs, les déposer et bloquer cette zone de dépôt, car un seul élément doit être dans une zone de dépôt. Je peux aussi faire glisser cet élément vers un autre div ou ailleurs sur la page (les zones droppables ne fonctionnent que si un div est abandonné) si j'ai fait une erreur mais je ne peux plus déposer un autre élément dans la div qui est vide encore.Modifier la position des divs avec jquery glisser une goutte

Comment est-ce que je peux de nouveau autoriser la chute dans ce Dropzone?

Et est-il possible de deux changer la position de deux div si l'un est traîné sur un autre?

Voici la partie pertinente de mon code:

<script type="text/javascript"> 
$ (init); 
function init() { 
    $(".dragzones").draggable({ 
     start: handleDragStart, 
     cursor: 'move', 
     revert: "invalid", 
    }); 
    $(".dropzones").droppable({ 
     drop: handleDropEvent, 
     tolerance: "touch",    
    }); 
} 
function handleDragStart (event, ui) {}  
function handleDropEvent (event, ui) { 
    $(this).droppable('disable'); 
    ui.draggable.position({of: $(this), my: 'left top', at: 'left top'}); 
    ui.draggable.draggable('option', 'revert', "invalid"); 
} 
</script> 
<body> 
<div id="alles"> 
<div class="dropzones" id="zone1"><div class="dragzones" id="drag1">Item 1</div></div> 
<div class="dropzones" id="zone2"><div class="dragzones" id="drag2">Item 2</div></div> 
<div class="dropzones" id="zone3"><div class="dragzones" id="drag3">Item 3</div></div> 
<div class="dropzones" id="zone4"><div class="dragzones" id="drag4">Item 4</div></div> 
    <div class="dropzones" id="zone11"></div> 
    <div class="dropzones" id="zone12"></div> 
    <div class="dropzones" id="zone13"></div> 
    <div class="dropzones" id="zone14"></div> 
</div> 
</body> 

EDIT: Voici la page actuellement: Drag&Drop Task

+0

Il y a beaucoup d'exemples utilisant le glisser-déposer non-html5, c'est ce que je recommanderais. – nycynik

+4

J'ai essayé l'exemple tinyurl dans Chrome et je pourrais très bien déposer des objets dans des dropzones vidées à nouveau? Qu'est-ce que je rate? –

+2

@ ink.robot nop, ça ne marche pas. Déposez un objet sur un boîtier vide. Ensuite, faites-le glisser vers l'emplacement d'origine et essayez de faire glisser un autre élément sur le boîtier vide. Tu ne peux pas. – j0k

Répondre

23

Voici un exemple de travail: http://jsfiddle.net/Gajotres/zeXuM/

Je pense que tous vos problèmes sont résolus ici.

  • activer/dropping désactiver fonctionne
  • éléments de retour ne les descend en dessous d'autres éléments
  • éléments de retour ne cache plus/les enlever
  • mieux des éléments de positionnement (il semble mieux)
  • il fonctionne sur les appareils mobiles (testé sur Android 4.1.1 Chrome et iPhone)

Voici un code jQuery utilisé:

$(document).on('pageshow', '#index', function(){  
    $(".dragzones").draggable({ 
     start: handleDragStart, 
     cursor: 'move', 
     revert: "invalid", 
    }); 
    $(".dropzones").droppable({ 
     drop: handleDropEvent, 
     tolerance: "touch",    
    }); 
}); 

function handleDragStart (event, ui) { } 

function handleDropEvent (event, ui) { 
    if (ui.draggable.element !== undefined) { 
     ui.draggable.element.droppable('enable'); 
    } 
    $(this).droppable('disable'); 
    ui.draggable.position({of: $(this),my: 'left top',at: 'left top'}); 
    ui.draggable.draggable('option', 'revert', "invalid"); 
    ui.draggable.element = $(this); 
} 

    // This is a fix for mobile devices 

/iPad|iPhone|Android/.test(navigator.userAgent) && (function($) { 

var proto = $.ui.mouse.prototype, 
_mouseInit = proto._mouseInit; 

$.extend(proto, { 
    _mouseInit: function() { 
     this.element 
     .bind("touchstart." + this.widgetName, $.proxy(this, "_touchStart")); 
     _mouseInit.apply(this, arguments); 
    }, 

    _touchStart: function(event) { 
     this.element 
     .bind("touchmove." + this.widgetName, $.proxy(this, "_touchMove")) 
     .bind("touchend." + this.widgetName, $.proxy(this, "_touchEnd")); 

     this._modifyEvent(event); 

     $(document).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse 
     this._mouseDown(event); 

     //return false;   
    }, 

    _touchMove: function(event) { 
     this._modifyEvent(event); 
     this._mouseMove(event); 
    }, 

    _touchEnd: function(event) { 
     this.element 
     .unbind("touchmove." + this.widgetName) 
     .unbind("touchend." + this.widgetName); 
     this._mouseUp(event); 
    }, 

    _modifyEvent: function(event) { 
     event.which = 1; 
     var target = event.originalEvent.targetTouches[0]; 
     event.pageX = target.clientX; 
     event.pageY = target.clientY; 
    } 

}); 

})(jQuery); 

L'auteur original d'un plug-in touchFix utilisé dans cet exemple est Oleg Slobodskoi.

1

Vous "Exemple" lien ressemble fonctionne correctement. Mais je voudrais donner une solution générique à votre problème.

Fondamentalement, vous regardez l'état de dropzone. Lorsque l'utilisateur dépose l'élément, vous vérifiez si dropzone est disponible ou non. si ce n'est pas "revert" true.

function handleDropEvent (event, ui) { 
    if ($(this).hasClass('occupied')) { 
     ui.draggable.draggable('option', 'revert', true); 
     return false; 
    } 
    $(this).append(ui.draggable); 
    ui.draggable.position({of: $(this), my: 'left top', at: 'left top'}); 
    ui.draggable.css('z-index', 0); 
    setTimeout(validateDropzones, 0); 
} 

exemple de travail complet est ici: http://jsfiddle.net/jaygiri/SRPm2/

Merci.

+0

Cela ne fonctionne pas sur les appareils mobiles (par exemple, iPad). – Omar

+0

Bien sûr, ce ne sera pas le cas. Les questions principales ressemblent à: "Comment est-ce que je peux permettre de laisser tomber dans ce Dropzone encore?" Je viens de montrer une logique pour y répondre - où nous regardons l'état de dropzone. Pour une prise en charge complète de votre application mobile jq, vous devez procéder comme suit: http://stackoverflow.com/a/8826958/647736 –

1

Ceci est aussi loin que je suis devenu:

$ (init); 
function init() { 
    $(".dragzones").draggable({ 
     start: handleDragStart, 
     cursor: 'move', 
     revert: 'invalid', 
     opacity: .5, 
    }); 
    $(".dropzones").droppable({ 
     drop: handleDropEvent, 
     tolerance: "touch", 
     out: handleDropRemove 
    }); 

    //prevents dragging to filled default droppables on start 
    $(".dropzones").each(function(){ 
    if ($(this).html().length) { 
     $(this).addClass('taken'); 
    } 
    }); 
} 



function handleDragStart (event, ui) {} 
function handleDropRemove(event, ui) { 
     //allows drop after removal 
     $(this).removeClass('taken'); 
}  
function handleDropEvent (event, ui) { 
    if ($(this).hasClass('taken')) { 
     //rejects drop if full 
     ui.draggable.draggable('option', 'revert', true); 
    } else { 
     //accepts drop if enpty 
     ui.draggable.position({of: $(this), my: 'left top', at: 'left top'}); 
     $(this).addClass('taken'); 
    } 
} 

Working Demo Here

Il y a des problèmes de couple que je suis en train de trier encore. Apparaît si le curseur touche le bas d'une zone de dépôt quand il est rempli, la fonction out est appelée. Je n'arrive pas à comprendre comment éviter cela.

+0

Cela ne fonctionne pas sur les périphériques mobiles (par exemple, iPad). – Omar

2

ÉDITÉ:

Sur chaque goutte réussie, vous pouvez enregistrer le dernier objet de goutte sur la draggable. Ainsi, lorsque le chariot se déplace vers un autre objet drop, vous pouvez activer la droppable de l'objet drop précédent.

Voir ci-dessous:

Essayez de modifier le handleDropEvent à:

function handleDropEvent(event, ui) { 
    if (ui.draggable.lastDropObject !== undefined) { 
     ui.draggable.lastDropObject.droppable('enable'); 
    } 
    var dropObject = $(this); 
    dropObject.droppable('disable'); 
    ui.draggable.position({ 
     of: $(this), 
     my: 'left top', 
     at: 'left top' 
    }); 
    ui.draggable.draggable('option', 'revert', "invalid"); 
    ui.draggable.lastDropObject = dropObject; 
} 

exemple de travail complet basé sur votre code source:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 

    <head> 
     <title>Drag & Drop with jQuery</title> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
     <meta name="title" content="" /> 
     <meta name="keywords" content="" /> 
     <meta name="description" content="" /> 
     <link href="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/Styletest.css" rel="stylesheet" type="text/css" /> 
     <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery.js"></script> 
     <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery-ui-1.8.23.custom.min.js"></script> 
     <script type="text/javascript" src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../Alle Seiten/JS/jquery.ui.touch-punch.min.js"></script> 
     <script type="text/javascript"> 
      var test; 
      $(init); 

      function init() { 
       $(".dragzones") 
        .draggable({ 
        start: handleDragStart, 
        cursor: 'move', 
        revert: "invalid" 
       }); 
       $(".dropzones") 
        .droppable({ 
        drop: handleDropEvent, 
        tolerance: "touch", 
       }); 
      }; 

      function handleDragStart(event, ui) {} 

      function handleDropEvent(event, ui) { 
       if (ui.draggable.lastDropObject !== undefined) { 
        ui.draggable.lastDropObject.droppable('enable'); 
       } 
       var dropObject = $(this); 
       dropObject.droppable('disable'); 
       ui.draggable.position({ 
        of: $(this), 
        my: 'left top', 
        at: 'left top' 
       }); 
       ui.draggable.draggable('option', 'revert', "invalid"); 
       ui.draggable.lastDropObject = dropObject; 
      } 



      function check() { 
       var i = 1; 
       var richtige = 0; 
       while (i <= 10) { 
        var j = i + 10; 
        if (document.getElementById('zone' + j) 
         .innerHTML.search('drag' + i + '"') == 27) { 
         document.getElementById('zone' + j) 
          .style.border = '2px solid green'; 
         richtige++; 
        } else { 
         document.getElementById('zone' + j) 
          .style.border = '2px solid red'; 
        } 
        i++; 
        alert(document.getElementById(zone + j) 
         .innerHTML); 
       }; 
      } 
     </script> 
    </head> 

    <body> 
     <div id="alles"> 
      <div id="hintergrundbildZuordnungsaufgaben"> 
       <img src="http://www.didaktik.physik.uni-muenchen.de/forschung/elektronenbahnen/Betaversion/Tests/../E-Feld/Bilder/Versuchsaufbau-Elektronenablenkroehre-unbeschriftet.png" width="740"> 
      </div> 
      <div class="dropzones" id="zone1"> 
       <div class="dragzones" id="drag1">Item 1</div> 
      </div> 
      <div class="dropzones" id="zone2"> 
       <div class="dragzones" id="drag2">Item 2</div> 
      </div> 
      <div class="dropzones" id="zone3"> 
       <div class="dragzones" id="drag3">Item 3</div> 
      </div> 
      <div class="dropzones" id="zone4"> 
       <div class="dragzones" id="drag4">Item 4</div> 
      </div> 
      <div class="dropzones" id="zone5"> 
       <div class="dragzones" id="drag5">Item 5</div> 
      </div> 
      <div class="dropzones" id="zone6"> 
       <div class="dragzones" id="drag6">Item 6</div> 
      </div> 
      <div class="dropzones" id="zone7"> 
       <div class="dragzones" id="drag7">Item 7</div> 
      </div> 
      <div class="dropzones" id="zone8"> 
       <div class="dragzones" id="drag8">Item 8</div> 
      </div> 
      <div class="dropzones" id="zone9"> 
       <div class="dragzones" id="drag9">Item 9</div> 
      </div> 
      <div class="dropzones" id="zone10"> 
       <div class="dragzones" id="drag10">Item 10</div> 
      </div> 
      <div class="dropzones" id="zone11"></div> 
      <div class="dropzones" id="zone12"></div> 
      <div class="dropzones" id="zone13"></div> 
      <div class="dropzones" id="zone14"></div> 
      <div class="dropzones" id="zone15"></div> 
      <div class="dropzones" id="zone16"></div> 
      <div class="dropzones" id="zone17"></div> 
      <div class="dropzones" id="zone18"></div> 
      <div class="dropzones" id="zone19"></div> 
      <div class="dropzones" id="zone20"></div> 
      <button id="check" value="Check" onclick="check()">Check</button> 
     </div> 
    </body> 

</html> 

J'espère que cela aide.

Questions connexes