Site icon Donner's Daily Dose of Drama

The HTML <IMG> tag and “Onload” event bugs in IE

The problem: a blog post is supposed to show a temperature chart. The chart is served by a remote server, running SQL Reporting Services. The table with the temperature data contains 100,000s of rows and the server that hosts the SQL database and Reporting Services is an older Athlon box. Serving that image can take a while.

Because it was not apparent to the site user that an image was being loaded, I wanted some kind of visual indicator – an animated gif that would be replaced with the chart once it had finished loading. After googling around a bit, I settled for the following approach:

 <img id="chartimg" onload="swap('chartimg','http://charturl');" 
     src="animation.gif" />
 <script type="text/javascript">
 function swap(imgID, imgSrc)
 {
   theImg=document.getElementById(imgID);
   if (theImg.src != imgSrc) // prevent event recursion
       pic1.onload = imgSrc;
 }
 </script>

This code already contains several iterations of attempts to fix the basic issue that IE shows. One is that you get into a recursive loop because the onload event fires when the src attribute is changed. Since the event handler is assigning a new image source, it would cause the event to fire again etc, resulting in a stack overflow error.

The other problem is that IE seems to process the tag parameters in the wrong order, firing the onload event prior to the src attribute being assigned. This is what most other people seem to have run into, based on other posts that I found.

So, the above code already takes care of both these issues – by testing the src attribute for the new URL, causing the onload event to fire only twice (once for the initial load of the animated GIF, the second time when the URL of the chart image is assigned).

This works in principle. The problem that I was still left with was that IE did not animate the GIF while the chart was loading in the background, no matter what I tried. For instance, using a temporary image variable did not fix the problem. The issue is that the thread handling the tag is locked up while any image loads. Since the animation was a key part of the requirement, I did not want to settle for a static image.
I tried to come up with a creative solution, such as waiting for the load into a Javascript variable to finish prior to assigning the SRC attribute a new value, but the Javascript function returns immediately and we never know when that is the case. Also, there is no such thing as an Onload event for a variable containing an image.
The only solution: The 2nd image needs to have its own tag, so that the firing of the Onload event does not interfere with the GIF animation.

The final solution below does exactly that – one IMG tag shows the animated GIF and a second hidden one is used to load the chart image. The hidden image has the Onload event handler. It fires when the chart has fully loaded and is available, and the event handler replaces the animated GIF with the chart image.

<img id="chartimg" src="progress_circle.gif" />
<img id="hiddenImg" onload="swap('chartimg','hiddenImg');"
    src="http://somesite/chart_url.aspx" style="display: none;"/>
<script type="text/javascript">
function swap(img1ID, img2ID)
{
  theImg1 = document.getElementById(img1ID);
  theImg2 = document.getElementById(img2ID);
  if (theImg1.src != theImg2.src)  //prevents recursive events
    theImg1.src = theImg2.src;
}
</script>

To view the result, visit http://medfieldblogs.net/temperature-in-medfield.

I realize this code does not validate, but it works, and that is all I needed.

Exit mobile version