web-dev-qa-db-ja.com

バニラJavaScriptのイベントハンドラー名前空間

私はjQueryのイベントハンドラーの名前空間に精通しています。特定の名前空間にイベントハンドラーを追加できます。

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

次に、その名前空間のすべてのイベントハンドラーを削除できます。

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

ここでの利点は、このネームスペース内のイベントのみを削除できることであり、維持する必要があるユーザー追加/追加イベントは削除できません。

誰かがjQueryを使用できない方法についてのヒントはありますか?

34
Tyler Conover

addEventListener および removeEventListener を探していると思います。 dispatchEvent を使用して、カスタムイベントを定義して発生させることもできます。

ただし、イベントリスナーを削除するには、イベント関数への参照を保持して、イベント全体をクリアするのではなく、削除する関数だけを削除する必要があります。

10
Will P.

まだこれを探している人のために、関数参照を追跡するヘルパーシングルトンを作成しました。

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
28
Andrew

このソリューションでは、イベントのネームスペースを使用する機能を備えたonメソッドとoffメソッドを持つようにDOMを拡張しました。

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 
16
vsync