我为DOM元素附加了一些功能,并希望在从DOM中删除元素时能够清除所有引用,以便可以对其进行垃圾收集,
我最初检测元素移除的版本是这样的:
var onremove = function(element, callback) {
var destroy = function() {
callback();
element.removeEventListener('DOMNodeRemovedFromDocument', destroy);
};
element.addEventListener('DOMNodeRemovedFromDocument', destroy);
};
然后我读到mutation events被MutationObserver取代了,所以我试着移植我的代码,这是我得到的结果:
var isDescendant = function(desc, root) {
return !!desc && (desc === root || isDecendant(desc.parentNode, root));
};
var onremove = function(element, callback) {
var observer = new MutationObserver(function(mutations) {
_.forEach(mutations, function(mutation) {
_.forEach(mutation.removedNodes, function(removed) {
if (isDescendant(element, removed)) {
callback();
// allow garbage collection
observer.disconnect();
observer = undefined;
}
});
});
});
observer.observe(document, {
childList: true,
subtree: true
});
};
这在我看来过于复杂(而且效率不是很高)。我是错过了什么还是这真的是应该的工作方式?
2条答案
按热度按时间agxfikkp1#
其实...是的,有一个更优雅的解决方案:)。
您添加的内容看起来不错,而且似乎经过了很好的优化。然而,有一种更简单的方法可以知道节点是否附加到DOM。
p5cysglq2#
在我看来,这个公认的答案是不可接受的,因为递归在不必要的时候是不好的,而且removednodes列表上的.contains()比遍历整个dom更快。或者,你可以定义一个自定义事件,并将其应用于任何你想监视其删除的元素,这里有一个使用变异观察器创建自定义“removed”事件的例子。