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.

Selector de JS del bucle del acordeón.

Intento conectar una matriz de objetos que hace referencia a iconos SVG en un bucle for a una matriz de contenido coincidente dejando que el índice del bucle for actúe como un mecanismo de emparejamiento. Ambas matrices se registran identificando todos los objetos relevantes, pero cuando llamo a los cambios de panel[i] obtengo que panel[i] es indefinido. acc[i] parece funcionar bien dentro del bucle for. ¿Cómo puedo asegurarme de que los event listeners de acc[i] se emparejen con sus paneles de posición de índice correspondientes para luego controlar el css en los paneles para cambiar la visualización de oculto a bloque?

¡Gracias!

const acc = document.querySelectorAll(".fas.fa-plus-circle.fa-3x");
const panel = document.querySelectorAll(".panel");
let i;
console.log(acc);
console.log(panel);
for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    console.log(panel[i]);
    if (panel[i].style.display === "block") {
      panel[i].style.display = "none";
    } else {
      panel[i].style.display = "block";
    }
  });
}

Note: In the translation, I converted the HTML entities to the actual special characters they represent for better readability.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está en el ámbito de la variable i. Dado que addEventListener está dentro del bucle for, cuando se desencadena el evento, el valor de i ya habría excedido la longitud de las matrices. Una solución a esto puede ser usar un cierre para vincular el valor actual de i al controlador de eventos. Puedes hacer esto envolviendo el controlador de eventos en una función y pasando i como parámetro. Así es como puedes modificar el código:

    const acc = document.querySelectorAll(".fas.fa-plus-circle.fa-3x");
    const panel = document.querySelectorAll(".panel");
    
    for (let i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", (function(index) {
        return function() {
          this.classList.toggle("active");
          console.log(panel[index]);
          if (panel[index].style.display === "block") {
            panel[index].style.display = "none";
          } else {
            panel[index].style.display = "block";
          }
        }
      })(i));
    }
    

    En el código modificado, envolvemos el controlador de eventos dentro de una IIFE (Expresión de Función Invocada Inmediatamente) y pasamos el valor actual de i como parámetro. Esto crea un nuevo cierre para cada iteración del bucle y vincula el valor actual de i al controlador de eventos. Ahora, cuando se desencadena el evento, se utiliza el valor correcto de i para acceder al elemento correspondiente en la matriz panel.

Comments are closed.