A good[ish] website
Web development blog, loads of UI and JavaScript topics
The forEach loop for beginners, and how to use it with a nodeLists, and HTMLCollections.
So the forEach loop loops and array and gives access to the current item through a callback function. It doesn’t return anything.
Here’s the basics:
var normalArray = ['foo', 'bar', 'baz', 'fooz']
normalArray.forEach(function (currentValue, index, array) {
console.log(currentValue + ' - ' + index + ' - ' + array)
})The callback params:
currentValueindexcurrentValue.arrayWhen querying elements on the page, the resulting collection is no an array, but:
getElementsByClassName() produces an HTMLCollectionquerySelectorAll() produces a nodeList.These return not arrays of nodes but nodeLists, which are freaky weird things — Douglas Crockford
Here’s our super simple HTML that we’re going to be working with:
<div class="module"></div>
<div class="module"></div>
<div class="module"></div>HTMLCollection or a nodeList are not arrays, per se, they’re "array-like objects", and we can’t use forEach right out the box. But what we can do is to call the Arrays forEach method directly, like so:
// Grab the wanted elements
var htmlCollection = document.getElementsByClassName('module')
Array.prototype.forEach.call(htmlCollection, function (element) {
console.log(element.tagName)
})The Array.prototype can be truncated to a pair of brackets [], like so:
;[].forEach.call(htmlCollection, function (element) {
console.log(element.tagName)
})Or you can spread the nodeList or the HtmlCollection and then use it like any other array:
var htmlCollection = [...document.querySelectorAll('.module')]
htmlCollection.forEach(function (element) {
console.log(element.tagName, 'foo')
})Just as a reminder that the good old for loop works great also:
for (var i = 0; htmlCollection.length < i; i++) {
console.log(htmlCollection[i].tagname)
}There are things forEach can’t do. The two words "for" and "Each" are taken very literally, you’re about to iterate every single element in the array, break or continue can’t be used. Here’s a non working example:
;['foo', 'bar', 'baz'].forEach(function (element, index) {
if (index > 3) {
// Does not work
break
// Likewise for:
// continue
}
console.log('Current ' + element + ', Index ' + index)
})You get an error: Uncaught SyntaxError: Illegal break statement.
Or just use a for loop if you need to break. I have a post about looping and manipulating objects that has a lot of good stuff related to this, have look.
Comments would go here, but the commenting system isn’t ready yet, sorry.