繁体   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