simple MutationObserver version of DOMNodeRemovedFromDocument

 ̄綄美尐妖づ 提交于 2020-01-22 14:16:46

问题


I attach some functionality to DOM elements and want to be able to clear all references when the element is removed from the DOM so it can be garbage collected,

My initial version to detect the removel of an element was this:

var onremove = function(element, callback) {
    var destroy = function() {
        callback();
        element.removeEventListener('DOMNodeRemovedFromDocument', destroy);
     };
     element.addEventListener('DOMNodeRemovedFromDocument', destroy);
};

Then I read that mutation events were deprecated in favor of MutationObserver. So I tried to port my code. This is what I came up with:

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

This looks overly complicated to me (and not very efficient). Am I missing something or is this really the way this is supposed to work?


回答1:


Actually... yes, there is a more elegant solution :).

What you added looks good and seems to be well optimized. However there is an easier way to know if the node is attached to the DOM or not.

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


来源:https://stackoverflow.com/questions/31798816/simple-mutationobserver-version-of-domnoderemovedfromdocument

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!