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:
setInterval()
to periodically check? Otherwise, I'm sort of back at the issue of the progress indicator hanging on large files.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.
It looks like a similar question was asked and answered here:
XmlHttpRequest.responseText while loading (readyState==3) in Chrome
and here:
Comet Jetty/Tomcat, having some browser issues with Firefox and Chrome
Basically - .responseText.length for Firefox and iPhone, .responseBody.length for IE, WebSockets for Chrome.
The second thread suggests bayeux/dojo encapsulate all this for you into a higher-level API so you don't have to write it yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With