2

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()  
Community
  • 1
  • 1
Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176

1 Answers1

3

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...

Community
  • 1
  • 1
Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
  • 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 - James MacFarlane Dec 02 '08 at 16:31
  • 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 Dec 02 '08 at 19:22
  • Yes, it worked out quite well, thank you. Now I have a progress bar while all the thumbnails are cached. – Diodeus - James MacFarlane Dec 03 '08 at 21:42