DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Single Event Listener for all elements in JS
Mysterio
Mysterio

Posted on

Single Event Listener for all elements in JS

Hello guys today i will be discussing an important topic called Event Delegation in Javascript.

What is Event Delegation ?

  • Suppose you have a 3 containers each having a button inside it and you want to attach an event listener to those buttons.So, you might do it by attaching the events separately to those buttons 3 times and that's a lot of work to do when the number of containers increases so does the size of your code and repitition of code as well.
  • To fix this problem , we will use event bubbling in which we will attacht the single event listener to the main containers having all the others containers and then using the "event" methods we can go down and up in the main container using some DOM methods.Using this technique we can attach the event listeners to all the buttons in a one event and also it will be applicable to the buttons which may be added in future automatically.
  • You will understand this better with the example below
<div class="main">
  <div class="container">
    <button class="btn">Button 1</button>
  </div>
  <div class="container">
    <button class="btn">Button 2</button>
  </div>
  <div class="container">
    <button class="btn">Button 3</button>
  </div>

  <p class="text"></p>
</div>
Enter fullscreen mode Exit fullscreen mode
const mainContainer = document.querySelector(".main");

mainContainer.addEventListener("click",(e) => {
  let buttonOnly = e.target.closest("button")

  if(buttonOnly === null) return;
  let textNode = buttonOnly.closest(".main").querySelector(".text");
  if(buttonOnly.classList.contains("btn")){
    textNode.innerText = buttonOnly.innerText;
  }
})
Enter fullscreen mode Exit fullscreen mode
  • So, what i did is accessed the main container using querySelector
  • Using the "closest" method i am searching for the buttons only, if the element is not a button then don't do anything.
  • Then i have attached the click event listener to the main container,it will also attach the click event on the child elements in the container, which we can manipulate using the event methods.
  • I have created a textNode variable and accessed the element having "text" class, what it is doing is using "closest" method i am finding the closest element having the "main" class which is the main container means going up in the DOM tree,then using the querySelector to access that element with the class "text"
  • With the if statement , i am checking that whether the element we have clicked has a class named "btn", if it is true, then set the textNode inner text to button inner text.

Example Codepen -

  • I have created multiple Dropdown with single event listener

You can contact me on -
Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

^^You can help me by some donation at the link below Thank youπŸ‘‡πŸ‘‡ ^^
β˜• --> https://www.buymeacoffee.com/waaduheck <--

Also check these posts as well
https://dev.to/shubhamtiwari909/css-iswherehas-and-not-2afd

https://dev.to/shubhamtiwari909/theme-changer-with-html-and-css-only-4144

https://dev.to/shubhamtiwari909/swiperjs-3802

https://dev.to/shubhamtiwari909/going-deep-in-array-sort-js-2n90

Top comments (3)

Collapse
 
posandu profile image
Posandu • Edited on

We can use the .querySelectorAll method instead of the method you've given (The buttons aren't added dynamically). This gives us less code and easy to understand.

const buttons = document.querySelectorAll(".dropdown-button"); // We get all the buttons

buttons.forEach((button) => {
  // We loop through all the buttons
  button.addEventListener("click", (e) => {
    // We add an event listener to each button
    e.preventDefault();

    e.target.setAttribute(
      "data-toggle-id",
      e.target.getAttribute("data-toggle-id") === "false" ? true : false
    );
  });
});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
shubhamtiwari909 profile image
Mysterio

Actually I used the loop approach first
Then i tried to implement it without loop ,i thought if the number of elements increases up to a large number,using a loop in that case could lead to low performance

Collapse
 
liviufromendtest profile image
Liviu Lupei

Interesting!

DEV

Thank you.

Β 
Thanks for visiting DEV, we’ve worked really hard to cultivate this great community and would love to have you join us. If you’d like to create an account, you can sign up here.