Подтвердить что ты не робот

Пространство имен обработчиков событий в JavaScript JavaScript

Я знаком с пространствами имен в обработчиках событий jQuery. Я могу добавить обработчик событий в определенное пространство имен:

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

И тогда я могу удалить все обработчики событий в этом пространстве имен:

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

Преимущество здесь в том, что я могу удалить только события в этом пространстве имен, а не любые добавленные пользователем/дополнительные события, которые должны поддерживаться.

У кого-нибудь есть какие-нибудь советы о том, как я не могу использовать jQuery, но добиться подобного результата?

4b9b3361

Ответ 1

Я думаю, что вы ищете addEventListener и removeEventListener. Вы также можете определить пользовательские события и запустить их с помощью dispatchEvent.

Однако, чтобы удалить прослушиватель событий, вам нужно сохранить ссылку на функцию события, чтобы удалить только функцию, которую вы хотите удалить, вместо очистки всего события.

Ответ 2

Для тех, кто все еще ищет это, я сделал вспомогательный синглтон, который отслеживает ссылки на функции для меня.

class EventHandlerClass {
  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 EventHandler = new EventHandlerClass();

Затем просто импортируйте EventHandler и используйте как:

EventHandler.addEventListener('keydown.doop', () => console.log("Doop"));
EventHandler.addEventListener('keydown.wap', () => console.log("Wap"));
EventHandler.removeEventListener('keydown.doop');
// keydown.wap is still bound

Ответ 3

В этом решении я расширил DOM, чтобы иметь методы on и off с возможностью использования пространства имен событий:

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