2

A wild handleEvent appeared 😮 !!!

 3 years ago
source link: https://dev.to/lapstjup/a-wild-handleevent-appeared-1f48
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Cover image for A wild handleEvent appeared 😮 !!!

A wild handleEvent appeared 😮 !!!

Jul 11 Originally published at blog.lakbychance.com

・3 min read

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 :-

const handleClick = () =>{console.log('You can remove me later safely')}
element.addEventListener('click',handleClick);
element.addEventListener('click',()=>console.log('Try and remove me noob'));
Enter fullscreen modeExit fullscreen mode

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 ?

Well here it is :-

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

element.addEventListener('click',someObj);
Enter fullscreen modeExit fullscreen mode

And :-

Jokes aside, it's always been there. It's just less spoken about. And I came across this when I solved this StackOverflow question and my mind was blowwwwnn !!!

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 :-

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)
    })
  }
}
Enter fullscreen modeExit fullscreen mode

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 :-

const handler = new Handler(element, {
  click: ()=>console.log('Yo I am clicky'),
  focus: ()=>console.log('FOCUS!!!'),
});
Enter fullscreen modeExit fullscreen mode

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 :-

  handler.register({
    click: () => console.log('Well I am new clicky')
  });
Enter fullscreen modeExit fullscreen mode

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 ?

handler.unregister('click');
Enter fullscreen modeExit fullscreen mode

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.

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 article for more insights into handleEvent.

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

Thank you for your time :D


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK