const divArr = []; for (let i = 0; i < 5; i++) { document.getElementById("h").innerHTML += `<div id=${i}>hello</div>`; divArr.push(document.getElementById(`${i}`)); } console.log(divArr); let divArrIndex = 0; setInterval(() => { document.getElementById(`${divArrIndex}`).style.backgroundColor = 'green'; if (divArrIndex > 4) { divArrIndex = 0; } divArrIndex += 1; }, 1000 / 1);
<div id="h">alsdjf;lkajsdf</div>
Pero, cuando uso
divArr[divArrIndex].style.backgroundColor = "green"
en vez de
document.getElementById(`${divArrIndex}`).style.backgroundColor='green';
Solo obtengo el último div verde. ¿Por qué? codepen: https://codepen.io/sai-nallani/pen/KKopOXZ?editors=1111
Al reasignarlo a innerHTML
, está destruyendo y recreando el contenido de #h
en cada iteración del bucle. Creas #0
, luego lo descartas y creas #0
y #1
, luego los descartas y creas #0
, #1
, #2
... Entonces los elementos que insertas en la matriz ya no existen en tu documento ( aunque las referencias a ellos en divArr
aún evitan que el recolector de basura los destruya por completo).
Cuando cambia el color de divArr[0]
, está cambiando el color de un elemento que solo existe en la memoria, pero ya no está en DOM. Sin embargo, #4
sigue siendo el #4
original, no se ha descartado, ya que no ha realizado más asignaciones a innerHTML
.
Una solución es reunir todos los divs después de haberlos construido todos. Puede usar otro bucle, pero la forma más fácil sería:
const divArr = Array.from(document.querySelectorAll('#h > div'));
(Dependiendo de lo que haga con él a continuación, es posible que no necesite Array.from
ya que NodeList
debería ser suficiente para muchos propósitos).
Otra solución es construir elementos por derecho propio, no cambiando el innerHTML
del padre:
const hEl = document.querySelector('#h'); for (let i = 0; i < 5; i++) { const divEl = document.createElement('div'); divEl.textContent = 'Hello'; divEl.id = i; hEl.appendChild(divEl); divArr.push(divEl); }
De esta manera, cada elemento se crea y se agrega a #h
sin afectar a ningún otro elemento que ya esté allí.