tags:

views:

69

answers:

2

The following works correctly:

alert("start");
loadData(); // takes a while
alert("finished");

loadData() is a method that inserts large amounts of data into a table in the DOM and takes a few seconds.

This, however, does not work as expected:

document.getElementById("mydiv").style.display = "block";
loadData(); // takes a while
document.getElementById("mydiv").style.display = "none";

The data is loaded into the table without displaying mydiv until the loading is completed and then mydiv is quickly displayed and gone.

But this works like it's supposed to:

document.getElementById("mydiv").style.display = "block";
alert("start");
loadData(); // takes a while
alert("finish");
document.getElementById("mydiv").style.display = "none";

mydiv is displayed, the alert dialog is shown, the data is loaded into the table, and then mydiv disappears, as expected.

Anyone know why the second code section above does not work properly?

+3  A: 

I dont know the exact reason, but i can think of is that LoadData is a heavy function so browser is busy evaluating that, so it holds the rendering. When u give alert in between it provides sufficient time to render div and then evaluate LoadData.

Work Around:

function void LoadData()
{
//Show Div here
//window.setTimeout(newFunc,100);
}

function newFunc()
{
 //Do data operations here
 //Hide Div
}
Nitin Midha
Yes, loadData() is a heavy function. But showing mydiv should be simple, right? And it also comes first in the code. So why does the browser skip it and go to the more difficult one? By the way, this happens on all the major browsers.
Ralph Stevens
By the way, your solution worked. I just don't know why :)
Ralph Stevens
the show div gets called, the timeout gets set, then javascript execution ends, control of the thread gets released back to the browser so that it can draw, then the timeout event happens, the event loop grabs the timeout event, and newFunc() is called.
Breton
It worked for you gave the browser enough time, 100 milliseconds, to render your page and in-turn time to execute the showing of the div. Keep in mind that if your page structure follows conformity your script will be loaded way before the rest of the document gets loaded, meaning you div is not available at the time when you loaded the scripting, this should account for the unwanted results you were getting.
drlouie - louierd
+2  A: 

Think of javascript as inserting some interpreted code into a larger program. The larger program looks a little like this:

void eventLoop () {
   struct event event;
   while(event = getEvent()){
        runJavascript(event);
        runBrowserCode();
        if(viewHasChanged) {
           redrawViewRegions();
        }
   }

}

This isn't really accurate at all, but it gives you a little bit of an idea. While javascript code is running, the browser is not doing anything else: including updating the view. it hasn't got up to that bit. The browser gui does not run in a seperate asynchronous thread, in parallel to the javascript as you seem to imagine. The browser has to wait for javascript to finish before it can do anything.

You can see the gui update when you use alerts, because, well- To display an alert you have to update the gui! so it's kind of a special case.

Breton
Thanks for clarification ..... So when in case of an alert a new event is raised which in turns lead to redraw View Regions and hence we see the Div. Please correct me if i am wrong.
Nitin Midha
I couldn't tell you exactly what happens, but my guess is that when you call "alert" you don't escape the "runJavascript" portion of the loop. The invokation of alert simply goes out and explicitly calls "redrawViewRegions" as part of its implementation. Alert is a blocking call, you the whole browser is effectively frozen until the user presses the "ok" button.
Breton
Breton, so the browser draws things only in between breaks in the javascript execution, like timeouts, waiting for user interaction, loading AJAX content, etc. In other words, if you have repeated javascript commands changing the user interface, the interface gets drawn only once reflecting the way it is supposed to look after all the commands (unless there was some kind of a "wait" in the code). Thanks for the explanation. I didn't know this at all. It makes sense.
Ralph Stevens