Check out a free preview of the full Vanilla JS: You Might Not Need a Framework course:
The "Advanced Event Handling" Lesson is part of the full, Vanilla JS: You Might Not Need a Framework course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano discusses attaching multiple event handlers per event/object and dispatching custom events. Student questions regarding removing event listeners with the parent element, if events with multiple functions fire synchronously, and if there is a limit to the number of event listeners are also covered in this segment.

Get Unlimited Access Now

Transcript from the "Advanced Event Handling" Lesson

[00:00:00]
>> So typically, we are going to use addEventListener. And also, addEventListener supports more advanced event handling. For example, we can pass a third argument with some options. For example, one option is once, that by default this is false. So typically, we set it as true. That means that the event will be fired once.

[00:00:22] After it was fired once, the eventHandler will be removed automatically. So if you add these to a click eventHandler on your button, you click once you execute the handler. You click again, nothing will happen, because the event was removed. Yeah, it's not suitable for a button, but it might be suitable for other situations where you're expecting that to happen once.

[00:00:47] So then you don't need to think about removing the EventListener about leaking options, blah, blah, blah. Passive, I will try to explain it really quickly. If you don't get it, it's fine, okay? But let me explain that with a scroll, since the simplest example is with a scroll.

[00:01:11] Remember that I mentioned that we are sharing the thread between my code and the browser, but it has to do with that. So what happens, for example, if you are scrolling with your finger, you are scrolling your phone with your finger, and there is a scroll event, so you can know when the user is scrolling the page.

[00:01:33] But then, in the JavaScript code, you are taking too much time from the CPU. Well, the browser has no time, to actually show the page moving while you're moving your finger when you are dragging your finger, okay? So because by default, the browser will wait for your eventHandler to see if you are changing the DOM.

[00:01:56] If you are changing the DOM, then it needs to repaint, re-layout before actually moving the layer, something like that. When you say passive, true, you are kind of saying, hey, browser, you can safely do whatever you wanna do on the screen that I'm not going to change the DOM.

[00:02:15] I'm simplifying this a lot, but just to give you an idea of what this is, okay? So it's like saying, hey, you can execute my EventListener passively, so don't wait for it to finish before doing your stuff. It something like that, it's more complex than that, but just to give you an idea.

[00:02:35] Anyway, there is an option the third argument where you can execute some code. And also, we have removeEventListener. Why do you wanna remove EventListeners? Well, to avoid having connections to things that you're not going to use anymore. This is only useful when you are doing a single-page application, and you are adding and removing elements on the page.

[00:03:01] Because I don't need to remove the EventListener for DOM content loader. Or if you have a button or a link but it's always on the screen, I don't need to unload my page. Because when the user is getting out of my page navigation or closing the browser, I don't need to clean up my JavaScript, everything will happen automatically.

[00:03:24] We don't clean up the Web app for when the user gets out. That's not how a Web app works, okay? So we use these only when we are injecting and removing elements. And we don't wanna get a lot of functions in memory that we don't use anymore. Does it make sense?

[00:03:49] That's kind of the idea. And this is actually pretty cool. And it's an underused feature that we're going to use it later. We can dispatch our own events. And not just for our own components that we haven't created yet. We can dispatch events in the document, in the Window object.

[00:04:11] So you create a new event with your own name, and you're not forced to follow the lowercase guideline. So it's just a string, and dispatch that event over an element. And that element can be a button, or it can be the document. So you can broadcast events through the DOM API for anyone that wants to listen for that event.

[00:04:37] Now, think about React Angular. This is kind of a context where you can dispatch events over the context, and anyone in the DOM can subscribe with a provider, and that's kind of that idea. So we can dispatch events from anywhere in the page, and anyone can listen for those events.

[00:05:06] And that event is a JavaScript object, so we can attach properties to it, metadata, or we can even extend from event. We can create our own class, extending from event with our own interface for that event, okay? So we can hook into the DOM event API. I'm not saying that you must use that, or you should always use this.

[00:05:33] It's just one technique that we have available when you're doing Vanilla JS, okay? Cool, do you have any question? Yeah.
>> I have two actually. So did you say that when DOM nodes are removed from the DOM specifically, that the EventListeners aren't removed? Do you have to remove them manually?

[00:05:56]
>> Let's review that part, because there are several possibilities here. So if you remove an element from the DOM, do we need to remove the EventListeners? It depends on what you wanna do. Because removing an element from the DOM doesn't mean that you are not going to use that element anymore.

[00:06:15] It means that you don't want it on the screen right now. So remember, a DOM element is a JavaScript object. It can be attached to the DOM or not. Maybe we can say, okay, what happens if we delete that object, that DOM element? And that's a different situation.

[00:06:37] But removing something from the DOM doesn't mean that you're throwing it away. You can still save that DOM element for later usage. So then you don't wanna maybe remove the EventListeners, because on the lifecycle of that element, you will still use it later. Okay, makes sense? So, the thing is that, if you're not going to use that element anymore, or if you delete the reference, you use the delete keyword in JavaScript, what will happen with the EventListener?

[00:07:10] Actually, it depends. It's not even a clear answer, because it depends if you also have that EventListener hooked somewhere else or not. So it's not so complicated, but it is complicated actually. It's not so simple. But something that you can do is to manage that yourself and say, okay, I'm going to remove the EventListener for that element.

[00:07:34] But more important is that when you don't need that EventListener anymore, let's say you have a button, you have a help button, okay, that is on your page all the time, but then you log out. When you log out, you need to remove an EventListener from it. Because now you are logged out, you don't wanna open a chat that connects to your account, because now you are logged out.

[00:08:01] The button is still there, so you are not removing the button from the DOM. It's not about the element itself, it's about the use case. Now, there are one or more event listens over that element that is still on the screen that you don't need anymore. So you remove the EventListener.

[00:08:19] That use case is more common, make sense? But yeah, the other problem is what happens with typically custom elements that we put on the screen, and then we'll remove from the screen and we won't use anymore later, okay? Cool, any other question?
>> I have one more actually.

[00:08:39]
>> Yeah, sure.
>> When you have multiple EventListeners for one event like load for example.
>> Yeah.
>> Did they fire synchronously one after the other or?
>> In JavaScript, nothing. So it depends on what you mean by synchronous. But I guess that you're you're saying if they being fired in parallel, okay, or something like that.

[00:09:02] In JavaScript, by default, you have only one thread. So nothing will happen in parallel, nothing. So no matter the question, everything will happen sequentially, in sequence. So in this case, when you have several EventListeners hooked to the same element on the same event, the system will fire them in sequence, okay?

[00:09:27] And if you need to do things in parallel, in those EventHandlers, you need to work with workers, web workers. But that's something that you make on your own. It's not going to work automatically, okay? But JavaScript is single threaded by default, sorry.
>> Is there a limit to how many EventListeners can be honored?

[00:09:49]
>> That's a good question. If they're limited, how many EventListeners can you hook? Actually, it depends on the implementation of every browser. I think there was someone doing a test, and some browsers were crashing after 5000 or something that. But I mean, in the real world, no. But there is always a limit, because it has to do with memory and browsers implementations.

[00:10:13] But I'm not pretty sure right now, but I don't think there is a limit in the spec. So but yeah, each browser might implement the things differently. So they might have their own limits or something like that, creating a DOM exception when that happens. But it's not happening in the real world, okay?

[00:10:32] Even really complex VR, games, somethings won't get into that level of problems.