0

Trying to learn javascript, jQuery, etc. Wrote an image loader object that attempts to load an image, and if it gets a load error, loads a different image. On Chrome (for Mac), but not on Safari or Firefox, I've found that after a load error, when I request a different image, Chrome will report that the load is complete before it has actually completed. An abbreviated version of what I'm doing:

(function() {
    "use strict";

    RG.ImageReloader = {
        create: function($img, inUseThisFlower, inUseThisLizard, inSuccessCallback) {

            return Object.create(ImageReloader.prototype,
                {   '$img'              : { 'value': $img },
                    'useThisFlower'     : { 'value': inUseThisFlower },
                    'useThisLizard'     : { 'value': inUseThisLizard },
                    'successCallback'   : { 'value': inSuccessCallback }
                });
        }
    };

    var flushCache = function(url) {
        return url + '?' + new Date().getTime();
    };

    RG.ImageReloader.prototype = {

    go: function() {
        var that = this;

        this.$img.on('load', function() { that.success(); }).on('error', function() { that.error(); });
        this.$img.attr('src', flushCache(this.useThisFlower));
    },

    error: function() {
        this.$img.attr('src', flushCache(this.useThisLizard));
    },

    success: function() {
        this.$img.off('load error');
        this.successCallback.call(this.$img);
    }

    };

}());

var r = RG.ImageReloader.create($('img'), someFlowerImage, someLizardImage, imageReady);
r.go();

For me, running Chrome 28.0.1500.95 (latest), this fiddleshows the problem. Although the code waits for all images to report completion, you can see that sometimes a partial table of images appears and the lizard appears afterward. You can also see that sometimes the image width and height are reported as zero. After lots of banging my head on the wall, I found that when the load error occurs, I have to use attr('src', ''), catch the error that results from doing so, and only then attempt to load the fallback image. Now my loader object works as expected. You can see the difference in this fiddle. Am I seeing the normal behavior, or a browser quirk, or am I doing something wrong or non-best-practice in my code?

P.S. I've read the jQuery notesfor .load() , and it does say something about cross-browser inconsistency and unreliability, but I wondered whether I'm just seeing that or actually doing something wrong, or if there's a more best-practices way to do it.

SaganRitual
  • 3,143
  • 2
  • 24
  • 40

2 Answers2

0

Try to call the image handler functions in the window.load event, not in document.ready:

$(window).load(function(){
//Handle images after they loaded
});
0

This seems to have gone unanswered, but I read in a comment to an answer on another question that the source of this Chrome OSX bug is solved with

if(newImg.complete || newImg.readyState === 4) {
     newImg.onload();
}

where img has been assigned with img = new Image();

Not an expert on JQuery but this ought point you in the right direction :-)

Community
  • 1
  • 1
Louis Maddox
  • 5,226
  • 5
  • 36
  • 66