entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

addEventListener en un loop

Hola, tengo un problema que me ha estado dando un dolor de cabeza durante dos días.

Quiero añadir "escuchadores" de eventos a varios enlaces en la página. EL objetivo es hacer una llamada ajax pasando parámetros que irán cambiando de valor para cada enlace.

El problema es que sólo se pasan los últimos valores de los parámetros al handler del addEventListener.

EL código que tengo es el siguiente:

vector_borrar_avisos = document.getElementsByClassName("borrar_aviso");

for (i = 0; i < vector_avisos.length; i++) {

    id_aviso = ids_avisos[i];

    nombre_tabla = nombres_tablas[i];

    vector_borrar_avisos[i].addEventListener("click", function () {event.stopPropagation(); borrar_aviso(id_aviso, nombre_tabla);}, false);

}

La verdad es que no entiendo porque ocurre esto, podría ser alguna deficiencia de javascript?

2 Respuestas

3votos

Leonardo-Tadei Puntos227020

Hola Quijote,

sin ver la página completa en dónde se aplica esto es difícil de decir qué pasa, pero se me ocurre que tu código está asumiendo que si vector_borrar_avisos tiene por ejemplo 5 elementos, serán elementos del 0 al 4... cuando en realidad al borrar por ejemplo el aviso 3, tenés ahora 4 alementos no consecutivos y enpieza a fallar el addEventListener()

Esto dependerá en gran parte de dónde y cuándo se ejecuta el código que nos mostrás... podrías poner un

console.log(i, vector_borrar_avisos[i]);

adentro del bucle para ver si la asignación es siempre a los elementos correctos.

Saludos

0voto

quijote108 comentado

Gracias por responder Leonardo. Verifiqué con el método que me dijiste y no hay ningún problema con la asignación del índice en relación al elemento. Yo concluyo que esto puede ser una falencia del lenguaje porque he probado de miles de formas comprobando la sintaxis y siempre ocurre lo mismo, incluso con elemento.onlick = function() {...}. Seguiré buscando información, en caso de que encuentre la respuesta la publicaré aquí.

0voto

Leonardo-Tadei comentado

Hola @quijote108,

no he visto código tuyo para hacerme una idea de tu trabajo, pero apelando a la estadística, puedo decirte que hay un 99,9% de posibilidades de que sea un error en tu código contra un 0.01% de que sea una falencia del lenguaje.

Si pudieses publicar una página funcional (dinámica o estática) en dónde podamos ver el código de alrededor y podamos repetir el fallo, seguramente podremos entre todos dar con el problema y proponerte una solución... hay que animarse a preguntar y a publicar, que no duele tanto como parece ;-)

0voto

quijote108 comentado

Mi objetivo al resumir el código es no aburrir a la gente, pero ya que dices que no queda claro, para la próxima vez plantearé el código de forma más extensa. Gracias por la observación.

0voto

Leonardo-Tadei comentado

Entiendo tu objetivo, pero una porción de código no sirve para hacer debugging, y es habitual tener que hacer funcionar el código para entender qué es lo que le pasa...

2votos

white Puntos75820

No es ninguna falencia de javascript, creo que el problema es que en el loop por elevacion siempre vas a tener el ultimo elemento definido, deberias o hacer una funcion aparte o una anónima con argumentos, aca abajo te dejo un ejemplo que probe en jsfiddle. mira en tu consola como los elementos otros click 01...10 regresan el ultimo elemento (la letra "j") de un array con letras [a...o], mientras que al hacer click en click 01...10 te devuelve correctamente los valores de la a a la j.

quedando tu codigo algo asi:

vector_borrar_avisos = document.getElementsByClassName("borrar_aviso");

for (i = 0; i < vector_avisos.length; i++) {
    (function (id_aviso, nombre_tabla) {
        vector_borrar_avisos[i].addEventListener("click", function () {
            event.stopPropagation();
            borrar_aviso(id_aviso, nombre_tabla)
        ;}, false);
    }(ids_avisos[i], nombres_tablas[i]));
}

http://jsfiddle.net/ympoL1d1/2/embedded/result/
http://jsfiddle.net/ympoL1d1/2/

update: actualize el ejemplo

0voto

quijote108 comentado

Gracias White, funciona perfecto. La explicación que encontré sodeando en internet es que el contexto de una variable cualquiera en javascript está sólo dentro de la función en la cual se define, por lo que si se crea una función dentro de otra, las variables que estaban definidas en la función que engloba a la otra quedan con el valor final que poseen. Por esto el valor de i que se pasa al addEventListener es el último de la iteración, pues es el último valor que toma la variable i dentro de la función "mayor".

De todas formas sigo pensando que se trata de una falencia o al menos un caso extraño, ya que la sintaxis de la solución es bastante extraña y no se parece mucho a la mayoría de lo que se escribe en javascript, es mi percepción.

0voto

white comentado

Tal cual, a esto se lo conoce como closures, una solucion es una envoltura ( el codigo que te propuse ). es algo confuso cuando se topa por primera vez. me alegro se haya resuelto ^^

http://www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta