JavaScript: supprimer l'écouteur d'événements

136

J'essaie de supprimer un écouteur d'événement à l'intérieur d'une définition d'écouteur:

canvas.addEventListener('click', function(event) {
    click++;
    if(click == 50) {
        // remove this event listener here!
    }
// More code here ...

Comment pourrais-je faire ça? this = event ... Merci.

Thomas
la source
8
trivial mais pour les futures références if(click == 50) {devraient être if( click === 50 )ou if( click >= 50 )- ils ne changeront pas la sortie, mais pour des raisons de bon sens, ces vérifications ont plus de sens.
rlemon
Bonne question ... comment le supprimer si je n'ai pas accès au contenu? Je veux supprimer les popups pour onclick sur les boutons en utilisant greasemonkey pour d'autres sites, mais à moins que je puisse référencer la fonction par son nom, je ne semble pas trouver un moyen de la supprimer.
JasonXA

Réponses:

122

Vous devez utiliser des fonctions nommées.

En outre, la clickvariable doit être en dehors du gestionnaire pour être incrémentée.

var click_count = 0;

function myClick(event) {
    click_count++;
    if(click_count == 50) {
       // to remove
       canvas.removeEventListener('click', myClick);
    }
}

// to add
canvas.addEventListener('click', myClick);

EDIT: Vous pouvez fermer autour de la click_countervariable comme ceci:

var myClick = (function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
})( 0 );

// to add
canvas.addEventListener('click', myClick);

De cette façon, vous pouvez incrémenter le compteur sur plusieurs éléments.


Si vous ne le souhaitez pas et que chacun d'entre eux ait son propre compteur, procédez comme suit:

var myClick = function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
};

// to add
canvas.addEventListener('click', myClick( 0 ));

EDIT: j'avais oublié de nommer le gestionnaire renvoyé dans les deux dernières versions. Fixé.

utilisateur113716
la source
14
+1 - J'en ai fait un violon et ça n'a pas marché. Mais c'était parce que j'avais besoin de cliquer cinquante fois :) Quel idiot je suis. Exemple simplifié ici: jsfiddle.net/karim79/aZNqA
karim79
4
@ karim79: J'aimerais pouvoir dire que je n'ai jamais rien fait de tel auparavant. : o) Merci pour le jsFiddle.
user113716
+1 La troisième option a fonctionné pour moi. Attribution d'un événement clé à un champ d'entrée pour effacer la validation. Nice one thanks
Gurnard
Vote positif, la troisième option ici est une partie importante de la compréhension de la liaison / dissociation JS
SW4
serait myClick = function(event){...}également considérée comme une fonction nommée?
Daniel Möller
80
   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

Devrait le faire.

Edeverett
la source
14
C'est cool! Doc on arguments.calleepour les parties intéressées: developer.mozilla.org/en/JavaScript/Reference/...
Ender
Merci, ça a beaucoup aidé.
John O
2
Malheureusement, cela ne fonctionne pas avec ECMAScript 5 (2009) ou version ultérieure, à partir du lien MDN: "La 5ème édition d'ECMAScript (ES5) interdit l'utilisation de arguments.callee()en mode strict. Évitez d'utiliser arguments.callee()en donnant un nom aux expressions de fonction ou en utilisant une déclaration de fonction où une fonction doit s'appeler. " (bien qu'il utilise callee()au lieu de callee, il est toujours supprimé, hué!)
Dai
59

Vous pouvez utiliser une expression de fonction nommée (dans ce cas, la fonction est nommée abc), comme ceci:

let click = 0;
canvas.addEventListener('click', function abc(event) {
    click++;
    if (click >= 50) {
        // remove event listener function `abc`
        canvas.removeEventListener('click', abc);
    }
    // More code here ...
}

Exemple de travail rapide et sale: http://jsfiddle.net/8qvdmLz5/2/ .

Plus d'informations sur les expressions de fonctions nommées: http://kangax.github.io/nfe/ .

Tama
la source
Intelligent. Un de ces rares cas où l’ENF est utile. Merci.
DanMan
7
element.querySelector('.addDoor').onEvent('click', function (e) { });
element.querySelector('.addDoor').removeListeners();


HTMLElement.prototype.onEvent = function (eventType, callBack, useCapture) {
this.addEventListener(eventType, callBack, useCapture);
if (!this.myListeners) {
    this.myListeners = [];
};
this.myListeners.push({ eType: eventType, callBack: callBack });
return this;
};


HTMLElement.prototype.removeListeners = function () {
if (this.myListeners) {
    for (var i = 0; i < this.myListeners.length; i++) {
        this.removeEventListener(this.myListeners[i].eType, this.myListeners[i].callBack);
    };
   delete this.myListeners;
};
};
Fenêtres en vinyle
la source
6

Si la solution de @ Cybernate ne fonctionne pas, essayez de casser le déclencheur dans sa propre fonction afin de pouvoir le référencer.

clickHandler = function(event){
  if (click++ == 49)
    canvas.removeEventListener('click',clickHandler);
}
canvas.addEventListener('click',clickHandler);
Brad Christie
la source
4

Si quelqu'un utilise jquery, il peut le faire comme ceci:

var click_count = 0;
$( "canvas" ).bind( "click", function( event ) {
    //do whatever you want
    click_count++;
    if ( click_count == 50 ) {
        //remove the event
        $( this ).unbind( event );
    }
});

J'espère que cela peut aider quelqu'un. Notez que la réponse donnée par @ user113716 fonctionne bien :)

Youssman
la source
2

Je pense que vous devrez peut-être définir la fonction de gestionnaire à l'avance, comme ceci:

var myHandler = function(event) {
    click++; 
    if(click == 50) { 
        this.removeEventListener('click', myHandler);
    } 
}
canvas.addEventListener('click', myHandler);

Cela vous permettra de supprimer le gestionnaire par son nom de lui-même.

Ender
la source
-4

Essayez ceci, cela a fonctionné pour moi.

<button id="btn">Click</button>
<script>
 console.log(btn)
 let f;
 btn.addEventListener('click', f=function(event) {
 console.log('Click')
 console.log(f)
 this.removeEventListener('click',f)
 console.log('Event removed')
})  
</script>
user3870075
la source