Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event Handler Namespace in Vanilla JavaScript

I'm familiar with namespaces in jQuery's event handlers. I can add an event handler in a specific namespace:

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

And then I can remove all event handlers in that namespace:

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

The advantage here is that I can remove only the events in this namespace, not any user-added/additional events that should be maintained.

Does anyone have any tips on how I can not use jQuery, but achieve a similar result?

like image 600
Tyler Conover Avatar asked Feb 16 '14 22:02

Tyler Conover


People also ask

What is an event namespace?

The event. namespace property returns the custom namespace when the event was triggered. This property can be used by plugin authors to handle tasks differently depending on the namespace used.

What are event handler properties JavaScript?

To react to an event, you attach an event handler to it. This is a block of code (usually a JavaScript function that you as a programmer create) that runs when the event fires. When such a block of code is defined to run in response to an event, we say we are registering an event handler.

How events are handled in JavaScript?

JavaScript's interaction with HTML is handled through events that occur when the user or the browser manipulates a page. When the page loads, it is called an event. When the user clicks a button, that click too is an event. Other examples include events like pressing any key, closing a window, resizing a window, etc.


2 Answers

For anyone still looking for this, I ended up making a helper singleton which keeps track of the function references for me.

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

Then just import EventHandler and use like:

EventHandler.addEventListener('keydown.doop', () => console.log("Doop")); EventHandler.addEventListener('keydown.wap', () => console.log("Wap")); EventHandler.removeEventListener('keydown.doop'); // keydown.wap is still bound 
like image 118
Andrew Avatar answered Sep 23 '22 07:09

Andrew


In this solution I've extended the DOM to have on and off methods with the ability to use events namespacing:

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 
like image 39
vsync Avatar answered Sep 24 '22 07:09

vsync