1

これは何年もの間私を悩ませてきたので、状況を説明するためにテストjsFiddleを作成しました。

コードは次のとおりです。

$('#test').on('click', function() {
    $(this).css('background', 'red');
    for (var i = 1; i < 100000; i++) {
        var el = document.createElement("div");
        el.innerHTML = "Another";
        document.getElementById("container").appendChild(el);
    }
});

さて、まず背景色を変えてから、子の作成が始まると思いました。forただし、ループが終了するまで色は変わりません。

ただし、ループsetTimeoutの代わりに遅延を設定した場合はそうではありません。for

var timeoutID = window.setTimeout(function () {
    $('#test').css('background', 'blue');
}, 2000);

このsetTimeout場合、2秒後に瞬間的に赤と青が表示されます。編集:これが2番目のケースのフィドルです。

なぜ私の最初のフィドルはそれがすることをするのですか?これは、他の多くの状況、特にAJAXに関して適用されます。

4

3 に答える 3

3

関数全体が実行されるまで、ブラウザーは再描画をトリガーしません。

次のように、タイムアウトがゼロのsetTimeoutでforをラップすることにより、forループを呼び出す前に再描画することができます。

$('#test').on('click', function() {
  $(this).css('background', 'red');
  setTimeout(function(){
    for (var i = 1; i < 100000; i++) {
        var el = document.createElement("div");
        el.innerHTML = "Another";
        document.getElementById("container").appendChild(el);
    }
  }, 0);
});
于 2012-07-11T05:16:28.097 に答える
1

javascriptにはメインスレッドが1つしかありません。

ループは、キューに入れられたものsetTimeouts()や背景の再描画など、すべてが発生するのをブロックします。

違いは、setTimeout()スタックであるため、大量の計算を必要としないため、100,000回の反復ループがより速く終了し、次のキューに入れられた関数(この場合は再描画)を実行できることです。

于 2012-07-11T05:24:02.797 に答える
0

私はそれの簡単な修正を試みましたhttp://jsfiddle.net/Pbgz3/12/。ループが実行される前に、実際に色が変わります。ループの反復を減らしたことを確認します。

于 2012-07-11T05:16:26.807 に答える