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

Posted

技术标签:

【中文标题】JS vs DOM 计时:.remove() 元素在视觉上发生,但遍历仍然包含它【英文标题】:JS vs DOM timing: .remove() element visually happens, but travesal still includes it 【发布时间】:2013-10-28 13:54:11 【问题描述】:

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

我在 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 的更深层次的工作原理,所以我们不会创建这些首先是问题。)

【问题讨论】:

【参考方案1】:

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

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

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

所以我会通过在回调中调用sendList 来处理它,在您的 DOM 元素被这样删除之后:

$('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'));
       
    );
);

【讨论】:

亚当,谢谢你的回复;很抱歉没有早点承认(我的想法)。但是,我还没有机会进行测试。上周是忙碌的一周。我还尝试在稍微不同的环境中执行此操作(Firefox 而不是我们通常的开发环境 Safari),并遇到了我们的 HTML 的问题:它使用 HTML 属性“onsearch”来挂钩要调用的函数,而不是一个更典型的 JQuery 绑定: $('#div').on ('search', function() )。我花了一些时间才弄清楚;正如我所说,对这个 JS 东西很陌生。 :)

以上是关于JS vs DOM 计时:.remove() 元素在视觉上发生,但遍历仍然包含它的主要内容,如果未能解决你的问题,请参考以下文章

JS:Html事件处理程序 vs DOM0级事件处理程序 vs DOM2级事件处理程序

jquery获取不到动态加载的dom元素是一种啥样的体验

[JS][jQuery]remove()与 empty()的差别

ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle

ES6 - 原生js遍历DOM - document.querySelectorAll(‘.xx‘)给DOM元素添加删除类名 - dom.classList.add切换类名toggle

Jquery 4种移除 清空元素的方法