count=1;
for(var i=0;i<5;i++){
   count++;
   $("#ImageProductLeft"+count.toString()).bind('click', function(){
           alert(i);                                                                                                                                    
   });
}

Quiero que cuando haga clic en ImageProductLeft1 muestre alert(1) y haga clic en ImageProductLeft2 muestre alert(2) y ...

Pero haga clic en todos los `ImageProductLeft1 show alert(5)

1
ashkufaraz 1 ago. 2011 a las 10:59

5 respuestas

La mejor respuesta
count=1;
for(var i=0;i<5;i++){
   count++;
   $("#ImageProductLeft"+count.toString()).bind('click', {i: i}, function(event){
         alert(event.data.i);
   });
}
1
scessor 1 ago. 2011 a las 07:04

Esto es un poco más elegante y flexible:

$("div[id^='ImageProductLeft']").each(function(index) {
    $(this).click(function() {
        alert(index);
    });
});

Puede tener tantos elementos que comiencen con ImageProductLeft como desee, y hacer clic en cualquiera alertará a sus respectivos índices.

Caso de prueba en vivo.

2
Shadow Wizard is Ear For You 1 ago. 2011 a las 07:09

Tiene este problema porque i en cada uno de los controladores de eventos que creó está apuntando a la misma ubicación en la memoria. Intenta usar esto:

count=1;
for(var i=0;i<5;i++){
   count++;

   $("#ImageProductLeft"+count.toString()).bind('click', 
       function(x){
           return function() { alert(x); };
       }(i)                                                                                                                                    
   });
}

Este es un error bastante común. Consulte esta página para obtener más información.

0
fsong 1 ago. 2011 a las 07:10
for (var i = 1; i<6; i++)
{
    $("#ImageProductLeft" + i.toString()).bind('click', function() {
        alert(i);
    });
}
0
Emanuele Minotto 1 ago. 2011 a las 07:04

Está creando una función en un bucle (cierres). Todas las variables se compartirán entre ellas, también i.

Cuando las funciones son llamadas eventualmente, el ciclo ya ha terminado y i tendrá el valor 5.

JavaScript no tiene alcance de bloque. Para crear un nuevo ámbito y capturar el valor de las variables, realiza una llamada a la función:

for(var i=0;i<5;i++){
   (function(x) {
       $("#ImageProductLeft"+count.toString()).bind('click', function(){
           alert(x);                                                                                                                                    
       });
   }(i));
}

Aquí usamos una función inmediata para "capturar" el valor de i.


Dicho esto, como está utilizando jQuery, hay otros métodos más elegantes para resolver esto, como se muestra en @ scessor's y @Shadow Wizard .

Sin embargo, es importante saber por qué funciona así y cómo se puede resolver en JavaScript "puro".

Los cierres pueden ser complicados. Sugiero echar un vistazo a Cierres de JavaScript para Dummies.

1
Community 23 may. 2017 a las 11:57