2

次のコードでは、html5<progress>タグの値がサイクルごとに更新されます。Chrome のコンソールを使用して、その値が動的に変化することも確認できます。しかし、レンダリングがサイクルの最後にのみ更新されるのはなぜでしょうか?

<!doctype html>
<meta charset="utf8"></meta>
<title></title>
<body>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>

  <button>click</button>
  <progress  min="0" max="10000" value="0"></progress>

  <script>
    $("button").click(function(){
        for(var i=0; i<8000; i++)
            $("progress").val(i)
    })
  </script>
4

2 に答える 2

7

これは、UI をロックしているためです。このコードは、UI を更新するコードと同じスレッドで実行されるため、プログレス バーの値を更新しても、プロセッサが UI を更新する時間はありません。

これを修正する最も簡単な方法は、タイムアウトでループを実行することです。

    $("button").click(function(){
        var count = 0;

        var timeout = setTimeout(doLoop, 0);

        function doLoop() {
            $("progress").val(count);
            count++;
            if(count < 8000) {
                var timeout = setTimeout(doLoop, 0);
            }
            else {
                clearTimeout(timeout)
            }
        }
    });

これで、コードが非同期で実行されます。これは、ループの処理中に UI スレッドが UI を更新する時間があることを意味します。

最新のブラウザーでこれを行うためのより高度な方法については、Web ワーカーも確認することをお勧めしますが、これは依然としてクロスブラウザーの最良の方法です。

于 2013-03-14T09:02:15.937 に答える