2011-06-26 10 views
19

Por ejemplo, tengo 10 a las etiquetas generadas a partir de una respuesta AJAX:¿Cómo generar controladores de eventos con bucle en Javascript?

<a href="#" id="b1">b1</a> 
<a href="#" id="b2">b2</a> 
<a href="#" id="b3">b3</a> 
<a href="#" id="b4">b4</a> 
<a href="#" id="b5">b5</a> 
<a href="#" id="b6">b6</a> 
<a href="#" id="b7">b7</a> 
<a href="#" id="b8">b8</a> 
<a href="#" id="b9">b9</a> 
<a href="#" id="b10">b10</a> 

necesito para asignar evento onclick a cada uno de ellos a través del bucle:

for(i=1; i<11; i++) { 
    document.getElementById("b"+i).onclick=function() { 
     alert(i); 
    } 
} 

Esto no funciona, se solo asigna onclick a la última etiqueta y alerta "11". ¿Cómo puedo hacer que esto funcione? Prefiero no usar jQuery.

+0

Debe llamar 'attachEvent' /' addEventListener' (a pesar de que no va a resolver su problema) – SLaks

+0

@SLaks ¿Por qué 'attachEvent' /' addEventListener' es más apropiado que 'element.onclick'? –

+0

@MicahHenning: para permitirle tener múltiples controladores. – SLaks

Respuesta

33

Todos sus controladores comparten la misma variable i.

Es necesario poner cada manipulador en una función separada que lleva i como un parámetro para que cada uno tiene su propia variable:

function handleElement(i) { 
    document.getElementById("b"+i).onclick=function() { 
     alert(i); 
    }; 
} 

for(i=1; i<11; i++) 
    handleElement(i); 
+0

Gracias, funcionó. – Caballero

+0

test.html: 11 TypeError no capturado: No se puede establecer la propiedad 'onclick' de nulo –

16

Un cierre es lo que está buscando:

for(i=1; i<11; i++) { 
    (function(i) { 
     document.getElementById("b"+i).onclick=function() { 
      alert(i); 
     }; 
    })(i); 
} 
+2

Diría que Caballero tiene un cierre en el que no quieren uno y que quieren un cierre buster para forzar la evaluación inmediata de 'i' . Eso es lo que está haciendo tu función de autoejecución. –

+1

Cierre/No-cierre ... ¡No me importa! Esta solución anónima/autoinvocada es hermosa :) Habría marcado esta. – Nick

+0

Mucho más elegante que tener una función separada. –

6

Hay dos formas de utilizar el cierre en este problema. La idea es crear un alcance con una instantánea de la variable "i" para cada iteración que utilizará el controlador de eventos.

Solución # 1 (como se mencionó por Kevin):

for(i=1; i<11; i++) { 
    (function(num) { 

     document.getElementById("b"+num).addEventListener('click', function() { 
      alert(num); 
     }); 

    })(i); 
} 

Solución # 2:

for (i=1; i<11; i++) { 
    document.getElementById("b"+i).addEventListener('click', (function(){ 
     var num = i; 
     return function() { 
      alert(num); 
     } 
    })()); 
} 
Cuestiones relacionadas