javascriptdomgetelementsbytagname

Remove then add elements one-by-one at intervals?


I'm currently writing a web application that needs all the elements in the <body> tag to be added into the page one by one, at regular intervals. The elements first need to be removed from the page, then put in setTimeout() functions at regular intervals to add them back in. Here's what I have so far:

window.onload = function() {
  var body = document.getElementsByTagName("body")[0];
  var time = 0;
  for (var i = body.children.length - 1; i > 0; i--) {
    var element = body.children[i];  // get element
    body.removeChild(element);  // remove element from page
    window.setTimeout(function() {  // in [time] seconds, add element back into page
      body.appendChild(element);
    }, time);
    time += 5000;  // five seconds between elements going into the page
  }
}

For some reason, this only adds in the first two elements, and the rest are ignored. I think it might be an issue with storing element in a setTimeout() call, but I'm not quite sure. Is there a better way to do this?


Solution

  • You need i <= 0, because you are skipping over the last child (the first element when looping backwards).

    window.onload = function() {
      setTimeout(function() {
        // BEGIN
        const body = document.body; // No need to call a method
        let time = 0;
        for (let i = body.children.length - 1; i >= 0; i--) {
          const removed = body.removeChild(body.children[i]); // remove element from page
          window.setTimeout(function() { // in [time] seconds, add element back into page
            body.appendChild(removed);
          }, time);
          time += 1000;  // 1 second between elements being added back
        }
        // END
      }, 1000); // Wait 1 second, then remove all
    }
    <p>One</p>
    <p>Two</p>
    <p>Three</p>
    <p>Four</p>
    <p>Five</p>

    If you want to loop forwards, change the way you set your duration.

    window.onload = function() {
      setTimeout(function() {
        // BEGIN
        const body = document.body; // No need to call a method
        let time = 0;
        for (let i = body.children.length - 1; i >= 0; i--) {
          const removed = body.removeChild(body.children[i]); // remove element from page
          window.setTimeout(function() { // in [time] seconds, add element back into page
            body.appendChild(removed);
          }, time);
          time = (body.children.length * 1000);  // 1 second between elements being added back
        }
        // END
      }, 1000); // Wait 1 second, then remove all
    }
    <p>One</p>
    <p>Two</p>
    <p>Three</p>
    <p>Four</p>
    <p>Five</p>