2013-03-11 16 views
19

Sto provando a creare un sito Web in cui l'utente può trascinare alcuni elementi (un elemento in su div) in altre div sulla pagina. Non è un tavolo o così, solo div da qualche parte sulla pagina.Cambia posizione di div con jquery trascina una goccia

Con html5 trascinare & rilasciare funziona correttamente, ora provo a farlo per i dispositivi mobili. Posso trascinare gli oggetti su div, rilasciarli e bloccare questo dropzone, perché solo un elemento dovrebbe trovarsi in una dropzone. Posso anche trascinare questo elemento su un altro div o da qualche altra parte sulla pagina (le aree trascinabili funzionano solo la prima volta che un div viene rilasciato) se ho fatto un errore ma non posso rilasciare un altro elemento nel div che è ora vuoto ancora.

Come posso abilitare il rilascio in questo Dropzone di nuovo?

Ed è possibile modificare due posizioni di due div se si è trascinati su un altro?

Ecco la parte rilevante del mio codice:

<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: Ecco la pagina ora di lavoro: Drag&Drop Task

+0

ci sono molti esempi di trascinamento della selezione non-html5, questo è quello che consiglierei. – nycynik

+4

Ho provato l'esempio minuscolo in Chrome e potrei benissimo rilasciare nuovamente gli oggetti in dropzones vuoti? Cosa mi manca? –

+2

@ ink.robot nop, non funziona. Lascia un oggetto in una custodia vuota. Quindi trascinalo nella posizione originale e prova a trascinare un altro elemento sulla custodia vuota. Non puoi – j0k

risposta

23

Ecco un esempio di lavoro: http://jsfiddle.net/Gajotres/zeXuM/

Credo che tutti i problemi sono risolti qui.

  • abilitazione/gocciolatore disabilitazione funziona
  • elementi non corrispondente alla loro scende sotto altri elementi
  • elementi di rinvio non nasconde più lunghi/rimuoverli
  • meglio elementi di posizionamento (un aspetto migliore)
  • funziona su dispositivi mobili (testato su Android 4.1.1 Chrome e iPhone)

Ecco un codice jQuery utilizzato:

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

Autore originale di un plugin touchFix utilizzato in questo esempio è Oleg Slobodskoi.

1

collegamento È "Esempio" sembra funzionare correttamente. Ma vorrei dare una soluzione generica al tuo problema.

Fondamentalmente si guarda lo stato di dropzone. Quando l'utente lascia l'oggetto, verifichi se dropzone è disponibile o meno. se non impostato "ripristina" vero.

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

esempio di lavoro completa è qui: http://jsfiddle.net/jaygiri/SRPm2/

Grazie.

+0

Questo non funziona sui dispositivi mobili (ad esempio iPad). – Omar

+0

Certo, non lo farà. Le domande principali assomigliano a: "Come posso abilitare il rilascio in questo Dropzone di nuovo?" Ho appena mostrato una logica per rispondere - dove guardiamo lo stato di dropzone. Per il supporto completo alla tua applicazione jq per dispositivi mobili, devi eseguire questa operazione: http://stackoverflow.com/a/8826958/647736 –

1

Questo è quanto ho ottenuto:

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

Ci sono un paio di questioni che sto cercando di risolvere ancora. Sembra che il cursore colpisca il fondo di una zona di rilascio quando è riempito, viene chiamata la funzione di uscita. Non riesco a capire come prevenirlo.

+0

Questo non funziona sui dispositivi mobili (ad esempio iPad). – Omar

2

Modificato:

Su ogni goccia di successo è possibile salvare l'oggetto ultima goccia sulla trascinabile. Quindi, quando il trascinamento spostabile su un altro oggetto di rilascio, è possibile abilitare il trascinabile dell'oggetto di rilascio precedente.

vedere qui sotto:

tenta di modificare il handleDropEvent a:

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

esempio di lavoro completa in base al codice sorgente:

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

Spero che questo aiuta.

Problemi correlati