首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在每个循环中更新进度条

在每个循环中更新进度条
EN

Stack Overflow用户
提问于 2015-06-23 02:27:49
回答 9查看 24.1K关注 0票数 16

我有一个进度条,我会在多次迭代的循环中更新它。

https://jsfiddle.net/k29qy0do/32/ (在单击start按钮之前打开控制台)

代码语言:javascript
复制
var progressbar = {};

$(function () {

    progressbar = {

        /** initial progress */
        progress: 0,

        /** maximum width of progressbar */
        progress_max: 0,

        /** The inner element of the progressbar (filled box). */
        $progress_bar: $('#progressbar'),

        /** Set the progressbar */
        set: function (num) {
            if (this.progress_max && num) {
                this.progress = num / this.progress_max * 100;
                console.log('percent: ' + this.progress + '% - ' + num + '/' + this.progress_max);

                this.$progress_bar.width(String(this.progress) + '%');
            }
        },

        fn_wrap: function (num) {
            setTimeout(function() {
                this.set(num);
            }, 0);
        }

    };

});


$('#start_button').on('click', function () {

    var iterations = 1000000000;

    progressbar.progress_max = iterations;

    var loop = function () {

        for (var i = 1; i <= iterations; i++) {

            if (iterations % i === 100) {

                progressbar.set(i); //only updates the progressbar in the last iteration

                //progressbar.fn_wrap(i); //even worse, since no output to the console is produced

            }
        }
    }

    //setTimeout(loop, 0);
    loop();

});

控制台会按照预期进行迭代更新。但是,进度条没有更新。

问题是浏览器窗口似乎“挂起”,直到循环结束。只更新控制台,而不更新进度条。

我已经尝试在几个地方添加setTimeout,如下所示。但这只会让事情变得更糟,因为在执行循环时,我甚至不会让控制台输出进度。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2015-07-27 21:31:47

好的,我在这个问题的答案中找到了一个解决方案:

Javascript: How to update a progress bar in a 'for' loop

代码语言:javascript
复制
var i = 0;
(function loop() {
    i++;
    if (iterations % i === 100) {
        progressbar.set(i); //updates the progressbar, even in loop    
    }   
    if (i < iterations) {
        setTimeout(loop, 0);
    }
})();

我的解决方案:https://jsfiddle.net/ccvs4rer/3/

票数 12
EN

Stack Overflow用户

发布于 2015-07-28 01:11:55

让我们把这个分解成几个步骤

步骤1:清理HTML

假设您的问题的目的是了解如何使用进度条,而不是样式或标签(加载,请耐心等)。让我们只有进度条和开始按钮。

代码语言:javascript
复制
<div id='progressbar-outer' style="">
    <div id='progressbar' style=""></div>
</div>
<button id="start_button">Start</button>

第2步:样式

让我们让用户可以看到进度条

代码语言:javascript
复制
#progressbar-outer {
    height:2em;
    border:5px solid #000;
    width:15em;
}
#progressbar {
    width:0%;
    background-color:#F00;
    height:100%;
}

步骤3:在该使用的地方使用setTimeout

在您的代码中,您已经使用setTimeout来设置进度条的值。但是,for循环仍处于活动状态。

代码语言:javascript
复制
for (var i = 1; i <= iterations; i++) {

    if (iterations % i === 100) {

        progressbar.set(i); //only updates the progressbar in the last iteration

        //progressbar.fn_wrap(i); //even worse, since no output to the console is produced

        //setTimeout(function() {
        //  progressbar.set(i);
        //}, 0);

    }
}

使用setTimeout不会影响代码的其余部分。因此,UI一直被扣为人质,直到循环结束。尝试以下代码。

代码语言:javascript
复制
$('#start_button').on('click', function () {

    var iterations = 100;

    progressbar.progress_max = iterations;

    var loop = function (value) {
        progressbar.set(value);
        if (value < iterations) setTimeout(function () {
            loop(value + 1)
        }, 30);
        else $('#progressbar').css('background-color', '#0F0');
    }


    loop(1);

});

预览

试试这个小提琴:https://jsfiddle.net/Ljc3b6rn/4/

票数 8
EN

Stack Overflow用户

发布于 2015-07-27 21:56:23

您真正需要的是一个异步循环,它允许浏览器在两次迭代之间更新DOM。

JSFiddle:http://jsfiddle.net/u5b6gr1w/

代码语言:javascript
复制
function delayedLoop(collection, delay, callback, context) {
    context = context || null;

    var i = 0,
        nextInteration = function() {
            if (i === collection.length) {
                return;
            }

            callback.call(context, collection[i], i);
            i++;
            setTimeout(nextInteration, delay);
        };

    nextInteration();
}

一些HTML:

代码语言:javascript
复制
<div class="progress-bar"><div style="width: 0"></div></div>

CSS的一次飞溅:

代码语言:javascript
复制
.progress-bar {
    border: 1px solid black;
    background-color: #f0f0f0;
}
.progress-bar div {
    background-color: red;
    height: 1.25em;
}

和一些JavaScript将东西连接在一起:

代码语言:javascript
复制
var progressBar = document.querySelector(".progress-bar div"),
    items = [1,2,3,4,5,6,7,8,9,10];

delayedLoop(items, 500, function(item, index) {
    var width = (item / items.length * 100) + "%";
    progressBar.style.width = width;
    progressBar.innerHTML = width;
});
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30987218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档