JS vs DOM计时:.remove()元素在视觉上发生,但travesal仍包含它

时间:2013-10-19 21:30:00

标签: javascript jquery json dom

我们尝试实现的功能的简短描述:我们在左侧有一个源对象列表,一个人可以将新项从列表拖到右边的列表中,因此项被添加到列表中在右边;他们还可以从右侧列表中删除项目。无论何时更改,右边的列表都会被保存。 (我不认为保存的方式/位置的具体细节......)

我遇到了JavaScript与DOM元素领域中的一些时间问题。可以删除右侧列表中已有的项目。我们有一些代码可以触发DOM元素上的“删除/删除”类型图标/按钮,它可以直观地和永久地从DOM中删除元素(即不需要带回'show “)。然后,这个可视化更改也应该出现在JS遍历DOM树以构建新的更新列表时构建的JSON对象中。

但是,调用此.remove()之后立即运行的这一块JS代码,应该刚删除的元素仍显示在JSON对象中。这不好。

以下是我认为在此处运行的相关代码位。它存在于Web浏览器中;其中大部分是在document.ready()函数中。给定的列表也可以有子部分,因此子列表部分和循环。

点击定义:

$('body').on('click', '.removeLine', function() {
var parent=$(this).parent().parent().parent();     //The button is a few DIVs shy of the outer container
var List=$(this).closest('article');     //Another parent object, containing all the 
parent.fadeOut( 300, 
    function() {
        parent.slideUp(300);
        parent.remove(); 
    }
);
sendList(List);    //  This builds and stores the list based on the DOM elements
});

然后,这个函数定义:

function sendList(List) {
var ListArray=[], 
    subListArray=[], 
    itemsArray = [], 
    subListName = "";
var ListTitle = encodeText(List.find('.title').html());

            // loop through the subLists
List.find('.subList').each(
        function(index, element) {
            subListName=($(this).find('header > .title').html());  // Get sublist Title
            subListID=($(this).attr('id'));               // Get subList ID

            // loop through the line items
            itemsArray=[];
            $(this).find('.itemSearchResult').each(
                function(index, element) {
                            //  Build item Array
                    if( $(this).attr('data-itemid')!= item ) {
                        itemArray.push( $(this).attr('data-itemid'));
                    }
                }
            );

             // Build SubList Array with items Array
            subListArray.push(
                    {
                        "subListName": subListName,
                        "subListID" : subListID,
                        "items" : itemsArray
                    }
            );
        }
); <!-- end SubList Loop -->

// Complete List Array with subListArray
ListArray ={
"ListName": ListTitle,
"ListID": List.attr('id'),
"subLists": subListArray
};
        // Send New List to DataLists Object - the local version of storage
updateDataLists(ListArray);
        // Update remote storage
window.location= URLstring + "&$Type=List" + "&$JSON=" + JSON.stringify(ListArray) + "&$objectID=" + ListArray.ListID;

};

似乎是'parent.remove()'步骤的交互,然后调用'sendList()'来交换它们的电线。在视觉上,屏幕上的对象看起来是正确的,但是如果我们检查发送到存储的数据,它将通过视觉上移除的对象来获取。

谢谢, Ĵ

PS。你可能会说,我们是Javascript的新手,所以我们的代码可能不是非常有效或正确。但是......它有效! (好吧,除了这个问题。我们已经遇到过这个问题了几次。我们有一个解决方法,但我想了解这里发生了什么。了解JS的更深层次的工作,所以我们不创建这些首先是问题。)

1 个答案:

答案 0 :(得分:4)

这里有一些事情要发生,但我将从异步编程的角度来解释它。

在元素从DOM中删除之前,您正在调用sendList 。在执行fadeOut回调(需要300毫秒)之后,才会从DOM中删除元素。

您的sendList函数会在您开始fadeOut后立即被调用,但您的程序不会等到sendList完成后才会调用fadeOut - 这就是回调是为了。

所以我会在你的DOM元素被删除之后通过调用回调中的sendList来接近它:

$('body').on('click', '.removeLine', function() {
    var el = $(this); //maintain a reference to $(this) to use in the callback
    var parent=$(this).parent().parent().parent();     //The button is a few DIVs shy of the outer container
    parent.fadeOut( 300, 
        function() {
            parent.slideUp(300);
            parent.remove(); 
            sendList(el.closest('article'));
       }
    );
});