2017-04-26 87 views
1

我有一個網頁,在加載過程中執行大量計算。正在運行腳本時進行JavaScript頁面更新

我想在頁面處於「思考」狀態時顯示一個微調欄,以便最終用戶知道延遲是可以預料的。

我打算這樣做的方式是顯示一個GIF文件,該文件將是一個旋轉輪,並隱藏將作爲我的輸出的表格。

問題是,一旦函數啓動,頁面的更新似乎凍結,直到函數完成。因此,最終用戶永遠不會看到「正在處理」部分。

示例代碼我放在一起展示我的問題是:

<!DOCTYPE html> 
<html> 
<body> 

<script> 
function show(id, value) { 
    document.getElementById(id).style.display = value ? 'block' : 'none'; 
} 
function Processing(x) 
{ 
    if (x === true) 
    { 
     show('page', false); 
     show('loading', true); 
    } 
    else 
    { 
     show('page', true); 
     show('loading', false); 
    } 
} 

function MainProcess() 
{ 
    Processing(true) // Set to "Show processing..." 

    var start = new Date().getTime(); // Sleep a few seconds 
    for (var i = 0; i < 5; i++) { 
     if ((new Date().getTime() - start) < 3000) { i = 1 } 
    } 
    Processing(false) // Set to "Show Completed processing..." 
} 

window.onload = function() { 
    show('page', false); 
    show('loading', false); 
}; 
</script> 

<div id="loading"> 
    <h1>Processing your request.</h1> 
</div> 

<div id="page"> 
    <DIV class="body"> 
     <h3>Done Processing your request.</h3> 
    </DIV> 
</div> 
<div id="buttons"> 
    <button onclick="MainProcess();">Start Timer</button> 
    <button onclick="Processing(false);">Set to Completed</button> 
    <button onclick="Processing(true);">Set to Processing</button> 
</body> 
</html> 

當我運行它,它提出了三個按鈕。

當你點擊「開始計時器」時,它應該顯示處理幾秒鐘,然後顯示完成。相反,該按鈕改變顏色,否則看起來什麼都不做,直到計時器完成,並且顯示完成。

(我是新來的JavaScript,但在其他幾種語言。經驗豐富的職業是否有一個「調用DoEvents」呼叫類型的我可以像在Visual Basic或PowerShell的?)

回答

1

問題似乎是在處理函數啓動之前DOM更新(即更改DIV上的顯示屬性)沒有完成。一種選擇是使用window.setTimeout耽誤你的處理功能的啓動,使DOM更新完成:

function MainProcess() 
 
{ 
 
    Processing(true); // Set to "Show processing..." 
 

 
    // Pause for 100 ms before starting time-consuming code to allow dom update to c 
 
    var domUpdateDelay = 100; 
 
    window.setTimeout(function() { 
 

 
         var start = new Date().getTime(); // Sleep a few seconds 
 
         for (var i = 0; i < 5; i++) { 
 
          if ((new Date().getTime() - start) < 3000) { i = 1 } 
 
         } 
 

 
         Processing(false) // Set to "Show Completed processing..." 
 
         }, 100); 
 
}

window.setTimeout有兩個參數:第一個參數是一個函數在x毫秒後運行,其中x是第二個參數。

這種方法的問題是setTimeout的適當延遲會因機器/用戶/瀏覽器/運行而異。但是,我的猜測是,這在99%的案例中可能不會成爲問題。

+0

所以我不得不延長應用程序的整體性能,以顯示用戶該應用程序正在工作..大聲笑 - 謝謝,這是行不通的。 –

0

我認爲你可以利用喜歡的setTimeout函數(https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout),說:

setTimeout(function() { 
    Processing(false); 
}, 5000); 

我覺得發生了什麼事是你幾乎崩潰與循環瀏覽器。出於演示目的,我可能誤解了您的問題的哪些部分。

+0

循環只是一個簡單的代碼snippit。 這個解決方案的問題是延遲更新值,但是一旦更新值,就不會給瀏覽器更新屏幕的空閒週期。延遲主進程允許「工作」代碼部分運行,然後延遲允許屏幕更新(從GUI編程日起,窮人的'DoEvents')。 –