JavaScript: rimuove il listener di eventi


136

Sto cercando di rimuovere un listener di eventi all'interno di una definizione di listener:

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

Come potrei farlo? this = event ... Grazie.


8
banali ma per i riferimenti futuri if(click == 50) {dovrebbero essere if( click === 50 )o if( click >= 50 )- non cambieranno l'output, ma per ragioni di sanità mentale questi controlli hanno più senso.
rlemon

Buona domanda ... come posso rimuoverlo se non ho accesso al contenuto? Voglio rimuovere i popup per onclick sui pulsanti utilizzando greasemonkey per altri siti, ma se non riesco a fare riferimento alla funzione per nome, non riesco a trovare un modo per rimuoverlo.
JasonXA,

Risposte:


122

È necessario utilizzare le funzioni denominate.

Inoltre, la clickvariabile deve essere esterna al gestore per incrementare.

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: potresti chiudere attorno alla click_countervariabile in questo modo:

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);

In questo modo è possibile incrementare il contatore su più elementi.


Se non lo desideri e desideri che ognuno abbia il proprio contatore, procedi nel seguente modo:

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: avevo dimenticato di nominare il gestore restituito nelle ultime due versioni. Fisso.


14
+1 - L'ho trasformato in un violino e non ha funzionato. Ma era perché dovevo fare clic cinquanta volte :) Che idiota sono. Esempio semplificato qui: jsfiddle.net/karim79/aZNqA
karim79

4
@ karim79: vorrei poter dire di non aver mai fatto nulla di simile prima. : o) Grazie per il jsFiddle.
user113716

+1 La terza opzione ha funzionato per me. Assegnazione di un evento chiave a un campo di input per cancellare la convalida. Bello grazie
Gurnard

Votazione, la terza opzione qui è una parte importante della comprensione del legame / svincolo JS
SW4

sarebbe myClick = function(event){...}considerata anche una funzione con nome?
Daniel Möller,

80
   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

Dovrebbe farlo.


14
Questo è fantastico! Doc su arguments.calleeper le parti interessate: developer.mozilla.org/en/JavaScript/Reference/…
Ender

Grazie, questo mi ha aiutato molto.
John O

2
Sfortunatamente questo non funziona con ECMAScript 5 (2009) o successivo, dal collegamento MDN: "La 5a edizione di ECMAScript (ES5) ne proibisce l'uso arguments.callee()in modalità rigorosa. Evitare di utilizzare arguments.callee()dando un nome alle espressioni di funzione o utilizzare una dichiarazione di funzione dove una funzione deve chiamarsi. " (anche se sta usando callee()invece di callee, è ancora rimosso, ciao!)
Dai

59

È possibile utilizzare un'espressione di funzione denominata (in questo caso la funzione è denominata abc), in questo modo:

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 ...
}

Esempio di lavoro rapido e sporco: http://jsfiddle.net/8qvdmLz5/2/ .

Ulteriori informazioni sulle espressioni di funzioni denominate: http://kangax.github.io/nfe/ .


Intelligente. Uno di quei rari casi in cui l'NFE è utile. Grazie.
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;
};
};

6

Se la soluzione di @ Cybernate non funziona, prova a spezzare il grilletto nella sua stessa funzione in modo da poterlo fare riferimento.

clickHandler = function(event){
  if (click++ == 49)
    canvas.removeEventListener('click',clickHandler);
}
canvas.addEventListener('click',clickHandler);

4

Se qualcuno usa jquery, può farlo in questo modo:

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 );
    }
});

Spero che possa aiutare qualcuno. Nota che la risposta data da @ user113716 funziona bene :)


2

Penso che potresti dover definire in anticipo la funzione del gestore, in questo modo:

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

Ciò ti consentirà di rimuovere il gestore per nome dall'interno di se stesso.


-4

Prova questo, ha funzionato per me.

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.