2013-09-27 5 views
10

大きなコレクションをループしてDOMに追加すると、DOMはすべてのアイテムが追加された後にのみ更新されます。 append()の呼び出し後にDOMが更新されないのはなぜですか?追加するたびにDOMを強制的にリフレッシュさせることができますか?jQueryループで追加 - DOMは最後まで更新されません

var i = 0; 
for (i=0; i<5000; i++) { 
    $('#collection').append('<li>Line Item</li>'); 
} 

Link to jsfiddle

注:私は(DOMリフローを避ける)より良いパフォーマンスは、ローカル変数へのすべての要素を追加して、DOMにその変数を追加することによって達成することができることを理解しています。しかし、すべての要素がレンダリングされるまで、最初のn要素を画面にレンダリングし、次にnをレンダリングします。あなたはしばらく一度のブラウザに制御をお返しする必要が

+0

大きなループをしている間にUIがフリーズしていると思うので、一気にすべてのことを行ったように見えますが、そうはしませんでした。 –

答えて

10

ブラウザが停止中のほとんどすべてのものJavascriptは実行中です。これには、例えば、DOMレンダリング、イベント処理、イメージアニメーションが含まれます。

DOMをレンダリングさせる唯一の方法は、Javascriptを終了することです。あなたは、更新後に再度コードを開始するsetTimeoutメソッドを使用することができます。

var i = 0; 

function appendSomeItems() { 
    for (var j=0; j<50; i++, j++) { 
    $('#collection').append('<li>Line Item</li>'); 
    } 
    if (i < 5000) window.setTimeout(appendSomeItems, 0); 
} 

appendSomeItems(); 

デモ:http://jsfiddle.net/Uf4N6/

+0

大きな説明と例、ありがとう! – Domenic

-3

それはあなたが何をしたいのか本当になら...

var i = 0; 
for (i=0; i<5000; i++) { 
    setTimeout(function() { 
     $('#collection').append('<li>Line Item</li>'); 
    }, 0); 
} 
2

var current = 0 


    function draw() { 
     var next = current + 10 
     for(var i = current; i < next; i++) { 
      $('#collection').append('<li>Line Item</li>'); 
     } 
     current = next 
     setTimeout(draw, 50); 
    } 

draw(); 
-2

一般的に、DOMに何度も手を触れないでください。あなたがすでに見てきたように、それはパフォーマンスのキラーです。

var result=""; 
for (i=0; i<5000; i++) { 
    result+='<li>Line Item</li>'; 
} 
$('#collection').append(result); 

このようにして、DOMに一度だけ触れます。

代わりに、配列を使用します。

var result=[]; 
for (i=0; i<5000; i++) { 
    result.push('<li>Line Item</li>'); 
} 
$('#collection').append(result.join("")); 
+0

注:すべての要素をローカル変数に追加し、その変数をDOMに追加することで、より良いパフォーマンス(DOMリフローを避ける)が達成できることを理解しています。しかし、すべての要素がレンダリングされるまで、最初のn要素を画面にレンダリングし、次にnをレンダリングします。 – Domenic

+0

○あります。申し訳ありませんがあなたの必要性に対処していません。 – Blaise