javascript div更新率

标签 javascript html

我有一个非常简单的 HTML/Javascript,如下所示 但是当我运行它时,标签只更新一次,当它是 99999 时,这不是我的预期行为。我希望标签“实时”更新。有什么办法可以强制它重绘。我试着把它放进一个

notice.style.display = 'none';
notice.innerHTML = i
notice.style.display = 'block';

但是还是不行。 非常感谢。

<html>
  <head>
  </head>
  <body>
    <label id = "esperanto-notice"></label>
    <script type="text/javascript">  
      var notice = document.getElementById("esperanto-notice")
      for(var i =0; i<100000; i++){
        notice.innerHTML = i
        console.log(i)
      } 
      console.log("done")
    </script>
  </body>
</html>

最佳答案

Javascript 尝试在更新 DOM 之前运行所有内联代码,因为后者很慢。您的整个循环在页面更新一次之前运行。

我们可以强制页面更新:

for(var i =0; i<100000; i++){
    notice.innerHTML = i;
    notice.getBoundingClientRect(); // Force DOM update to get latest size
    console.log(i);
} 

但是,当 DOM 正在更新时,它仍然直接返回到 JS 以继续运行循环 - 这更新速度比您看到的要快,并且仍然似乎挂起。

您需要做的是暂停 JS 执行,以便页面有机会更新

我们可以使用异步 JS 函数来完成此操作 - 完成当前 JS block 但将回调函数排队等待稍后触发(在本例中是在用户看到它之后):

var notice = document.getElementById("esperanto-notice");
var i = 0;

// Function to write the next value, increment, and queue up the next timeout
var nextFunc = function() {
  console.log(i);
  notice.innerHTML = i++;
  if (i < 100000)
    setTimeout(nextFunc, 16); // 16ms is 60FPS 
  else
    console.log('done');
}

// Start it off
nextFunc();
<label id="esperanto-notice"></label>

现在整个 JS 运行,nextFunc 执行一次。它还将其排队等待 16 毫秒后再次触发,但在此之前它会让浏览器更新页面。

每次 nextFunc 触发它都会使用 setTimeout排队下一次执行,然后页面有一个框架要更新(以便用户看到它),然后再次触发。

现代浏览器专门提供了等待下一帧的功能:requestAnimationFrame :

var notice = document.getElementById("esperanto-notice");
var i = 0;

// Function to write the next value, increment, and queue up the next timeout
var nextFunc = function() {
  console.log(i);
  notice.innerHTML = i++;
  if (i < 100000)
    // Request the next visible frame to continue
    requestAnimationFrame(nextFunc); 
  else
    console.log('done');
}

// Start it off
nextFunc();
<label id="esperanto-notice"></label>

除非您需要支持旧版本的 IE (<=9),否则这是最好的方法,因为 requestAnimationFrame 可以处理任何帧持续时间(setTimeout 可能有问题如果你有很多卡顿)。

最后,新的语言关键字 asyncawait 可以让您的代码更简单。您可以保持循环并抽象等待 DOM 更新。下一个片段只能在 Chrome 和 FX 等现代浏览器上运行(但可以使用 Babel 或 TypeScript 来支持 IE):

(async function() {
  var notice = document.getElementById("esperanto-notice");
  for (var i = 0; i < 100000; i++) {
    console.log(i);
    notice.innerHTML = i;
    
    // Pass back to the DOM until the next frame
    await new Promise(r => requestAnimationFrame(r));
  }

  console.log('done');
})();
<label id="esperanto-notice"></label>

关于javascript div更新率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43385886/

相关文章:

php - 单击 HTML 表格数据并插入到文本区域

javascript - Vuejs 获取组件 HTML 并通过 ajax POST 发送

html - 有序列表未将嵌套数字正确应用于第二项

html - 在保持列对齐的同时将文本居中放置在图像上

html - 如何使用 webpack 服务图像?

javascript - Material ui 版本 4-11.4 的文档丢失

php - 如何使用 javascript 中的 onclick 事件链接到另一个 php 页面?

javascript - KineticJS 如何为图像设置动画

javascript - 加载大背景图像

html - 按钮不存在时呈现输入组