【问题标题】:JavaScript. a loop with innerHTML is not updating during loop executionJavaScript。在循环执行期间没有更新带有 innerHTML 的循环
【发布时间】:2011-12-27 23:53:43
【问题描述】:

我正在尝试在每个循环中从 Javascript 刷新一个 div 并查看 1、2、3、...。 以下代码有效,但仅显示最终结果 (9998)。 如何显示所有步骤? 提前谢谢你。

<html>
<head>
</head>
<body>

<div id="cadre" style="width=100%;height=100%;">
    <input type="button" value="Executer" onclick="launch();"/>
    <div id="result" ></div>
</div>

<script type="text/javascript">
     function launch(){
        for (inc=0;inc<9999;inc++){
            document.getElementById('result').innerHTML = inc;
        }
     }
</script>

</body>
</html>

【问题讨论】:

  • innerHTML 是魔鬼,别再用了。
  • @Raynos 有没有明确的替代品?

标签: javascript innerhtml partial-page-refresh


【解决方案1】:

JavaScript 执行和页面渲染在同一个执行线程中完成,这意味着当您的代码正在执行时,浏览器不会重绘页面。 (尽管即使它在 for 循环的每次迭代中都重新绘制页面,它也会如此之快,以至于您真的没有时间查看各个数字。)

您想要做的是使用setTimeout()setInterval() 函数(window 对象的两种方法)。第一个允许您指定将在设定的毫秒数后执行一次的函数;第二个允许您指定将在指定的时间间隔重复执行的函数。使用这些,在您的代码执行之间会有“空格”,浏览器将有机会重绘页面。

那么,试试这个:

function launch() {
   var inc = 0,
       max = 9999;
       delay = 100; // 100 milliseconds

   function timeoutLoop() {
      document.getElementById('result').innerHTML = inc;
      if (++inc < max)
         setTimeout(timeoutLoop, delay);
   }

   setTimeout(timeoutLoop, delay);
}

请注意,函数timeoutLoop() 会通过setTimeout() 调用自身 - 这是一种非常常见的技术。

setTimeout()setInterval() 都返回一个 ID,该 ID 本质上是对已设置计时器的引用,您可以将其与 clearTimeout()clearInterval() 一起使用以取消任何尚未发生的排队执行,所以实现你的功能的另一种方法如下:

function launch() {
   var inc = 0,
       max = 9999;
       delay = 100; // 100 milliseconds

   var iID = setInterval(function() {
                            document.getElementById('result').innerHTML = inc;
                            if (++inc >= max)
                               clearInterval(iID);
                         },
                         delay);
}

显然,您可以根据需要更改 delay。请注意,在这两种情况下,inc 变量都需要在计时器正在执行的函数之外定义,但是由于闭包的魔力,我们可以在launch() 中定义它:我们不需要全局变量。

【讨论】:

  • 据我了解,第一个示例的技巧在于调用堆栈。
【解决方案2】:
var i = 0;

function launch(){
           var timer = window.setInterval(function(){
               if( i == 9999 ){
                   window.clearInterval( timer );
               }
               document.getElementById('result').innerHTML = i++;
           }, 100);
}

launch();

【讨论】:

  • 这将尝试每秒将document.getElementById('result').innerHTML 设置为9999 10,000 次。
  • 感谢 Oddan,但我已经尝试过这个解决方案,而且它也只显示最终结果,但会有延迟。
  • 编辑后的版本更好,但不会止步于 9,999,它会一直持续下去。
  • 是的,它正在工作!谢谢你。现在,我必须了解与您提供的第一个版本的区别。
  • 这是自愿的,为了引导你不要犯错误......我在开玩笑..这就是你编码抢夺时发生的事情。第一个版本是无缝的,没有条件停止间隔......你没看到区别吗?真的吗?
【解决方案3】:

试试

document.getElementById('result').innerHTML += inc;

【讨论】:

  • 这是错误的。序列可能是 0、1、3、7 或更糟:连接数字。
猜你喜欢
  • 2011-12-18
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
相关资源
最近更新 更多