在以下代码中,每个cicle都会更新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>
答案 0 :(得分: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工作者,但这仍然是最佳的跨浏览器方式。
答案 1 :(得分:3)
您可以使用animate
方法让条形图的进度对用户更加明显,如下所示:
$("button").click(function(){
for(var i=0; i<800; i++)
$("progress").animate({ value: "+=10" }, 1);
})
您可以在此处看到它:http://jsfiddle.net/qZJN3/