-1

I have a list of elements and I'd like to add a click event to each one that will call a function and pass it an index of a list. In the case below I'm defining itemIndex as 0 and incrementing it each loop. When the click event is called the index it uses is 3 (number of loops +1) instead of the number of the loop. How can I solve this problem?

let itemIndex = 0;
itemList.forEach(item => {
    const itemFragment = document.importNode(this.itemTemplate.content, true);

    //add click event
    itemFragment.querySelector('.part').addEventListener('click', () => {
        loadItem(itemList[itemIndex]);
    });
    //append product to body row

    itemTarget.appendChild(itemFragment);
    itemIndex++;
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
lawrencehagman
  • 471
  • 1
  • 3
  • 16
  • 3
    [See this question.](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Dave Newton Aug 18 '20 at 21:59

1 Answers1

3

Just use the index argument in forEach. Currently, you are incrementing the same outer variable on each iteration, so each event handler accesses the same value.

itemList.forEach((item, itemIndex) => {
        const itemFragment = document.importNode(this.itemTemplate.content, true);
        
        //add click event
        itemFragment.querySelector('.part').addEventListener('click', () => {
            loadItem(itemList[itemIndex]);
        });
        //append product to body row
    
        itemTarget.appendChild(itemFragment);
    });

In your case though, you don't actually need the index itself but the item on each iteration, so just pass item to loadItem.

itemList.forEach(item => {
        const itemFragment = document.importNode(this.itemTemplate.content, true);
        
        //add click event
        itemFragment.querySelector('.part').addEventListener('click', () => {
            loadItem(item);
        });
        //append product to body row
    
        itemTarget.appendChild(itemFragment);
    });
Unmitigated
  • 76,500
  • 11
  • 62
  • 80