views:

1706

answers:

1

I am building a slideshow with a few hundred images and would like to build a nice loading bar, so the idea was to preload the images using JavaScript, then initialize the rest of the UI afterwords.

Preloading the images is not a problem, but getting the browser to update the status as things load is. I've tried a few things, but the browser will only repaint the display after it finishes.

I've even tried the script from this question, but I get the same results.

Here's what I've got so far (imgList is an array of filenames. I'm using Prototype.)

var imageBuf = []
var loadCount = 0
$('loadStatus').update("0/"+imgList.length)

function init() {
    imgList.each(function(element){
     imageBuf[element] = new Image()
     //imageBuf[element].onload = window.setTimeout("count()",0) // gives "not implemented" error in IE
     imageBuf[element].onload = function(){count()}
     imageBuf[element].src = "thumbs/"+element
    })
}

function count() {
    loadCount++
    $('loadStatus').update(loadCount+"/"+imgList.length)
}

init()
+2  A: 

Try using the function from my answer to this question:

function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) {
  var itemIndex = 0;
  (function() {
    var remainingDataLength = (data.length - itemIndex);
    var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength;
    if(itemIndex < data.length) {
      while(currentChunkSize--) {
        workerCallback(data[itemIndex++]);
      }
      setTimeout(arguments.callee, timeout);
    } else if(completionCallback) {
      completionCallback();
    }
  })();
}


// here we are using the above function to take 
// a short break every time we load an image
function init() {
  incrementallyProcess(function(element) {
    imageBuf[element] = new Image();
    imageBuf[element].onload = function(){count()};
    imageBuf[element].src = "thumbs/"+element;
  }, imgList, 1, 250, function() { 
    alert("done loading"); 
  });
}

You may want to modify the chunk size parameter as well as the length of the timeout to get it to behave just like you want it to. I am not 100% sure this will work for you, but it is worth a try...

Jason Bunting
That's very slick Jason. Nice work. You'll likely get the answer for this one, but I will leave the question open until tomorrow.
Diodeus
If it works, that's great. I use this in my own projects where we are loading large quantities of data - giving the user the perception that something is happening, even if incrementally, is better than the app stalling and dumping everything into the UI at once.
Jason Bunting
Yes, it worked out quite well, thank you. Now I have a progress bar while all the thumbnails are cached.
Diodeus