3
votes

I have a code that post to a php script that reads all files in a folder and returns them, all of them are img's, the jquery parses the information, on a var that's an array each image is saved as an img object with the src , width, height and attr, on successed I want to check if each image is loaded and then finally on complete fire another function and remove a div. But I don't know how to check if the image has loaded completely, I've been fooling around with .complete but it never seem's to load, the function calls itsef upon until the img is loaded and then returns true so it can keep going. here's the code, it's kind of messy and probably not a nice coding.

var gAllImages = [];
function checkFed()

{
    var leni = gAllImages.length;   
    for (var i = 0; i < leni; i++) {


        if (!gAllImages[i].complete) {
            var percentage = i * 100.0 / (leni);
            percentage = percentage.toFixed(0).toString() + ' %';
            console.log(percentage);
            //  userMessagesController.setMessage("loading... " + percentage);
            checkFed();

            return;

        }

    //userMessagesController.setMessage(globals.defaultTitle);
    }
}


 if($('slideshow')){
 var topdiv = '<div id="loading"><div class="centered"><img src="/karlaacosta/templates/templatename/images/ajax-loader.gif" /></div> </div>';
    $('#overall').append(topdiv);
    //console.log('alerta');
    var jqxhr = $.post('http://localhost/karlaacosta/templates/templatename/php/newtest.php', function(data){



        var d = $.parseJSON(data);
        //console.log(d[1]);



        if(typeof(d) == 'object' && JSON.parse){
            var len = d.length;
            //console.log(len);



            for(var i = 0; i < len; i++){
                var theImage = new Image();
                var element = d[i].split('"');
                //        console.log(element);
                //      console.log(element[4]);
                theImage.src = '/karlaacosta/images/Fotografia/TODO'+element[0];
                theImage.width = element[2];
                theImage.height = element[4];                   
                theImage.atrr = element[6];
                gAllImages.push(theImage);

            }





        // console.log(html);
        }else{
            console.log('error');
        }
    }).success(function (){




    setTimeout('checkFed', 150);




    }).error(function(){
        var err = '<div id="error"><h2>Error: Lo sentimos al parecer no se pueden cargar las imagenes</h2></div>';
        $('#loading').append(err);

    }).complete(
        function(){
            var len = gAllImages.length;
            var html = '<ul class="slides">'    
            for(var i = 0; i < len; i++){
                html += '<li><img src="'+gAllImages[i].src+'" width="'+gAllImages[i].width+'" height="'+gAllImages[i].height+'" attr="'+gAllImages[i].attr+'" /></li>';


            }
            html += '</ul>';
            $('#slideshow').append(html);
        }
        );
 jqxhr.complete(function(){
    //
    imageSlide();
    $('#loading').remove();
    //
    console.log('completed');
});
}

If I take out the recursivity of checkFed() obviously the script finishes and when the images are put on the html they are loaded fine and fast, are in the cache never being loaded? any other sugestions on other parts of the code are also welcomed.

3
You can use the img load callback. stackoverflow.com/questions/3877027/…lucuma
I don't have time to analyze and answer this right now, but just note that setTimeout(checkFed(), 4000); does not schedule checkFed to run four seconds from now. It runs checkFed right away and then passes its return value to setTimeout. I don't see that checkFed returns a function, so that might be part of the problem. Remove the () from after checkFed if your goal is to schedule it to run four seconds later.T.J. Crowder
I would like to answer this question but I do not have time at the moment. It seems the provided answers won't make the cut.Alexander

3 Answers

7
votes

I want to check if each image is loaded and then finally on complete fire another function and remove a div. But I don't know how to check if the image has loaded completely

Fundamentally, checking for image load success is simple:

var theImage = new Image();
var element = d[i].split('"');
$(theImage).load(function() {
    // The image has loaded (from cache, or just now)
    // ...do something with the fact the image loaded...
});
theImage.src = '/karlaacosta/images/Fotografia/TODO'+element[0];

The key thing above is to hook the load event before you set its src. If you set src first, and the image is in cache, the load event can fire before the next line of code hooking it, and you'll miss it.


Here's an example: Live copy | source

HTML:

<img src="http://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG">
<p>When you see the image above, 
<input type="button" id="theButton" value="Click Me"></p>

JavaScript:

jQuery(function($) {

  $("#theButton").click(function() {
    var img = document.createElement('img');
    $(img).load(function() {
      display("Image <code>load</code> event received");
    });
    img.src = "http://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG";
    document.body.appendChild(img);
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

As you can see, I'm using the same img src in each case. And reliably on every browser I've ever tried, I do receive the load event.

0
votes

Its not doable in a reliable cross browser way without a plugin, due to browser caching and event model weirdness. Try imagesLoaded or waitForImages.

https://github.com/desandro/imagesloaded

https://github.com/alexanderdickson/waitForImages

0
votes

Nowadays you should definitely just check the .complete value. Example:

var imgs = document.querySelectorAll("img");
imgs.forEach(function(e) { console.log(e.src + ":" + e.complete); });

For details, see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/complete

All the hacks that try to collect URLs and use new Image() and set .src and follow progress events will fail if the cache headers do not allow suitable caching to allow another image from same URL to be used as a proxy for loading the image in the actual content. Note that even if that proxy detection would somewhat work per caching, it could still fail in practice if browser implemented e.g. image rendering asyncronously.

If .complete is not supported by the user agent, following the progress events for the proxy object is the least bad option to do. However, if .complete is supported, it's the only real way to query the real status.