Event Delegation

Event Delegation

In previous articles of this series, we discovered many things about a DOM Event. We know how events are listened to or what happens behind the curtain for every event occurrence.

In this article, we will take a look at a common problem regarding DOM events faced by developers and a particular design pattern that aims to solve it.

Read all articles from this series

Problem

See the Pen DOM-Event-delegation-problem by Avadhut Prabhudesai (@avadhut23) on CodePen. " data-card-controls="0" data-card-theme="light">

Considering the example in this pen, we have a card component that has 3 clickable/actionable items.

  • An 'Add to favorite' icon
  • A 'View' button
  • An 'Add to cart' button

In order to respond to these, we need to set up event listeners for each of them.

  • Click listener on Fav icon may toggle favorite state on the card.
  • Click listener on View button may navigate to a details page.
  • Click listener on Add to cart button may add the item to cart.

So, where is the problem?

Event listeners are one of the main causes of 'Memory Leaks'. A memory leak is a very serious issue for web performance and must be avoided at all times. Read more about 'Memory Leaks'

Consider a scenario where there is a list of 1000 such cards. Then we will have 3000 click event listeners in our app.

Also, an element can have more actionable items. It does not make sense to add different click listeners for each item on every card in the list. This will drastically increase the total number of listeners on the page.

EVENT DELEGATION to the rescue

Event delegation is a pattern that solves this problem. It is based on the combination of

  • Event Flow / Event Propagation
  • target property

Event Flow / Event propagation

Read more about Event Flow

Most events have 2 phases, CAPTURE and BUBBLE. It means the parent of an element on which event occurred, will be notified in each phase.

target property

Every event listener receives an 'Event' object as an argument. This 'Event' object is propagated to all parent elements in both CAPTURE and BUBBLE phases. This object contains several properties related to the event. One of the properties is target which contains a DOM element on which the event has occurred.

Voila !!!

Combine Event Propagation with the target property and we have our solution.

We know that whenever an action item on the card is clicked, the click event will propagate to all its parents with an Event Object. This event object will contain a reference to a DOM element on which the click event originally occurred.

See the Pen DOM-Event-delegation-solution by Avadhut Prabhudesai (@avadhut23) on CodePen. " data-card-controls="0" data-card-theme="light">

As shown in the pen, we have a single click event listener on the card.

When the user clicks on fav icon or View button or Add to cart button, the event is bubbled up to the div with id 'card'. We have a click event listener on this card element which is invoked and receives an event object.

This event object contains the target property which refers to the DOM element object which the user has clicked. Since it is another DOM element, we can access all the attributes on it. In our example, we access the id attribute to determine which action item was clicked.

A word of caution

Event delegation is a kind of abstraction. As with any other abstraction, we should avoid overdoing it.

To make it worse, we can have a single click event on the entire document and perform branching based on the target property. We certainly do not want to take it to this level. A developer needs to make this decision based on the requirements and code architecture.

Finally...

We have seen that an event object plays a vital role in event delegation. In the next article, I will try and explore more properties and methods of this event object.

Stay tuned...