Understanding event delegation in javaScript
Tags: webdev, javascript, programming, tutorial
Published: 2024-05-01 15:41:07



## Introduction

Let's assume you have multiple elements that need to perform the same function when an event happens. You would normally add an event listener to each element individually. This will create multiple copies of the same callback function, which could affect the overall performance of your page. This method is usually inefficient, especially with hundreds or thousands of elements. The best way to solve this problem is to use event delegation.

## What is event delegation?

Event delegation is an event-handling technique that takes advantage of event bubbling to handle events at a higher level in the DOM tree. In event delegation, one event handler is used to handle events for multiple elements. Instead of attaching an event listener to each element, we attach it to a common parent of all the elements we’re listening for an event on. Then use the `e.target`  to determine where the event happened.

## Event propagation: bubbling and capturing

To better understand event delegation, you will first need to understand the concept of event propagation.
Event propagation describes how events travel up and down the DOM tree during the **capturing** and **bubbling** phases.
When a user clicks an element, the event is not generated at the target element. Instead, the event is generated at the top of the DOM tree (at the document root). The event then travels down from the document root to the target where it will be handled. This phase is called the capturing phase.
After the event is handled at the target element, the event travels up from the target element to the DOM tree In the bubbling phase. During this phase, the event passes through all the parents of the target and triggers an event in them. This bubbling phase is what makes event delegation possible


## Benefits of event delegation

- Too many event handlers can cause performance issues in large applications. Event delegation reduces the number of event handlers in your code. This will improve performance, especially when you are handling a large number of elements

- Event delegation reduces the amount of memory your application consumes. Event listeners increase the memory footprint of your application, which in turn makes it run slower.

- It allows you to write clean and maintainable code.

- It allows you to add elements dynamically. Any new child element added to the parent will automatically be covered by the event handler as long as it matches the set criteria.

## Event delegation in practice

Now let’s write some code to see how event delegation works.
HTML:
  

```
<ul class="fruits-container">
	<li class="fruit">Banana</li>
      <li class="fruit">Apple</li>
      <li class="fruit">Orange</li>
      <li class="fruit">Watermelon</li>
    </ul>
```


CSS:

```
.fruits-container {
        display: flex;
        gap: 3rem;
        list-style: none;
        background-color: aquamarine;
      }
      .fruit {
        text-decoration: none;
        font-size: 2rem;
        cursor: pointer;
      }
```

Instead of attaching an event listener to each `li` element here, we’ll add one event listener to their common parent, which is the `ul`.

```
document.querySelector(".fruits-container").addEventListener("click", function (e) {
  console.log(e.target);
});
//output
//when you click the container, the console will log:
<ul class = “fruits-container”>
//when you click the list items, the console will log:
<li class = “fruit”>
```

The `event object` (e) has a `target `property, which signifies the element on which an event happened. So in this case, `e.target` is the element on which the click happened. If you click the parent element, the console will log information about the parent. If you click any of the `li`, the console will log information about the `li`.
Since we’re only interested in the clicks that happen on the `li` and not the parent `ul`, we’ll use the `e.target` to isolate the clicks on the `li`.

```
document
  .querySelector(".fruits-container")
  .addEventListener("click", function (e) {
    //isolating the clicks on the links
    if (e.target.classList.contains("fruit")) {
      e.target.style.color = "blue";
      console.log(e.target);
    }
  });


```

This code says that if `e.target` (the element on which the click happened contains the class ‘fruit’, change the color of that element to red upon clicking. So now, if you click any of the `li`, its color will change to red because it contains the class ‘fruit’. If you click the parent element, nothing will happen because it does not contain the required class. Therefore, it does not meet the condition. 

**Output**
Before clicking:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kf20s9u7yon6651eimg.png)

After clicking:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m65hr0icis3b20fby1ep.png)
Here, you can see the color of the `li` was black before clicking, after clicking it turned red. 

## Conclusion

Event delegation is a useful technique that allows you to write cleaner code and create fewer event listeners for similar logic. The idea is that you delegate the handling of an event that happened on an element to its parent or ancestor instead of the element itself. 
It improves code performance and reduces bulky code. Event delegation can be used for handling tabbed components, accordion components, dropdown menus or to implement smooth scrolling on navigation links.