web-dev-qa-db-fra.com

Suppression d'un écouteur d'événements anonyme

Est-il possible de supprimer un écouteur d'événements ajouté comme ceci:

element.addEventListener(event, function(){/* do work here */}, false);

Sans remplacer l'élément?

48
erikvold

Il n'existe aucun moyen de supprimer proprement un gestionnaire d'événements à moins que vous n'ayez stocké une référence au gestionnaire d'événements lors de la création.

Je vais généralement les ajouter à l'objet principal de cette page, puis vous pouvez les itérer et les éliminer proprement lorsque vous avez terminé avec cet objet.

19
Joe

Vous pouvez supprimer l'écouteur d'événements comme ceci:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
16
icktoofay

Anonymous bound écouteurs d'événements

La façon la plus simple de supprimer tous les écouteurs d'événements d'un élément est de lui attribuer son outerHTML. Cela permet d'envoyer une représentation sous forme de chaîne du code HTML via l'analyseur HTML et d'assigner le code HTML analysé à l'élément. Parce qu'aucun JavaScript n'est transmis, il n'y aura pas d'écouteurs d'événements liés.

document.getElementById('demo').addEventListener('click', function(){
    alert('Clickrd');
    this.outerHTML = this.outerHTML;
}, false);
<a id="demo" href="javascript:void(0)">Click Me</a>

Anonymous délégué écouteurs d'événements

La seule mise en garde concerne les écouteurs d'événements délégués ou les écouteurs d'événements sur un élément parent qui surveillent chaque événement correspondant à un ensemble de critères sur ses enfants. La seule façon de passer est de modifier l'élément pour ne pas répondre aux critères de l'écouteur d'événement délégué.

document.body.addEventListener('click', function(e){
    if(e.target.id === 'demo') {
        alert('Clickrd');
        e.target.id = 'omed';
    }
}, false);
<a id="demo" href="javascript:void(0)">Click Me</a>
10
user4639281

Vous pouvez essayer d'écraser element.addEventListener et faites ce que vous voulez.
Quelque chose comme:

var orig = element.addEventListener;

element.addEventListener = function (type, listener) {
    if (/dontwant/.test(listener.toSource())) { // listener has something i dont want
        // do nothing
    } else {
        orig.apply(this, Array.prototype.slice.apply(arguments));
    }
};

