Why ForEach Array Method Is Not A Function On Looping Over Document.getElementsByClassName
Solution 1:
document.querySelectorAll
returns a NodeList
not an Array
. Never fear, tho!
You can use Function.prototype.call to change the context of the Array.prototype.forEach
function.
var nodes = document.querySelectorAll('span');
var colors = ['red', 'orange', 'gold', 'lawngreen', 'dodgerblue', 'deepskyblue', 'blueviolet'];
Array.prototype.forEach.call(nodes, function(elem, idx) {
// do something
elem.style.color = colors[idx];
});
<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
<span>E</span>
<span>F</span>
<span>G</span>
EDIT
Actually my doubt is why
forEach
does not directly work on return ofdocument.getElementsByClassName
That's because document.getElementsByClassName
reutrns an HTMLCollection
not an Array
. HTMLCollection
does not have a forEach
method on its prototype.
var nodes = document.getElementsByTagName('span');
console.log(nodes.constructor.name);
//=> HTMLCollection
<span>A</span>
Solution 2:
From what I tested:
<ul>
<li class="test"></li>
<li class="test"></li>
<li class="test"></li>
<li class="test"></li>
<li class="test"></li>
<li class="test"></li>
<li class="test"></li>
</ul>
<script type="text/javascript">
var elementList = document.querySelectorAll("li");
console.log(elementList.constructor);
var elementList2 = document.getElementsByClassName("test");
console.log(elementList2);
console.log(elementList2.constructor);
</script>
querySelectorAll
returns:
NodeList() { [native code] }
while getElementsByClassName
returns:
HTMLCollection() { [native code] }
Pretty much, as the previous answer mentioned, the HTML collection doesn't have access to the forEach method.
EDIT1: Difference between HTMLCollection, NodeLists, and arrays of objects seems to answer some of the differences!
EDIT2: It seems like you can iterate through an HTML Collection with the technique using ES6 mentioned here: For loop for HTMLCollection elements
Solution 3:
We can interact with an HTML Collection as if it’s an array in many other ways. We can use index numbers to access data. It looks like an array. But it functions a bit differently. First of all, a bit of a distinction. I’ve heard nodeList and HTMLCollection used somewhat interchangeably. They’re both DOM lists, but the only real difference is that HTMLCollection is more specific. It contains DOM elements that are the same, whereas a nodeList can contain a variety of DOM elements. That’s why querySelectorAll returns a nodeList but getElementsByTagName returns an HTMLCollection. Interestingly enough, forEach works on a nodeList but not an HTMLCollection.
Now there are a number of ways to iterate over a HTMLCollection;
var p = document.getElementsByTagName("p") for(var i = 0; i < p.length; i++) { console.log(p)}
Check other ways here https://medium.com/@larry.sassainsworth/iterating-over-an-html-collection-in-javascript-5071f58fad6b
Post a Comment for "Why ForEach Array Method Is Not A Function On Looping Over Document.getElementsByClassName"