【问题标题】:Shift list element order in several <ul> at once if one of <li> changes position如果 <li> 之一改变位置,则一次移动多个 <ul> 中的列表元素顺序
【发布时间】:2015-09-15 20:54:24
【问题描述】:

我正在使用拖放功能来允许用户对页面上的元素进行排序。我有几个 &lt;ul&gt; 元素,其中有 &lt;li&gt; 元素(所有 &lt;ul&gt; 包含 3 个 &lt;li&gt; 元素),其中每个无序列表对应一个月,所以

<ul class="dragable" id="month-june">
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>

<ul class="dragable" id="month-july">
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>

<ul class="dragable" id="month-august">
 <li>Item 1</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>

<!-- etc.. -->

一旦发生.drop() 事件,我想以某种方式对所有列表进行排序(基本上用户在拖动项目后将其放置到位)。我正在更改 dom 中的列表位置,因此它们总是在那里排序,例如,如果 8 月的第 3 项在 7 月在第 1 项和第 2 项之间移动,它将如下所示:

<ul class="dragable" id="month-july">
 <li>Item 1</li>
 <li>Item 3</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>

现在我需要弄清楚如何将第 3 项从 7 月下推到 8 月的无序列表,并在它之后下推所有其他项。如果例如从 6 月的第 1 项被拖到第 2 项和第 3 项之间的 7 月,这应该具有反之亦然的效果,在这种情况下,它上面的所有内容都应该向左移动。因此,我需要在任何给定时间在所有列表中都有 3 个项目。

这是进一步显示它的图像,希望能更好地解释它:(将中间部分视为初始部分,而不是箭头显示项目被拖动的位置以及它之前和之后的列表会发生什么取决于位置)

这是否可以在不使用 id 或类的情况下完成,而是依赖下一个和上一个元素(无序列表),因为在这种情况下,我不知道确切的月份。

这是一个非常简单的 js fiddle 拖放行为:DEMO

【问题讨论】:

  • 你可以创建一个 jsfiddle,jsfiddle.net
  • @dreamweiver 刚刚添加到问题底部
  • 只是为了总结您的要求,1. 您希望在每次拖放后对列表进行排序。 2.如果目标列表包含新项目,则应将其删除。 3.总体上不应该有任何重复。
  • 2 - 不确定你的意思,不应该删除任何元素,只是相应地改变位置,除了你总结的所有声音都是正确的。
  • @dreamweiver 如果有帮助:api.jqueryui.com/1.10/sortable/#event-activate 我相信更改事件是应该进行排序的事件

标签: javascript jquery list dom


【解决方案1】:

Drop 更新

$(".sortable-queue").sortable({
    revert: true,
    scroll: false,
    connectWith: ".connected-sortable",
    placeholder: "item-dragable-placeholder",
    receive: function (event, ui) {
        var target = $(event.target).parent().parent();
        var source = ui.sender.parent().parent();
        var children = target.parent().children();

        var start = children.index(source);
        var end = children.index(target);

        // bubble up?
        if (start < end) {
            for (var i = start; i < end; i++) {
                $(children[i]).find("ul").append($(children[i + 1]).find("li").first().detach())
            }
        }
        // bubble down?
        else if (start > end) {
            for (var i = start; i > end; i--) {
                $(children[i]).find("ul").prepend($(children[i - 1]).find("li").last().detach())
            }
        }
        // same pulldown
        else
            return;
    }
}).disableSelection();

它所做的只是识别源 uls 和目标 uls 的 div 包装器。然后它使用它来确定目标 ul 是高于还是低于源 ul。

如果它在下面,它会逐步遍历从源到目标的所有包装器,从后续包装器中获取第一个 li 并将其添加到其末尾。

如果它在上面,同样的事情会发生,唯一的区别是它是从末尾挑选并添加到开头的。

如果源和目标包装器相同,我们不需要做任何事情。


小提琴 - https://jsfiddle.net/ajdw2u0b/


拖动时更新

var source;
$(".sortable-queue").sortable({
    revert: true,
    scroll: false,
    connectWith: ".connected-sortable",
    placeholder: "item-dragable-placeholder",
    start: function(event, ui) {
        source = ui.item.parent().parent().parent();
    },
    over: function (event, ui) {
        var target = $(event.target).parent().parent();
        var children = target.parent().children();
        var start = children.index(source);
        var end = children.index(target);

        // same pulldown
        if (start === end) {
            console.log(start)
            return;
        }
        // bubble up?
        else if (start < end) {
            for (var i = start; i < end; i++) {
                $(children[i]).find("ul").append($(children[i + 1]).find("li:not(.ui-sortable-helper):not(.item-dragable-placeholder)").first().detach())
            }
        }
        // bubble down?
        else if (start > end) {
            for (var i = start; i > end; i--) {
                $(children[i]).find("ul").prepend($(children[i - 1]).find("li:not(.ui-sortable-helper):not(.item-dragable-placeholder)").last().detach())
            }
        }

        source = target;
    }
}).disableSelection();

逻辑几乎相同。唯一的区别是

  1. 您在over 上进行更新(当您将项目拖到放置目标上时)。
  2. 您必须维护源包装器值,而不是从 ui 对象中获取它,因为一旦将鼠标悬停在放置目标上,您就会对其进行更改。

请注意,在选择要分离的元素时,您必须排除被拖动的元素和占位符。


小提琴 - https://jsfiddle.net/f4655x9n/

【讨论】:

  • 有效!但我在将项目拖到列表时仍然看到 4 个元素,一旦我释放它,它们似乎很好地整理自己,我尝试将接收事件更改为更改,但它似乎不起作用
  • 已添加!做测试:-)
猜你喜欢
  • 2020-12-17
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2012-10-03
  • 1970-01-01
  • 2016-07-11
相关资源
最近更新 更多