How can I tell when changes to jquery html() have finished?
use .ready jQuery function
$("#divToChange").html(newHTML).ready(function () {
// run when page is rendered
});
As a commenter already mentioned, JavaScript is single threaded, so you can't get race conditions.
What may trip you up however, is the fact that the UI will not update itself based on JavaScript, until a thread is finished. This means that the entire method must finish, including all code after you call html(...)
, before the browser will render the content.
If your code after calling html(...)
relies on the layout of the page being recalculated before continuing, you can do something like this:
$("#divToChange").html(newHTML);
setTimeout(function() {
// Insert code to be executed AFTER
// the page renders the markup
// added using html(...) here
}, 1);
Using setTimeout(...)
with a time of 1
in JavaScript defers execution until after the current JavaScript code in the calling function finishes and the browser has updated the UI. This may solve your problem, though it is difficult to tell unless you can provide a reproducible example of the error you're getting.
It's 7 years latter and I just ran into a scenario exactly like the one @mikel described, where I couldn't avoid a "timer based solution". So, I'm just sharing the solution I developed, in case anyone out there is still having issues with this.
I hate having setTimeout
s and setInterval
s in my code. So, I created a small plugin that you can put where you think it's best. I used setInterval
, but you can change it to setTimeout or another solution you have in mind. The idea is simply to create a promise and keep checking for the element. We resolve the promise once it is ready.
// jquery.ensure.js
$.ensure = function (selector) {
var promise = $.Deferred();
var interval = setInterval(function () {
if ($(selector)[0]) {
clearInterval(interval);
promise.resolve();
}
}, 1);
return promise;
};
// my-app.js
function runWhenMyElementExists () {
// run the code that depends on #my-element
}
$.ensure('#my-element')
.then(runWhenMyElementExists);