A wild handleEvent appeared 😮 !!!
Tags: javascript, uiweekly, webdev, codepen
Published: 2021-07-11 12:18:39

Let's say, we have a DOM element by the name of `element` and we want to add event listeners to it. How would you do so ?

Here are two ways which can come into mind :-
```js
const handleClick = () =>{console.log('You can remove me later safely')}
element.addEventListener('click',handleClick);
element.addEventListener('click',()=>console.log('Try and remove me noob'));
```

Now when it comes to removing these event listeners, it's not possible to remove the second one since it's anonymous and for first one we can just do `element.removeEventListener('click',handleClick);`


What if I told you there is a way and a syntax you might not be familiar with when it comes to event listeners ?

![you're lying](https://i.gifer.com/D5UY.gif)

Well here it is :-

```js
const someObj = {
handleEvent: (e)=>console.log(`I am ${e.type} event`);
}

element.addEventListener('click',someObj);
```
And :-

![this is fine](https://media2.giphy.com/media/eIfYQTaK3148kmMCxT/giphy.gif)


Jokes aside, it's [always](https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent) been there. It's just less spoken about. And I came across this when I solved [this](https://stackoverflow.com/questions/67671873/typescript-handleevent-definition/67672217#67672217) StackOverflow question and my mind was blowwwwnn !!! 


![mind blown](https://www.icegif.com/wp-content/uploads/mind-blown-icegif-3.gif)


Also, You can just remove the event listener like so `element.removeEventListener('click',someObj);`

After finding this, I thought to myself that what if I make a bare minimum `Handler` class which can abstract the **registration** and **unregistration** bit and work on the same principle ? 

And this is how it looks :-

```js
class Handler {
  #element
  #eventMap = {}

  constructor(element, eventMap) {
    this.#element = element
    this.register(eventMap)
  }

  handleEvent(e) {
    this.#eventMap[e.type](e)
  }

  register(eventMap) {
    this.#eventMap = { ...this.#eventMap, ...eventMap }
    Object.keys(this.#eventMap).forEach((event) => {
      this.#element.addEventListener(event, this)
    })
  }

  unregister(event) {
    this.#element.removeEventListener(event, this)
  }

  unregisterAll() {
    Object.keys(this.#eventMap).forEach((event) => {
      this.#element.removeEventListener(event, this)
    })
  }
}
```

But what made me go for a class implementation ? Well now we know that we can pass an **object** to `add/removeEventListener`, we can have a custom `Handler` class inside which `this` will point to the **object instance** and come into use. 

Let's look at a usage sample of this code :-

```js
const handler = new Handler(element, {
  click: ()=>console.log('Yo I am clicky'),
  focus: ()=>console.log('FOCUS!!!'),
});
```
What the above does it that for `element`, it registers both the anonymous functions for respective events. And if you go further to register another function for `click` like so :-

```js
  handler.register({
    click: () => console.log('Well I am new clicky')
  });
```
This will override the existing `click` function that we had without any worry of handling its removal and add this new anonymous function. 

Now if you want to explicitly `unregister` the `click` function, how would you do so ?

```js
handler.unregister('click');
```
![that's it](https://i.pinimg.com/originals/f5/8e/b2/f58eb2e7e1f40e78a36bd9a8bb1ba4e1.gif)

So **anonymous** or **non-anonymous**, the `Handler` class will ensure that for each **event type**, only one function is registered for the same element. But what if I want to register multiple functions for same **event type** for the same element ?

Well in that case, you can create another instance of `Handler` class with same `element` and let it be responsible for it. 

![single responsibility](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2iOSIwsdMSZUSbtjbL-Z5QHtgKsCMqLyr0g&usqp=CAU)

It's still a new concept to me and maybe I might have derived some wrong conclusions. But I will be more than happy to know more about it. Did you know this ? If so, have you used this ? Do you not prefer it ? Any bottlenecks ? Feel free to bash that comment section 💪.

You can go through [this](https://webreflection.medium.com/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38) article for more insights into `handleEvent`. 

Here is a codepen where you can play with this implementation :-

{% codepen https://codepen.io/lapstjup/pen/ExWmBVX %}


### Thank you for your time :D