Search code examples
javascriptmutation-observers

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


Is it possible to observer mutations on a DOM node that doesn't exist yet?

Example:

My app creates a div at some point: <div id="message" data-message-content="foo" data-message-type="bar" />.

I want to watch for the creation & change of this div.

var mutationObserver = new MutationObserver(function(mutations){
  // Some code to handle the mutation.
});

mutationObserver.observe(
    document.querySelector('#message'),
        { 
            attributes: true, 
            subtree: true, 
            childList: true, 
            characterData: false 
        }
    );
);

Right now this returns an error since #message is null (the div hasn't been created yet).

Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

An obvious solution is to watch the body and check if any of the mutations are the creation of div#Message, but this seems like a bad idea / or possibly bad for performance.


Solution

  • Only an existing node can be observed.

    You can use document.getElementById() in MutationObserver callback, it's super fast compared to enumeration of all mutated nodes (see also Performance of MutationObserver).

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

    Usage:

    waitForAddedNode({
        id: 'message',
        //parent: document.querySelector('.container'),
        recursive: true,
    }, el => {
        console.log(el);
    });