es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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);
    }
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con setTimeOut en este código es que no funcionará como se espera debido al closure. Las funciones showone y hideone se crean dentro del bucle for, y como hacen referencia a la variable i, que se incrementa en cada iteración del bucle, todas harán referencia al mismo valor de i que es igual a els.length-1 al final del bucle.

    Esto significa que cuando se ejecutan las funciones setTimeout, el valor de i ya habrá alcanzado su valor máximo de els.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 funciones showone y hideone. De esta manera, cada función tendrá su propia copia de la variable i y funcionarán como se espera.

    Otra solución es usar la palabra clave let en lugar de var al declarar la variable i. let crea una variable con alcance de bloque, lo que significa que cada iteración del bucle tendrá su propia copia de la variable i.

    Aquí tienes un ejemplo de cómo crear un closure alrededor de la variable i:

    function changestyle() {
        var els = document.getElementsByClassName("submenu");
        for (let i = 0; i < els.length-1; i++) {
            (function(index) {
                const showone = function() {
                    els[index].style.display = 'block';
                };
                const hideone = function() {
                    els[index].style.display = 'none';
                };
                setTimeout(showone, 2000);
                setTimeout(hideone, 2000);
            })(i);
        }
    }
    

    En este ejemplo, estamos envolviendo las funciones showone y hideone dentro de una expresión de función que se invoca inmediatamente (IIFE) que toma la variable i como argumento y crea un closure alrededor de ella. Pasamos el valor actual de i a la IIFE usando (i) como argumento, y dentro de la IIFE usamos index en lugar de i para hacer referencia al elemento actual en la matriz els.

Comments are closed.