我使用jQuery UI排序可排序连接的列表.更新事件似乎运行两次.
这是完整的可排序的电话:
$(".pageContent").sortable({
handle: ".quesText",connectWith: ".pageContent",containment: "section",start: function(e,ui){
ui.placeholder.height(ui.item.height());
},placeholder: "sortable-placeholder",opacity: 0.5,cursor: "move",cancel: "input,select,button,a,.openClose",update: function(e,ui){
var thisItem = ui.item;
var next = ui.item.next();
var prev = ui.item.prev();
var thisNumber = thisItem.find(".quesNumb");
var nextNumber = next.find(".quesNumb");
var prevNumber = prev.find(".quesNumb");
var tn = parseInt(thisNumber.text());
var nn = parseInt(nextNumber.text());
var pn = parseInt(prevNumber.text());
var quesNumbs = $(".quesNumb");
var newItemId = thisItem.attr("id").replace(/_\d+$/,"_");
//test if we are dragging top down
if(ui.position.top > ui.originalPosition.top){
quesNumbs.each(function(i){
var thisVal = parseInt($(this).text());
var grandparent = $(this).parent().parent();
var grandId = grandparent.attr("id").replace(/_\d+$/,"_");
if(thisVal > tn && (thisVal <= pn || thisVal <= (nn - 1))){
$(this).text(thisVal - 1 + ".");
grandparent.attr("id",grandId + (thisVal - 1));
}
});
if(!isNaN(pn) || !isNaN(nn)){
if(!isNaN(pn)){
//for some reason when there is a sender pn gets updated,so we check if sender exists
//only occurs sorting top down
if($.type(ui.sender) !== "null"){
var senderId = ui.sender.attr("id");
thisNumber.text(pn + 1 + ".");
thisItem.attr("id",senderId + "_" + (pn + 1));
alert(thisItem.attr("id"));
}
else {
thisNumber.text(pn + ".");
thisItem.attr("id",newItemId + pn);
alert(thisItem.attr("id"));
}
}
else {
thisNumber.text(nn - 1 + ".");
}
}
else {
//something will happen here
}
}
//otherwise we are dragging bottom up
else {
quesNumbs.each(function(i){
var thisVal = parseInt($(this).text());
if(thisVal < tn && (thisVal >= nn || thisVal >= (pn + 1))){
$(this).text(thisVal + 1 + ".");
}
});
if(!isNaN(pn) || !isNaN(nn)){
if(!isNaN(pn)){
thisNumber.text(pn + 1 + ".");
}
else {
thisNumber.text(nn + ".");
}
}
else {
//something will happen here
}
}
}
});
这是运行两次的部分:
if($.type(ui.sender) !== "null"){
var senderId = ui.sender.attr("id");
thisNumber.text(pn + 1 + ".");
thisItem.attr("id",senderId + "_" + (pn + 1));
alert(thisItem.attr("id"));
}
else {
thisNumber.text(pn + ".");
thisItem.attr("id",newItemId + pn);
alert(thisItem.attr("id"));
}
当排序保持在同一列表中时,我希望只能获得一个警报,因为ui.sender为空.当一个项目离开一个列表去转到另一个,那么ui.sender将不再是null.
问题是当我将一个项目移动到一个新的列表中时,我会收到2个警报消息.它更像是在更新功能运行一次后设置ui.sender,然后再次运行更新功能.显然这是不好的,因为我覆盖不应该被覆盖的数据.
如果是这样,我应该如何重写代码以避免覆盖数据?
编辑
我相信每次更改列表DOM时调用更新事件,而不仅仅是一般的DOM.因此,对于具有DOM更改的每个列表,运行更新.当我将一个项目移动到新列表中时,我正在更新两个列表.
所以我猜这个新问题是:如何重写这个代码,知道它会发射两次?是否组合接收和删除事件可以实现这一点?
解决方法
我对每个可排序的事件进行了一些调查.这是我的发现,按照它们发生的顺序列出:
$(".pageContent").sortable({
start: function(e,ui){
//Before all other events
//Only occurs once each time sorting begins
},activate: function(e,ui){
//After the start event and before all other events
//Occurs once for each connected list each time sorting begins
},change: function(e,ui){
//After start/active but before over/sort/out events
//Occurs every time the item position changes
//Does not occur when item is outside of a connected list
},over: function(e,ui){
//After change but before sort/out events
//Occurs while the item is hovering over a connected list
},sort: function(e,ui){
//After over but before out event
//Occurs during sorting
//Does not matter if the item is outside of a connected list or not
},out: function(e,ui){
//This one is unique
//After sort event before all drop/ending events unless **see NOTE
//Occurs,only once,the moment an item leaves a connected list
//NOTE: Occurs again when the item is dropped/sorting stops
//--> EVEN IF the item never left the list
//--> Called just before the stop event but after all other ending events
},beforeStop: function(e,ui){
//Before all other ending events: update,remove,receive,deactivate,stop
//Occurs only once at the last possible moment before sorting stops
},remove: function(e,ui){
//After beforeStop and before all other ending events
//Occurs only once when an item is removed from a list
},receive: function(e,ui){
//After remove and before all other ending events
//Occurs only once when an item is added to a list
},ui){
//After receive and before all other ending events
//Occurs when the DOM changes for each connected list
//This can fire twice because two lists can change (remove from one
//list but add to another)
},deactivate: function(e,ui){
//After all other events but before out (kinda) and stop
//Occurs once for each connected list each time sorting ends
},stop: function(e,ui){
//After all other events
//Occurs only once when sorting ends
}
});
解决我的问题我只是强制我的更新功能的内容只运行一次,将其包装在一个if else语句中,检查ui.sender.基本上它说如果ui.sender不存在,那么这是第一次通过更新功能,我们应该做这个功能,否则什么都不做.