0

I want to change the visibility of the elements of class container_element with an interval of one second one by one. i tried solve my problem with for loop but when i try to setInterval in for loop it stops and doesnt show anything.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task</title>
</head>
<style>
    .container {
        border: 5px solid;
        text-align: center;
    }

    .container_element {
        visibility: hidden;
    }
</style>

<body>
    <div class="container">
        <div class="container_element"></div>
        <div class="container_element"></div>
        <div class="container_element">✈️</div>
        <div class="container_element"></div>
        <div class="container_element"></div>
        <div class="container_element"></div>
    </div>
</body>
</html>

i tried this,but it did not work.

<script>
    function showDiv() {
        var items = document.querySelectorAll(".container_element");
        for (i = 1; i < items.length; i++) {
            setInterval(() => {
                items[i].style.visibility = 'visible';
            }, 1000);
        }
    }
    showDiv();
</script>

rikobgrff
  • 17
  • 4
  • By the time the interval has passed, i = items.length, which doesn't exist. FYI, you are skipping the first item, since you init with `i=1` instead of `i=0`. – mykaf Apr 11 '23 at 16:34
  • The execution of your for loop does not wait for the given interval. See https://stackoverflow.com/a/75762382/120955 and https://stackoverflow.com/a/38948753/120955 – StriplingWarrior Apr 11 '23 at 16:37

2 Answers2

2

Don't use a loop, setInterval() already makes the function repeat. Each iteration of that should make the next element visible.

function showDiv() {
  let i = 0;
  var items = document.querySelectorAll(".container_element");
  let interval = setInterval(() => {
    items[i].style.visibility = 'visible';
    i++;
    if (i >= items.length) {
      clearInterval(interval);
    }
  }, 1000);
}

showDiv();
.container {
  border: 5px solid;
  text-align: center;
}

.container_element {
  visibility: hidden;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Task</title>
</head>

<body>
  <div class="container">
    <div class="container_element"></div>
    <div class="container_element"></div>
    <div class="container_element">✈️</div>
    <div class="container_element"></div>
    <div class="container_element"></div>
    <div class="container_element"></div>
  </div>
</body>

</html>
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

You should use an async/await approach to simplify your logic:

showContainerElements();

async function showContainerElements() {
  const items = document.querySelectorAll('.container-element');
  for (let i = 0; i < items.length; i++) {
    await sleep(1000);
    items[i].classList.add('container-element-visible');
  }
}

async function sleep(delayInMs) {
  return new Promise(function(resolve) {
    setTimeout(resolve, delayInMs);
  });
}
.container {
  border: 5px solid;
  text-align: center;
}

.container-element {
  visibility: hidden;
}

.container-element-visible {
  visibility: visible;
}
<div class="container">
  <div class="container-element"></div>
  <div class="container-element"></div>
  <div class="container-element">✈️</div>
  <div class="container-element"></div>
  <div class="container-element"></div>
  <div class="container-element"></div>
</div>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132