JavaScript。在循环执行期间没有更新带有 innerHTML 的循环

Posted

技术标签:

【中文标题】JavaScript。在循环执行期间没有更新带有 innerHTML 的循环【英文标题】:JavaScript. a loop with innerHTML is not updating during loop execution 【发布时间】: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 有没有明确的替代品? 【参考方案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 或更糟:连接数字。

以上是关于JavaScript。在循环执行期间没有更新带有 innerHTML 的循环的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套for循环的Javascript多维数组-无法正常工作

JavaScript学习系列博客_11_JavaScript中的for语句

带有innerHtml循环的Javascript幻灯片不起作用

有没有办法在 Ruby 中使用带有任何方法的 while 循环来执行冒泡排序算法?

python有趣用法汇总(持续更新)

Qt 在处理时更新(重绘)文本框