2

Ahora mismo intento hacer un console.log cada segundo.

Tengo 5 div con un data distinto cada uno. Con un forEach consigo obtener todos los data uno por uno, pero, siempre se hace un console.log con todos a la vez.

window.addEventListener('load', ()=>{

  document.querySelector('.magic').addEventListener('click', ()=>{
    startGame();
  })
});

function startGame(){
  document.querySelectorAll('.cont').forEach(item=>{
    let dat = item.getAttribute('data');
    recursiveColor(dat);
  });
}

function recursiveColor(dat){
  setTimeout(function(){console.log(dat)},1000);
}
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
    <title>013 : paleta</title>
    <link rel="stylesheet" type="text/css" href="css/013.css">
    <script src="js/013.js"></script>
</head>
<body>
    <div class="plt">
        <div class="red cont" data="red"></div>
        <div class="blu cont" data="blue"></div>
        <div class="yel cont" data="yellow"></div>
        <div class="gre cont" data="green"></div>
        <div class="pur cont" data="purple"></div>
    </div>
<button type="button" class="magic">MAGIA</button>
</body>
</html>

No creo entender bien una de las dos funciones:

  • O bien no entiendo el bucle forEach y el resultado que me da
  • O bien no entiendo el setTimeout
  • (o no entiendo ninguno)

¿Qué es lo que estoy haciendo mal? ¿Cómo consigo que se ejecute una orden console.log cada segundo?



[EDIT]

Bien, ya conseguí lo que quería, hasta cierto punto. Ya que ahora me surge la duda de si sería mejor hacerlo con un intervalo, ya que setTimeout hace que al final se me rompa la secuencia:

window.addEventListener('load', ()=>{

  document.querySelector('.magic').addEventListener('click', ()=>{
    startGame();
  })
});

function startGame(){
  document.querySelectorAll('.cont').forEach((item, index)=>{
    let dat = item.getAttribute('data');
    recursiveColor(item, dat, (index+1)*1000);
  });
}

function recursiveColor(item, dat, time){
  setTimeout(function(){
    item.style.backgroundColor = 'white';
  },time);
  setTimeout(function(){
    item.style.backgroundColor = dat;
  },time+1000);
  setTimeout(startGame,6000);
}
.cont{
    width:50px;
    height:50px;
    border:1px solid #000;
    margin:0 15px;
    display: inline-block;
    float: left;
}

.red{
    background: red;
}
.blu{
    background: blue;
}
.yel{
    background: yellow;
}
.gre{
    background: green;
}
.pur{
    background: purple;
}
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
    <title>013 : paleta</title>
    <link rel="stylesheet" type="text/css" href="css/013.css">
    <script src="js/013.js"></script>
</head>
<body>
    <div class="plt">
        <div class="red cont" data="red"></div>
        <div class="blu cont" data="blue"></div>
        <div class="yel cont" data="yellow"></div>
        <div class="gre cont" data="green"></div>
        <div class="pur cont" data="purple"></div>
    </div>
<button type="button" class="magic">MAGIA</button>
</body>
</html>

Tarda un poco, quizá unas 4 secuencias, pero al final se rompe haciendo que todos los cuadrados se apaguen y enciendan a la vez intermitentemente cada pocos milisegundos...

Quizá sería mejor hacerlo con un intervalo, pero quiero saber de antemano si el problema que surge con este cambio es cosa de la programación o si es un bug.

AQMR
  • 1,236
  • 5
  • 13
  • No, ya que la cuestión en mi pregunta trata sobre un bucle forEach y un setTimeout, no un bucle for. Entiendo perfectamente el bucle for. No es una pregunta duplicada. – AQMR Mar 24 '21 at 12:53

1 Answers1

3

Cambia estas 2 funciones así:

function startGame(){
  document.querySelectorAll('.cont').forEach((item, index)=>{
    let dat = item.getAttribute('data');
    recursiveColor(dat, (index+1)*1000);
  });
}

function recursiveColor(dat, time){
  setTimeout(function(){console.log(dat)},time);
}

El problema que tienes actualmente es que al mismo tiempo, estas diciendo a todos que dentro de un segundo se muestren en consola... entonces todos esperan un segundo y todos se muestran... lo que debes hacer es asignar un tiempo distinto a cada uno para que se muestren en consola. Por eso agregué el parametro time a la funcione recursiveColor, y lo configure desde el startGame.

Así el index 0 se muestra en 1000 milisegundos, el index 1 en 2000 milisegundos... y así sucesivamente.

Pipe
  • 1,557
  • 1
  • 7
  • 8