The way we add and remove event listeners on DOM elements hasn’t change much for two decades. It's methods: addEventListener
, and removeEventListener
do a decent job, but if we want to dynamically add and remove the listeners, these methods become impractical.
Let’s see why is that so, and consider a potential solution.
The problem
This is how an event listener is registered on the target element:
target.addEventListener(type, listener, options);
And this is how it’s removed:
target.removeEventListener(type, listener, options);
The problem with this is the fact that removeEventListener
method, requires parameters of identical value the listener was registered with, requiring us to save and keep track of these parameters.
For each registered listener that we might want to remove later, we would need to store it’s defining variables: target, type, and listener.
Imagine how cluttered our code would become if we register a dozen removable event listeners. We would potentially need a lot of variables... This practice then becomes cluttery and repetitive.
The solution
A better way DOM could handle this is if the addEventListener
method would return an instance of the subscription object which would hold all the defining parameters. Such object instances could hold methods like ‘unmount’, ‘mount’, or ‘update’...
So instead of just registering the listener, we could also reference the subscription:
const sub1 = target.addEventListener(type, listener, options);
Unmount the subscription:
sub1.unmount();
// instead of this:
target.removeEventListener(type, listener, options);
Update the subscription:
sub1.update({name: type2});
// instead of this:
target.removeEventListener(type, listener, options);
target.addEventListener(type2, listener, options);
Good news is that I've made a library that implements this idea: It’s called Subvent and You can read more about it here...
Subvent.js: Managing event subscriptions in DOM
Filip Biterski ・ Mar 7 ・ 2 min read
... or start using it straight away:
Subvent
Create event subscriptions in DOM. Manage them with update
, unmount
and mount
methods.
Abstracts DOM's addEventListener
, and removeEventListener
methods into a subscription object.
Installation
In node projects:
npm install --save subvent
import {Subvent} from 'subvent'
// or use the shorthand:
import {on} from 'subvent'
In browsers:
<head>
<script src="https://unpkg.com/subvent@latest/dist/iife/subvent.js"></script>
</head>
Usage
Get the DOM nodes first:
const el1 = document.getElementById('element-1');
const el2 = // ...
const el3 = // ...
const el4 = // ...
Define the event subscription
const evtSub1 = new Subvent(el1, 'click', () => {...});
- creates an instance of Subvent
- the instance represents an event subscription
The shorthand on
function is also available:
const evtSub2 = on(el2, 'click', (
…
Top comments (9)
Awesome post! Learned a problem and was served the solution
This idea is pretty much used as a starting point and then expanded into a whole paradigm for observables and rxjs.
youtube.com/playlist?list=PL55RiY5...
rxjs.dev/guide/overview
I don't understand how the solution would solve the "save and keep track of these parameters" since you'd still need to "save and keep track" of the return value of
addEventListener
.Well, it's a single variable per subscription, instead of many. Maybe I should have worded it better. :)
Whole library for two methods? Don`t know dude.
A little more then that, but yes. I understand people are sceptical. The lib is most usefull for larger event-driven apps to help with organizing subscriptions.
is "unmount();" is specifically your developed library's method?? because console through me an error that there is nothing like "unmount();" is available in javascript.
Yes. If You want to use it, read installation instructions in the repository.
Oh... sure I will use it :)