Vanilla JavaScript中的事件处理程序命名空间

时间:2014-02-16 22:10:33

标签: javascript javascript-events namespaces

我熟悉jQuery事件处理程序中的命名空间。我可以在特定的命名空间中添加事件处理程序:

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

然后我可以删除该命名空间中的所有事件处理程序:

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

这里的优点是我只能删除此命名空间中的事件,而不是任何应该维护的用户添加/附加事件。

有没有人有关于我如何不使用jQuery的任何提示,但是获得了类似的结果?


谢谢!

3 个答案:

答案 0 :(得分:20)

对于仍然在寻找这个的人,我最终制作了一个帮助单例,它跟踪我的函数引用。

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

然后只需导入事件并使用如下:

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

答案 1 :(得分:15)

在此解决方案中,我已将DOM扩展为具有onoff方法,并且能够使用事件命名空间:

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 

答案 2 :(得分:10)

我认为您正在寻找addEventListenerremoveEventListener。您还可以使用dispatchEvent定义自定义事件并触发它们。

但是,要删除事件侦听器,您需要保留对事件函数的引用,以仅删除要删除的函数,而不是清除整个事件。