Rome
Rome

Reputation: 442

How to addEventListener and function with element as a parameter to multiple elements?

My goal is to have a bunch of div with clickable words to pass their ids to a Javascript function when one of them is clicked by the user. It works flawlessly for

    <div id="wordbox">
        <div id="pd"><h4>pdf</h4><br></div>
        <div id="an"><h3>analysis</h3></div>
        <div id="ai"><h2>artificial intelligence</h2></div>
        <div id="tr"><h4>trends</h4><br><br></div>
        <div id="dm"><h3>data mining</a></div>
    </div>
 var word = document.getElementById("pd");
 word.addEventListener("click", function(){ showSlide(word.id) });

but I don't manage to get it working for all elements. This fails:

  var wb = document.getElementById("wordbox").children;

  wb.forEach(function (element, index){
    element.addEventListener("click", function(){
      showSlide(element.id);
    });
  }); 

Any ideas?

Upvotes: 1

Views: 64

Answers (2)

Arun P Johny
Arun P Johny

Reputation: 388326

wb is not a real array, it is an array-like object called live HTMLCollection. You can get an array using Array.from(). You can also use document.querySelectorAll() to select the elements

var wb = document.querySelectorAll("#wordbox > div");
// new browsers - https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#bcd:api.NodeList.forEach
// wb
// To support older browsers
Array.from(wb)
  .forEach(function(element, index) {
  element.addEventListener("click", function() {
    console.log(element.id);
  });
});
<div id="wordbox">
  <div id="pd">
    <h4>pdf</h4><br></div>
  <div id="an">
    <h3>analysis</h3>
  </div>
  <div id="ai">
    <h2>artificial intelligence</h2>
  </div>
  <div id="tr">
    <h4>trends</h4><br><br></div>
  <div id="dm">
    <h3>data mining</a>
  </div>
</div>

Upvotes: 1

woat
woat

Reputation: 451

When you select the children from a node, it actually returns an array-like collection which is similar but not quite an array. In order to use forEach you first need to convert it into an array, and in the case below, I used the spread syntax to convert it into an array that allows me to use forEach.

const wb = document.querySelector('#wordbox')
const children = [...wb.children]

children.forEach(child => {
  child.addEventListener('click', () => {
    console.log(child.id)
  })
})
<div id="wordbox">
    <div id="pd"><h4>pdf</h4><br></div>
    <div id="an"><h3>analysis</h3></div>
    <div id="ai"><h2>artificial intelligence</h2></div>
    <div id="tr"><h4>trends</h4><br><br></div>
    <div id="dm"><h3>data mining</a></div>
</div>

Upvotes: 2

Related Questions