Felipe
Felipe

Reputation: 413

Unable to loop through HTMLCollection with forEach

I am trying to assign a click event for each element that has a class name of director__card--iconBox. The way that I am selecting these elements is by getElementsByClassName. With the current code written, I am testing the function to apply a background-color of its parents div to red. The end goal is to be able to flip the div and to display the backside of the div that will come later.

const toggleButton = document.getElementsByClassName("director__card--iconBox");

toggleButton.forEach((el) =>
  el.addEventListener("click", (event) => {
    const card = event.target.parentElement.querySelector(".director__card");
    card.classList.toggle("open");
  })
);



I am getting back an HTMLCollection. My thoughts is that this won't work because of an HTMLCollection? I have tried querySelectorAll to bring back a Node List, yet the NodeList returns empty..

Upvotes: 12

Views: 13351

Answers (3)

Raghavendra N
Raghavendra N

Reputation: 3082

You can also loop through the elements in the HTMLCollection by calling the item() method on the collection. The item() method returns the element located at the specified offset from the collection. Example:

const toggleButtons = document.getElementsByClassName("your-class-name");

for (let i = 0; i < toggleButtons.length; i++) {
    console.log(toggleButtons.item(i));
}

Upvotes: 0

choz
choz

Reputation: 17848

HTMLCollection is an array-like object but it does not have forEach method.

There are multiple ways you can iterate it with;

e.g.

Create an array out of it;

Array.from(toggleButton).forEach((el) =>
  el.addEventListener("click", (event) => {
    const card = event.target.parentElement.querySelector(".director__card");
    card.classList.toggle("open");
  })
);

Use for..of

for (let item of toggleButton) {
    item.forEach((el) =>
        el.addEventListener("click", (event) => {
            const card = event.target.parentElement.querySelector(".director__card");
            card.classList.toggle("open");
        });
    );
}

Or, just for loop.

for (let i = 0, len = toggleButton.length; i < len; i++) {
    toggleButton[i].forEach((el) =>
        el.addEventListener("click", (event) => {
            const card = event.target.parentElement.querySelector(".director__card");
            card.classList.toggle("open");
        });
    );
}

Upvotes: 21

Spectric
Spectric

Reputation: 31987

The reason querySelectorAll wasn't returning anything was because you didn't add a . at the start (remember, querySelectorAll accepts a DOMString that must a valid CSS Selector). This caused it return an array of elements with the tag name director__card--iconBox instead of an array of elements with the class director__card--iconBox.

Try the following:

const toggleButton = document.querySelectorAll(".director__card--iconBox");

toggleButton.forEach((el) =>
  el.addEventListener("click", (event) => {
    const card = event.target.parentElement.querySelector(".director__card");
    card.classList.toggle("open");
  })
);

Upvotes: 3

Related Questions