2017-07-05 24 views
1

我想检测当一个节点(节点X,说)不再可用,可能是因为它已被删除或因其父(或它的双亲父母)被删除。检测当一个节点被删除(或从DOM中删除,因为父母是)

到目前为止,所有我能想到的是使用突变观察员在页面上看到的任何删除,并检查删除的节点是节点X或有节点X的后裔。

有没有更简单的方法?


请注意:据我了解,该链接的问题(这个问题“是重复”)问“我怎么能检测[直接]删除一个节点”。我问“我如何检测节点或其父(或任何其他祖先)的删除”。

据我了解,这是不是与突变观察家简单:你需要检查每一个节点被删除,看它是否是一个祖先。

这是我寻求确认或否认。

据我理解,就是从链接的问题不同。

+1

*“有没有更简单的方法?”......你甚至尝试过吗? – charlietfl

+0

是的。我阅读了文档并尝试了似乎是合理的猜测。也许有一些我错过或误解了 – josinalvo

+0

(请注意,我并不是说我提出的方式太复杂了,我只是想知道是否有更直接的方法) – josinalvo

回答

3

这里是(直接地或者因为父除去

var target = document.querySelector('#to-be-removed'); 
 

 
var observer = new MutationObserver(function(mutations) { 
 
    // check for removed target 
 
    mutations.forEach(function(mutation) { 
 
    var nodes = Array.from(mutation.removedNodes); 
 
    var directMatch = nodes.indexOf(target) > -1 
 
    var parentMatch = nodes.some(parent => parent.contains(target)); 
 
    if (directMatch) { 
 
     console.log('node', target, 'was directly removed!'); 
 
    } else if (parentMatch) { 
 
     console.log('node', target, 'was removed through a removed parent!'); 
 
    } 
 

 
    }); 
 
}); 
 

 
var config = { 
 
    subtree: true, 
 
    childList: true 
 
}; 
 
observer.observe(document.body, config); 
 

 

 
var qs = document.querySelector.bind(document); 
 
qs('#ul').addEventListener('click', function(){qs('ul').remove();}, false) 
 
qs('#li').addEventListener('click', function(){qs('#to-be-removed').remove();}, false)
<ul> 
 
    <li>list item 1</li> 
 
    <li>list item 2</li> 
 
    <li id="to-be-removed">list item 3</li> 
 
    <li>list item 4</li> 
 
</ul> 
 

 
<button id="ul">remove ul</button> 
 
<button id="li">remove li</button>

0

这在堆栈溢出之前已经被问到了。 How to detect element being added/removed from dom element?

如果你只是要检查的东西是否存在在特定时间点,你可以很明显这样做:

if (!document.querySelector(".nonexistent")) { 
    console.log("doesn't exist"); 
} 

否则突变观察是你唯一的选择。

1

如果被去除的子树是接受的答案将会失败识别元件是如何除去一个实现从文档中移除后发生变异。例如:

target.parent.remove(); 
target.remove(); 

会产生一个调用突变观察员父节点去除(目标节点去除将不会被报告给观察者,因为它发生时,已经从文档中删除的子树)。作为目标不再是孩子

var parentMatch = nodes.some(parent => parent.contains(target));

在接受的答案

将返回false。问题是突变事件报告是批处理的,并且在删除节点时不能依赖状态保持与调用突变观察者时的状态相同。

出于这个原因,面临着类似的问题,因为提问者,我创建的目标节点的祖先的WeakSet。使用连接到文档根目录的突变观察者,我比较了这个集合和目标的突变。如果突变节点删除事件包含此集合或目标节点中的节点,我知道目标节点已从树中删除。这并不意味着该节点仍然被删除(它可能已被添加回去),或者该节点仍然是我的祖先的子集。但我可以肯定,该节点在过去被删除。

您必须小心区分突变后的DOM状态和当您收到突变事件时的状态。