122 votes

Javascript removeEventListener ne fonctionne pas

J'ai le code suivant pour ajouter un écouteur d'événements

 area.addEventListener('click',function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          },true);

Cela fonctionne correctement comme prévu.. Plus tard, dans une autre fonction, j'ai essayé de supprimer l'écouteur d'événements en utilisant le code suivant

 area.removeEventListener('click',function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          },true);

Mais l'écouteur d'événements n'est pas supprimé.. Pourquoi cela se produit-il? Y a-t-il un problème avec mon removeEventListener()? Remarque: Ici, area est quelque chose comme document.getElementById('monId')

0 votes

192voto

duri Points 8246

Cela est dû au fait que les deux fonctions anonymes sont des fonctions totalement différentes. L'argument de votre removeEventListener n'est pas une référence à l'objet fonction qui était attaché précédemment.

 function foo(event) {
     app.addSpot(event.clientX,event.clientY);
     app.addFlag = 1;
 }
 area.addEventListener('click',foo,true);
 area.removeEventListener('click',foo,true);

73 votes

+1 True. liaison(this) va changer la signature. Donc toujours assigner la fonction à une var après avoir lié this en utilisant la fonction bind API afin que le même var puisse être utilisé dans removeListener. Vous verrez ce problème plus évident en typescript

4 votes

Cela ne vous permettra pas de passer des paramètres de fonction par exemple foo(1)

37 votes

Si quelqu'un utilise des classes, essayez quelque chose comme this.onClick = this.onClick.bind(this) avant tout auditeur, puis btn.addEventListener('click', this.onClick), enfin btn.removeEventListener('click', this.onClick)

28voto

Slavik Points 518

Je trouve que pour l'objet windows, le dernier paramètre "true" est requis. La suppression ne fonctionne pas s'il n'y a pas de drapeau de capture.

23voto

ph1lb4 Points 1014

Dans un composant de fonction React, assurez-vous de définir le callback avec le crochet useCallback(() => {}). Si vous ne le faites pas, le callback sera différent à chaque réexécution et la méthode removeEventListener ne fonctionnera pas.

const scrollCallback = useCallback(() => { // faire qqch. }, []);
window.addEventListener("scroll", scrollCallback, true);
window.removeEventListener("scroll", scrollCallback, true);

0 votes

Cela a sauvé ma vie, je pensais que c'était une constante donc cela ne serait pas redéclaré lors du ré-affichage mais ...

0 votes

React n'utilise pas d'écouteurs d'événements explicites, donc cela ne semble pas avoir grand-chose à voir avec le poste de question réelle.

8voto

Sirko Points 32515

Vous créez deux fonctions différentes dans les deux appels. Ainsi, la deuxième fonction n'a aucun lien avec la première et le moteur peut supprimer la fonction. Utilisez un identifiant commun pour la fonction à la place.

var handler = function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          };
area.addEventListener('click', handler,true);

plus tard, vous pouvez supprimer le gestionnaire en appelant

area.removeEventListener('click', handler,true);

5voto

ThiefMaster Points 135805

Pour le supprimer, stockez la fonction dans une variable ou utilisez simplement une fonction nommée et passez cette fonction à l'appel de removeEventListener :

function areaClicked(event) {
    app.addSpot(event.clientX, event.clientY);
    app.addFlag = 1;
}

area.addEventListener('click', areaClicked, true);
// ...
area.removeEventListener('click', areaClicked, true);

2 votes

Mais comment puis-je passer des arguments (ici événement) à cette fonction... C'est pourquoi j'ai utilisé une fonction anonyme.

1 votes

Cela est passé par le navigateur. Peu importe si vous définissez la fonction séparément ou non.

3 votes

AVERTISSEMENT: J'ai découvert ce qui n'allait pas avec mon approche. La méthode removeEventListener() fonctionne UNIQUEMENT avec des FONCTIONS NOMMÉES. Elle NE fonctionne PAS avec des fonctions anonymes ! Lorsque j'ai modifié le code pour tenir compte de cela, tout s'est déroulé comme prévu. Vous devez définir une fonction NOMMÉE dans votre fermeture, et renvoyer une référence à une instance de celle-ci avec les paramètres transmis par la fermeture. Faites cela, et removeEventListener() fonctionnera parfaitement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X