jQuery 可通过 droppable 排序
Posted
技术标签:
【中文标题】jQuery 可通过 droppable 排序【英文标题】:jQuery sortable with droppable 【发布时间】:2012-05-07 16:26:10 【问题描述】:我的小提琴:http://jsfiddle.net/Yc9WY/42/
您将在此处看到两组,每组定义了 3 个可放置容器。您可以将事件从组 1 移动到组 2,并移动到任何插槽。这工作得很好。
一旦组已满,我希望用户能够通过上下移动事件来对该组进行排序。如果他们愿意,他们仍然应该能够将活动移出群组。
您会看到我开始集成可排序库的注释掉的代码,但出现了奇怪的行为。
注意:我不能只用 sortable 替换我的 draggable/dropable。我需要明确定义可放置区域(每组 3 个),以便事件可以存在于组 1 的插槽 1 和 3。
这是我的代码
$(document).ready(function()
// $(".sort").sortable(
// revert: true
// );
$(".drag").draggable(
//connectToSortable: ".sort",
revert: true
//helper: clone
);
$(".sort").droppable(
drop: function(event, ui)
if (!($(this).children(".drag").size() == 1))
$(this).append(ui.draggable);
ui.draggable.css(
left: 0,
top: 0
);
);
);
<div>Group 1:
<ul class="parent">
<li class="sort"><a href="" class="drag">event 1</a></li>
<li class="sort"><a href="" class="drag">event 2</a></li>
<li class="sort"></li>
</ul>
</div>
<div>
Group 2
<ul class="parent">
<li class="sort"></li>
<li class="sort"><a href="" class="drag">event 3</a></li>
<li class="sort"><a href="" class="drag">event 4</a></li>
</ul>
</div>
我真的很苦恼,谢谢大家!
【问题讨论】:
请将相关代码添加到您的问题中。虽然 jsfiddle 非常适合测试,但不应依赖于问题上下文。 对不起,丹,代码已添加 【参考方案1】:我破解了:)
小提琴(和 CSS): http://jsfiddle.net/jhogervorst/CPA5Y/
HTML:
<div class="group">
<h1>Group 1</h1>
<ul class="parent">
<li class="droppable"><span class="draggable">Item 1</span></li>
<li class="droppable"><span class="draggable">Item 2</span></li>
<li class="droppable"></li>
</ul>
</div>
<div class="group">
<h1>Group 2</h1>
<ul class="parent">
<li class="droppable"><span class="draggable">Item 3</span></li>
<li class="droppable"></li>
<li class="droppable"><span class="draggable">Item 4</span></li>
</ul>
</div>
JavaScript:
$(".draggable").draggable(
revert: true,
revertDuration: 0
);
$(".droppable").droppable(
activeClass: "active",
hoverClass: "hover",
accept: function (draggable)
// The droppable (li element).
var droppable = $(this);
// The droppable which contains the draggable, i.e., the parent element of the draggable (li element).
var draggablesDropable = draggable.parent();
// Is the draggable being dragged/sorted to the same group?
// => We could just sort it, because there's always enough space inside the group.
if (droppable.parent().is(draggablesDropable.parent()))
return true;
// Nope, the draggable is being dragged/sorted to another group.
// => Is there an empty droppable left in the group to which the draggable is being dragged/sorted?
else if (droppable.parent().find(".draggable").size() < droppable.parent().find(".droppable").size())
return true;
// Nothing true?
return false;
,
drop: function(event, ui)
// The droppable (li element).
var droppable = $(this);
// The draggable (span element).
var draggable = ui.draggable;
// The droppable which contains the draggable, i.e., the parent element of the draggable (li element).
var draggablesDropable = draggable.parent();
// Is the draggable being dragged to it's own droppable?
// => Abort, there's nothing to drag/sort!
if (droppable.is(draggablesDropable))
return;
// Is the draggable being dragged to an empty droppable?
else if (!droppable.find(".draggable").size())
// Just drop the draggable there.
droppable.append(draggable);
// Is the draggable being dragged/sorted to the same group?
// => We can just sort it, because there's always enough space inside the group.
else if (droppable.parent().is(draggablesDropable.parent()))
// Is the draggable being dragged up?
if (droppable.parent().find(".droppable").index(draggablesDropable) > droppable.parent().find(".droppable").index(droppable))
// Add the dragged draggable's droppable before the droppable.
draggablesDropable.insertBefore(droppable);
// No, the draggable is being dragged down.
else
// Add the dragged draggable's droppable after the droppable.
draggablesDropable.insertAfter(droppable);
// Nope, the draggable is being dragged/sorted to another group.
// => Is there an empty droppable left in the group to which the draggable is being dragged/sorted?
else if (droppable.parent().find(".draggable").size() < droppable.parent().find(".droppable").size())
// Find the first empty droppable in which the draggable is being dragged/sorted.
var emptyDroppable = $($.grep(droppable.parent().find(".droppable"), function (item)
// Are there draggables inside this droppable?
// => Return TRUE if not.
return !$(item).find(".draggable").size();
)).first();
// Clone the dragged draggable's droppable before itself, because we need to remember it's position after moving it.
var draggablesDropableClone = draggablesDropable.clone().insertBefore(draggablesDropable);
// Is the draggable being dragged above the empty droppable?
if (droppable.parent().find(".droppable").index(emptyDroppable) > droppable.parent().find(".droppable").index(droppable))
// Add the dragged draggable's droppable before the droppable.
draggablesDropable.insertBefore(droppable);
// No, the draggable is being dragged below the empty droppable.
else
// Add the dragged draggable's droppable after the droppable.
draggablesDropable.insertAfter(droppable);
// Remove the position of the dragged draggable, because there's still some css left of the dragging.
draggable.css("top": 0, "left": 0);
// Add the first empty droppable before the cloned draggable's droppable. Remove the latter afterwards.
draggablesDropableClone.before(emptyDroppable).remove();
);
【讨论】:
嗨乔纳森,你的代码实际上和我的代码完全一样:) - 也许我不清楚问题是什么。用 3 个事件填满一列后,尝试将底部的事件拖到顶部。即,对列中的事件进行排序。这就是我要找的。span> @JasonWells 尝试拖动框的深灰色部分。 (我添加了一个指示可排序区域的图标:jsfiddle.net/jhogervorst/CPA5Y/1) 啊,我明白了。谢谢!如果用户仍然可以抓取链接并使其在同一组内可排序,但如果在原始组之外变成可拖动的,那么最佳做法是。这样,我不依赖我的用户选择文本/链接旁边的区域。这有意义吗? 是的,我绝对明白你的意思。你不能用两个空项目来做一个跨越两列的可排序吗?使用一些 CSS,您可以实现与我所做的相同的效果。 --- 编辑:嗯,现在我想这似乎是不可能的。排序时项目会跳转到其他位置。困难的一个…… 我正在努力。不过有点难。一个组中是否总是只有三个事件?以上是关于jQuery 可通过 droppable 排序的主要内容,如果未能解决你的问题,请参考以下文章
jquery如何通过'draggable'和'droppable'来排序't项目“互相吃”?
JQuery UI:在 Droppable Drop 时取消排序
jQuery UI Droppable and Sortable - 放置在正确的排序位置