12

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

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

在进入 javascript 执行之前,我可以做些什么来告诉浏览器更新屏幕。例如 Application.DoEvents 或后台工作线程。

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

4

4 回答 4

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();
于 2010-06-08T08:51:30.040 回答
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);
    }
}

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

于 2010-06-08T08:51:59.337 回答
1

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

显示 gif,然后调用:

window.setTimeout(myFunction, 100)

在“myFunction”中做繁重的工作。

于 2010-06-08T08:40:18.060 回答
0

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

var body = $('body');
body.css("cursor", "wait");
lengthyProcess();
body.css("cursor", "");
于 2010-06-08T08:40:36.303 回答