显示javascript执行进度

时间:2010-06-08 08:36:05

标签: javascript progress

我有一些javascript函数需要大约1到3秒。 (一些循环或mooML模板代码。)

在此期间,浏览器刚冻结。我尝试在开始操作之前显示“加载”动画(gif图像)并在之后隐藏它。但它只是不起作用。浏览器在渲染图像之前会冻结,并在函数结束时立即隐藏它。

在进入javascript执行之前,我有什么办法可以告诉浏览器更新屏幕。有点像Application.DoEvents或后台工作线程。

所以有关如何显示javascript执行进度的任何意见/建议。我的主要目标浏览器是IE6,但也适用于所有最新的浏览器

4 个答案:

答案 0 :(得分:19)

这是因为IE6中的所有内容都在同一个线程中执行 - 甚至可以为gif设置动画。

确保在开始之前显示gif的唯一方法是分离执行。

function longRunningProcess(){
    ....

    hideGif();
}

displayGif();
window.setTimeout(longRunningProcess, 0);

但是在执行longRunningProcess时,这仍会使浏览器冻结 为了允许交互,您必须将代码分解为更小的片段,可能就像这样

var process = {
    steps: [
        function(){
            // step 1
            // display gif
        },
        function(){
            // step 2
        },
        function(){
            // step 3
        },
        function(){
            // step 4
            // hide gif
        }
    ],
    index: 0,
    nextStep: function(){
        this.steps[this.index++]();
        if (this.index != this.steps.length) {
            var me = this;
            window.setTimeout(function(){
                me.nextStep();
            }, 0);
        }
    }
};

process.nextStep();

答案 1 :(得分:1)

也许你可以在显示动画gif和运行繁重代码之间加入延迟。

显示gif,然后致电:

window.setTimeout(myFunction, 100)

在“myFunction”中做重物。

答案 2 :(得分:1)

您必须使用更复杂的技术来显示长时间运行功能的进度。

假设你有一个这样的函数运行得足够长:

function longLoop() {
    for (var i = 0; i < 100; i++) {
        // Here the actual "long" code
    }
}

为了保持界面响应并显示进度(同时避免“脚本在某些浏览器中花费太长时间......”消息),您必须将执行分成几个部分。

function longLoop() {
    // We get the loopStart variable from the _function_ instance. 
    // arguments.callee - a reference to function longLoop in this scope
    var loopStart = arguments.callee.start || 0;

    // Then we're not doing the whole loop, but only 10% of it
    // note that we're not starting from 0, but from the point where we finished last
    for (var i = loopStart; i < loopStart + 10; i++) {
        // Here the actual "long" code
    }

    // Next time we'll start from the next index
    var next = arguments.callee.start = loopStart + 10;
    if (next < 100) {

        updateProgress(next); // Draw progress bar, whatever.
        setTimeout(arguments.callee, 10);
    }
}

我没有测试过这个实际的代码,但我之前使用过这种技术。

答案 3 :(得分:0)

在运行该功能之前尝试设置wait光标,然后将其删除。在jQuery中你可以这样做:

var body = $('body');
body.css("cursor", "wait");
lengthyProcess();
body.css("cursor", "");