为什么jquery sortable中的update事件在测试ui.sender时似乎运行了两次

Jak*_*itz 10 jquery jquery-ui-sortable

我正在使用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
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这是似乎运行两次的部分:

                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"));
                }
Run Code Online (Sandbox Code Playgroud)

我期待只得到一个alert作为ui.sendernull当排序保持不变名单内.当一个项目离开列表去另一个项目时,ui.sender将不再是null.

问题是当我将项目移动到新列表时,我将收到2条警报消息.它好像在更新函数运行一次后设置ui.sender然后再次运行更新功能.显然这不好,因为我覆盖的数据不一定会被覆盖.

如果是这种情况,我应该如何重写代码以避免覆盖数据?

编辑

我相信每次更改列表DOM时都会调用update事件,而不仅仅是DOM.因此,对于每个具有DOM更改的列表,都会运行更新.当我将一个项目移动到新列表时,我正在更新两个列表.

所以我想新的问题是:我如何重写这段代码知道它会触发两次?是否有可以实现此目的的Receive和Remove事件的组合?

Jak*_*itz 46

我对每个可排序的事件做了一些调查.以下是我的调查结果,按照发生的顺序列出:

$(".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
    },
    update: function(e,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
    }
});
Run Code Online (Sandbox Code Playgroud)

在解决我的问题时,我只是通过将其包装在一个if else检查的语句中来强制我的更新函数的内容只运行一次ui.sender.基本上它说如果ui.sender不存在那么这是第一次通过更新功能,我们应该做的功能,否则什么都不做.

  • 源代码永远不会出现:[sortable.js](https://github.com/jquery/jquery-ui/blob/master/ui/sortable.js#L1281) - 停止事件是最后一个事件 (6认同)
  • @Cholesterol感谢输入更有意义.但我在这里得到的信息是通过我对每个事件的测试.我通过调用console.log("whatever-this-event-is")来测试该事件.我的调查结果是更新事件在停止事件之前发出了它的日志. (3认同)