In JavaScript, what is the best way to convert a NodeList to an array?
JavascriptArraysDomJavascript Problem Overview
The DOM method document.querySelectorAll()
(and a few others) return a NodeList
.
To operate on the list, e.g. using forEach()
, the NodeList
must first be converted to an Array
.
What's the best way to convert the NodeList
to an Array
?
Javascript Solutions
Solution 1 - Javascript
With ES6 you can simply do:
const spanList = [...document.querySelectorAll("span")];
Solution 2 - Javascript
With ES6 you can use Array.from(myNodeList)
. Then use your favourite array method.
var myNodeList = document.querySelectorAll('.my-selector');
// ALT 1
Array.from(myNodeList).forEach(function(el) {
console.log(el);
});
Use an ES6 shim to make this work in older browsers too.
If you are using a transpiler (for example Babel) there are two more alternatives:
var myNodeList = document.querySelectorAll('.my-selector');
// ALT 2
for (var el of myNodeList) {
el.classList.add('active'); // or some other action
}
// ALT 3
[...myNodeList].forEach((el) => {
console.log(el);
});
Solution 3 - Javascript
You can convert it to an array by using the slice
method from the Array
prototype:
var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);
Furthermore, if all you need is forEach
, you can invoke that from the Array
prototype, without coercing it to an array first:
var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
console.log(el);
});
In ES6, you can use the new Array.from
function to convert it to an array:
Array.from(elList).forEach(function(el) {
console.log(el);
});
This is currently only in bleeding edge browsers, but if you're using a polyfill service you will have access to this function across the board.
If you're using an ES6 transpiler, you can even use a for..of
loop instead:
for (var element of document.querySelectorAll('.some .elements')) {
// use element here
}
Solution 4 - Javascript
Why convert? - just call
function of Array directly on element collection ;)
[].forEach.call( $('a'), function( v, i) {
// do something
});
assuming $ is your alias for querySelectorAll, of course
edit: ES6 allows for even shorter syntax [...$('a')]
(works in Firefox only, as of May 2014)
Solution 5 - Javascript
nodeList.forEach() is now an official standard and supported in all current browsers.
2020 update:Older browsers can use the polyfill below.
> To operate on the list in javascript, e.g. using forEach(), the NodeList must be converted to an Array.
That's not true. .forEach()
works in current browsers. If it's missing, you can use a polyfill to add .forEach() from Array to NodeList and it works fine:
if ( ! NodeList.prototype.forEach ) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
You can now run:
myNodeList.forEach(function(node){...})
To iterate over NodeLists just like Arrays.
This produces much shorter and cleaner code than .call() everywhere.
Solution 6 - Javascript
Does it have to be forEach
? You could simply use a for
loop to iterate over the list:
for (var i = 0; i < elementList.length; i++) {
doSomethingWith(elementlist.item(i));
}
Solution 7 - Javascript
Well, this works for me too:
const elements = Object.values( document.querySelector(your selector here) )
Object.values()
returns Array
of values of given object. NodeList
is object, as is everything in JS.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
But it's not compatible with IE, so i guess Array.prototype.*array_method*.call(yourNodeList)
is the best option. With this you can invoke any array method on your NodeList
Solution 8 - Javascript
ES6 allows cool ways like var nodeArray = Array.from(nodeList)
but my favorite one is the new spread operator.
var nodeArray = Array(...nodeList);
Solution 9 - Javascript
That worked with me in ES6
lets assume you have nodelist like that
<ul>
<li data-time="5:17">Flexbox video</li>
<li data-time="8:22">Flexbox video</li>
<li data-time="3:24">Redux video</li>
<li data-time="5:17">Flexbox video</li>
<li data-time="7:17">Flexbox video</li>
<li data-time="4:17">Flexbox video</li>
<li data-time="2:17">Redux video</li>
<li data-time="7:17">Flexbox video</li>
<li data-time="9:54">Flexbox video</li>
<li data-time="5:53">Flexbox video</li>
<li data-time="7:32">Flexbox video</li>
<li data-time="2:47">Redux video</li>
<li data-time="9:17">Flexbox video</li>
</ul>
const items = Array.from(document.querySelectorAll('[data-time]'));
console.log(items);
Solution 10 - Javascript
I use the following because I think it's easiest to read:
const elements = document.getElementsByClassName('element');
[...elements].forEach((element) => {
// code
});
Solution 11 - Javascript
Assuming elems is a nodeList:
var elems = document.querySelectorAll('select option:checked');
then it can be turned into an array as follows:
var values = [].map.call(elems, function(obj) {
return obj.value;
});
Solution 12 - Javascript
TypeScript version:
const allDayElements: Element[] = [].slice.call(document.querySelectorAll('span'));