Observe mutations on a target node that doesn't exist yet

≡放荡痞女 提交于 2019-11-29 22:25:54

Only an existing node can be observed.

But don't worry, since getElementById is insanely fast compared to enumeration of all mutations' added nodes, waiting for the element to appear won't be taxing at all as you will see in Devtools -> Profiler panel.

function waitForAddedNode(params) {
    new MutationObserver(function(mutations) {
        var el = document.getElementById(params.id);
        if (el) {
            this.disconnect();
            params.done(el);
        }
    }).observe(params.parent || document, {
        subtree: !!params.recursive,
        childList: true,
    });
}

Usage:

waitForAddedNode({
    id: 'message',
    parent: document.querySelector('.container'),
    recursive: false,
    done: function(el) {
        console.log(el);
    }
});

Always use the devtools profiler and try to make your observer callback consume less than 1% of CPU time.

  • Whenever possible observe direct parents of a future node (subtree: false)
  • Use getElementById, getElementsByTagName and getElementsByClassName inside MutationObserver callback, avoid querySelector and especially the extremely slow querySelectorAll.
  • If querySelectorAll is absolutely unavoidable inside MutationObserver callback, first perform the querySelector check, on the average such combo will be much faster.
  • Don't use Array methods like forEach, filter, etc. that require callbacks inside MutationObserver callback because in Javascript function invocation is an expensive operation compared to the classic for (var i=0 ....) loop, and MutationObserver callback may fire 100 times per second with dozens, hundreds or thousands of addedNodes in each batch of mutations on complex modern pages.
  • Don't use the slow ES2015 loops like for (v of something) inside MutationObserver callback unless you transcompile and the resultant code runs as fast as the classic for loop.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!