Fastest way to convert JavaScript NodeList to Array?
2021 update: nodeList.forEach() is now standard and supported in all current browsers (around 95% on both desktop & mobile).
So you can simply do:
document.querySelectorAll('img').forEach(highlight);
Other cases
If you for some reason want to convert it to an array, not just iterate over it - which is a completely relevant use-case - you can use [...destructuring]
or Array.from
since ES6
let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);
This also works for other array-like structures that aren't NodeLists
HTMLCollection
returned by e.g.document.getElementsByTagName
- objects with a length property and indexed elements
- iterable objects (objects such as
Map
andSet
)
Outdated 2010 Answer
The second one tends to be faster in some browsers, but the main point is that you have to use it because the first one is just not cross-browser. Even though The Times They Are a-Changin'
@kangax (IE 9 preview)
Array.prototype.slice can now convert
certain host objects (e.g. NodeList’s)
to arrays — something that majority of
modern browsers have been able to do
for quite a while.
Example:
Array.prototype.slice.call(document.childNodes);
In JavaScript, what is the best way to convert a NodeList to an array?
With ES6 you can simply do:
const spanList = [...document.querySelectorAll("span")];
Convert NodeList to array
First, don't use document.all
-- it's non-standard and deprecated. Use document.getElementsByTagName
to get the DIV elements in your case.
Second, don't extend DOM objects such as NodeList
-- built-in objects are a very strange breed and are not required to behave like any other objects that you generally work with. See this article for an in-depth explanation of this: What's wrong with extending the DOM.
How to convert a DOM node list to an array in Javascript?
NodeLists are host objects, using the Array.prototype.slice
method on host objects is not guaranteed to work, the ECMAScript Specification states:
Whether the slice function can be applied successfully to a host object is implementation-dependent.
I would recommend you to make a simple function to iterate over the NodeList
and add each
existing element to an array:
function toArray(obj) {
var array = [];
// iterate backwards ensuring that length is an UInt32
for (var i = obj.length >>> 0; i--;) {
array[i] = obj[i];
}
return array;
}
UPDATE:
As other answers suggest, you can now can use in modern environments the spread syntax or the Array.from
method:
const array = [ ...nodeList ] // or Array.from(nodeList)
But thinking about it, I guess the most common use case to convert a NodeList to an Array is to iterate over it, and now the NodeList.prototype
object has the forEach
method natively, so if you are on a modern environment you can use it directly, or have a pollyfill.
Convert NodeList to Array for a Stepper to work with IE
I would just iterate though the the nodeList with something like a for loop and add the nodelist item to the array . Something like this:
let bulletsArray = [];
let bullets = document.querySelectorAll('bullets');
for(let i = 0; i < bullets.length; i++) {
bulletsArray.push(bullets[i])
}
Heres a working demo: https://codepen.io/inklingboi/pen/BapmdBw?editors=1010
Note: my initial idea was to use Array.from() but after checking its compatibility list on mdn https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from i noticed that it isnt supported in IE
JavaScript: Node List to Array Conversion
Use querySelectorAll
and select all elements under class captn
with an id
beginning with caption
, then convert the node list to array usingArray.from
and lastly map
through the array, returning a new array containing only the textContent
var captions = Array.from( document.querySelectorAll('.captn [id^="caption"]'));
var captionsText = captions.map(function(caption) { return caption.textContent;});
document.write(captionsText);
<div> <ul id="caption" class="captn"> <li id="caption0">caption 0</li> <li id="caption1">caption 1</li> <li id="caption2">caption 2</li> <li id="caption3">caption 3</li> <li id="caption4">caption 4</li> <li id="caption5">caption 5</li> </ul></div>
How could I convert from NodeList to Array and work with this Array in others class?
I've tried creating my own method but ufortunatelly I couldnt fix it on this way.
Finally what I did is create an ArrayList and inlcude the NodeValue of each item in the Array. Then, now I have an Arraylist with all items from my QueryXML ready to use.
Final code:
ArrayList<String> IPtable=new ArrayList<String>();
QueryXML getNodes = new QueryXML(Queries);
NodeList IPs = getNodes.query();
for (int n=0; n<IPs.getLength();n++){
String ip =IPs.item(n).getNodeValue();
IPtable.add(ip);
}
ArrayList<String> IPSubnet=new ArrayList<String>();
QueryXML getSubnets = new QueryXML(Queries1);
NodeList subnets = getSubnets.query();
for (int s=0; s<subnets.getLength();s++){
String subnet =subnets.item(s).getNodeValue();
IPSubnet.add(subnet);
}
I'm not sure that It's the right way, but at less it works properlly and fast. I hope it'll useful for somebody else.
JavaScript DOM - Using NodeLists and Converting to an Array
You can iterate all the <li>
items in each <ul>
in the page like this while able to separately tell which <ul>
they are in:
var list = document.getElementsByTagName("ul");
for (var i = 0; i < list.length; i++) {
var items = list[i].getElementsByTagName("li");
for (var j = 0; j < items.length; j++) {
console.log(items[j]);
}
}
Or, if you just want all <li>
tags, not broken out by <ul>
:
var items = document.getElementsByTagName("li");
for (var i = 0; i < items.length; i++) {
console.log(items[i]);
}
A nodeList or HTMLCollection can be iterated with a simple for
loop as seen above. These objects do not have array methods, but can be copied into an array if you really want to use array methods.
Note, it is probably simpler to use document.querySelectorAll()
for listing all the <li>
elements and you may want to target a specific <ul>
tag by putting an id on it in case there are other <ul>
and <li>
elements in the page.
<ul id="buglist">
<li>Horse Flies</li>
<li>Bed bugs</li>
<li>Mosquito</li>
<li>Ants</li>
<li>Mites</li>
<li>Cricket</li>
<li>Woolly Bear Caterpillar</li>
<li>Fleas</li>
<li>Worms</li>
<li>Leeches</li>
</ul>
var items = document.querySelectorAll("#buglist li");
for (var j = 0; j < items.length; j++) {
console.log(items[j]);
}
A nodeList or HTMLCollection can be copied into an array like this:
var list = Array.prototype.slice.call(document.querySelectorAll("#buglist li"), 0);
list.forEach(function(item) {
console.log(item);
});
Error in Changing from nodeList to Array in forEach method
todoList.childNodes
will also include non-element nodes like text and comment. These non-element nodes do not have a style
property, and when you will try to manipulate these by doing todo.style.display
, it will rightfully throw this error
Cannot set property 'display' of undefined
To get a collection of only the element nodes, use todoList.children
instead.
(Also, there is no issue in the nodeList to an Array conversion. It is fine)
Related Topics
JavaScript Onclick Event Over Flash Object
Add/Delete Table Rows Dynamically Using JavaScript
Check a Radio Button with JavaScript
Keycode on Android Is Always 229
\U200B (Zero Width Space) Characters in My Js Code. Where Did They Come From
How to Remove Tinymce and Then Re-Add It
How to Get a HTML Element from a String with Jquery
How to Do a Horizontal Scroll on Mouse Wheel Scroll
How to Access the Contents of an Svg File in an <Img> Element
Drop-Down Box Dependent on the Option Selected in Another Drop-Down Box
How to Access Shadow Dom Elements Through the Parent Document
How to Get the HTML for a Dom Element in JavaScript
Get Value of Input Field Inside an Iframe
Getting Bootstrap's Modal Content from Another Page
How to Maintain a Websockets Connection Between Pages