Reputation: 149
I put together an image preloader which works fine, but what doesn't work is updating the status after every image that has been loaded. Instead, all images are loaded and "done" (last line) is the only thing that shows up. It does work when I use an alert instead of the innerHTML command, but that is obviously of no use. What am I doing wrong?
<div id="preloader">
<span id="preloader_status"> </span>
<script language="JavaScript">
imageObj = new Image();
images = new Array();
images[0]="bigimage.gif"
images[1]="anotherbigimage.gif"
/* and so on */
var i = 0;
var o = (images.length);
for (i=0;i<o;i++) {
var status = (Math.round(100*(i/o)));
imageObj.src=images[i];
document.getElementById("preloader_status").innerHTML = status;
}
document.getElementById("preloader_status").innerHTML = "done";
</script>
</div>
Upvotes: 0
Views: 409
Reputation: 707318
To show image load progress, you will need to hook into the onload
event for the images so you can track when their loading is actually complete. Images are loaded asychronously so assigning .src
only STARTS the loading of the image. It is not completed until later when the onload
handler is called. Because of that, your existing code will just immediately show "done" because it isn't tracking when the images are actually done loading.
In addition, you were successively assigning a new .src
value to the same image object which is going to abort the previous image loading. You need to create a new image object for each new image you are loading.
You can fix your code like this:
<div id="preloader">
<span id="preloader_status"> </span>
<script language="JavaScript">
var imageSrcs = [
"bigimage.gif",
"anotherbigimage.gif"
/* and so on */
];
function preloadImages(list, statusID) {
var img, cnt = 0;
var progress = document.getElementById(statusID);
var preloads = [];
for (var i = 0; i < list.length; i++) {
img = new Image();
img.onload = function() {
++cnt;
var loadPercent = Math.round(100*(cnt/list.length));
progress.innerHTML = loadPercent;
if (cnt == list.length) {
progress.innerHTML = "done";
}
}
img.src = list[i];
preloads.push(img);
}
}
preloadImages(imageSrcs, "preloader_status");
</script>
</div>
Upvotes: 1
Reputation: 29745
The for loop will happen almost instantly, because images load asynchronously; setting imageObj.src
will just start the image request and move on to the next. It will not block the execution of the loop. This will cause the effect you're seeing, i.e the last line of the code is executed straight away.
I think what you're looking for is the JavaScript Image onload
event, which will fire when an image has finished loading.
var image = new Image();
image.onload = function() {
// always called
alert('image loaded');
};
image.src = 'image.jpg';
Code was pinched from this article.
Upvotes: 1