views:

228

answers:

4

I have a rather long running javascript code which adds a new "div" element to the document. It looks like in IE this change is being rendered only after the script is finished, which is not the case in FF.

Any idea how to make it work ? This script is actually supposed to run forever, kind of "main loop".

+2  A: 

I would avoid using a persistent, ever-running script. If you need things to happen on a recurring schedule, periodically, then use Window.SetTimout/SetInterval. Otherwise, use events. There are numerous JS frameworks out there, such as Mootools, that make it easy to implement you're own custom events, which should eliminate the need for a "main loop".

http://mootools.net/

jrista
Still, is it a bad practice to have a "main loop" or it is not supposed to work at all ?P.S. I have a very simple and very specific case which is much, much more simple to implement using a loop rather than any event based frameworks. It's like 5 lines of code with the loop, and a few dozens at least with events...
Demiurg
To my knowledge, it won't work. Scripting engines are not multi-threaded yet...they run concurrently with the page. There is work being done to support threading for the web, but it is slow, and likely years away from being widely adopted enough to be viable. It is also generally a bad practice. The browser is the main loop, you shouldn't be trying to create your own. You should be responding to events fired by page content.
jrista
@Demiurg — As you've discovered, it simply doesn't work in some JS engines. Switching to timeouts is easy, though… just change `while (true) { /* code */; }` to `(function loop() { /* code */; window.setTimeout(loop, 100); })();` for example.
Ben Blank
OK guys, you convinced me, will have to rewrite it :)
Demiurg
Thanks for the tip!
Demiurg
NP. :) Glad to be of help.
jrista
+1  A: 

Don't use a script that constantly runs, JavaScript is not meant to be used like that. Use event-based code or scheduler-based code. I'm pretty sure if you have a constantly running script you will trigger a "some scripts on this page are taking an abnormally long amount of time to run" type of popup from some browsers. It should not be expected behavior.

Brian Schroth
+1  A: 

This script is actually supposed to run forever, kind of "main loop".

You can't do that in JavaScript. While you keep control of the thread of execution, the browser can't do anything, like check for clicks. In this state the browser is unresponsive and can appear to have crashed. Eventually most browsers will pop up a warning saying the script isn't playing nice, and give the user a button to click to unceremoniously kill it off.

Instead, you must return control to the browser as normal and ask it to call you back a bit later by using window.setTimeout(function, delay) for a one-off or window.setInterval(function, period) to have it keep calling back every so often. Any state you want to maintain over calls will have to be stored in global or instance variables.

bobince
+1  A: 

The reason for this behavior is the manner in which Internet Explorer re-paint the window on DOM changes; in other words it is due to reflow.

Unless I'm mistaken, IE will queue the reflow tasks, and will act on them when the script thread has finished executing. If you write code to never halt the thread, reflow will never happen and you will never visualize the changes in DOM.

The alternative method that others have suggested - using window.setTimeout() and window.setInterval() is viable and will help in resolving the problem due to brief pauses available to the browser to act on the reflow tasks.


You will find this related SO question on when reflow occurs to be useful.

Vineet Reynolds