web-dev-qa-db-fra.com

evénement onClick dans une boucle For

J'ai essayé de créer une boucle avec pour et d'incrémenter un événement onclick, mais cela ne fonctionne pas.

Une partie de js:

 var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
    itemLists = $('game').getElementsByTagName('li'); // 9 items

    for( var i = 0; i < itemLists.length; i++ ) {
         // i already egal to 9
         itemLists[i].onclick = function() {
              // do something
         }
    }

Mais dans ce cas, la boucle For est déjà terminée avant que je puisse cliquer sur un élément de la liste.

De plus, j'aimerais obtenir la liste d'éléments sur laquelle j'ai cliqué et la sauvegarder dans un tableau. J'ai essayé un gameCase [this] (dans la fonction onclick), mais je ne sais pas si c'est la bonne façon.

13
jbr

John Resig couvre très bien ce sujet dans "Les secrets du ninja JavaScript" ( http://ejohn.org/apps/learn/#59 )

Vous devrez créer une portée temporaire pour préserver la valeur de i

for ( var i = 0; i < itemLists.length; i++ ) (function(i){ 
  itemLists[i].onclick = function() {
      // do something
  }
})(i);

Modifier:

var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
$listParent = $('game').find('ul'), // li's parent
itemLists = $('game').getElementsByTagName('li'); // 9 items

var listHandler = (function() {
  var i = 0;

  return function() {
    // $(this) will in here refer to the clicked li
    i++ // increment i

    if ( i === 9 ) {
      $listParent.off('click', 'li', listHandler); //remove eventhandler when i reaches 9
    }
  }
}());

$listParent.on('click', 'li', listHandler); // attach eventhandler to ul element

Cela devrait faire ce que vous voulez, je ne peux pas le tester maintenant puisque je suis au travail.

21
ruuska

Enveloppez votre auditeur:

onclick = (function(i) {return function() {
    ...
};})(i);

Cela corrige vos problèmes de portée variable.

5
elslooo

Désolé si je n'ai pas bien compris votre question, D'après le code, je comprends que vous essayez d'ajouter un gestionnaire onclick à tous les éléments de la liste trouvés dans la balise de jeu (peut-être que ce devrait être un class/id ). 

La boucle for sera exécutée lors du chargement de la balise de script/fichier sans aucune interaction de l'utilisateur.

Si vous souhaitez affecter une fonction utilisant la valeur actuelle du compteur. Utilisez le code suivant:

itemLists[i].onclick = (function() {
    return function() {
         // TODO ---
        // Your handler code here
}
})();
1
Dev Shangari