0

I am working on a Phonegap application in which I am trying to display a varying amount of images to the user. My GUI follows the principles found in this article.

I know how many images I will be getting before I make my ajax GET request, so I add the correct amount of images that display a loading gif to the relevant div using jQuery's append method. I then begin my ajax request.

In my success callback I have the following method

imageblock.forEach(function(entry)
{   
    changeImage(i, entry, i*1000);
    i++;                            
});

the changeImage() function is as follows:

function changeImage(index, src, timeout)
{
    setTimeout(function()
    {
        $("#image"+index).attr("src", 'data:image/png;base64,'+src);
    },timeout);
}//changeImage

Without using the setTimeout() I have observed the app to hang while it renders the images. So this works just fine, as it apparently gives the browser enough time to render the image.

I was wondering if there was a better way than waiting a fixed interval of time to load the next image. I looked into onLoad() but that seems to fire when I originally create the image tag that displays the loading gif. Is there any way to tell when the image is done rendering?

DrS
  • 301
  • 1
  • 2
  • 14
  • As per this: http://stackoverflow.com/questions/910727/jquery-event-for-images-loaded you should use this: https://github.com/desandro/imagesloaded – datashaman Jan 28 '14 at 16:15

4 Answers4

0

You can use the 'Image' class in Javascript. You do this by creating a new instance of the Image class and add an 'onload' event (which is dispatched when the image is loaded correctly).

Sample code:

function changeImage(index, src, timeout)
{
    setTimeout(function()
    {
        $("#image"+index).attr("src", 'data:image/png;base64,'+src);

        var img = new Image();

        img.src = 'data:image/png;base64,'+src;
        img.onload = function() {
            alert("Image loaded!");
        };
    }, timeout);
}//changeImage
Dillen Meijboom
  • 961
  • 6
  • 13
0

I recently researched on this subject and found some solutions, was it on SO or blog posts. I ended up trying the solution from Paul Irish , which seemed to be the ultimate working solution. Unfortuntely, I never got it to work properly on all browsers, so I just left this idea aside and will check periodically if anything exists that works in all cases...

Community
  • 1
  • 1
Laurent S.
  • 6,501
  • 2
  • 26
  • 39
0

You can use imagesloaded (https://github.com/desandro/imagesloaded)

Using imagesLoaded you can set an event handler to know when an image is loaded.

var imgLoad = imagesLoaded("images_selector");
function onAlways( instance ) {
  console.log('all images are loaded');
}
imgLoad.on( 'always', onAlways );
Usse
  • 66
  • 5
0

Here is what I ended up doing:

Instead of creating a placeholder loading image for each image I am expecting, I create a single loading image, and then perform my ajax GET. In my success callback, I save each of the images into an array (in my case the 'images' are base64 encoded). Once I have them all in an array, I manually call the method loadNextImage(i) which will create a new image that has the onLoad property onLoad="loadNextImage(i++)". This seems to have the desired effect of loading each image sequentially and doesn't slow down too bad.

For anybody interested here is my new success callback:

imageblock.forEach(function(entry)
{   
    images[i] = entry;
    i++;
    currentimagesdisplayed = i;
});
loadNextImage(0);

and here is the loadNextImage() function:

function loadNextImage(i)
{
    var id = 'image'+i;
    var src = 'data:image/png;base64,'+images[i];
    i++;
    var onload = 'loadNextImage(' + i + ')';
    if(!(i>images.length))
    {
        $('#TownClerkPortalResultsImages').prepend('<img height="50%" width="100%" id ="' + id + '" src ="' + src + '" onLoad="' + onload + '"  />');
    }//if
    else
    {
        $("#recordsloader").hide();
    }//else

I will mess around with some css to see if I can't make it look fancy and have them fade in or something. If this still is unsatisfactory I will look into the other answers.

DrS
  • 301
  • 1
  • 2
  • 14