I'm working on a Javascript/jQuery powered image preloader, and have hit a bit of a snag. While as of currently it provides the progress based on loaded_images / total_images
, this is not very accurate given a page could have a thousand 1kB images, and a single 1MB image.
I'm looking for a way to incorporate filesize into the progress calculations. Now, I've looked into some (cross browser compatible) tricks at capturing the filesize of a given image, and it seems that Ajax requests for Content-Length
were the most reliable (in terms of accuracy) like so:
var imageSizeTotal = 0;
var ajaxReqest = $.ajax({
type: 'HEAD',
url: 'path/to/image',
success: function(message){
imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
}
});
Now, I find this method to be quite useful, as I can provide a status message of Initializing while the necessary requests are taking place. However my issue now is two-fold:
- Is there any way possible to capture the bytes loaded of a given image object, perhaps using
setInterval()
to periodically check? Otherwise, I'm sort of back at the issue of the progress indicator hanging on large files. - How can I force the actual progress calculator, etc., portion of the script to wait until the necessary Ajax requests are completed (displaying Initializing or whatever), so it can go ahead with the loading?
Also, here's the script I currently use, which again, calculates progress based on the number of images, regardless of filesize or bytes received.
var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;
$('#preloaderCurtain')
.bind('preloaderStart', function(){
$(this)
.show();
$('*')
.filter(function(e){
if($(this).css('background-image') != 'none'){
preloaderTotal++;
return true;
}
})
.each(function(index){
preloaderCurrent = new Image();
preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
preloaderCurrent.onload = function(e){
preloaderLoaded++;
if(preloaderLoaded == preloaderTotal - 1){
$('#preloaderCurtain')
.trigger('preloaderComplete')
}
$('#preloaderCurtain')
.trigger('preloaderProgress')
};
});
})
.bind('preloaderComplete', function(){
$(this)
.fadeOut(500)
startAnimation();
})
.bind('preloaderProgress', function(e){
$('#preloaderProgress')
.css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
.text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
})
.trigger('preloaderStart');
Hopefully I'll be able to turn this into a plugin, once I work the bugs out of it.
setInterval()
based checks on the completion of the filesize array. When full, begin the preload. – Tetzel