拖拽排序后数据没更新怎么办?

ლ雨欣 阅读 108

我用原生 JS 实现了一个简单的列表拖拽排序,视觉上元素位置变了,但绑定的数据数组根本没变,后续提交表单还是按原始顺序传的,这咋整?

我试过在 drop 事件里手动交换数组项,但总感觉索引对不上,有时候还报错。是不是得在拖拽过程中就同步更新数据?

这是我的关键代码:

function handleDrop(e) {
  const draggedId = e.dataTransfer.getData('text/plain');
  const draggedEl = document.getElementById(draggedId);
  const targetEl = e.target.closest('li');
  if (targetEl && targetEl !== draggedEl) {
    targetEl.parentNode.insertBefore(draggedEl, targetEl.nextSibling);
    // 这里怎么同步更新 data 数组?
  }
}
我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
FSD-秀丽
拖拽完成后,直接根据DOM顺序重新生成数组就行了,别在drop里搞索引交换,那玩意儿容易出错。

function handleDrop(e) {
const draggedId = e.dataTransfer.getData('text/plain');
const draggedEl = document.getElementById(draggedId);
const targetEl = e.target.closest('li');
if (targetEl && targetEl !== draggedEl) {
targetEl.parentNode.insertBefore(draggedEl, targetEl.nextSibling);
}

// 拖拽完成后重新获取数据
const listItems = document.querySelectorAll('#your-list li');
const newData = Array.from(listItems).map(item => item.dataset.id);
console.log(newData); // 这就是更新后的数据数组
}


核心思路就是别在拖拽过程中试图精确追踪索引变化,等拖拽结束了,遍历一遍DOM节点,按顺序提取id,数据自然就同步了。
点赞
2026-03-19 08:17
欧阳柯豫
DOM操作和数组操作必须同步进行。先用 Array.from(parent.children) 获取当前DOM顺序对应的数组,然后根据元素在DOM中的位置计算索引,用 splice 移动数组项:

function handleDrop(e) {
const draggedId = e.dataTransfer.getData('text/plain');
const draggedEl = document.getElementById(draggedId);
const targetEl = e.target.closest('li');
const list = draggedEl.parentNode;

if (targetEl && targetEl !== draggedEl) {
// DOM 交换
list.insertBefore(draggedEl, targetEl.nextSibling);

// 数据同步 - 用DOM顺序重建数组
const newOrder = Array.from(list.children).map(el => el.id);
// 或者根据索引移动
const fromIndex = data.findIndex(item => item.id === draggedId);
const toIndex = Array.from(list.children).indexOf(targetEl);

const [item] = data.splice(fromIndex, 1);
data.splice(toIndex, 0, item);
}
}


核心就一句:DOM变了你得知道对应数组里的哪一项,然后手动调数组的 splice,别指望DOM自动帮你同步。
点赞
2026-03-13 00:05