Skip to content

47 Event Delegation

Biswajit Sundara edited this page Aug 22, 2023 · 2 revisions

Event delegation is a design pattern in JavaScript where you attach a single event listener to a parent element to manage and handle events that occur on its child elements.

  • Instead of attaching event listeners to each individual child element
  • you delegate the responsibility to the parent element to listen for events and handle them based on the event's target
  • target means the specific child element that triggered the event

1. The problem

Let's say on a shopping page, we have categories parent div & category cards as children

  • If we click on Laptops -> navigate to Laptops page, Camera -> Camera page etc.
  • If we keep adding click event listener to all category cards it would be too many to handle
  • Also in infinite scrolling, the cards would keep loading.
 +--------------------------------------------------------+
 |   Parent Node                                          |
 +--------------------------------------------------------+
 |                                                        |
 | +-------------+  +-------------+  +-------------+      |
 | |   Child 1   |  |   Child 1   |  |   Child 1   |      |
 | +-------------+  +-------------+  +-------------+      |
 |                                                        |
 +--------------------------------------------------------+
//script.js
document.querySelector("#laptop").addEventListener("click", () => {
  window.location.href = "/laptop";
});

document.querySelector("#camera").addEventListener("click", () => {
  window.location.href = "/camera";
});

document.querySelector("#shoes").addEventListener("click", () => {
  window.location.href = "/shoes";
});
//index.html
<div>
  <p>Categories</p>
  <button id="laptop">Laptops</button>
  <button id="camera">Camera</button>
  <button id="shoes">Shoes</button>
  </div>
<script src="./script.js"></script>

2. The Solution

Instead of attaching so many event listener to the children we can attach the event listener to the parent

  • The event's will propagate up to the parent due to event bubbling
  • If we click on the child, the click event will be invoked of the parent
  • We have added the check for tag because we have a paragraph also inside the parent div.
//script.js
document.querySelector("#categories").addEventListener("click", (e) => {
  if (e.target.tagName === "BUTTON") {
    window.location.href = `/${e.target.id}`;
  }
});
<div id="categories">
   <p>Categories</p>
   <button id="laptop">Laptops</button>
   <button id="camera">Camera</button>
   <button id="shoes">Shoes</button>
</div>
<script src="./solution/script.js"></script>

3. Form Example

Let's say we have few text boxes where we want to transform the data to uppercase

  • Then instead of attaching bunch of event listeners to the individual text boxes
  • We can add a property where we need uppercase and handle the transformation at the parent level.
//script.js
document.querySelector("#form").addEventListener("keyup", (e) => {
  if (e.target.dataset.uppercase !=undefined) {
    e.target.value = e.target.value.toUpperCase();
  }
});
//index.html
<div id="form">
  <input type="text" id="name" data-uppercase>
  <input type="text" id="pan" data-uppercase>
  <input type="text" id="mobile">
</div>
<script src="./script.js"></script>

4. Benefits (pros)

  • Memory consumption will be less as we are attaching one event listener instead of many
  • Mitigates the risk of performance bottle neck
  • Less code - as we are writing one event listener instead of many
  • DOM manipulation - As we need to keep attaching the event listener to the child elements (esp incase of infinite scrolling)

5. Limitation

  • All events are not bubbled up like blur, scroll, resize etc.
  • Sometimes we use stop propagation in the children so it won't support event delegation

Clone this wiki locally