In web development, it's often necessary to know when an image has fully loaded, especially when performing actions that depend on the image being ready. This article explores various JavaScript methods to detect the load completion of both single and multiple images, covering traditional approaches and modern ES6+ features like Promises.
Understanding DOMContentLoaded vs window.onload
Before diving into image loading, it's important to distinguish between two key events:
DOMContentLoaded(or jQuery'sready): Fires when the HTML is fully parsed and the DOM tree is built, but external resources like images may not have loaded yet.window.onload: Waits for all resources (images, scripts, stylesheets) to be fully loaded.
For image-specific checks, we need to listen to the image's own load event, not the document's.
1. Single Image (Already in the DOM)
If the image element is already present in the HTML document:
<img id='myImage' src='https://example.com/image.jpg' >
Using jQuery:
$(document).ready(function(){
$('#myImage').load(function(){
// Image loaded successfully
console.log('Image loaded via jQuery');
});
});
Using Vanilla JavaScript (with cross-browser support):
var imgElement = document.getElementById('myImage');
imgElement.onload = imgElement.onreadystatechange = function(){
if(!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete'){
// Image loaded
console.log('Image loaded via vanilla JS');
}
};
Notes:
- Internet Explorer 8 and below do not support the
onloadevent for images, but they do supportonreadystatechange. - The
readyStateproperty indicaets the loading state; values"loaded"or"complete"mean the image is ready. - For brevity, the following examples will omit the
readyStatefallback, but consider it for legacy support.
2. Single Image (Dynamically Created)
When creating an image element dynamically via JavaScript:
var img = new Image();
img.src = 'https://example.com/image.jpg';
img.onload = function(){
// Image loaded
console.log('Dynamic image loaded');
};
3. Single Image with ES6 Promise
Promises provide a cleaner way to handle asynchronous events:
new Promise((resolve, reject) => {
let img = new Image();
img.src = 'https://example.com/image.jpg';
img.onload = function(){
resolve(img);
};
img.onerror = reject;
}).then((loadedImg) => {
console.log('Image loaded via Promise');
// Further operations with loadedImg
}).catch(() => {
console.error('Image failed to load');
});
4. Multiple Images (Traditional Appproach)
To track loading of several images, use a counter:
var images = [];
var loadedCount = 0;
var imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg',
'https://example.com/image4.jpg'
];
var totalImages = imageUrls.length;
for(var i = 0; i < totalImages; i++){
images[i] = new Image();
images[i].src = imageUrls[i];
images[i].onload = function(){
loadedCount++;
if(loadedCount === totalImages){
// All images loaded
console.log('All images loaded');
}
};
}
5. Multiple Images with Promise.all()
Using Promise.all() offers a more elegant solution:
let imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg',
'https://example.com/image4.jpg'
];
let loadPromises = [];
let images = [];
for(let i = 0; i < imageUrls.length; i++){
loadPromises[i] = new Promise((resolve, reject) => {
images[i] = new Image();
images[i].src = imageUrls[i];
images[i].onload = function(){
resolve(images[i]);
};
images[i].onerror = reject;
});
}
Promise.all(loadPromises).then((loadedImages) => {
// All images loaded
console.log('All images loaded via Promise.all');
}).catch(() => {
console.error('At least one image failed to load');
});
Summary
- For a single image in the DOM, use the
loadevent (withonreadystatechangeas fallback for older IE). - For dynamically created images, attach the
onloadhandler before settingsrc. PromiseandPromise.all()provide a modern, readable way to handle image loading, especially for multiple images.- Always consider error handling with
onerrorto catch loading failures.