Définition des gestionnaires d'événements à l'aide d'une boucle for

J'étais en train de jouer avec javascript, sur jsfiddle et j'ai eu un problème étrange. Je ne peux pas comprendre pourquoi je ne parviens pas à configurer les onclick événements onclick via une boucle for:

Html:

 <table border="1" cellspacing="1" width="500"> <tr id="headerRow"> <td>Header1</td> <td>Header2</td> <td>Header3</td> <td>Header4</td> </tr> <tr> <td>books</td> <td>red</td> <td>peas</td> <td>321</td> </tr> <tr> <td>tapes</td> <td>blue</td> <td>jello</td> <td>654</td> </tr> </table> 

Js exécuté dans DOM ready:

 var arr = document.getElementById('headerRow') .getElementsByTagName("td"); // Why does this work?? /*arr[0].onclick = function() { alert(arr[0].innerHTML); }; arr[1].onclick = function() { alert(arr[1].innerHTML); }; arr[2].onclick = function() { alert(arr[2].innerHTML); }; arr[3].onclick = function() { alert(arr[3].innerHTML); }; */ //But this doesn't???? for(var i = 0; i < arr.length; i++) { arr[i].onclick = function() { alert(arr[i].innerHTML); }; } 

Http://jsfiddle.net/xzmMj/4/

i ne contiendra pas l'indice actuel tel que vous l'intention, mais plutôt la dernière valeur que arr.length , c'est-à-dire la arr.length

Une solution rapide et sale serait de faire quelque chose comme ça

 for(var i = 0; i < arr.length; i++) { (function(_i){ arr[_i].onclick = function() { alert(arr[_i].innerHTML); }; })(i); } 

Ce que cela fait, est de saisir la valeur actuelle de i dans une nouvelle variable _i dans la fermeture de l'instruction que vous exécutez, de sorte que ça va rester et être la valeur que vous attendez chaque fois que votre gestionnaire onclick est appelé.

Vous avez besoin d'une fermeture, sinon l' arr[i] s'effectue sous un autre champ et souffle.

 for(var i = 0; i < arr.length; i++) { arr[i].onclick = function(text) { return function () { alert(text); }; }(arr[i].innerHTML); } 

http://jsfiddle.net/xzmMj/5/

C'est une erreur commune. i est une variable globale que vous incrémentez dans la boucle for. Une fois la boucle terminée, je serai égal à 4. Ensuite, dans la fonction de gestion des clics, vous essayez d'afficher arr[i].innerHTML , qui est maintenant arr[4].innerHTML . arr[4] évidemment n'existe pas, donc vous obtenez une erreur.

Pour un correctif facile, changez l' alert(arr[i].innerHTML) pour alert(this.innerHTML) . this , dans le contexte de la fonction du gestionnaire de clics, renvoie à l'élément <TD> .