Javascript image preload race condition

Hello all.

I'm trying to resolve a race condition I'm having with Netscape 4.7, Opera, and Mozilla (don't seem to have it with IE yet, but that doesn't mean it can't happen).

What I have to do is load an image, calculate it's height/width, and based on what I get back determine if I have to resize the image (and proportionally resize it as opposed to trying to slam it into a window and skew the image all around).

My problem is that the image.height and image.width only returns proper values once the image is preloaded.

So, here is the logic which I think I need to implement in a function for all of this to work:
1) preload the image based on URL
2) wait for the image to complete (have some trigger tell me that it's complete)
3) extract the original height/width of the image and return the value to the caller.

What I get however is problems. I was able to dig up one trigger image.onload which can fire once the image is loaded. I also have the image.complete flag which I can test to see if the image is finished loading into cache. However, it's my while loop which is causing me problems. It seems that if I stick myself in a while loop and check to see when the image is finished preloading, the thread of execution is never given back to the browser to finish loading up the image (likely in the background). So, as long as I'm in the while loop, the image does not seem to load. However, until the image is loaded, I have to remain in the loop. Catch-22.

The other possibility (using the image.onload trigger) can't work either, as I cannot seem to guarentee when it will go off (not serializable -- I cannot seem to direct the thread of execution back to the function which called the image to be loaded). Fubar.

Here is the code which demonstrates the problem. To set it up, simply have two images (image1.jpg and image2.jpg)in the same directory as this html file and it'll go:

Also notice that the image I preloaded (image01) seems to work (likely because the race condition doesn't seem to come up on my workstation). It's the image I preload in the functions which I can't ever get to work properly.

Any clue as to what I can do here? How can I get the image size reliably from a function call without having to wonder if that race condition is going to occure?

Thought you made up that phrase 'race condition' - so I looked it up - hah! Excellent...shows what I know.

A question: since the 'race condition' seems to be created by running two scripts - the preloader and the table writer - why don't you use a different methodology altogether? No sense pitting a scripting routine which hinges on network download speed (glacially slow compared to a client program) against a tiny JavaScript. This:

while (!tmpImage.complete) {
continue;
};

makes me wanna reboot...

If I'm seeing your purpose here, what you want is a prompt message - 'Please wait - images loading' - and, when the onload handlers of all the preload objects have run, output the rest of the page. As M. Hirsch suggested, you could poll for this; I prefer keeping it event-driven, setting up each onload handler to call a routine which checks a (persistent) counter which starts at images.length and is decremented by each load. Either way should be fine.

You should always set a preload object's onload handler, or set up to check its .complete property, before setting the .src property...running off a local drive, with cached images, load time is very fast.

Yeah, don't let that "while - continue" loop get to you, it's just to prove a point.

In most languages, you can release the thread of execution to another function and wait to have it returned to you. However, I'm not sure Javascript allows anything similar to this, so I was trying to think of some way to loop until I get a positive responce that my image is loaded. From what I can tell, most browsers pass the image loading onto a background process (this is efficient, because it lets your browser become responsive while downloading images).

Harumph. Maybe I'm going about it the wrong way (I'm new at Javascript, and am trying to learn it's erratic behaviours).

Here's my scenario. Maybe someone can find a new approach which I can take.

I have a list of images which I have to fit inside a box (say 100x100 px). It a slide show of images found on a database (I don't control the image content, just the presentation). When these are passed to me (via JSP tag library), I want to resize the image if needed in an intelligent manner.

My first impression was to preload the image, calculate the height/width, and output the image onto the document by setting the <img height = y, width = x) tag accordingly (a little highschool math and my images don't get stretched). My problem is that for this function to work, I have to have the images completely preloaded before the image.height and .width to work.

Another thought that just occured to me is that I could set a trigger which automatically resizes all images after they have all registered being loaded. Can you resize the height/width of an image? I was given the impression that these were read-only values, and that once defined I'm bound by them.

Hmm...how does one intelligently resize a rectangular image to fit a square frame? If all the images are square, this:

<img width="100" height="100" src="......

..will, believe it or no, do the trick. You don't even need to set both dimensions: whether in HTML or JS, resize an image on one side and the browser proportionately resizes it on the other. If the supplied images are rectangular, something like this might do: