12

約1〜3秒かかるJavaScript関数がいくつかあります。(一部のループまたは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

おそらく、アニメーションGIFを表示してから重いコードを実行するまでの間に遅延を入れることができます。

gifを表示し、次のように呼び出します。

window.setTimeout(myFunction, 100)

「myFunction」で重いことをしてください。

于 2010-06-08T08:40:18.060 に答える
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 に答える
0

wait関数を実行する前にカーソルを設定し、後でカーソルを削除してみてください。jQueryでは、次のように実行できます。

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