Can I force the browser to render DOM changes during javascript execution
Asked Answered
J

4

7

Is there a way to force the browser to render DOM changes during the execution of JavaScript? In the following example, only the '1000' will be displayed and I do understand that this is caused by having only a single thread processing the JavaScript executing but I was wondering if there is a way to force the browser to render each DOM change?

Example:

var el = document.getElementById("#fixup"),
   i;

for (i = 1; i <= 1000; i++) {
   // can i force this DOM update to the rendered?
   el.innerHTML = i.toString());
}
Jhelum answered 12/11, 2015 at 22:48 Comment(2)
Usually by breaking execution into sequential calls to setTimeout or setInterval with a short pause (maybe even 0 since it will never actually be zero).Dipteral
No, you cannot force the browser to do anything. It'll do what it wants when wants to. This includes not rendering anything (headless browser) or not executing your script at all :-)Dilisio
E
6

You can do it with timers. Here's an example:

var el = document.getElementById("fixup");
var speed = 10;
for (var i = 1; i <= 1000; i++) {
  setTimeout(function(i) {
      el.innerHTML = i;
  }, speed * i, i);
}
<div id="fixup"></div>

Probably not the best way though, having 1000 timers from the get go is kind of fishy.

An alternative:

var el = document.getElementById("fixup");
var speed = 10, i = 0, limit = 1000;
  setTimeout(function loop() {
      el.innerHTML = i++;
      if(i <= limit){
        setTimeout(loop, speed);
        }
  }, speed);
<div id="fixup"></div>

Ultimately this would be the best if you don't care for the speed at which elements are rendered:

var el = document.getElementById("fixup");
var speed = 10, i = 0, limit = 1000;
  window.requestAnimationFrame(function loop() {
      el.innerHTML = i++;
      if(i <= limit){
        window.requestAnimationFrame(loop);
        }
  });
<div id="fixup"></div>
Evergreen answered 12/11, 2015 at 23:0 Comment(1)
Thank you for the very helpful feedback! How did you btw create the nice code snippets?Jhelum
M
0

If you are only supporting chrome if you call

alert("check the box to prevent these")

and it will update the DOM every time it is called but if other browsers come on it could be very annoying

Mongeau answered 12/11, 2015 at 23:1 Comment(0)
B
0

If you are trying to have DOM show 1-1000, then create a div object every loop and appendChild() to your el. Then instead of showing 1000, you can see 1- 1000.

inside of the forloop,

var newDiv = document.createElement("div");
newDiv.innerHTML = i;
el.appendChild(newDiv);

and out of the loop. Basically, every time it loops, you are creating a new div, assigning the value to (this) newDiv, and appending it the parent node. I hope this helped.

Breuer answered 12/11, 2015 at 23:2 Comment(0)
F
-1

Take a look at the for performence test HERE and you will see that the for loop is really fast and it can loop 1000 in ~0.135 second, so if you want to display all iteration you have to use setTimedout() to slowdown the operation.

Farleigh answered 12/11, 2015 at 22:57 Comment(2)
Browsers will not render a new image until the current thread stops, so you need to stop processing entirely, not just slow down. ;-)Dipteral
Hi @RobG, you see that my answer is helpfull or i should remove it :)Farleigh

© 2022 - 2024 — McMap. All rights reserved.