浏览器渲染和JavaScript执行的同步/异步性质

浏览器渲染和JavaScript执行的同步/异步性质

问题描述:

我有是怎么回事,所以我想添加视觉指示器,而它在进步,需要几秒钟进行一些处理。

I have some processing that is going to take a few seconds so I want to add a visual indicator while it is in progress.

.processing
{
  background-color: #ff0000;
}

<div id="mydiv">
  Processing
</div>

脚本:

$("#mydiv").addClass("processing");
// Do some long running processing
$("#mydiv").removeClass("processing");

我天真认为类将被应用到div和UI将被更新。然而,在浏览器中运行这个(在Firefox至少)股利从不突出。为什么我的我的div永远不会被突出显示,以我能有人解释?该类补充道,处理发生,然后类被删除;用户界面不会更新之间,用户不会看到红色的背景。

I naively thought that the class would be applied to the div and the UI would be updated. However, running this in the browser (in Firefox at least) the div is never highlighted. Can someone explain to me why my my div never gets highlighted? The class is added, the processing takes place and then the class is removed; the UI is not updated in between and the user never sees the red background.

我知道JS是单线程的,但我一直presumed浏览器的渲染会为同步运行,当DOM被更新。是我的假设不正确的?

I know JS is single-threaded but I'd always presumed the browser rendering would run synchronously as and when the DOM is updated. Is my assumption incorrect?

而更重要的,什么是达到这个效果的推荐的方法?我一定会导致使用的setTimeout 来使处理缓慢异步和回调的工作?必须有,因为我真的没有任何需要异步这里表现的更好方法;我只是想在UI刷新。

And more importantly, what is the recommended way to achieve this effect? Do I have to result to using setTimeout to make the slow processing asynchronous and work with a callback? There must be a better way as I really don't have any need for async behaviour here; I just want the UI to refresh.

编辑:

的jsfiddle: http://jsfiddle.net/SE8wD/5/

JSFiddle: http://jsfiddle.net/SE8wD/5/

(请注意,你可能需要调整循环迭代的次数,给你自己的电脑上合理的延迟)

(Note, you may need to tweak the number of loop iterations to give you a reasonable delay on your own PC)

我不建议冻结浏览器的重量脚本。
在这种情况下,我preFER改变code不冻结浏览器和DOM。
如果在你的code有一定的循环,可以调用带(使用setInterval的)延迟的功能和存储一些状态变量的地方。
例如:

I not recommend to freeze browser for a weight script. In this case I prefer to change the code for not freeze browser and DOM. If in your code there is some loop, you can call a function with a delay (using setInterval) and store some status variable somewhere. For example:

for(var i=0; i<1000000; i++) {
    // do something
}

可以是:

var i = 0;
var intervalID;
var _f = function() {
    // do something
    i++;
    if(i==1000000) clearInterval(intervalID);
}
intervalID  = setInterval(_f,1);

或类似的和更优化的东西。
您code将是一个略微复杂一点,慢..。而是让你prevent浏览器冻结,你可以让一个先进的preLOAD状态栏。

Or something of similar and more optimized. Your code will be a little bit more complex, and slower.. . but so you prevent browser freeze and you can make an advanced preload status bar.