Asignar controladores de clic en el bucle for

Resuelto Philip asked hace 13 años • 6 respuestas

Tengo varios div #mydiv1, #mydiv2, #mydiv3, ... y quiero asignarles controladores de clic:

$(document).ready(function(){
  for(var i = 0; i < 20; i++) {
    $('#question' + i).click( function(){
      alert('you clicked ' + i);
    });
  }
});

Pero en lugar de mostrarse 'you clicked 3'cuando hago clic #mydiv3(como ocurre con cualquier otro clic), aparece 'you clicked 20'. ¿Qué estoy haciendo mal?

Philip avatar Nov 04 '10 04:11 Philip
Aceptado

Es un error común crear cierres en bucles en Javascript. Necesitas tener algún tipo de función de devolución de llamada como esta:

function createCallback( i ){
  return function(){
    alert('you clicked' + i);
  }
}

$(document).ready(function(){
  for(var i = 0; i < 20; i++) {
    $('#question' + i).click( createCallback( i ) );
  }
});

Actualización del 3 de junio de 2016: dado que esta pregunta todavía está ganando terreno y ES6 también se está volviendo popular, sugeriría una solución moderna. Si escribe ES6, puede usar la letpalabra clave, que hace que la ivariable sea local para el bucle en lugar de global:

for(let i = 0; i < 20; i++) {
  $('#question' + i).click( function(){
    alert('you clicked ' + i);
  });
}

Es más corto y más fácil de entender.

Harmen avatar Nov 03 '2010 21:11 Harmen

Para aclarar, i es igual a 20 porque el evento de clic no se habrá activado hasta que finalice el ciclo.

Donald avatar Nov 03 '2010 21:11 Donald
$(document).ready(function(){
  for(var i = 0; i < 5; i++) {
   var $li= $('<li>' + i +'</li>');
      (function(i) {
           $li.click( function(){
           alert('you clicked ' + i);
         });
      }(i));
      $('#ul').append($li);
  }
});
user1490857 avatar Jun 05 '2013 12:06 user1490857