2013-03-11 45 views
19

我正在尝试构建一个网站,用户可以将一些项目(div上的一项)拖到页面上的其他div上。它不是一张桌子,只是在页面上的某个位置。用jquery更改div的位置,拖放一下

随着HTML5拖动&下降它运作良好,现在我尝试为移动设备做到这一点。我可以将项目拖到div上,将它们放在那里并阻止这个dropzone,因为只有一个元素应该放在dropzone中。我也可以将这个元素拖放到另一个div或者页面上的其他地方(如果我犯了一个错误,那么droppable区域只能在第一次放下div时工作),但是我不能在现在为空的div中放置另一个项目再次。

我该如何启用Dropzone再次放入此Dropzone?

是否有可能两个改变两个div的位置,如果一个被拖动另一个?

这里是我的代码的相关部分:

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

编辑: 这里是现在的工作页面:Drag&Drop Task

+0

有很多使用非html5拖放的例子,那就是我会推荐的。 – nycynik 2013-03-11 18:34:52

+4

我尝试过Chrome中的tinyurl示例,我可以很好地将物品放入清空的dropzones中吗?我错过了什么? – 2013-03-11 21:59:11

+2

@ ink.robot nop,它不起作用。将物品放在空箱子上。然后将其拖动到原来的位置,并尝试将其他物品拖到空的箱子上。你不能。 – j0k 2013-03-15 22:43:09

回答

23

这里有一个工作示例:http://jsfiddle.net/Gajotres/zeXuM/

我认为所有的问题都解决了这里。

  • 启用/禁用下探工程
  • 元素返回不再丢弃它们下面的其他元素
  • 元素返回不再隐藏/删除
  • 更好的元素定位(它看起来更好)
  • 它的工作原理(在Android 4.1.1 Chrome和iPhone上测试)

下面是使用的jQuery代码:

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

此示例中使用的touchFix插件的原始作者是Oleg Slobodskoi

1

你“示例”链接看起来正常工作。但我想为您的问题提供通用解决方案。

基本上你会看到dropzone的状态。当用户放弃物品时,检查是否有dropzone可用。如果没有设置“恢复”为真。

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

全部工作的例子是在这里:http://jsfiddle.net/jaygiri/SRPm2/

感谢。

+0

这不适用于移动设备(例如iPad)。 – Omar 2013-03-16 09:52:35

+0

当然,它不会。主要问题如下所示:“我怎样才能使Dropzone再次进入Dropzone?”我只是展示了一个逻辑来回答它 - 我们在哪里查看dropzone的状态。为了全面支持您的jq移动应用程序,您需要执行以下操作:http://stackoverflow.com/a/8826958/647736 – 2013-03-18 16:40:19

1

这是据我已经得到了:

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

有我想排序还是一对夫妇的问题。似乎光标在填充时是否碰到拖放区域的底部,out函数正在被调用。我似乎无法弄清楚如何防止这种情况。

+0

这不适用于移动设备(例如iPad)。 – Omar 2013-03-16 09:51:38

2

编辑:

在每一个成功的下降可以节省可拖动的最后一滴对象。因此,当可拖动对象移动到另一个对象时,您可以启用之前放置对象的可放置对象。

见下文:

尝试修改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; 
} 

全部工作示例:

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

我希望这有助于。