Search code examples
javascriptforeachtimer

setTimeout in forEach loop only shows specific element in sequence


When the start button is clicked, a sequence of colors should light up on the board. The array of colors is consoled logged and the box element with the corresponding color is selected. The timeout function with the changeOpacity function changes the opacity of the boxes color for a few seconds then brings it back to normal to create the desired effect.

This part of the code is what's explained above.

btn.addEventListener('click', ()=> {
  if (!gamePlay) {
    gamePlay=true;
    createSequence(number);
    gameClicks.forEach((color,i)=> {
      box=document.querySelector(`.box[data-color=${color}]`)
      setTimeout(()=> {
        changeOpacity();
      }, 200*i);
    })
  }
});


function changeOpacity() {
  box.classList.toggle('active');
  setTimeout(()=> {
  box.classList.toggle('active');
  }, 300);
}

However, my problem is that only one color in particular is lighting up when the sequence is ran. That is quite odd to me. For example, when start is clicked, maybe only the box with the color attribute of yellow will light up. I don't understand why that is happening.


Solution

  • Pass changeOpacity the current box (and make sure to properly scope the box inside the function rather than having it be an implicitly global variable):

    btn.addEventListener('click', () => {
      if (!gamePlay) {
        gamePlay = true;
        createSequence(number);
        gameClicks.forEach((color, i) => {
          const box = document.querySelector(`.box[data-color=${color}]`)
          setTimeout(() => {
            changeOpacity(box);
          }, 200 * i);
        })
      }
    });
    
    
    function changeOpacity(box) {
      box.classList.toggle('active');
      setTimeout(() => {
        box.classList.toggle('active');
      }, 300);
    }