DEV Community

loading...
Cover image for Event Delegation - What is it and why should I care?

Event Delegation - What is it and why should I care?

paulryan7 profile image Paul Ryan ・3 min read

It is very common in an interview scenario to be asked to explain event delegation, showing an understanding makes you a much stronger candidate. Thankfully, it is not too complicated.

Event Listeners

The first area we must venture into is getting an understanding of event listeners. Event Listeners are essentially something that listens for an event. Some very common examples are:

  • keydown
  • click
  • load

Here is some example code that adds an event listener to a div that has an id of myDiv

    // event target
    const myDiv = document.querySelector('#myDiv')
    // adding the listener
    myDiv.addEventListener('click', () => { alert("oh my god i've been clicked") })

So when our div gets clicked we fire off the alert function.

One important thing to note is that event listeners are added on page load, so in the above example when the page is loaded our javascript is executed and tries to find the element with the id of myDiv.

That all sounds great but what if that element is not available on page load? Well, then it’s time for event delegation!

Event Delegation

So imagine we have a ul and on the click of a button, a li is added to our ul. When a li is clicked, we want to remove it from our ul, the problem is we do not have access to each li on page load as they simply haven’t been added. Click here for a Codepen example that will demonstrate this, visually we can also imagine it like this:

Adding items to list

What we want to do is find our if a li in our list has been clicked.

The html for the above is the following:

    <div class="container">
      <ul class="my-list">

      </ul>
      <button onclick="addItem()">Add Item</button>
    </div>

So when the page is loaded we have access to the my-list class so that is what we should use as our initial target.

    const myList = document.querySelector('.my-list');
    myList.addEventListener("click", removeItem);
    function removeItem(e) {
      // e.target is the element which dispatched the event
      console.log(e.target);
      // e.currentTarget is the element which the event listener
      // is added to
      console.log(e.currentTarget);
    }

So as commented in the above, when a click happens we get the e object, this has the property target which is the element that was clicked i.e. the li and also has the currentTarget property which is where our event listener has been added on page load i.e. our ul element.

Since we want to remove an li, we will use the target property. To remove the li we can do the following:

    function removeItem(e) {
      event.target.matches("li") ? e.target.parentNode.removeChild(e.target) : null;
    }

We first check that element clicked is indeed a li and if it is we remove that element!

That is what event delegation is all about, but we should also discuss event bubbling a little too.

Event bubbling is quite simple, it means that when we click on a DOM element that this event will be bubbled the whole way up the DOM. So in our case when we click on the li, this is bubbled up to our ul then to our div and so on.

You can stop this behavior by using:

    e.stopPropagation()

In most cases, you won’t need to use it but it is great to know.

Why event bother using Event Delegation?

So we don’t have to use event delegation, we could have added an event listener to each li when it is added but this will add lots of extra code and will increase the number of event listeners on your page by an n amount (n being the number of items added). This will increase the overall memory on your page which will make performance suffer, so it is a very bad idea. In short, event delegation is great!

Now go ahead and smash that interview question!

Discussion

pic
Editor guide