使用jQuery UI使可拖动元素在droppable中可排序

解决

所以我用connectWith属性稍微研究了sortable() ,发现解决方案比我想象的要简单,但是由于draggable()droppable() ,我认为它有点倒退。

这是小提琴: http : //jsfiddle.net/DKBU9/12/


原始问题如下:

这是以前的SO问题的延伸,我认为应该将其分开。

最初的问题在这里: jQuery UI – 在drop事件之后克隆droppable / sortable列表 。 它涉及重新初始化克隆元素上的droppable处理程序。

最重要的是,我试图允许从初始列表中拖动的元素在可放置列表中进行排序。

这是一个小提琴,基本上是原始问题的结果: http : //jsfiddle.net/DKBU9/7/

和所需的代码,因为SO喜欢抱怨和膨胀这些post:

HTML

 
  • foo1
  • foo2
  • foo3

JS

 $(function() { $('#draggables > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('.droppable > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('#draggables').droppable({ accept: '.droppable > li', drop: function(event, ui) { ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }); initDrop($('.droppable')); }); function initDrop($element) { $element.droppable({ accept: function(event, ui) { return true; }, drop: function(event, ui) { if($(this).hasClass('new')) { var clone = $(this).clone(); $(this).after(clone); $(this).removeClass('new'); initDrop( clone ); } ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }).sortable({ items: 'li', revert: false, update: function() { cleanUp(); } }); } function cleanUp() { $('.droppable').not('.new').each(function() { if($(this).find('li').length == 0) { $(this).remove(); } }); } 

参考问题: Jquery UI结合了可排序和可拖动

我一直试图用这个问题来解决我的问题,因为结果正是我想要实现的,特别是在接受的答案的评论中提供的最后一个小提琴,但我似乎无法弄清楚如何考虑到微小的差异,使其适应我的代码。 例如,该问题中的小提琴克隆了可拖动而不是拖动实际元素,并且与我不同的是不允许将元素拖回到初始列表中。

因此,非常感谢任何尝试为我的代码获得结果的帮助。

此外,在该示例中, accept属性被设置为返回true的函数。 这是什么原因? 这不仅仅意味着它会接受任何东西,或任何可拖动的元素?

编辑:我读了几个答案,只使用了sortable()与connectWith属性,但由于某种原因我不认为它做了我需要的,部分是因为我不希望初始列表也可以排序。 但是,单独使用sortable()似乎可以获得我正在使用的function,但我还没有调整所有事件处理程序。

看到这个小提琴

它会使项目在新列表中可以删除和排序,但不会在初始中(根据您的编辑)。

有一些技巧:

1)从draggable开始,我添加了一个新函数,因为我们需要留下一个占位符(使用一个克隆),这样容器在拖动过程中不会跳转,我们需要将新元素初始化为draggable。

 function initDraggable($element) { $($element).draggable({ connectToSortable: '.droppable', revert: function(droppableObj) { if(droppableObj === false) { $(this).removeClass('dragging'); return true; } else { return false; } }, helper: 'clone', start: function(e, ui) { $draggingParent = $(this).parent(); $(this).addClass('dragging'); } }); } 

注意connectToSortable: .droppable (作为清理,我认为你应该将droppable改为sortable);

注意还要revert: – 这使我们有机会在revert:删除’拖动’类(使原始(克隆)元素不可见)。

最后,有一个start添加’拖动’类,使得原始(克隆)元素在拖动过程中不可见。 它还设置$ draggingParent,用于检查是否正在从#draggables.droppables拖动项目。

2)然后是#draggablesdroppable()

  $("#draggables").droppable({ drop: function(ev, ui) { if($draggingParent[0] === $(ui.helper).parent()[0]) { //dragged from draggables to draggables $(ui.draggable).removeClass('dragging'); } else { if(ui.draggable.parent()) var $clone = $(ui.draggable).clone(); $(ui.draggable).remove(); $clone.removeClass(); $clone.removeAttr('style'); initDraggable($clone); $(this).append($clone); } } 

请注意, drop handler检查是否从#draggables.droppables删除了此元素,并相应地执行操作。

3)最后,正如您已经提到的,我们真的希望droppable可以排序:

 function initDroppableSort($element) { $element.sortable({ items: 'li', connectWith: ".droppable,#draggables", revert: true, stop: function(event, ui) { $(ui.item).removeClass('dragging'); $('.dragging').remove(); if($(this).hasClass('new')) { var clone = $(this).clone(); clone.empty(); $(this).after(clone); $(this).removeClass('new'); initDroppableSort( clone ); } cleanUp(); } }); } 

注意connectWith ,特别是它指的是.droppable#draggables