I've learned something today...
Date: 02/20/08
(Javascript Community) Keywords: browser, css
I'm prototyping an AJAX page at the moment, getting the DOM and the response handlers to play nicely together before actually bolting the server on underneath. This basically involves creating a transport object and setting its responseText to some hard-coded JSON, then calling my response handler directly.
All went swimmingly until this morning, when I tried adding "updating" effects - for the moment, just change the background-color around the field(s) in question and then change it back. They simply wouldn't show up. I put it down to the sheer speed of doing things with no network activity - must be changing and changing back really fast! - but when I bogged the response handler down with a second's worth of useless tasks and the changes still didn't show up, it was clear something wasn't right. I wasted about two hours on increasingly desperate CSS hackery before stepping back and trying something else.
The problem is that the browser isn't updating the display until it's finished working its way through the entire function chain - the onchange event calls showUpdating then doAjaxUpdate which calls update_onSuccess which calls showNotUpdating, and only then does the display update as a result of everything that happened in all those functions - by which time the style is set back to how it started.
The solution - break that chain. Instead of being lazy and just calling
updateExperiments_onSuccess(transport);
directly, wrap it in a setTimeout:
setTimeout(function(){updateExperiments_onSuccess(transport);},1000);
Now, the onchange event calls showUpdating and doAjaxUpdate - the timeout is set up, but that first chain then ends and the display is updated. Then the timeout kicks in and starts the second chain, after which the display is put back as it was. (The 1000 is only to be certain I'd see the effect on screen for a significant amount of time. The important part is that we're using setTimeout at all.)
Of course, this is a far more accurate representation of what will happen during a real AJAX call, too.
I've encountered similar problems before, trying to persuade the display to update immediately, and always given up, re-designing the page to avoid it or finding a messy work-around. Next time, I'll give this a try.
Source: http://community.livejournal.com/javascript/150603.html