Javascript DOMNodeRemovedFromDocument的简单变体观察者版本

Javascript DOMNodeRemovedFromDocument的简单变体观察者版本,javascript,dom,Javascript,Dom,我为DOM元素附加了一些功能,希望在从DOM中删除元素时能够清除所有引用,以便对其进行垃圾收集 我最初检测元素移除的版本如下: var onremove = function(element, callback) { var destroy = function() { callback(); element.removeEventListener('DOMNodeRemovedFromDocument', destroy); }; e

我为DOM元素附加了一些功能,希望在从DOM中删除元素时能够清除所有引用,以便对其进行垃圾收集

我最初检测元素移除的版本如下:

var onremove = function(element, callback) {
    var destroy = function() {
        callback();
        element.removeEventListener('DOMNodeRemovedFromDocument', destroy);
     };
     element.addEventListener('DOMNodeRemovedFromDocument', destroy);
};
然后我读到有人反对,赞成。所以我尝试移植我的代码。这就是我想到的:

 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
    });
};

这在我看来过于复杂(而且效率不高)。是我遗漏了什么,还是这真的是我应该做的事?

事实上。。。是的,有一个更优雅的解决方案:)

您添加的内容看起来不错,而且似乎优化得很好。但是,有一种更简单的方法可以知道节点是否连接到DOM

function onRemove(element, onDetachCallback) {
    const observer = new MutationObserver(function () {
        function isDetached(el) {
            if (el.parentNode === document) {
                return false;
            } else if (el.parentNode === null) {
                return true;
            } else {
                return isDetached(el.parentNode);
            }
        }

        if (isDetached(element)) {
            observer.disconnect();
            onDetachCallback();
        }
    })

    observer.observe(document, {
         childList: true,
         subtree: true
    });
}

observer.disconnect()
应该在
isDetached
案例中调用,对吗?@robert你能给我一个es5版本吗?很难从arrow函数中破解。(您还使用了在线编辑器无法转换的单箭头)还想知道上述代码是否适用于某些特定的DOM元素侦听器??(假设我替换了observer.observe(),我检查了tobib代码它在上述情况下运行良好这是CoffeeScript。现代浏览器支持箭头函数,但不支持CoffeeScript。我发现了一个更简单的
isDetached
检查,它使用
closest()
方法检查节点是否仍在文档中:
isDetached=(el)=>!el.closest('html')
请在js问题上发布js答案。