簡體   English   中英

如何在JS中強制重繪?

[英]How to force repaint in JS?

我想要達到的目標:

  1. 用戶點擊一個元素
  2. 屏幕顯示“計算進行中”屏幕
  3. 系統執行耗時的數學計算
  4. 屏幕顯示結果(“完成”)

這是剝離的代碼:

<div id ="di" onclick="calc()">initial</div>
<script>

function calc()
{
var n,a=0;
document.getElementById('di').textContent="calculation in progress";
for(n=0;n<1000000000;n++) // Here's the time consuming calculation
    {
    a=a+n; // for clarity's sake, I removed a complicated math formula here
    }
document.getElementById('di').textContent="done "+a;
}
</script>

當我運行它並單擊div時,它需要一段時間,然后將文本更改為“完成”,因此用戶根本看不到“計算進行中”消息-這是我的問題。

為了強制屏幕重新繪制以在計算開始之前顯示消息,其他線程建議修改CSS,隱藏並立即取消隱藏元素或使用setTimeout,但是沒有任何效果。

這將是一個繪制復雜數學對象(分形)的程序,我將使用canvas而不是div,但是我簡化了上面的示例。 由於將來會有圖形界面,因此不能選擇使用“ alert()”-計算完成后,“計算進行中”屏幕應立即變為“完成”。

IMO處理此問題的簡單方法是通過計時器函數以“較小”的塊執行計算,例如:

function calcFractal(x0, y0, x1, y1) {
    ... compute the fractal for the tile (x0, y0)-(x1, y1) ...
}

var x = 0, y = 0;

function nextTile() {
    calcFractal(x, y, x+tw, y+th);
    x += tw;
    if (x >= width) {
        x = 0;
        y += th;
    }
    if (y < height) setTimeout(nextTile, 0);
}

nextTile();

這使您可以顯示進度(例如,包括分形的低分辨率,計算的百分比)並允許中斷(例如,帶有停止按鈕的onclick事件)。

如果磁貼不是很小,那么開銷是可以接受的,仍然可以合理地響應重新繪制和用戶交互來保持頁面。

您需要等待一毫秒或與Worker進行計算。

第一個示例可能是最簡單的,而不是直接調用calc ,而是創建一個新函數

function caller() {
     // insert "calculation in progress" in the body
    setTimeout(calc, 1);
}

然后呼叫caller

由於現代瀏覽器可能會延遲重新繪制以獲得更好的幀速率,因此帶有setTimeout版本可能無法在太低的超時時間內工作。

如果可能,您需要使用requestAnimationFrame 如果它不可能,那么@Bálint答案應該可以工作,但是超時時間要大得多(在Firefox中我的測試中,它的工作時間是20-30附近)。 實際超時值取決於瀏覽器(可能也取決於系統)

function very_long_func(){
   el= document.getElementById('di');

   requestAnimationFrame( function(){
      //edit dom for new frame;
      el.textContent = 'calculation in progress' 
      //browser will wait for this functions end, before start redraw.
      //So actual calucation must run outside of it
      setTimeout( function_with_actual_calculation, 1 ); 

   })
}
function function_with_actual_calculation(){
     //..your math here + updating textContent to "done" in the end.
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM