Here’s (One Way) How You Wait For An Image To Load In Javascript

Tinkering with some Javascript for the header on Gwen’s art page, I came across an interesting point – what do you do if you want to run a script as soon as an image is loaded?

Some of the issues:

  • Your browser can load parts in whatever order it wishes – so if your Javascript file loads before your image, you’re too soon.
  • If you try to use an onload event in Javascript, they don’t always work – specifically, if the image is already in the browser cache, you won’t have the event fire.
  • If you DO use an event, and the image is loaded before the Javascript is loaded, then the event fires with no code to react to it.
    Philosophical Question: If an image of a tree loads in a browser and no jquery is around to respond to the .onload, does it count?
  • If you set an arbitrary time limit to ‘wait and see’, there’s always going to be a slow connection out there that takes even longer.
  • And once you move to more complicated web pages (for example, frameworks like WordPress) you have even less control over when and how your Javascript will be loaded and run.

The comic below makes fun of ‘wait and see’ programming:

commitstrip.com

However, here is one solution, using the <img> onload event (which in testing seems to fire on all occasions):

  • Put the images you need as <img> tags in the HTML of your page. You can hide them with CSS tags (visibility:hidden; display:none;) if necessary.
  • In the page’s <head> section, add this javascript:
    <script type="text/javascript">
    var loadingFlags=[1,1];
    function setLoadingFlags(i){loadingFlags[i]=0;}
    </script>

    For each image, decide on an index (making sure ‘loadingFlags‘ has enough entries to handle them all), and then include them with an onload handler:

    <img src="imgA.gif" id="myimg0" onload="setLoadingFlags(0)" />
    <img src="imgB.gif" id="myimg1" onload="setLoadingFlags(1)" />

    …etc.

  • Now your Javascript can run anywhere,anytime, since the <img> onload is always called, whether in the cache or not. Until these flags are zero, they aren’t loaded. This makes your Javascript easier, since you don’t have to worry about sequencing:
    function processImages()  
    {
      if ( loadingFlags[0] || loadingFlags[1] )
      {
        // check often until loaded
        window.setTimeout(processImages,50);
        return;
      }
      // both found - do your work
    
    }
  • As long as the call to load this Javascript comes after the variable setup in the HTML, you should be OK, since it will just call over and over until both flags are set to 0 via onload.
  • Need to reload images? The ids are added to the <img> tags in the example above for just that reason. You set the flags again to 1, change the .src address, and then poll until they turn to 0.
    function loadSomeMore()  
    {
      loadingFlags[0]=1;
      document.getElementById("myimg0").src="imgX.gif";
      loadingFlags[1]=1;
      document.getElementById("myimg1").src="imgY.gif";
      window.setTimeout(processImages,50);
    }

Some cautions:

  • The example code here uses two images, but the idea can be limited to 1, or expanded to as many as necessary. Of course, lots of large images loading in the background all at once will to endear you to visitors, So take note of your bandwidth!
  • If an image doesn’t load (broken link for example,) then you’ll need a plan for what to do next. For example, use a counter to check how long the wait has been, and do something else if the images don’t load.
  • In theory (and testing) the <img> onload is reliable. But like loading, there may be a failure. Always plan for what to do if this happens, and try to have a test routine in place.

Although this code won’t solve every issue, it might help with the occasional synchronization issues between .js and .html files. Hope it helps!

3 thoughts on “Here’s (One Way) How You Wait For An Image To Load In Javascript