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级事件处理程序
[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