How to Wait for All Images to Load in jQuery
Executing jQuery functions before images finish downloading often
causes incorrect dimension calculations, broken animations, or
unexpected layout shifts. While the standard
$(document).ready() executes as soon as the HTML structure
is parsed, it does not wait for external assets like images to render.
This guide explains how to properly delay jQuery execution until all
images are fully loaded across the entire page or within specific
containers.
Method 1: The Native Window Load Event
The simplest and most common method to wait for all page
assets—including stylesheets, scripts, and images—to load is using
jQuery's $(window).on('load', ...).
Unlike $(document).ready(), the load event
on the window object fires only after every resource has
completely downloaded.
$(window).on('load', function() {
// All images and resources are fully loaded
console.log('All images are loaded.');
// Run your layout or dimension-dependent code here
var imageHeight = $('#my-image').height();
});Method 2: Handling Specific Images with Promises
If you only need to wait for a specific set of images—such as an
image gallery—waiting for the entire page to finish loading can create
an unnecessary delay for users. You can use JavaScript
Promise.all() alongside jQuery to monitor a specific group
of images.
function waitForImages($container) {
var promises = [];
$container.find('img').each(function() {
var img = this;
if (!img.complete) {
var promise = new Promise(function(resolve) {
$(img).one('load error', function() {
resolve();
});
});
promises.push(promise);
}
});
return Promise.all(promises);
}
// Usage
$(document).ready(function() {
waitForImages($('#gallery')).then(function() {
console.log('All gallery images are loaded.');
// Initialize carousel, masonry, or other scripts here
});
});Checking img.complete is essential. If an image is
already cached by the browser, the load event might not
fire at all, causing code that relies strictly on event listeners to
hang indefinitely.
Method 3: Using the
imagesLoaded Library
For complex layouts like Masonry grids or infinite scrolling, handling cached images, CSS background images, and dynamically injected content natively can be tricky. The lightweight third-party library imagesLoaded is the standard solution in the jQuery ecosystem.
Once the library is included on your page, you can bind it directly to any jQuery selector:
$('#container').imagesLoaded()
.always(function(instance) {
console.log('All images are loaded or failed to load.');
})
.done(function(instance) {
console.log('All images successfully loaded.');
// Execute dependent code here
})
.fail(function() {
console.log('At least one image failed to load.');
})
.progress(function(instance, image) {
var result = image.isLoaded ? 'loaded' : 'broken';
console.log('Image is ' + result + ' for ' + image.img.src);
});Summary
- Use
$(window).on('load', ...)if your code depends on every image on the entire page and you do not want to use external libraries. - Use
Promise.all()withimg.completeverification if you only need to wait for images within a specific section of the page. - Use the
imagesLoadedlibrary when dealing with dynamic content, cached assets, or complex UI components like isotope and masonry layouts.