Grow your CSS skills. Land your dream job.

Last updated on:

Fixing .load() in IE for cached images

The .load() function fires when the element it's called upon is fully loaded. It is commonly used on images, which may not be fully loaded when the JavaScript originally runs, and thus would return incorrect information about themselves (e.g. height/width). Most browsers deal with this fine. IE can cause problems, when images on the page are cached.

Selecting the image and changing it's src attribute to append a random parameter (based on the date). This will trick IE into firing the .load() function properly.

myImge = $("<img />")
   .attr("src",anyDynamicSource+ "?" + new Date().getTime());

Now the .load() function will work, even in IE:

$(myImge).load(function() {
   alert("will alert even in IE")
});
See the first comment for a warning about using this technique with a CDN.

Comments

  1. This method can really hurt some cdn servers. By calling the image with ‘?[whatever randomness you want]‘ you are creating a copy of that file that propagates through the server farm with that extra randomness as the file name.

    someImg.jpg -> someImg.jpg gets propagated to the cdn.
    someImg.jpg?20100318000302 -> someImg.jpg?20100318000302 gets propagated to the cdn.
    someImg.jpg?20100318000303 -> someImg.jpg?20100318000303 gets propagated to the cdn.

    On smaller sites that don’t use cdn this may be a fine method, but it is not a viable option for higher end sites (CNN.com, PGATOUR.com, NBA.com, etc).

    • Eliazer
      Permalink to comment#

      Thanks, Which solution would you suggest in such a case?

      Thanks again.

    • Sorry Eliazer, I still do not have a solution for this case.
      I was just making it a point to bring it up as my team got dinged pretty hard for doing this type of method, and I wanted to help others avoid it if possible.

    • Mark
      Permalink to comment#

      To avoid breaking caching and CDNs I append the image’s MD5 as a parameter, this also works to force browsers to update cached CSS files. Here’s an example of a cached CSS link emitted from PHP, image links should be constructed in the same way:

      <?php
          // returns the URL with its MD5 appended as a variable (used to force browsers to update their cached stylesheets)
          function AppendMD5Variable($url)
          {
              // get the $url's md5
              $md5 = md5_file($url);
              // return the url with the md5 appended as a variable
              return $url.'?md5='.$md5;
          } 
      ?>
      <link rel="stylesheet" href="<?php echo AppendMD5Variable("http://www.somesite.com/wp-content/themes/company/reset.css") ?>" type="text/css" media="all" />
      

      which emits:

      <link rel="stylesheet" href="http://www.somesite.com/wp-content/themes/company/reset.css?md5=d18499a24db47778f4147ee7a6b84434" type="text/css" media="all" />
      

      Hope this helps someone (and I hope this is formatted well, not used ‘markdown’ before).

  2. Permalink to comment#

    jQuery 1.4.2 already does this for you (using the $.ajax() function however). Just put cache : false to the AJAX setup and it should do it for you.

    • TeMc
      Permalink to comment#

      This has nothing to do with AJAX requests, it’s about normal img-tags and firing a function when the image is loaded (ie. [img onload=this-function /]), and not about $(target).load(‘http address’, function(){}); which is something totally different.

      jQuery has several functions with equal names, and depending on the context something may mean something different.

      such as click() means trigger the click event, but click(function(){ }), means bind a click handler.

      See also

      http://api.jquery.com/load/

      http://api.jquery.com/load-event/

  3. Permalink to comment#

    Thanks for this. I think I will take a slightly different approach in my case. The problem with doing it this way is that you loose all the benefits of image caching in all other browsers and I don’t want to reduce everyone elses experience just because of IE7.

    Instead I am going to leave the .load function there but also have a setTimeout function that will do the same as the load (since in my case it’s only removing a class it’s not a problem). I am sure there’s a better way though. Anyone?

    • Matt

      Excellent find Ben!!!

      This is a much better solution. Chris should add this to his blog post!!!

      It doesn’t break caching, and it works in old IE.

  4. as John Jimenez mentioned, given method will increase CDN hit ratio, there is an easier method to accomplish this, heres pseudo code:

    $('img').each(function() {
        if ($(this).height() > 0) {
           our callback
        } else {
           $(this).load(function() {
             our callback
           });
        }
    });
  5. Permalink to comment#

    Thanks. Now it is working in all browsers great.

    var url = any dynamic url;
    var img = new Image();
    $(“<img/>”) // Make in memory copy of image to avoid css issues
    .attr(“src”, url+ “?” + new Date().getTime())
    .load(function() {
    // Do any stuff
    });

    • vishal suri
      Permalink to comment#

      Hello bhanu partap , i need your help , i am suffering from same issue , but not able to get clear

  6. I have the same problem but not sure where to start fixing it. Could someone please spend two mins and have a quick look at this problem.
    URL: http://www.media21a.co.uk/development/unknown/

    Any/All help will be credited thank you.

  7. Here is a one line solution that you can use insted of $(‘img’).load(function(){ //// });

    
    $('img').each(function(){  this.src = this.src + '?random=' + (new Date()).getTime()}).load(function(){
     alert("will alert even in IE")
    });
    
  8. I was struggling with this issue on one of the sites I’m making and actually there’s a bit better way to fixing this. It turn out the bug is fixed if you add “load” first and only after that change “src” for the image.

    So actually the best way would be to

    $('img').load(function() { ... }).attr('src', 'new_image_source'); 

    it worked for me as a charm on multiple runs for the same already cached images.

    Have a nice day

  9. Permalink to comment#

    Thank You Rytis! Very simple, but very effective. Kind of makes sense really ;)

  10. Mark
    Permalink to comment#

    Thank you Jeebus for the existence of this page. And props to Rytis and Chris too.

  11. Jet
    Permalink to comment#

    Depending on what you’re doing, this also does the trick:
    $('').load(function() { // }).load();
    So yeah, in other browsers your function might get called twice, but it shouldnt be too hard to check for this one.

  12. Reinier Kaper
    Permalink to comment#

    Rytis: you saved my life man!
    IE7 was giving me a hard time with this and I didn’t prefer the method of appending a timestamp because of the issues raised before.

    Thanks!

  13. Glad I could help :) it saved my own sanity also :D

  14. Props to Rytis for that … this worked for me

    
        $('.look-book-wrapper img').each(function() {
    	
    	   var new_image_source = ($(this).attr('src'));	
     
           $(this).load(function() {
        		$(this).fadeIn('slow');
        	})
        	.attr('src', new_image_source); 
        	//.attr({src: $(this).attr('src') + '?time=' + (new Date()).getTime() });
        });
    
  15. Bjørn T.

    Rytis: Thanks for saving my day, and the little hair I’ve got left from all the frustration.

  16. Thank you so much! Its works great!

  17. Thanks a lot. useful like always.

  18. Permalink to comment#

    Rytis, you the man!! Thanks.

  19. Permalink to comment#

    Oooo!! Is there anything you don’t know?
    I prefer the solution of Chris because it fits better to my code.

  20. John
    Permalink to comment#

    Why are you wrapping it in jQuery twice?

    myImge = $("")
    $(myImge).load(...)
    

    So that is equivalent to $($("<img />"))

  21. Hank
    Permalink to comment#

    Thanks a lot Nme, check the height instead of using the load was the way to go to solve the problem with the older versions of IE that do not fire the load function a second time.
    You sir just saved my day.

  22. Permalink to comment#

    Thanks rytis.

  23. Nut315
    Permalink to comment#

    Just a note on some of the answers. $("#element").load(function() { }); has been depreciated as of jQuery 1.8 and should be replaced with the following:

    
    $("#element").bind("load", function() { });
    
  24. Raghav
    Permalink to comment#

    Thanks for the post. I was having exactly the same issue. Fixed it in straight way i used your code

  25. Lucian Adamson
    Permalink to comment#

    I know browser sniffing is considered bad practice, however on something like this where checking for support isn’t what you need I think it would be rightly justified. As a person commented earlier, why sacrifice the caching of other people and slow their experience for the other users who chose the frowned upon IE route. You could just check if browser is IE and apply this method, if you don’t use CDN that is.

  26. I think I came up with a better solution that a) Works no matter when you attach the onload handler – before or after setting the src – and b) doesn’t create copies of your images on the server.

    Turns out, you don’t have to add a random query param to the image. Simply do this:

    $("img").attr("src", $("img").attr("src"));
    

    As you can see, the src attribute is set to the same value it was before. That way, IE doesn’t even reload the image, it just fires the onload Event, which is exactly what we want. :-)

  27. vipul
    Permalink to comment#

    here better solution with jquery.

    $("img").one('load', function() {
    // your code here
    }).each(function() {
    if(this.complete) {
    $(this).load();
    }
    });

  28. Permalink to comment#

    Is there any benefit in using a ‘#’ rather than a ‘?’ in the querystring? I’ve seen instances where a ‘#’ will still use the cached image rather than a cache breaking ‘?’ – such as http://www.post-hipster.com/2008/10/20/using-javascript-to-refresh-an-image-without-a-cache-busting-parameter/

    • Brad
      Permalink to comment#

      That seems like a valid point. Can’t read the linked article as I’m at work but I would imagine the pound sign might be less disruptive than a param question mark.

  29. Mark
    Permalink to comment#

    Hi, I need load background image for div.

    <div id="low"></div>
    <div id="high"></div>
    

    When I click on low, so I need show high with background image. In Chrome etc. I have solution, but in IE after click background of div flashes.

    Thank you for your tip.

  30. thinsoldier
    Permalink to comment#

    It seems Firefox 33 is just as unreliable when it comes to load events for cached images. :(

Leave a Comment

Posting Code

  • Use Markdown, and it will escape the code for you, like `<div class="cool">`.
  • Use triple-backticks for blocks of code.
    ``` 
    <div>
      <h1>multi-line block of code</h1>
      <span>be cool yo.</span>
    </div>
    ```
  • Otherwise, escape your code, like <code>&lt;div class="cool"&gt;</code>. Markdown is just easier though.

Current ye@r *

*May or may not contain any actual "CSS" or "Tricks".