HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Use Promise to wait until DOM element exists

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
untilwaitpromisedomelementexistsuse

Problem

I need to create a JavaScript Promise that will not resolve until a specific HTML element is loaded on the page.

I don't have any way of knowing when this element will be loaded, other than to simply poll the DOM for it.

It seems there should be a more concise way to accomplish this task. I don't want anything that's "clever" to the point of being difficult to understand, but I'm open to any feedback on this pattern.

The code must be ES5 compatible for the most part. Polyfills are probably ok, but it has to run on IE10+.

function getContainer() {
    return new Promise(function (resolve, reject) {
        waitForContainerElement(resolve);
    });
}

function waitForContainerElement(resolve) {
    var $configElement = $("#container");
    if ($configElement.length === 0) {
        setTimeout(waitForContainerElement.bind(this, resolve), 30);
    } else {
        resolve($configElement);
    }
}


Usage:

getContainer.then(function($container){
    ...
});


I would normally implement a max poll time, but didn't want that to cloud the issue here.

Solution

One idea would be to put the script tags at the end of the document's body - not in the head at all. It's a common trick in itself, often used to speed up load time, because it means no time is spent parsing scripts before moving on to the page's actual content. It also means that the scripts will have everything that's "before" them in the DOM ready for use.

Alternatively: If you're unwilling to move all the scripts, but still willing to simply wait for the document to report ready, there's no need for polling. See MDN's documentation for more. You may want to check document.readyState first, since attaching an event listener too late (after the document has loaded), is pointless: The event only fires once.

But wait! It appears you're already using jQuery, in which case all you have to do is:

$(function () {
  // code to run on document ready
});


That code can resolve a promise, but usually you'd just put that in your various scripts to make sure they only run once the document's ready (e.g. $(initWidget); where initWidget is whatever function kicks something off). It's how most jQuery scripts are written.

Code Snippets

$(function () {
  // code to run on document ready
});

Context

StackExchange Code Review Q#91947, answer score: 4

Revisions (0)

No revisions yet.