Let's talk about NodeLists, the magical results of a querySelectorAll()
query.
It's not an array, but it looks and behaves like one.
It can be tricky looping over these elements, and there are multiple ways of looping them.
How the selector looks like:
const items = document.querySelectorAll('li');
console.log(items);
The result:
1. Basic for loop
This is by far the best supported method, if support as many browsers as possible this is the way to go.
for (let i = 0; i < items.length; i++) {
items[i].addEventListener('click', function() {
console.log(`Text = ${items[i].innerText}`);
});
}
It's just not the most modern or visible appealing method.
2. for...of loop
We can also use the for...of
loop.
for (const item of items) {
item.addEventListener('click', () => {
console.log(`2: Text = ${item.innerText}`);
});
}
This is supported by all modern browsers and work pretty well.
3. forEach loop
My all-time favourite too loop NodeList elements is the forEach loop.
It's the most easy method, but will only work in modern browsers.
items.forEach(item => {
item.addEventListener('click', () => {
console.log(`3: Text = ${item.innerText}`);
});
});
This method can be extended by converting it to an array before.
[].forEach.call(items, function(item) {
item.addEventListener('click', function() {
console.log(`3.1: Text = ${item.innerText}`);
});
});
Or, we can use the spread operator to convert it into an array:
[...items].forEach(item => {
item.addEventListener('click', () => {
console.log(`3.2: Text = ${item.innerText}`);
});
});
There you go, three ways (+ iterations) on how to loop over nodeList elements.
You can also have a play around with this Codepen.
Thank you for reading, and let's connect!
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter
Top comments (14)
Thanks for the post!
I would note that while forEach is versatile and easy on the eyes, the other loops have the advantage of allowing an early break/continue/exit.
forEach loops will iterate over every single element even if you've done what you need to, so if you want to do something greedily (like find the first node that matches some condition), you're better off using a traditional for loop.
Aside from that I also tend to lean towards forEach!
Ah yes, would it not stop if you would in that case put a return inside the forEach?
Not according to this code I just threw into my browser console:
The above logs 0, 1, 2, undefined, 4. Also the MDN docs state in a big yellow warning box "There is no way to stop a forEach() loop other than by throwing an exception": developer.mozilla.org/en-US/docs/W...
They also recommend using for...of or for...in if breaking out early is desired :) 🙇
Ah good to know indeed!
In most cases, I always want to attach listeners to all, but indeed strong argument!
Good list of the options!
Instead of
[].forEach
, I believe the recommended "support old browsers" variant is:Ah yes if you need to fully support every single browser indeed.
I gave up on IE support, so didn't even include this, but you are right!
I use death-to-ie11.com/ often; and charge customers/clients 2x if they want IE support!
So I'm with you :D
Nice! Good tip on charging double haha
I recommend it!
Don't bin IE because you (and I) hate it, but giving that it will take you about twice as long, charge double!
100% working for companies who serve big old-school companies you have to.
They often use IE because of their 90's it setup.
Thank you for sharing! 😊
You are most welcome, hope it helps.
I for one "always" need to research the best way to loop them.
🙋♂️ big fan of the spread operator
100% Super easy to use.