JQuery可排序列表,其中一些元素按顺序冻结?

时间:2012-02-16 20:19:59

标签: javascript jquery jquery-ui

我正在寻找一种方法来获得类似JQuery的可排序列表(link),但是其中一些元素处于固定的不可分割位置。

使某些元素无法区分是微不足道的,但是它们的位置不会保持固定,因为它们上方和下方的可拖动元素的数量可能会发生变化。

更具体一点: 我有排名顺序的10个项目的列表。我希望用户能够通过拖动(可排序列表)来更改某些项目的排名,但不能更改其他冻结元素的排名。标准的JQuery可排序不可分割功能允许通过更改冻结项目上方或下方的元素数量来更改冻结项目的等级。

我已尝试通过"交换"手动执行此操作拖动时列出元素。即,当将列表元素拖过非冻结元素时,交换两个元素的位置。这给出了我想要的语义,但项目被明显拖动"跳跃"在它的新位置和当前的拖累之间位置。 (我希望它保持在当前拖动位置;只有它在DOM中的位置应该改变。但是当DOM位置改变时,必须重新计算拖动偏移坐标。而且我不知道如何同时执行这两个DOM位置变化和拖动偏移坐标原子地改变,防止两者之间的重绘。目前,有时在两者之间进行重绘,并且元素可见(尽管很快)跳跃。)

修改 这是一个显示我的手动方法的jsfiddle: link。玩了一会儿,你会注意到我提到的闪烁/跳跃。

3 个答案:

答案 0 :(得分:14)

我看了你的小提琴,有另一个想法,这是使用sortable做到这一点的一种方法:在start上存储每个data对象中的固定索引位置固定项目,然后在任何change上,将固定项目移回原位。

$(function() {   
    $('#rankings').sortable({
        axis: 'y',
        items: '.sortable',
        start: function () {
            $(this).find("li:not(.sortable)").each(function () {
                $(this).data("fixedIndex", $(this).index());
            });
        },        
        change: function () {
            $(this).find("li:not(.sortable)").each(function () {
                $(this).detach().insertAfter($("#rankings li:eq(" + ($(this).data("fixedIndex")-1) + ")"));
            });
        }
    });
});

使用如下列表:

<ol id="rankings">
    <li class="sortable">Dog</li>
    <li class="">Cat</li>
    <li class="sortable">Parrot</li>
    <li class="sortable">Gerbil</li>
    <li class="sortable">Snake</li>
    <li class="">Goldfish</li>
</ol>

Seems to work

答案 1 :(得分:4)

我想我可能已经破解了它 - http://jsfiddle.net/q5c4Y/3/。虽然相当挑战。一路上有一些帮助

  • 使用更多结构化标记
  • 使用droppable的over事件交换列表项,但不使用drop事件(改为使用dragstop)
  • 在内部项目上设置一些定位,以便在更改其父元素后将它们保持在正确的位置

虽然,阅读@ graphicdivine上面的答案,看起来你真正需要的是jquery ui sortable

答案 2 :(得分:1)

1)如果您不想更改的项目全部位于列表的顶部和/或底部,则可以在列表外部创建这些项目,从而仅允许对OTHER项目进行排序并保留排名不可改变的。

2)您是否可以使用“停止”事件来检查您所需要的排名是否已被保留?即,检查第4个排名项目上方仍然只有3个项目,如果没有,则将新的“第4个”移动到具有第4个不可变等级的项目之下?基本上,在物品被拖入非法地点后强制重新移动物品?