user2636556
user2636556

Reputation: 1915

jquery .one() load and error events not working

i have a simple html, that i want an event to trigger once the last image is loaded, or if there is an error on the last image being loaded. here is my code

html

<div id="compare-table-scrollable">
    <img src="www.bla.com/1.png" />
    <img src="www.bla.com/2.png" />
    <img src="www.bla.com/3.png" />
</div>

Jquery

var imageCount = $('#compare-table-scrollable img').length;
var counterIMG = 0;
$('#compare-table-scrollable img').one("load error",function(){
           counterIMG++;
           if (counterIMG == imageCount)  // do stuff when all have loaded
           {
                alert(counterIMG);
           }
});

here is my FIDDLE

Upvotes: 1

Views: 2810

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074385

You're not hooking the events until very late in the page load process, after the events have already fired. Note the second drop-down box on the upper left side of jsFiddle, which says "onload". This is jsFiddle's extremely surprising default, which is to wrap your JavaScript code in a window load event handler. That handler doesn't get fired until all the images have loaded or failed to load.

If you change that drop-down to no wrap - <body>, you get the alert: http://jsfiddle.net/X4AmG/3/

That said, with the images being specified in the markup, I'd be worried about a load or error event managing to get fired before your code hooked up its handlers. For that reason, I'd probably do something like this instead:

// Get the images
var imgs = $('#compare-table-scrollable img');

// Schedule the first check for DOM ready
$(checkForImagesDone);

// Our check function
function checkForImagesDone()
{
  var counter = 0;
  imgs.each(function()
  {
    if (this.complete)
    {
      ++counter;
    }
  });
  if (counter === imgs.length)
  {
    alert("All complete");
  }
  else
  {
    setTimeout(checkForImagesDone, 50); // 50ms
  }
}

Upvotes: 0

Reinstate Monica Cellio
Reinstate Monica Cellio

Reputation: 26143

Here's one I wrote myself a while back. It's very similar to what you have above, but a little more robust...

function onImagesLoaded($container, callback) {
    var $images = $container.find("img");
    var imgCount = $images.length;
    if (!imgCount) {
        callback();
    } else {
        $("img", $container).each(function () {
            $(this).one("load error", function () {
                imgCount--;
                if (imgCount == 0) {
                    callback();
                }
            });
            if (this.complete) $(this).load();
        });
    }
}

And how to use it...

onImagesLoaded($("#compare-table-scrollable"), function() {
    alert("images loaded");
});

Notice the addition of if (this.complete), which allows the function to count images that are cached and therefore load before the function is called.

Upvotes: 2

Related Questions