基于拖动元素的可排序js更改数组

Sortable js change array based on dragged element

我有一个任务列表,我希望能够将它们四处拖动并让 sortOrder 数组更改为新顺序,这就是我想出的,但它不能正常工作,有时我得到订单,有时我不..例如,如果我将第一个元素拖到第二个位置它有效,但如果我拖到最后一个位置它不是......而且如果我向上拖动它通常是错误的..我是什么做错了吗?或者这可以通过其他方式完成吗?我需要跟踪 previous/next id,因为 sortOrder 中可能还有其他不可见的元素,因此我需要在可见元素之前或之后添加拖动的元素。 谢谢

const sortOrder = ["7","x", "5","y", "55", "1"],
  tasks = document.getElementById("tasks");

Sortable.create(tasks, {
  scroll: true,
  scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
  scrollSpeed: 10, // px, speed of the scrolling
  bubbleScroll: true, // apply autoscroll to all parent elements, allowing for easier movement
  revertOnSpill: true,
  group: 'shared',
  animation: 0,
  dataIdAttr: 'id',
  ghostClass: 'task-ghost',
  dragClass: 'task-drag',
  onEnd: (evt) => {
    // let newIndex;
    console.log('previousElementSibling', evt.item.previousElementSibling);
    console.log('nextElementSiblingElementSibling', evt.item.nextElementSiblingElementSibling);
    console.log('oldIndex', evt.oldIndex);
    console.log('newIndex', evt.newIndex);
    let neighborIndex;
    // drag up or down
    if (evt.oldIndex < evt.newIndex) neighborIndex  = sortOrder.indexOf(evt.item.previousElementSibling?.id || sortOrder[0]);
    else neighborIndex = sortOrder.indexOf(evt.item.nextElementSibling?.id);
    console.log("neighborIndex",neighborIndex);
    // remove element from array
    sortOrder.splice(sortOrder.indexOf(evt.item.id), 1); 
    // add element to specific position
    sortOrder.splice(neighborIndex, 0, evt.item.id);
    console.log(sortOrder);
  }
})
.tasks {
  list-style-type: none;
}
li {
  border: solid 1px red;
  margin: 4px;
  width: 200px;
}

.task-ghost{ opacity: 0; }
.task-drag{ opacity: 1;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<ul class="tasks" id="tasks">
  <li id="7" class="task">element 7</li>
  <li id="5" class="task">element 5</li>
  <li id="55" class="task">element 55</li>
  <li id="1" class="task">element 1</li>
</ul>

我已经取得了不错的效果,如果有人有更好的方法请告诉我。

const sortOrder = ["7", "x", "5", "y", "55", "1"],
  tasks = document.getElementById("tasks");

Sortable.create(tasks, {
  scroll: true,
  scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
  scrollSpeed: 10, // px, speed of the scrolling
  bubbleScroll: true, // apply autoscroll to all parent elements, allowing for easier movement
  revertOnSpill: true,
  group: 'shared',
  animation: 0,
  dataIdAttr: 'id',
  ghostClass: 'task-ghost',
  dragClass: 'task-drag',
  onEnd: (evt) => {
    // let newIndex;
    console.log('previousElementSibling', evt.item.previousElementSibling);
    console.log('nextElementSiblingElementSibling', evt.item.nextElementSiblingElementSibling);
    console.log('oldIndex', evt.oldIndex);
    console.log('newIndex', evt.newIndex);
    let neighborIndex;
    sortOrder.splice(sortOrder.indexOf(evt.item.id), 1); // stergem pe ala pe care l-am tras de sus
    if (evt.oldIndex < evt.newIndex) neighborIndex = sortOrder.indexOf(evt.item.previousElementSibling.id) + 1;
    else neighborIndex = sortOrder.indexOf(evt.item.nextElementSibling.id);
    sortOrder.splice(neighborIndex, 0, evt.item.id); // il adaugam dupa vecin
    console.log(sortOrder);
  }
})
.tasks {
  list-style-type: none;
}

li {
  border: solid 1px red;
  margin: 4px;
  width: 200px;
}

.task-ghost {
  opacity: 0;
}

.task-drag {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js"></script>
<ul class="tasks" id="tasks">
  <li id="7" class="task">element 7</li>
  <li id="5" class="task">element 5</li>
  <li id="55" class="task">element 55</li>
  <li id="1" class="task">element 1</li>
</ul>