You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery Sortable拖拽时保持源列表固定顺序的实现咨询

实现拖拽项放回源列表时回到初始位置的方案

这个需求确实没法通过jQuery UI Sortable的原生配置直接实现,但我们可以通过记录初始位置+监听拖拽回调事件来搞定,思路很清晰,我给你整理了可行的实现方案:

核心思路

  1. 提前给源列表(#sortable1)的每一项标记它的初始位置索引
  2. 监听Sortable的receive事件,当项从自定义列表(#sortable2)拖回源列表时,根据预存的索引把它插回初始位置

完整实现代码

HTML(和你的原代码一致,无需修改)

<ul id="sortable1" class="connectedSortable" style="border: 1px solid;">
 <li class="ui-state-default">Item 1a</li>
 <li class="ui-state-default">Item 2a</li>
 <li class="ui-state-default">Item 3a</li>
 <li class="ui-state-default">Item 4a</li>
 <li class="ui-state-default">Item 5a</li>
</ul>

<ul id="sortable2" class="connectedSortable" style="border: 1px solid;">
 <li class="ui-state-default">Item 1b</li>
 <li class="ui-state-default">Item 2b</li>
 <li class="ui-state-default">Item 3b</li>
 <li class="ui-state-default">Item 4b</li>
 <li class="ui-state-default">Item 5b</li>
</ul>

CSS(和你的原代码一致,无需修改)

body {
 font-family: Arial, Helvetica, sans-serif;
}
table {
 font-size: 1em;
}
.ui-draggable, .ui-droppable {
 background-position: top;
}
#sortable1, #sortable2 {
 border: 1px solid #eee;
 width: 142px;
 min-height: 20px;
 list-style-type: none;
 margin: 0;
 padding: 5px 0 0 0;
 float: left;
 margin-right: 10px;
}
#sortable1 li, #sortable2 li {
 margin: 0 5px 5px 5px;
 padding: 5px;
 font-size: 1.2em;
 width: 120px;
}
.ui-state-highlight {
 height: 1.5em;
 line-height: 1.2em;
}

JavaScript(修改后的核心逻辑)

$(function() {
  // 给sortable1的每一项标记初始位置索引
  $("#sortable1 li").each(function(index) {
    $(this).data("original-index", index);
  });

  $("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable",
    placeholder: "ui-state-highlight",
    // 监听元素被拖入列表的事件
    receive: function(event, ui) {
      const targetList = $(this);
      const draggedItem = ui.item;
      const sourceList = ui.sender;

      // 仅处理从sortable2拖回sortable1的情况
      if (targetList.attr("id") === "sortable1" && sourceList.attr("id") === "sortable2") {
        const originalIndex = draggedItem.data("original-index");
        // 根据初始索引计算插入位置
        const targetPrevItem = $("#sortable1 li").eq(originalIndex - 1);
        
        if (targetPrevItem.length) {
          draggedItem.insertAfter(targetPrevItem);
        } else {
          draggedItem.prependTo("#sortable1");
        }

        // 刷新sortable状态,确保排序逻辑正常
        $("#sortable1").sortable("refresh");
      }
    }
  }).disableSelection();
});

代码说明

  • 初始位置标记:页面加载时遍历#sortable1的所有项,用data-*属性存储它们的初始顺序索引(从0开始),即使列表是动态生成的,只要在渲染完成后执行这段遍历代码即可。
  • 归位逻辑:在receive回调中,判断当前接收列表是源列表且元素来自自定义列表时,取出预存的初始索引,将元素插入到对应的位置——索引为0则插在最前面,否则插在对应索引前一个元素的后面。
  • 状态刷新:调用sortable("refresh")更新组件内部状态,避免后续拖拽出现异常。

这个方案兼容jQuery 3.x版本,完全满足你的需求~

内容的提问来源于stack exchange,提问作者user2399035

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:07:29