How to tell when an image is already in browser cache in IE9?

IE9 is showing false complete property with the following:

$("<img/>",{src:"http://farm2.static.flickr.com/1104/1434841504_edc671e65c.jpg"}).each(function(){console.log(this.complete);});

If you run this code in a browser console, (allow enough time for the image to load) then run it again. IE9 is the only browser I’ve tested showing false the second time. This seems to be a known bug, from some simple google searching.
I need a workaround if anyone has one.

  • jQuery or JavaScript: Determine when image finished loading
  • How do I find the number of 'complete' images?
  • Are there useful uses of readyState different from “4” (complete) in a XHR.onreadystatechange callback?
  • This could be a timing issue, as letting the code above set a global variable a la:

    var img = $("<img....
    

    and then testing that variable’s properties gives different results:

    img[0].complete === true
    

    and

     img[0].readyState === "complete"
    

    There must be some other way of getting this infomation. Any ideas… Thanks!

  • How do I find the number of 'complete' images?
  • jQuery or JavaScript: Determine when image finished loading
  • Are there useful uses of readyState different from “4” (complete) in a XHR.onreadystatechange callback?
  • 5 Solutions collect form web for “How to tell when an image is already in browser cache in IE9?”

    I use this:

    function doWhenLoaded(obj,callback) {
    
    if($.browser.msie) {
        var src=$(obj).attr("src");
        $(obj).attr("src","");
        $(obj).attr("src",src);
    }
    
    $(obj).one("load",callback).each(function(){
        // alert(this.readyState+" "+this.src);
        if(
            this.complete
            || this.readyState == "complete"
            || this.readyState == 4
            || ($.browser.msie && parseInt($.browser.version) == 6)
        ) {
            $(this).trigger("load");
        }
    }); 
    }
    

    A sample:

    doWhenLoaded("#main_background_img",function(){
        $("#main_background_img").slideDown(1000);  
    }); 
    

    This is how i usually preload an image:

    var img = new Image();
    $(img).attr('src', "foo.jpg");
    if (img.complete || img.readyState === 4) {
        // image is cached
        alert("the image was cached!");
    } else {
        $(img).load(function() {
            // image was not cached, but done loading
            alert("the image was not cached, but it is done loading.");
        });
    }
    

    I haven’t deeply debugged it in IE9, but I haven’t ran into any issues with it.

    the code was pulled from https://github.com/tentonaxe/jQuery-preloadImages/blob/master/jquery.preloadimages.js and modified.

    You could try an AJAX request on the image and see the status code. If it’s 304 it means the image was cached. Not sure how well that would work though. Maybe AJAX does some cache-busting.

    I know this was asked a million years ago, but I figure I would contribute my solution which is similar but has less overhead and i/o.

    Basically, you create a custom jQuery method that performs the similar feats all in one function:

    $.fn.imgLoad = function(callback) {
        return this.each(function() {
            if(callback){
                if(this.complete || (this.readyState === 4) || (this.readyState === 'complete')) {
                    callback.apply(this);
                } else {
                    $(this).one('load.imgCallback', function(){
                        callback.apply(this);
                    });
                }
            }
        });
    }
    

    This consolidates the checking of all possible events into one (both cached and uncached), but also makes the method chainable. You can call it with:

    $('img').imgLoad(function(){
        console.log('loaded');
    });
    

    Works cross-browser, back to IE6. Notice it checks for caching first, and if not triggers a namespaced load event only once to prevent reloads in case you call the function with that logic twice, but also to allow custom load events to be bound (if applicable).

    You can’t tell if it’s cached, but you can force a fresh load by “salting” the filename:

    src:"http://farm2.static.flickr.com/1104/1434841504_edc671e65c.jpg?"+new Date()