如果<li>中的一个更改位置,则立即在几个<ul>中移动列表元素顺序

Ilj*_*lja 5 javascript jquery dom list

我正在使用拖放功能,允许用户在页面上订购元素.我有几个<ul>元素,<li>里面有元素(都<ul>包含3个<li>元素),每个无序列表对应一个月,所以

<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.. -->
Run Code Online (Sandbox Code Playgroud)

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

<ul class="dragable" id="month-july">
 <li>Item 1</li>
 <li>Item 3</li>
 <li>Item 2</li>
 <li>Item 3</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

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

这是进一步显示它的图像,希望更好地解释它:(考虑中间部分作为初始,而不是箭头显示项目被拖动的位置以及根据位置在列表之前和之后发生的情况)

在此输入图像描述

这可以在不使用id或类的情况下完成,但依赖于下一个和前一个元素(无序列表),因为我不确切知道在这种情况下几个月会跟着什么.

这是非常简单的js摆弄拖放行为:DEMO

pot*_*ngs 1

掉落更新

$(".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();
Run Code Online (Sandbox Code Playgroud)

它所做的只是识别源 ul 和目标 ul 的 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();
Run Code Online (Sandbox Code Playgroud)

逻辑几乎是一样的。唯一的区别是

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

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


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