2
votes

nommer une fonction et y ajouter des écouteurs d'événements provoque «non défini»

Je suis encore nouveau dans JavaScript et je rencontre le problème ci-dessous.

Je voudrais nommer / déclarer ma fonction, puis utiliser son nom comme auditeur pour ajouter / supprimer facilement des événements de clic. la raison principale en est que je peux supprimer les événements de clic chaque fois qu'une condition se produit.

Bref de ce que j'essaie de réaliser:

for (let i = 0; i < cards.length; i++) {
    card = cards[i];
    card.addEventListener('click', function game() {
      //
}

Le problème que j'ai est lorsque j'ajoute l'événement comme ceci:

for (let i = 0; i < cards.length; i++) {
    card = cards[i];
    card.addEventListener('click',  game);
}

J'obtiens une erreur avec la fonction nommée strong> jeu qui dit:

i n'est pas défini

Cependant, cette erreur ne se produit pas lorsque je place la fonction comme anonyme dans le paramètre d'écoute.

function game() {
// 
}

Déclaration de i code > globalement n'a pas fonctionné ni de passer i comme paramètre.

  • Code complet avec fonction anonyme : Ici li >
  • Code complet avec fonction nommée (ce que je veux travailler): Ici


3 Réponses :


1
votes

Pour accéder à différents i s, vous avez besoin de différentes fermetures, et donc vous avez différentes références de fonction. Vous pouvez les stocker directement dans la carte pour pouvoir les supprimer plus tard:

const game = i => () => {
  // ...
 };

for (let i = 0; i < cards.length; i++) {
  const card = cards[i];
  card.addEventListener('click', card._click = game(i));
}

Ensuite, vous pouvez les supprimer plus tard avec:

card.removeEventListener("click", card._click);

La même chose fonctionne également si vous déplacez le jeu à l'extérieur et ajoutez un paramètre curry pour i (peut-être plus propre):

for (let i = 0; i < cards.length; i++) {
  const card = cards[i];
  card.addEventListener('click', card._click = function game() {
    //
  });
}


2 commentaires

Merci beaucoup pour l'aide! Une question si cela ne vous dérange pas, pourquoi ne puis-je pas renommer "card._click" en quelque chose comme "cardListener" par exemple?


@abdulelah vous pouvez :) assurez-vous simplement que la propriété n'existe pas déjà sur la carte ...



0
votes

Votre problème est que votre fonction jeu ne connaît pas i car i n'existe pas dans votre jeu fonction en raison de la portée variable. Pour résoudre ce problème, vous pouvez passer i comme argument dans game comme ceci:

function game(i) {

Dans la ligne ci-dessus, vous appelez un la fonction flèche, qui appelle ensuite la fonction jeu . Cela vous permet de passer un argument dans game.

Et puis dans votre méthode game , acceptez la variable i comme un argument:

card.addEventListener('click', _ => game(i));

Voir l'exemple de travail ici a>


0 commentaires

0
votes

Vous devriez lire la portée lexicale en javascript pour comprendre pourquoi i n'est pas disponible dans la fonction nommée game

À l'intérieur de la fonction de jeu , il ne peut faire référence qu'à des variables qui sont dans une portée lexicale (ou à l'intérieur de ce qui est un sujet en soi)

En termes simples, vous pouvez passer le 'i' au jeu pour le faire fonctionner. Mais comme addEventListener attend une fonction, vous devez créer une fabrique de fonctions qui utilise un peu de fermeture

éditez votre jeu comme

let game = (i) => () => {
  //existing game function 
}

utilisez maintenant card.addEventListener ('click', game (i)); et cela devrait fonctionner comme prévu

Voici un violon fonctionnel pour votre référence: https://jsfiddle.net/uch1arny/2/


0 commentaires