jQuery .load() not firing on images (probably caching?)

13,436

Solution 1

A way would be to add a "dummy variable" at the end of the URL that you use to grab the image... such as the time in milliseconds appended as a query string param.

Edit: Preventing the Browser to Cache images is a very bad idea in 99% of the cases as it will slow down your application. Instead you should check if an image is already loaded, and if not wait for the load event to complete.

Solution 2

I think this has been discussed before. It’s not the caching per se that is the problem but the timing: the images may already have been loaded by the time the event handler is attached (so it never gets fired). This may also occur if no caching happens, for example in a multithreaded browser on a very fast connection. Fortunately, there is a property .complete that you can use:

var load_handler = function() {
    loadedImages++;
    …
}
$(this).find('img').filter(function() {
    return this.complete;
}).each(load_handler).end().load(load_handler);

You can also create your own event attach function:

jQuery.fn.extend({
    ensureLoad: function(handler) {
        return this.each(function() {
            if(this.complete) {
                handler.call(this);
            } else {
                $(this).load(handler);
            }
        });
    }
});

And then call it as follows:

$(this).find('img').ensureLoad(function(){
    loadedImages++;
    if(loadedImages == $this.find('img').length){
    …
});

Solution 3

As Ron and El Guapo said, the answer is to add a query at the end of the URL. I did this like this:

$(this).find('img').each(function(){
   $(this).attr('src',$(this).attr('src')+'?'+new Date().getTime())  
}).load(function(){
   //This will always run now!
Share:
13,436
Oscar Godson
Author by

Oscar Godson

Fork me on Github: http://github.com/oscargodson Read my stuff: http://oscargodson.com

Updated on June 14, 2022

Comments

  • Oscar Godson
    Oscar Godson almost 2 years

    I have some pretty basic jQuery code:

    ...
    $(this).find('img').load(function(){
       loadedImages++;
       if(loadedImages == $this.find('img').length){
    ...
    

    However, thats not firing consistently. It fires if i do a hard refresh or close my browser, but a normal refresh, or just hitting the same URL twice at any time without erasing the cache makes the .load() never fire.

    Any ideas on how to fix this?

  • Diodeus - James MacFarlane
    Diodeus - James MacFarlane about 13 years
    That's not crude, that's common practice. :)
  • El Guapo
    El Guapo about 13 years
    @Diodeus -- Very true... I'll edit the post so it doesn't look so ill-conceived... thanks.
  • hakunin
    hakunin over 11 years
    In case you are dynamically changing src of image and rely on "load" event to do something with it when it loads, you can trigger load manually if the image is in cache already by like so: image.attr('src', <newimage>); if(image[0].complete) { image.trigger('load') }
  • Johann
    Johann almost 11 years
    @Diodeus It's not common practice if your are creating HttpHandlers to rewrite Urls.
  • James Goodwin
    James Goodwin almost 11 years
    Whilst this does answer the original question, it prevents your images being cached by the browser, not ideal as it will slow down the page loading.
  • jeffkee
    jeffkee almost 11 years
    This is a very elegant solution, a better answer than the one accepted. The one that was accepted is a crude solution but it also prevents caching. In my app, there are 30+ high res photos showing up, so I had an issue where the first load would take a while until all images were loaded and sizes calculated (diff size each time), and when re-visiting, the cache caused the load() to not fire up at all. If I disable caching it will take long to load each time visitor comes in.
  • ChaseMoskal
    ChaseMoskal over 10 years
    @Diodeus: It is crude. You then are actually losing the magical wonders of cacheing -- something you definitely want on your website.
  • doug65536
    doug65536 over 8 years
    I've often heard this referred to as cache busting.
  • doug65536
    doug65536 over 8 years
    The delay caused by the cache miss just hides the problem though, in this case.
  • Kuzeko
    Kuzeko over 7 years
    I'm not sure if this is a good fix, but I had the same problem and I just needed to fire up some js when I was sure all images were loaded, so I solved by putting the listener on window $( window ).load(...)
  • Blackbam
    Blackbam about 6 years
    This definitly must be the accepted solution. Preventing the whole cache is a terrible idea!