使用jQuery UI将可拖动元素排序在可拖放内
解决
所以我研究了sortable()
和更多的connectWith
属性,发现解决方案比我想象的要简单,但是由于draggable()
和droppable()
原因,我在考虑它的倒退。
这是小提琴:http://jsfiddle.net/DKBU9/12/
原始问题如下:
这是以前的SO问题的延伸,我觉得应该分开。
原始问题在这里:jQuery UI - 在drop事件之后的克隆droppable /可排序列表。 它认为重新初始化克隆元素上的droppable处理程序。
最重要的是,我尝试允许从最初列表拖拽的元素在可拖拽列表中排序。
这里是一个小提琴,基本上说明了当前行为是原始问题的结果:http://jsfiddle.net/DKBU9/7/
而所需的代码,因为它喜欢抱怨和膨胀这些帖子:
HTML
<ul id="draggables">
<li>foo1</li>
<li>foo2</li>
<li>foo3</li>
</ul>
<ul class="droppable new">
</ul>
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结合可排序和可拖动
我一直试图使用这个SO问题来解决我的问题,结果正是我想要实现的,特别是在接受的答案的评论中提供的最后一个提琴,但我似乎无法弄清楚考虑到细微的差异,以适应我的代码。 例如,该问题中的小提琴克隆可拖动而不是拖动实际元素,与我的不同,不允许将元素拖回初始列表。
所以任何帮助尝试获得我的代码的结果将不胜感激。
另外,在那个例子中, accept
属性被设置为一个返回true的函数。 这是什么原因? 这不仅仅意味着它会接受任何东西,或任何可拖动的元素?
编辑:我读了一些只用sortable()和connectWith属性的答案,但由于某种原因,我不认为它做了我所需要的,部分原因是我不希望最初的列表也可以排序。 但是,单独使用sortable()似乎获得了我之后的功能,但我还没有适应所有的事件处理程序。
看到这个小提琴 。
它会使项目在新列表中可丢弃和排序,但不会在最初(根据您的编辑)。
有几个窍门:
1)从可拖拽开始,我添加了一个新函数,因为我们需要留下一个占位符(使用克隆),以便在拖拽时容器不会跳过,我们需要将新元素初始化为可拖拽。
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排序);
请注意revert:
- 这使我们有机会去除“拖动”类(这会使原始(克隆)元素不可见)恢复。
最后,还有一个start
添加了“拖动”类,这会在拖动过程中使原始(克隆)的元素不可见。 它还设置$ draggingParent,用于检查项目是否从#draggables
或.droppables
。
2)然后是#draggables
的droppable()
:
$("#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
处理程序将检查此元素是否从#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
。
上一篇: Make draggable element sortable within droppable using jQuery UI
下一篇: Resume download from Download Manager android when download is failed