Espace de noms du Gestionnaire d'événements dans Vanilla JavaScript

Je suis familier avec les espaces de noms dans les gestionnaires d'événements de jQuery. Je peux ajouter un gestionnaire d'événements dans un espace de noms spécifique:

$('#id').on('click.namespace', _handlerFunction);

Et puis je peux supprimer tous les gestionnaires d'événements dans cet espace de noms:

$('#id').off('.namespace');

L'avantage ici est que je ne peux supprimer que les événements de cet espace de noms, pas les événements ajoutés par l'utilisateur/supplémentaires qui doivent être maintenus.

Quelqu'un at-il des conseils sur la façon dont je ne peux pas utiliser jQuery, mais obtenir un résultat similaire?


Merci!!

23
demandé sur Tyler Conover 2014-02-17 02:10:32

3 réponses

Je pense que vous êtes à la recherche pour addEventListener et removeEventListener. Vous pouvez également définir des événements personnalisés et les déclencher à l'aide de dispatchEvent.

Cependant, pour supprimer un écouteur d'événement, vous aurez besoin de conserver une référence à la fonction d'événement à supprimer la fonction que vous souhaitez supprimer au lieu d'effacer la totalité de l'événement.

8
répondu Will P. 2014-02-16 22:25:00

Pour ceux qui cherchent encore ceci, j'ai fini par faire un singleton d'aide qui garde une trace des références de fonction pour moi.

class EventClass {
  constructor() {
    this.functionMap = {};
  }

  addEventListener(event, func) {
    this.functionMap[event] = func;
    document.addEventListener(event.split('.')[0], this.functionMap[event]);
  }

  removeEventListener(event) {
    document.removeEventListener(event.split('.')[0], this.functionMap[event]);
    delete this.functionMap[event];
  }
}

export const Event = new EventClass();

Ensuite, il suffit D'importer un événement et d'utiliser comme:

Event.addEventListener('keydown.doop', () => console.log("Doop"));
Event.addEventListener('keydown.wap', () => console.log("Wap"));
Event.removeEventListener('keydown.doop');
// keydown.wap is still bound
11
répondu Andrew 2017-06-08 03:44:04

Dans Cette solution, j'ai étendu le DOM pour avoir des méthodes on et off avec la possibilité d'utiliser l'espace de noms des événements:

var events = {
  on(event, cb, opts){
    if( !this.namespaces ) // save the namespaces on the DOM element itself
      this.namespaces = {};

    this.namespaces[event] = cb;
    var options = opts || false;
    
    this.addEventListener(event.split('.')[0], cb, options);
    return this;
  },
  off(event) {
    this.removeEventListener(event.split('.')[0], this.namespaces[event]);
    delete this.namespaces[event];
    return this;
  }
}

// Extend the DOM with these above custom methods
window.on = Element.prototype.on = events.on;
window.off = Element.prototype.off = events.off;


window
  .on('mousedown.foo', ()=> console.log("namespaced event will be removed after 3s"))
  .on('mousedown.bar', ()=> console.log("event will NOT be removed"))
  .on('mousedown.baz', ()=> console.log("event will fire once"), {once: true});

// after 3 seconds remove the event with `foo` namespace
setTimeout(function(){
    window.off('mousedown.foo')
}, 3000)
Click anywhere 
11
répondu vsync 2017-09-19 10:03:34