Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS: iterating over result of getElementsByClassName using Array.forEach

I want to iterate over some DOM elements, I'm doing this:

document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {   //do stuff }); 

but I get an error:

document.getElementsByClassName("myclass").forEach is not a function

I am using Firefox 3 so I know that both getElementsByClassName and Array.forEach are present. This works fine:

[2, 5, 9].forEach( function(element, index, array) {   //do stuff }); 

Is the result of getElementsByClassName an Array? If not, what is it?

like image 985
Steve Claridge Avatar asked Oct 06 '10 10:10

Steve Claridge


People also ask

How do I iterate over document getElementsByClassName?

Iterate Through Elements Returned by getElementsByClassName getElementsByClassName method is to use the for-of loop. We call document. getElementsByClassName with 'slide' to return an HTML element collection object with all the divs. Then we use the for-of loop to loop through each item.

Does getElementsByClassName return array?

The getElementsByClassName method of Document interface returns an array-like object of all child elements which have all of the given class name(s).

What does the JS getElementsByClassName () return?

The getElementsByClassName() method returns an array-like of objects of the child elements with a specified class name. The getElementsByClassName() method is available on the document element or any other elements. The method returns the elements which is a live HTMLCollection of the matches elements.

Does getElementsByClassName return NodeList?

The getElementsByClassName() method returns a collection of all elements in the document with the specified class name, as a NodeList object.


2 Answers

No. 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); }); 
like image 165
Tim Down Avatar answered Sep 22 '22 00:09

Tim Down


You can use Array.from to convert collection to array, which is way cleaner than Array.prototype.forEach.call:

Array.from(document.getElementsByClassName("myclass")).forEach(     function(element, index, array) {         // do stuff     } ); 

In older browsers which don't support Array.from, you need to use something like Babel.


ES6 also adds this syntax:

[...document.getElementsByClassName("myclass")].forEach(     (element, index, array) => {         // do stuff     } ); 

Rest destructuring with ... works on all array-like objects, not only arrays themselves, then good old array syntax is used to construct an array from the values.


While the alternative function querySelectorAll (which kinda makes getElementsByClassName obsolete) returns a collection which does have forEach natively, other methods like map or filter are missing, so this syntax is still useful:

[...document.querySelectorAll(".myclass")].map(     (element, index, array) => {         // do stuff     } );  [...document.querySelectorAll(".myclass")].map(element => element.innerHTML); 
like image 40
Athari Avatar answered Sep 25 '22 00:09

Athari