2013-07-16 95 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可以被忽略。