Cómo mejorar el setTimeout?
¿Por qué no funciona setTimeOut en este código? Estoy intentando mostrar los submenús uno por uno, no estoy seguro si esta es la forma correcta. Alguien me dijo que hay un problema en el cierre.
El código:
function changestyle(){
var els = document.getElementsByClassName("submenu");
for(var i = 0; i < els.length-1; i++)
{
const showone = function(){
els[i].style.display = 'block';
};
const hideone = function(){
els[i].style.display = 'none';
};
setTimeout(showone, 2000);
setTimeout(hideone, 2000);
}
}
davy.ai
El problema con
setTimeOut
en este código es que no funcionará como se espera debido al closure. Las funcionesshowone
yhideone
se crean dentro del buclefor
, y como hacen referencia a la variablei
, que se incrementa en cada iteración del bucle, todas harán referencia al mismo valor dei
que es igual aels.length-1
al final del bucle.Esto significa que cuando se ejecutan las funciones
setTimeout
, el valor dei
ya habrá alcanzado su valor máximo deels.length-1
y todos los submenús se mostrarán o se ocultarán simultáneamente.Para solucionar este problema, una solución es crear un closure alrededor de la variable
i
pasándola como argumento a las funcionesshowone
yhideone
. De esta manera, cada función tendrá su propia copia de la variablei
y funcionarán como se espera.Otra solución es usar la palabra clave
let
en lugar devar
al declarar la variablei
.let
crea una variable con alcance de bloque, lo que significa que cada iteración del bucle tendrá su propia copia de la variablei
.Aquí tienes un ejemplo de cómo crear un closure alrededor de la variable
i
:En este ejemplo, estamos envolviendo las funciones
showone
yhideone
dentro de una expresión de función que se invoca inmediatamente (IIFE) que toma la variablei
como argumento y crea un closure alrededor de ella. Pasamos el valor actual dei
a la IIFE usando(i)
como argumento, y dentro de la IIFE usamosindex
en lugar dei
para hacer referencia al elemento actual en la matrizels
.