Loop Over a HTMLCollection Using The ES6 Spread Operator

About this time last year I released a little coffee blog called Beanhere. It was a fun little project that I used as an excuse to try and teach myself some new techniques, turns out that I did learn quite a lot. Now twelve months later I am going to start breaking down some of my more interesting takeaways in this little blog series - so here’s Beanhere hot tip number one.

How do you neatly loop over HTML DOM Nodes without using jQuery?

Assuming you’re authoring your javascript using ES6 syntax, very easily using a combination of two new operators in the language, spread and forEach. Note, this would work just as well using any other Array method, such as map.

// first select all of the items..
const items = document.getElementsByClassName('item');
// Using the new spread operator, we can transform this HTMLCollection
// into an array, which gives us access to a bunch of useful methods
const itemsArray = [...items];
// itemsArray now = a array(5) [div.item, div.item, div.item, div.item, div.item]
// now we have an array we can easily use over them using forEach
itemsArray.forEach((item, index) => {
    // each of items is an 'Element', which gives you access to a bunch
    // of object methods https://developer.mozilla.org/en-US/docs/Web/API/Element
    // also, you can access the index of the loop

but we can make this one step shorter!
Also if you don't need the index, feel free to omit it
note we already defined const items above
[...items].forEach( item => /* do something */ );

or if you were feeling really wild...
this is potentially less performant, if there's any chance
you'll be running this loop more than once, you'll definitely
want to store the HTMLCollection in memory first, but that's up to you
[...document.getElementsByClassName('item')].forEach(item => /* do something */);

You can achieve a very similar outcome by using the new Array method, from
This will definitely be easier to read for those unfamiliar with the spread syntax
Array.from(items).forEach(item => /* do something */);

So that’s all pretty cool! Turns out there are a bunch of ways to do this now natively within javascript, which negates the need for one of my favourite jQuery methods, the each loop. How did I use this on Beanhere you ask? All over the place. Most notably when attaching event handers, which looks something like this..

[...myButtons].forEach(el => el.addEventListener('click', myFunc));

Easy! There’s an interactive version of these examples over on Codepen, or you can see it in real life action over at Beanhere.


Back to archive