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

标签 javascript jquery json dom

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

我在 JavaScript 与 DOM 元素领域的时间问题上遇到了一些问题。可以删除已在右侧列表中的项目。我们有一些代码在 DOM 元素上的“删除/删除”类型图标/按钮上触发,应该从 DOM 中直观地永久删除该元素(即不需要通过“显示”将其带回').当 JS 遍历 DOM 树以构建新的更新列表时,此视觉变化也应该显示在构建的 JSON 对象中。

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

以下是我认为在此处运行的相关代码。这存在于网络浏览器中;其中大部分在 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()”的调用使它们的线路交叉。从视觉上看,屏幕上的对象看起来是正确的,但如果我们检查发送到存储的数据,它会与视觉上删除的对象一起通过。

谢谢, J

附言。您可能会说,我们在 Javascript 方面是新手,因此我们的代码可能不是非常高效或合适。但是......它有效! (好吧,除了这个问题。我们已经遇到过几次这个问题。我们有一个解决方法,但我宁愿了解这里发生了什么。了解 JS 的更深层次的工作原理,所以我们不会创建这些问题摆在首位。)

最佳答案

这里发生了一些事情,但我将从异步编程的 Angular 来解释它。

您正在 元素从 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'));
       }
    );
});

关于javascript - JS vs DOM 时序 : . remove() 元素在视觉上发生,但 travesal 仍然包含它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19471381/

相关文章:

json - 防止 Marshal 在结构的字符串字段上转义引号

javascript - 使用setInterval重新启动浏览器游戏

javascript - 在可编写脚本的浏览器插件中处理只读/只写属性的最佳方法

javascript - 在父窗口中调用 iframe 函数

jquery - 使用 jQuery 制作多个 div 动画

javascript - 在日期范围之间过滤数据表

javascript - Prototype - 形成原型(prototype)监听器和 dom 监听器的集合

javascript - Js库进入浏览器

java - 像这样的简单json。创建和解析

mysql - 从 mysql 存储过程中的 json 数据访问 json 对象