Is it possible to determine when setting an innerHTML has loaded? I'm not sure if it's a synchronous operation. I assume the 'building the DOM' is synchronous, but loading tags, contents, etc isn't.
So in a nutshell - is there a way to get an event when innerHTML has completed loading?
Thanks!
The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images.
The onload event occurs when an object has been loaded. onload is most often used within the <body> element to execute a script once a web page has completely loaded all content (including images, script files, CSS files, etc.).
It looks like @zahanm answer won't work if you replace the entire document HTML, which was what I needed. So I had to draw back to setInterval
. Based on @shawndumas answer I've created a more modern approach using Promise:
function waitUntilSelectorExist(selector, interval = 100, timeout = 20000) {
let intervalId;
let elapsed = 0;
let promise = new Promise(function(resolve, reject) {
intervalId = setInterval(() => {
let element = document.querySelector(selector);
if (element !== null) {
clearInterval(intervalId);
resolve(element);
}
elapsed += interval;
if (elapsed > timeout) {
clearInterval(intervalId);
reject(`The selector ${selector} did not enter within the ${timeout}ms frame!`);
}
}, interval);
});
return promise;
}
Also I use querySelector
instead, so you can search for whatever selector you like, either .class
, #id
, etc.
If the function ever find the querySelector
within the document the Promise
will resolve, so you can use it with the new await
keyword.
(async() => {
try {
await waitUntilSelectorExist("#test");
console.log("Do stuff!");
} catch (error) {
console.warn(error); // timeout!
}
})();
Of course you could also wrap around MutationObserver
within a Promise
if you are really just changing some elements within the document:
function waitUntilSelectorExist(selector) {
let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
let promise = new Promise(function(resolve) {
let observer;
observer = new MutationObserver(function(mutations) {
let element = document.querySelector(selector);
if (element !== null) {
observer.disconnect();
resolve();
}
});
observer.observe(document.body, { childList: true, subtree: true });
});
return promise;
}
You need to use DOM Mutation Observers, which currently only work in Chrome and Firefox. They replace the performance-killing DOM Mutation Events.
Example code, from HTML5Rocks:
var insertedNodes = [];
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
for (var i = 0; i < mutation.addedNodes.length; i++)
insertedNodes.push(mutation.addedNodes[i]);
})
});
observer.observe(document, { childList: true });
console.log(insertedNodes);
Here is the DOM4 spec.
Please, don't use the setTimeout()
hacks. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With