CpILL
CpILL

Reputation: 6999

How to tell if an image is loaded or cached in JQuery?

Seems the .load() function doesn't fire if the image has been cached before. So if you want to make sure one images has loaded before you load and show another (i.e. Magnifier) you can't do something like:

$(img_to_load_first)
    .load(
        $(img_to_load_last)
            .src("2nd.png");
    )
    .src("1st.png");

So how does one ensure loading order in JQuery?

Upvotes: 6

Views: 12849

Answers (4)

chriscrossweb
chriscrossweb

Reputation: 348

You can also check if your image has a width or height to detect if it has already loaded.

For example:

var img = _content.find('img');
  if(img[0].width >0 || img[0].height > 0 ) {
  console.log('already loaded image');
  } else {
  img.on('load', function() {
    console.log('image loaded');
  });
}

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

If you want to wrap all this functionality in a jQuery extension method, try this (which should work waiting for any number of images):

$.fn.imagesLoaded = function () {
    var def = $.Deferred();
    var count = this.length;
    this.each(function () {
        if (this.complete) {
            if (!--count) {
                def.resolve();
            }
        } else {
            $(this).load(function () {
                if (!--count) {
                    def.resolve();
                }
            });
        }
    });
    return def.promise();
}

and then simply use like this:

$(img_to_load_first).imagesLoaded().done(function () {
    $(img_to_load_last).src("2nd.png");
});

Upvotes: 2

CpILL
CpILL

Reputation: 6999

Thanks Sparkey,

I'll give that a try but it looks good. I found a extensive discussion on the topic here: http://www.bennadel.com/blog/1007-jQuery-Attr-Function-Doesn-t-Work-With-IMAGE-complete.htm

which lead me to the "jQuery 'onImagesLoad' Plugin" here: http://includes.cirkuit.net/includes/js/jquery/plugins/onImagesLoad/1.1/documentation/

which seems to solve the issue like so:

$imgs.each(function(i, val){
    $(this).bind('load', function(){
        // ...
    }).each(function(){
        if (this.complete || this.complete === undefined){ this.src = this.src; } //needed for potential cached images
    });
});

Which pretty much boils down to what you said, only his completed check also test for "undefined".

Upvotes: 2

sparkey0
sparkey0

Reputation: 1690

What you'll have to do is handle your load bindings selectively. You can verify load by testing the Image object property complete.

For example:

$('.load_selector').each(function(){

    if (!this.complete) {
        $(this).load(function(){
            // handle image load event binding here
        });
    } else {
        // handle image already loaded case
    }

});

Note that above, this (used alone) refers to the DOM reference to the image object provided by jQuery.

Upvotes: 18

Related Questions