2010-06-08 41 views
12

我有一些JavaScript函數需要大約1到3秒。 (一些循環或mooML模板代碼)。顯示javascript執行進度

在此期間,瀏覽器剛被凍結。我試圖在開始操作之前顯示一個「加載」動畫(gif圖像)並將其隱藏起來。但它不起作用。瀏覽器在渲染圖像之前凍結,並在函數結束時立即隱藏。

有什麼我可以做,告訴瀏覽器之前進入JavaScript執行更新屏幕,喜歡的東西Application.DoEvents或後臺工作線程。

因此,有關如何顯示JavaScript執行進度的任何意見/建議。我的主要目標瀏覽器是IE6,但也應該對所有最新的瀏覽器

+0

你有沒有嘗試把JavaScript放入window.onload事件? – NibblyPig 2010-06-08 08:40:13

+0

@SLC它不屬於那裏 – Midhat 2010-06-08 08:58:41

回答

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(); 
+0

真棒...很酷的修復。謝謝 – Novice 2010-08-05 16:12:13

1

也許你可以把顯示gif動畫和運行重碼之間的延遲工作。

顯示GIF和呼叫:

window.setTimeout(myFunction, 100) 

做重的東西在 「myFunction的」。

0

嘗試在運行該功能之前設置wait光標,然後再將其移除。在jQuery中,您可以這樣做:

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

沒有jQuery,它甚至是_shorter_! 'document.body.style.cursor = 「等待」'。神奇! – Alsciende 2010-06-08 10:07:47

+0

@Alsciende,實際上,它更長。 'document.body.style.cursor =「等待」''對$(「身體」)。CSS(「光標」,「等待」)',但我認爲,每個人都應該使用可用的最簡單的方法。 – 2010-06-08 10:26:58

+5

事實上,jQuery的解決方案是非常70K長... – 2010-06-08 11:26:42

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); 
    } 
} 

我還沒有測試過這個實際的代碼,但我之前使用過這種技術。

+0

我喜歡這個解決方案,謝謝! – 2013-05-31 22:20:42