views:

27

answers:

3

In my JavaScript code I am first calling a function to update an image:

document.getElementByID("i1").src = newImage;

then a few statements later the alert() function is called to display a message:

alert("image updated!");

However, when I run this code, what actually happens is that the alert box is popped up before the image is updated. When I click the "OK" button in the dialog to take the alert box down, the image updates.

Why is the order of these events not being preserved? And is there some kind of synchronizing function I can call to wait for the image update to complete before the alert dialog is displayed?

I'm open to restructuring the code in some ways (i.e., using something other than the alert() function), but I'd prefer a solution that allows the existing code to work as intended.

+3  A: 

Simple.

Setting the src property of the image initiates the loading of the image. But since the loading happens asynchroneously, the alert box displays before the loading completes.

Tor Haugen
A: 

The alert box blocks the updating of the image in the background. What the browser does is the downloading of the image (you can see this with wireshark or something similar) but the browser doesn't change anything on the web page while JavaScript is executed. If you have computationally intensive javascript methods, try using WebWorkers.

levu
+4  A: 

Image loading is asynchronous. What you need is a callback for when the image is loaded.

If you are using jQuery, you can do it like this:

var img = $('#i1');
img.load(function() {
    alert('image updated!');
});
img.src = newImage;

If you are using Prototype, you can do it this way:

var img = $('i1');
Event.observe(img, 'load', function(e) {
    alert('image updated!');
});
img.src = newImage;

Note that in either case it's important that you first define the callback, then set the image src.

Ben Lee
This looks like a viable direction (thanks!). I'm currently using vanilla JavaScript -- does it offer a way to set a callback?
Bart Stewart
This will work in most browsers: img.onload = function () { alert('image updated!'); }
Ben Lee
Just remember to put that *before* the "img.src = newImage" line. The event handler has to be defined first. Also, if using that instead of one of the frameworks, be sure to test in every browser you care about (including mobile browsers). The img.onload handler is not a W3C standard, so it's possible some browsers might not respect it.
Ben Lee