2013-07-16 96 views
1

寻找解决方案或者甚至只是一些背后的例子中的“底层”理论。DOM操作不能按顺序执行

看来DOM的操作发生在非阻塞的方式。换句话说,没有流控制来等待DOM语句的执行。

在这个例子中:http://jsfiddle.net/qHVJX/

两个语句是一个onclick事件之后执行。

  1. 转变文字从左到右

    document.getElementById('text').className = 'tr'; 
    
  2. 环一堆的时间暂停执行。

    for(var i = 0,temp=1000000000; i<temp;i++){var dummy=0;} 
    

如果在每个语句然后执行流控制被阻断,如所预期,该文本将转移左至右依次由来自环路短暂的停顿。相反,文本移位发生在循环迭代之后。

这表明className语句在循环获得执行优先级时排队。

在这个例子中:http://jsfiddle.net/qHVJX/1/

三个语句onClick事件之后执行:

  1. 移文本左至右

    document.getElementById('text').className = 'tr'; 
    
  2. 环一堆时间停止执行。

    for(var i = 0,temp=1000000000; i<temp;i++){var dummy=0;} 
    
  3. 从右到左移动文本。

    document.getElementById('text').className = 'tl'; 
    

同样,如果在每个语句执行然后,如所预期的流量控制被阻断,文本将转移左至右依次通过短暂的停顿而循环迭代,后跟文本从右移回到左边。

取而代之的是,循环被执行并且文本从左到右和从右到左的重绘从不发生。这说明了一个竞争条件。

setTimeout()可以暂停执行足够长的时间,以便DOM语句执行它的操作并避免排队,但是;没有办法知道每个陈述要花多长时间。如果间隔设置为短于不会达到预期的结果。如果时间间隔设置得比它需要的时间长,那么性能会受到影响。

无论如何阻止DOM操作期间执行没有setTimeout()的开销吗?某种回调例程可能?

任何有识之士将不胜感激。谢谢。

+0

setTimeout(fn,0)应该足够长,即使是最长的数据集... – dandavis

回答

0

的setTimeout是绝对正确的方式也,如果它只是一个几毫秒的分辨率。

你的环路只是阻止浏览器更新。 此外,它不是循环需要处理的可预测持续时间。关于一个智能的JavaScript编译器,如果循环没有任何好处,Loop可以被忽略。