Javascript进度条不更新'在飞行',而是一次一次进程完成

Javascript progress bar not updating 'on the fly', but all-at-once once process finished?

本文关键字:一次一次 进程 飞行 更新 Javascript      更新时间:2023-09-26

我有一个循环,应该更新一个进度条作为循环但是,它只在循环实际完成后一次性给进度条上色。我记得有一个类似的问题,如果我使用警报语句,着色将工作,所以我认为它与线程的并发性有关。为了解决我的老问题,我使用了setTimeout。然而,这仍然不能让我的进度条实时着色。

我是这样做的:

for (var i = 0; i < numOfRows; i++) {
    setTimeout('ColourBlock(' + i + ')', 0);
    // do_work
}
function ColourBlock (position){
    document.getElementById("block" + position).style.backgroundColor = "orange";
}

有人告诉我这可能是由于JavaScript优化?有人能帮忙吗?

这与线程无关。它是关于这样一个事实:当代码进行一系列快速的DOM或样式更改时,浏览器不会尝试在每次更改之间更新视图。相反,它会等待事情平静下来,然后重新绘制。

如果您按照您所描述的为每个更改编写一个非零超时值(例如100毫秒)的序列,那么您将看到它发生。正如你所写的,在零毫秒超时的情况下,所有的更新都将在很短的时间内发生——可能不到一毫秒,除非你有数千个这样的块。

(注意,您的示例代码不会为每次更改提供100作为超时;你必须把它们放到更远的未来,每增加100个。或者您可以使用间隔计时器,并在最后一次更新后取消它。

浏览器在执行javascript代码时不会更新UI。当代码完成并将控制权交还给UI时,更新将同时发生。

这也是为什么它与警报一起工作的原因——当警报弹出时,javascript执行被暂停,控制权被返回到UI。

您需要使用闭包,以便当您调用ColourBlock时使用i被调用时的值(在下面的代码中分配给currentPosition)。尝试将for循环更改为如下内容:

for (var i = 0; i < numofrows; i++) {
    (function() {
        var currentPosition = i;
        setTimeout(function() {
            ColourBlock(currentPosition);
        }, 500);
    })();

尝试增加setTimeout周期的时间。当我遇到类似的问题时,我们使用了200毫秒的间隔,它成功了。