Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespace vanilla JavaScript events like in jQuery

In jQuery, when you set an event, you are able to namespace it. This means (if you want) you can have multiple resize window events, for example, and be able to unbind them individually without unbinding all events on that selector.

Example of jQuery namespacing:

$(window).on('scroll.myScrollNamespace, function() ...

I'm wondering how I can create a namespace in plain JavaScript. This obviously would not work:

window.addEventListener('resize.myScrollNamespace', function() ...
like image 352
30secondstosam Avatar asked Jun 12 '15 10:06

30secondstosam


People also ask

What does jQuery use the event namespace for?

The event. namespace property in jQuery is used to return the custom namespace whenever the event is triggered. It is used to handle tasks differently depending on the namespace used.

What is an event namespace?

Definition and Usage 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 events can you listen for JavaScript?

The most common events you might “listen out for” are load , click , touchstart , mouseover , keydown .

What method can be used to listen for DOM events?

The addEventListener() method allows you to add event listeners on any HTML DOM object such as HTML elements, the HTML document, the window object, or other objects that support events, like the xmlHttpRequest object.


2 Answers

As @rsp answer correctly solves the problem of unbinding the correct handler, it doesn't really answer the problem of namespacing. To handle this you would need to do a bit more coding like this:

function on(elm, evtName, handler) {
  evtName.split('.').reduce(function(evtPart, evt) {
    evt = evt ? evt +'.'+ evtPart : evtPart;
    elm.addEventListener(evt, handler, true);
    return evt;
  }, '');
}

function off(elm, evtName, handler) {
  evtName.split('.').reduce(function(evtPart, evt) {
    evt = evt ? evt +'.'+ evtPart : evtPart;
    elm.removeEventListener(evt, handler, true);
    return evt;
  }, '');
}

// Your handler
function onScroll(e) { ... }

// To bind it
on(window, 'scroll.myScrollNamespace', onScroll);

// To unbind it
off(window, 'scroll.myScrollNamespace', onScroll);

So to sum up: this actually sets several event listeners - one for each part of your namespacing. This functionality is unfortunately not natively supported, but as you can see it can be achieved relatively simple. Just be wary that even though this script support deep namespacing (eg. scroll.parent.child) it would bind a lot of event listeners (3 in this case), and thus is inadvisable.

You could possibly do this more performant, but this gets it done.

like image 144
Tokimon Avatar answered Sep 28 '22 01:09

Tokimon


If instead of an anonymous function:

window.addEventListener('resize', function () {...});

you use a named function:

window.addEventListener('resize', function myScroll() {...});

then you may be able to use:

window.removeEventListener('resize', myScroll);

Make sure that you have myScroll in scope. When you remove the listeners in a different place than you add them, maybe you should define your functions in some outer scope and use their names in addEventListener in the same way as in the removeEventListener:

function myScroll() {
  // ...
}

window.addEventListener('resize', myScroll);

window.removeEventListener('resize', myScroll);

If you want to be able to remove many listeners at once, then you will have to store them in some array and call removeEventListener for each of its elements.

See the EventTarget.removeEventListener() documentation.

like image 29
rsp Avatar answered Sep 28 '22 01:09

rsp