如何用jQuery UI Sortable插件实现元素位置交换而非整体重排
实现jQuery UI Sortable元素位置交换而非移位
核心思路
jQuery UI Sortable默认是整体移位排序,要实现仅交换拖动元素与目标元素的位置,得绕开它的默认逻辑——在拖动结束后手动交换两个元素的DOM位置,同时避开中间固定的禁用元素。
实现代码
$(function() { $("#sortable").sortable({ // 只允许拖动非禁用的头像元素 items: "div.ui-item:not(.ui-state-disabled)", // 禁止向中间固定的禁用元素放置 cancel: ".ui-state-disabled", // 用克隆元素做拖动助手,避免原元素提前移位 helper: "clone", // 拖动取消后原元素回原位,方便后续手动交换 revert: true, // 记录拖动元素的初始位置 start: function(event, ui) { ui.item.data("originalIndex", ui.item.index()); }, // 拖动结束后执行交换逻辑 stop: function(event, ui) { const originalItem = ui.item; const placeholder = ui.placeholder; let targetItem; // 根据占位符的前后元素确定目标(排除禁用元素) if (placeholder.prev().length && !placeholder.prev().hasClass("ui-state-disabled")) { targetItem = placeholder.prev(); } else if (placeholder.next().length && !placeholder.next().hasClass("ui-state-disabled")) { targetItem = placeholder.next(); } // 执行位置交换 if (targetItem) { const originalPos = originalItem.data("originalIndex"); const targetPos = targetItem.index(); // 根据位置关系插入,实现交换 originalPos < targetPos ? targetItem.insertBefore(originalItem) : targetItem.insertAfter(originalItem); } // 取消Sortable默认的移位动作 $(this).sortable("cancel"); } }); });
关键细节解释
helper: "clone":拖动时显示克隆的元素,原元素留在原位,避免默认排序导致的元素移位,保证交换逻辑准确。revert: true:拖动结束后原元素自动回到初始位置,我们再手动交换它和目标元素,完全替代默认的排序行为。- 目标元素过滤:只选择非禁用的元素作为交换目标,确保中间4个固定位置的元素不会被触动。
sortable("cancel"):彻底禁用Sortable的默认排序逻辑,只保留我们自定义的交换功能。
替代方案
如果觉得自定义jQuery UI Sortable太麻烦,可以试试:
- 原生JS实现:监听
dragstart、dragover、drop事件,手动处理元素交换,灵活性拉满。 - 轻量插件:比如SortableJS,它原生支持交换模式,简单配置就能实现你要的效果,不用写大量自定义代码。
内容的提问来源于stack exchange,提问作者arderoma
相关产品推荐
相关产品推荐

