JavaScript Event Delegation

10/08/2020 2 min read
JS

Event delegation is a simple and powerful pattern for event handling. Consider the following situation. You have an image gallery with n number of images in it, something like this:

<div id="gallery-container">
   <img class="image" src="https://source.unsplash.com/100x100/?person" />
   <img class="image" src="https://source.unsplash.com/100x100/?woman" alt="Woman" />
   <img class="image" src="https://source.unsplash.com/100x100/?man" alt="Man" />
   <img class="image" src="https://source.unsplash.com/100x100/?camera" alt="Camera" />
   <img class="image" src="https://source.unsplash.com/100x100/?television" alt="TV" />
</div>
<div id="image-description"></div>

You have a simple task – show an image description (the value of the alt attribute) every time a user clicks on one of the images. Inject the correct image description to the div with the image-description id.

Now, there are a few ways you could attach event listeners to your images. You could wait for DOM load and then, forEach on your images. But what happens if you load more images to your gallery container? Will you foreEach again!?  

Event delegation is all about finding a common ancestor, a kind of stable point of reference. In our example, all the images are contained inside the gallery container. So, we can attach an event handler on the container and dispatch the correct functionality relative to our event.target. This is how I would solve the gallery situation with event delegation:

// DOM Elements
const $galleryContainer = document.getElementById("gallery-container");
const $imageDescription = document.getElementById("image-description");

// Functions
const showImageDescription = () => {
  // Check if event target is an image
  if (event.target.classList.contains("image")) {
    // Check if image has an alt attribute
    let imageDescription = "No Description Found!";
    if (event.target.hasAttribute("alt")) {
      //  Check if alt attribute is not empty
      $imageDescription.innerText = event.target.getAttribute("alt") ?? imageDescription;
    } else {
      $imageDescription.innerText = imageDescription;
    }
  }
};

// Event Listeners
$galleryContainer.addEventListener("click", showImageDescription);

Related Posts