Iterating Over Result of Getelementsbyclassname Using Array.Foreach

Iterating over result of getElementsByClassName using Array.forEach

No, it's not an array. As specified in DOM4, it's an HTMLCollection (in modern browsers, at least. Older browsers returned a NodeList).

In all modern browsers (pretty much anything other IE <= 8), you can call Array's forEach method, passing it the list of elements (be it HTMLCollection or NodeList) as the this value:

var els = document.getElementsByClassName("myclass");

Array.prototype.forEach.call(els, function(el) {
// Do stuff here
console.log(el.tagName);
});

// Or
[].forEach.call(els, function (el) {...});

If you're in the happy position of being able to use ES6 (i.e. you can safely ignore Internet Explorer or you're using an ES5 transpiler), you can use Array.from:

Array.from(els).forEach((el) => {
// Do stuff here
console.log(el.tagName);
});

How to correctly iterate through getElementsByClassName

According to MDN, the way to retrieve an item from a NodeList is:

nodeItem = nodeList.item(index)

Thus:

var slides = document.getElementsByClassName("slide");
for (var i = 0; i < slides.length; i++) {
Distribute(slides.item(i));
}

I haven't tried this myself (the normal for loop has always worked for me), but give it a shot.

Using forEach on an array from getElementsByClassName results in “TypeError: undefined is not a function”

That's because document.getElementsByClassName returns a HTMLCollection, not an array.

Fortunately it's an "array-like" object (which explains why it's logged as if it was an object and why you can iterate with a standard for loop), so you can do this :

[].forEach.call(document.getElementsByClassName('myClass'), function(v,i,a) {

With ES6 (on modern browsers or with Babel), you may also use Array.from which builds arrays from array-like objects:

Array.from(document.getElementsByClassName('myClass')).forEach(v=>{

or spread the array-like object into an array:

[...document.getElementsByClassName('myClass'))].forEach(v=>{

Unable to loop through HTMLCollection with forEach

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");
});
);
}

Toggle classes with getElementsByClassName inside a foreach loop with Javascript

Lots of ways to do this. Ensure that you are adding event listeners to all the divs and not just the first one.
Looking at your current code you can follow this approach.

this inside event listener belongs to the element that triggered the event. So when we do this.getElementsByClassName we are querying for classes only inside that particular element.

getElementsByClassName does not return an array. It returns a collection which is array-like. To use forEach() on that array-like object converting it into an array is required. Using the ... (spread) operator to convert the collection into an array.

[...document.getElementsByClassName('read-more-div')].forEach(x => x.addEventListener('click', function() {

this.getElementsByClassName('read-more-btn1')[0].classList.toggle('hide');
this.getElementsByClassName('read-more-btn2')[0].classList.toggle('hide');

return false

}));
body {
background-color: #000000;
color: #ffffff;
}

p,
button {
background-color: #000000;
color: #ffffff;
border: none;
padding: 0;
margin: 0;
}

.read-more-btn1 {
color: #888888;
cursor: s-resize;
}

.read-more-btn2 {
cursor: n-resize;
}

.read-more-btn1:hover {
color: #ffffff;
}

.hide {
display: none;
}
<div>Project A

<div class="read-more-div">

<button class="read-more-btn1">Read more...</button>
<p class="read-more-btn2 hide">Toggle this project text</p>

</div>

</div>

<div>Project B

<div class="read-more-div">

<button class="read-more-btn1">Read more...</button>
<p class="read-more-btn2 hide">Toggle this project text</p>

</div>

</div>

<div>Project C

<div class="read-more-div">

<button class="read-more-btn1">Read more...</button>
<p class="read-more-btn2 hide">Toggle this project text</p>

</div>

</div>

Using entries() in a for-of loop, iterating over an HTMLCollection

Entries method is available for arrays. However, getElementsByClassName does not return an array. Instead it returns an HTMLCollection. You need to first convert it into array. There are two ways you can do that:

  1. Using Array.prototype.slice
function toArray(arr) {
return Array.prototype.slice.call(arr);
}

toArray(document.getElementsByClassName('foo'));

  1. Using ES6 spread
function toArray(arr) {
return [...arr];
}

toArray(document.getElementsByClassName('foo'));


Related Topics



Leave a reply



Submit