ps .: ce n'est pas recommandé, mais ça fera l'affaire (je ne l'ai pas testé)

4
w35l3y

Modifier: Comme Manngo suggéré par commentaire, vous devez utiliser . Off () au lieu de . unbind () as . unbind () est déconseillé à partir de jQuery 3.0 et remplacé depuis jQuery 1.7.

Même si c'est une vieille question et qu'elle ne mentionne pas jQuery, je posterai ma réponse ici car c'est le premier résultat pour le searchterm 'jquery remove anonymous event handler'.

Vous pouvez essayer de le supprimer en utilisant la fonction . Off () .

$('#button1').click(function() {
       alert('This is a test');
});

$('#btnRemoveListener').click(function() {
       $('#button1').off('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button1">Click me</button>
<hr/>
<button id="btnRemoveListener">Remove listener</button>

Cependant, cela ne fonctionne que si vous avez ajouté l'écouteur à l'aide de jQuery - pas . AddEventListener

Trouvé ici .

3
general64

L'affectation de gestionnaires d'événements avec des fonctions littérales est délicate - non seulement il n'y a aucun moyen de les supprimer, sans cloner le nœud et le remplacer par le clone - vous pouvez également affecter par inadvertance plusieurs fois le même gestionnaire, ce qui ne peut pas se produire si vous utilisez un référence à un gestionnaire. Deux fonctions sont toujours traitées comme deux objets différents, même si elles sont identiques.

2
kennebec

Vieille question, mais voici une solution.

À strictement parler, vous ne pouvez pas supprimer un écouteur d'événements anonyme à moins de stocker une référence à la fonction. Étant donné que le but de l'utilisation d'une fonction anonyme n'est probablement pas de créer une nouvelle variable, vous pouvez plutôt stocker la référence dans l'élément lui-même:

element.addEventListener('click',element.fn=function fn() {
    //  Event Code
}, false);

Plus tard, lorsque vous souhaitez le supprimer, vous pouvez effectuer les opérations suivantes:

element.removeEventListener('click',element.fn, false);

N'oubliez pas que le troisième paramètre (false) doit avoir la valeur même que pour l'ajout de l'écouteur d'événements.

Cependant, la question elle-même en appelle une autre: pourquoi?

Il y a deux raisons d'utiliser .addEventListener() plutôt que la méthode plus simple .onsomething():

Tout d'abord, il permet d'ajouter plusieurs écouteurs d'événements. Cela devient un problème lorsqu'il s'agit de les supprimer de manière sélective: vous finirez probablement par les nommer. Si vous souhaitez tous les supprimer, la solution outerHTML de @ tidy-giant est excellente.

Deuxièmement, vous avez la possibilité de choisir de capturer l'événement plutôt que de le bulles.

Si aucune des raisons n'est importante, vous pouvez très bien décider d'utiliser la méthode plus simple onsomething.

2
Manngo

Si vous utilisez jQuery, essayez la méthode off

$("element").off("event");
0
uingtea

Avec la spécification de langage ECMAScript2015 (ES2015, ES6), il est possible de faire avec cette fonction nameAndSelfBind qui transforme comme par magie un rappel anonyme en un nommé et même lie son corps à lui-même, permettant à l'écouteur d'événements de se retirer de à l'intérieur et à supprimer d'une portée externe ( JSFiddle ):

(function()
{
  // an optional constant to store references to all named and bound functions:
  const arrayOfFormerlyAnonymousFunctions = [],
        removeEventListenerAfterDelay = 3000; // an auxiliary variable for setTimeout

  // this function both names argument function and makes it self-aware,
  // binding it to itself; useful e.g. for event listeners which then will be able
  // self-remove from within an anonymous functions they use as callbacks:
  function nameAndSelfBind(functionToNameAndSelfBind,
                           name = 'namedAndBoundFunction', // optional
                           outerScopeReference)            // optional
  {
    const functionAsObject = {
                                [name]()
                                {
                                  return binder(...arguments);
                                }
                             },
          namedAndBoundFunction = functionAsObject[name];

    // if no arbitrary-naming functionality is required, then the constants above are
    // not needed, and the following function should be just "var namedAndBoundFunction = ":
    var binder = function() 
    { 
      return functionToNameAndSelfBind.bind(namedAndBoundFunction, ...arguments)();
    }

    // this optional functionality allows to assign the function to a outer scope variable
    // if can not be done otherwise; useful for example for the ability to remove event
    // listeners from the outer scope:
    if (typeof outerScopeReference !== 'undefined')
    {
      if (outerScopeReference instanceof Array)
      {
        outerScopeReference.Push(namedAndBoundFunction);
      }
      else
      {
        outerScopeReference = namedAndBoundFunction;
      }
    }
    return namedAndBoundFunction;
  }

  // removeEventListener callback can not remove the listener if the callback is an anonymous
  // function, but thanks to the nameAndSelfBind function it is now possible; this listener
  // removes itself right after the first time being triggered:
  document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
  {
    e.target.removeEventListener('visibilitychange', this, false);
    console.log('\nEvent listener 1 triggered:', e, '\nthis: ', this,
                '\n\nremoveEventListener 1 was called; if "this" value was correct, "'
                + e.type + '"" event will not listened to any more');
  }, undefined, arrayOfFormerlyAnonymousFunctions), false);

  // to prove that deanonymized functions -- even when they have the same 'namedAndBoundFunction'
  // name -- belong to different scopes and hence removing one does not mean removing another,
  // a different event listener is added:
  document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
  {
    console.log('\nEvent listener 2 triggered:', e, '\nthis: ', this);
  }, undefined, arrayOfFormerlyAnonymousFunctions), false);

  // to check that arrayOfFormerlyAnonymousFunctions constant does keep a valid reference to
  // formerly anonymous callback function of one of the event listeners, an attempt to remove
  // it is made:
  setTimeout(function(delay)
  {
    document.removeEventListener('visibilitychange',
             arrayOfFormerlyAnonymousFunctions[arrayOfFormerlyAnonymousFunctions.length - 1],
             false);
    console.log('\nAfter ' + delay + 'ms, an event listener 2 was removed;  if reference in '
                + 'arrayOfFormerlyAnonymousFunctions value was correct, the event will not '
                + 'be listened to any more', arrayOfFormerlyAnonymousFunctions);
  }, removeEventListenerAfterDelay, removeEventListenerAfterDelay);
})();
0
DDRRSS

Ce qui suit a assez bien fonctionné pour moi. Le code gère le cas où un autre événement déclenche la suppression de l'auditeur de l'élément. Pas besoin de déclarations de fonction au préalable.

myElem.addEventListener("click", myFunc = function() { /*do stuff*/ });

/*things happen*/

myElem.removeEventListener("click", myFunc);
0
Ice101781

La méthode Jquery .off () supprime les gestionnaires d'événements qui étaient attachés avec .on ()

0
Compunction