How to wait until an element exists in JavaScript

Reading Time: 2 minutes 🕑

Last updated: August 26, 2022.

To wait to do something until an element exists in the DOM, you can use JavaScript MutatationObserver API.

As the name suggests, it can be used to listen out for changes in the DOM. You can then fire a (callback) function in response to this.

First, select the area you want to monitor for changes. In this example, we monitor the entire DOM for changes:

/* Select a target to observe */

// Select the entire DOM for observing:
const target = document.querySelector('body');

Next, create a new observer instance by calling new MutationObserver(). This accepts a callback function that runs when the change we are looking out for occurs.

When this callback function is run, we check if the DOM contains an element with an ID of new-div. If this is true, this element exists, and the message is logged to the console:

/* Create a new observer instance */

// Select the entire DOM for observing:
const target = document.querySelector('body');

// Create a new observer instance:
const observer = new MutationObserver(function() {
    if (document.getElementById('new-div')) {
        console.log("The new div was just appended!");
    }
});

Next, create a configuration object, containing the property childList: true. This specifies that we want to observe for any changes in child elements (e.g. if a new one is added).

Finally, call the observe method on the new observer instance, passing in the target (the DOM) and config (observe for changes in children).

/* Set configuration options and start the observer */

// Select the entire DOM for observing:
const target = document.querySelector('body');

// Create a new observer instance:
const observer = new MutationObserver(function() {
    if (document.getElementById('new-div')) {
        console.log("The new div was just appended!");
    }
});

// Set configuration object:
const config = { childList: true };

// Start the observer
observer.observe(target, config);

Try running this and nothing will happen. This is because every time there is a mutation in the DOM, the if statement is run but won’t be true.

But let’s now make it true after a slight delay, using setTimeout():

/* Working example, observer for a new <div> with ID 'new-div' */

// Select the entire DOM for observing:
const target = document.querySelector('body');

// Create a new observer instance:
const observer = new MutationObserver(function() {
    if (document.getElementById('new-div')) {
        console.log("The new div was just appended!");
        // Do something with new div element
        observer.disconnect();
    }
});

// Set configuration object:
const config = { childList: true };

// Start the observer
observer.observe(target, config);

// Create the mutation we are listening out for
setTimeout(() => { 
    const div = document.createElement('div');
    div.id = 'new-div';
    document.body.append(div); 
},3000);

It is good practice to stop observing if you are no longer listening out for something.

You can do this by calling the disconnect method on the observer instance. It is still possible to start the observer again at a later time.