views:

112

answers:

2

Hi, recently I've encountered a problem with IE. I have a function

function() {
    ShowProgress();
    DoSomeWork();
    HideProgress();
}

where ShowProgress and HideProgress just manipulate the 'display' CSS style using jQuery's css() method.

In FF everything is OK, and at the same time I change the display property to block, progress-bar appears. But not in IE. In IE the style is applied, once I leave the function. Which means it's never shown, because at the end of the function I simply hide it. (if I remove the HideProgress line, the progress-bar appears right after finishing executing the function (more precisely, immediately when the calling functions ends - and so there's nothing else going on in IE)).

Has anybody encountered this behavior? Is there a way to get IE to apply the style immediately?

I've prepared a solution but it would take me some time to implement it. My DoSomeWork() method is doing some AJAX calls, and these are right now synchronous. I assume that making them asynchronous will kind of solve the problem, but I have to redesign the code a bit, so finding a solution just for applying the style immediately would much simplier.

Thanks rezna

A: 

Try throwing the HideProgress method into a setTimeout. For example:

function() {
    ShowProgress();
    DoSomeWork();
    setTimeout(HideProgress,0);
}

Even though the delay is supposedly 0 milliseconds, this will have the net effect of throwing the HideProcess method to the end of the queue and may give the browser the breathing room it needs.

[Edit] I should have mentioned that this method does have a drawback if you invoke this method very often and rapidly: a race condition. You could end up with a previous timeout executing while another DoSomeWork() is executing. This will happen if DoSomeWork take a very long time to finish. If this is a risk, you may want to implement a counter for your progress bar and only execute HideProgress if the counter that started it is the same as the counter's present value.

Andrew
the problem is not the HideProgress, but the face that during execution of DoSomeWork() the progress-bar is not visible...
rezna
If you remove `HideProgress()` and/or `DoSomeWork()` does the progress bar show up at all? Can you post your ShowProgress function?
Andrew
it's written in the original question:(if I remove the HideProgress line, the progress-bar appears right after finishing executing the function (more precisely, immediately when the calling functions ends - and so there's nothing else going on in IE)).my ShowProgress() is simplefunction ShowProgress() { $('#my-id').css('display', 'block');}
rezna
Wow. I've never seen IE behave that way. One last idea: rather than applying the style through jQuery, try applying it directly. I'm not saying that you should deploy it this way, but rather to see where the problem lies. `function ShowProgress() {document.getElementById('my-id').style.display='block'}`.
Andrew
Nope, still the same. The style is visually applied after leaving the code-block.
rezna
It must be the synchronous request then. The style change is likely deferred, but then gets blocked by the request. That's really disappointing. Janmoesen's idea of throwing DoSomeWork into a timeout might work then. But I honestly don't know. Sorry.
Andrew
+1  A: 

Synchronous requests block the entire UI, which is horrible. You are right in your assumption, but if you want to continue down this path to the inner circles of $hell, try this:

function () {
    ShowProgress();
    window.setTimeout(function () {
        DoSomeWork();
        HideProgress();
    }, 0);
}

Note that I have not tested this. Try playing with the time-out value (currently 0) if you still do not see anything.

janmoesen
yeah I thought so. playing with setTimeout is quite tricky and I think it will bring in some even worse problems.so I'm going to redesign the code :)
rezna