Home > Enterprise >  Is there a way to call eventListner on any of multiple elements with same className or ID. Only the
Is there a way to call eventListner on any of multiple elements with same className or ID. Only the

Time:08-18

devs. I got stuck while building a project. I have a list of menu items, about ten of them, with the same ID name and I will like to edit each of them if any is clicked. using js, I did this;

    
    const menuElement = document.querySelector('#menuElement')
    const darktheme = document.querySelector('.dark')

    loadEventListener()
    
    function loadEventListener() {
        menuElement.addEventListener('click', draw)
    }

    function draw() {
        menuElement.style.background = 'var(--primary-color)'
    }

However, when I click on the first menu element, it responds. but, it does not for the rest.

Thanks.

CodePudding user response:

Yes. But, instead of setting up multiple event listeners on all the elements you want, use "Event Delegation" and set up a single event listener on a common ancestor element, then let the event bubble up to that ancestor. In the event callback, you then check to see if the event originated at an element that you care to handle and, if so, handle it.

And note, that ids must be unique, however multiple elements can have the same class, so that's the way to go.

EXAMPLE:

// Set up an event handler on a common ancestor
document.addEventListener("click", function(event){
  // Check to see if the event originated at an element with the "foo" class
  if(event.target.classList.contains("foo")){
    // Handle the event any way you want
    event.target.classList.add("bold");
  }
});
.bold { font-weight:bold; }
<p>Clilck on any of the lines. Only the ones with the "foo" class will get bolded.</p>
<div >XYZ</div>
<div >XYZ</div>
<div >XYZ</div>
<div >XYZ</div>
<div >XYZ</div>
<div >XYZ</div>

CodePudding user response:

You can use querySelectorAll() to use a CSS selector and get all elements in the document that match that selector in a NodeList. Then you could use forEach() to attach an event listener to each of those elements.

Here a small working example.

window.addEventListener("DOMContentLoaded", e => {
  document.querySelectorAll(".myclass").forEach((element, i) => {
    element.addEventListener("click", () => console.log(`Div ${i} was clicked.`))
  });
})
.myclass {
  border: 1px solid black;
  padding: 10px;
  margin: 5px;
}
<div >Div 0</div>
<div >Div 1</div>
<div >Div 2</div>
You should also wait for the DOM to be loaded before attaching event handlers using the DOMContentLoaded event.

You cannot use an ID as IDs must be unique!

Another way to do it is using event delegation as outlined in Scott Marcus's answer.

  • Related