JavaScript. цикл с innerHTML не обновляется во время выполнения цикла - PullRequest
6 голосов
/ 13 ноября 2011

Я пытаюсь обновить div из Javascript в каждом цикле и увидеть 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>

Ответы [ 3 ]

19 голосов
/ 13 ноября 2011

Выполнение 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() возвращают идентификатор, который по сути является ссылкой на установленный таймер, который можно использовать с 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(): нам не нужны глобальные переменные.

0 голосов
/ 12 июля 2012

Попробуйте

document.getElementById('result').innerHTML += inc;
0 голосов
/ 13 ноября 2011
var i = 0;

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

launch();
...