How to effectively attach eventListeners to DOM elements

Anonymous functions are great way to quickly get the job done, but can be a huge problem when used carelessly. It is especially when attaching eventListeners to DOM elements. Take the code below for example. Here we are attaching an eventListner to the element for the “click” event. Now, later lets say for some reason or requirement we need to remove this “click” listener.

var element = document.getElementById("my-id");
element.addEventListener("click", function() {
// handle event

After this point we don’t have any reference to this handler since we forgot to keep a reference to it hence we cannot call the removeEventListener on the element, and the function stays in the browse memory.

Now assume the same scenario with multiple elements. An appropriate example of it might be when a NxN grid of elements is created. Lets assume that the cells in the grid is being created dynamically and appended to the DOM. If these cells need to have some event handler we might end-up doing the following:

var newCell = getNewCell(); // function to create a new cell

newCell.addEventListenet("click", function() {
// handle code

This way we ended up creating NxN anonymous functions to which we don’t have references to, in case event listeners need to be removed. Even after the element does not exist in the DOM, it is the browser to decide when to remove these abandoned listeners from its memory. But as a programmer its our job to clean up the mess we created.

How to fix this:

A better approach to add eventListeners to DOM elements would be to have some kind of reference to them as below:

function myListener(event, target) {
// handle the event

var newCell = getNewCell();

newCell.addEventListener("click", myListener);

Now whenever needed, this listener can to removed from the element:

newCell.removeEventListener("click", myListener);

Sometimes, there is a requirement of firing en event listener only once (for example an init button to be clicked for initializing the application). In that case, the addEventListener method can accept an optional object parameter with a Boolean property “once” to tell the browser that this listener needs to be fired only once and after that the listener needs to be removed. So in such cases adding anonymous function as eventListeners can be considered fine (but not with multiple elements as we are still creating several anonymous functions which will sit there untill the event occurs for the first time).

myElement.removeListener("click", function() {}, {capture: false, once: true, passive: true});

So it is quite essential to take precautions when attaching anonymous functions as eventListeners especially with multiple elements.