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.
1 Answer 1
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.
-
\$\begingroup\$ I like this pattern
jQuery(function($) {
now you use thejQuery
variable in global scope and get a local variable ($
) pointing to jQuery. \$\endgroup\$Andreas Louv– Andreas Louv2015年05月28日 08:36:23 +00:00Commented May 28, 2015 at 8:36
meta
tag, but waiting for DOM ready is bullet-proof \$\endgroup\$