2

在下面的代码中,html5<progress>标记的值会在每个 cicle 中更新。我还可以使用 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 worker,但这仍然是最好的跨浏览器方式。

于 2013-03-14T09:02:15.937 回答
3

您可以使用该animate方法使栏的进度对用户更加可见,如下所示:

$("button").click(function(){
    for(var i=0; i<800; i++)
        $("progress").animate({ value: "+=10" }, 1);
})

你可以在这里看到它的实际效果:http: //jsfiddle.net/qZJN3/

于 2013-03-14T09:08:09.387 回答