我的问题与本文中描述的问题非常相似:
Javascript progress bar not updating 'on the fly', but all-at-once once process finished?
我有一个调用一些服务的脚本,并处理一些操作。 我正在尝试创建一个进度条,指示最终用户的脚本执行的当前状态。我计算进程(#currentaction / #totalactions)以指示进度,并在每次使用此新值处理操作时更新DOM。
但是,只有在所有操作完成后才会更新DOM。 我在我的函数中放置了一个setTimeout,由于某种原因,DOM仍然没有逐步更新,它只在整个jscript执行时才更新。
这是我的JScript的一个例子
var pos = RetrievePos();
_TOTALCOUNT = (pos.length);
for(var i = 0; i < pos.length; i++) {
var cpos = pos[i];
CreateObject(cpos, id);
}
function CreateObject(cpos, id)
{
setTimeout(function() {
//do work here, set SUCCESS OR ERROR BASED ON OUTCOME
...
//update gui here
var scale = parseFloat(_SUCCESS + _ERRORS) / parseFloat(_TOTALCOUNT);
var totWidth = $("#loaderbar").width();
$("#progress").width(parseInt(Math.floor(totWidth * scale)));
}, 500);
}
我已经尝试围绕整个CreateObject调用设置setTimeout函数,只围绕DOM调用,但似乎没有什么可以做的。
我可能在这里遗漏了一些非常明显的东西,但我真的没有看到它。
有什么想法吗?
谢谢,
答案 0 :(得分:4)
您的代码无法正常工作的原因是CreateObject
函数会快速连续多次调用,每次立即提示500分钟后执行某些操作。 setTimeout()
不会暂停执行,它只会将某个函数排队,以便在将来某个时间调用。
因此,基本上,500毫秒不会发生任何事情,然后您的所有更新都会立即发生(当然,技术上也是如此)。
尝试这样做,将每个函数调用排队500ms。
for (var i = 0; i < pos.length; i++) {
setTimeout((function(i) {
return function() {
var cpos = pos[i];
CreateObject(cpos, id);
}
})(i), i * 500);
}
并从setTimeout
移除CreateObject
来电。
注意使用自动调用的函数来确保setTimeout调用中的变量i
正确绑定到i
的当前值而不是其最终值
答案 1 :(得分:0)
我认为你在CreateObject中做的不仅仅是setTimeout吗? 如果不是,最好只是从循环中调用setTimeout。
我怀疑你正在使用JQuery。如果是这样,请尝试使用动画
$('#progress')。animate({width:parseInt(Math.floor(totWidth * scale))},'slow');
因为那将调用它自己的更新代码,它可能会解决问题。如果没有完整的代码,我无法确切地说出这里的问题是什么。我也是一个PrototypeAPI头,而不是JQuery头。
答案 2 :(得分:0)
@gazhay:您可能有一点,使用jQuery的.animate函数可以绕过这个问题。
但是,我找到了解决此问题的方法。我修改了JScript以不再使用for循环,而是使用递归函数。看起来DOM没有得到更新,直到FOR循环完全终止......任何人都可以确认这个吗?
我用以下脚本对此进行了测试:
这不起作用:
for(var i = 0; i < 1000; i ++)
{
setTimeout(function() {document.getElementById('test').innerHTML = "" + i;}, 20);
}
虽然这确实有效:
function dostuff(i)
{
document.getElementById("test").innerHTML = i;
if(i<1000)
setTimeout(function(){ dostuff(++i);}, 20);
}
var i = 0;
dostuff(i);