jQueryUI可排序的占位符索引不正确

时间:2016-10-13 08:52:10

标签: jquery-ui

我有一个具有相应数据数组的可排序列表,我需要在重新排序列表时更改数组的顺序。我用这个代码

o.dom.$editor.find('.sortable').sortable({
    start: function(event, ui) {
        var start_pos = ui.item.index();
        ui.item.data('startIndex', start_pos); // store original index
    },
    change: function(event, ui) {
        var start_pos = ui.item.data('startIndex'); // get original index
        var index = ui.placeholder.index() - 1; // get new index
        console.log(start_pos, index); // log start and end positions for debugging

        ui.item.data('startIndex', index); // store new index
    }
});

举个例子,假设我有这个清单:

A
B
C

我按住列表项A并将其向下拖动到底部,更改事件触发两次,首先使用项B交换项A,然后使用C交换A,控制台显示:

0 1
1 2

这是正确的。现在(没有从上一次拖动中释放鼠标),我将项目A拖回到顶部,再次将更改事件触发两次,使用C交换A,然后使用B交换A,控制台显示:

2 1
1 0

一切都好。 现在,如果我释放鼠标,并开始将项目B拖到顶部,则更改事件将触发一次,使用A交换B,但控制台显示:

1 -1

哪个错了。这里发生了什么?我一直试图解决这个问题几个小时。

jsfiddle:https://jsfiddle.net/4dtdk2qo/1/

1 个答案:

答案 0 :(得分:0)

问题出在var index = ui.placeholder.index() - 1;行。

  • 当您将项目从上到下移动时,ui.placeholder.index()的索引从1开始
  • 当您将项目从下向上移动时,ui.placeholder.index()的索引从0开始

我改变了索引的逻辑。

$(function(){
  $('.sortable').sortable({
    start: function(event, ui) {
	  var start_pos = ui.item.index();
	  ui.item.data('startIndex', start_pos);
	},
	change: function(event, ui) {
	  var start_pos = ui.item.data('startIndex');
	  var index = ui.placeholder.index();
	  index = (start_pos > index) ? index : index - 1; 
	  $("#output").append(start_pos + ' ' + index + '<br>');
      ui.item.data('startIndex', index);
	}
  });
})
li{
  display: block;
  background: lightgreen;
  margin:20px 0;
}

#output{
  width:100%;
  min-height: 20px;
  background: lightgray;
}
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<ul class='sortable'>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

<div id="output">