3

I am only discovering the DOM as a beginner, and now I am a little bit confused.

I have read in one article, that nodeList is just an array-like element - it shows up in console as an array but it is not possible to use array methods (like forEach or map) on it. But when I tried this (in table made with JS, function table()):

let node = document.querySelectorAll('td')

node.forEach(function(node){
  node.style.border = 'thin solid #000';
  node.textContent = 'cell';
console.log(node);
})

It worked as I wanted - as an array.

Apart from it, this code created only empty array, without nodeList inside:

 let node = document.querySelectorAll('td')
 let nodeToArray = Array.apply(node);

 console.log(nodeToArray);

I tried spread operator:

let nodeToArray = [document.querySelectorAll('td')]

And it turned nodeList to array, but only with one number - maybe it's caused by creating td with looping?

And, of course, the forEach method didn't work with "Cannot set property 'border' of undefined."

let nodeToArray = [document.querySelectorAll('td')]
  nodeToArray.forEach(function(nodeToArray){
    nodeToArray.style.border = 'thin solid #000';
    nodeToArray.textContent = 'cell';
console.log(nodeToArray);

So, how am I supposed to change nodeList to array? Or is it possible to work with nodeList more, as it was array? (I want to create chessboard and therefore I need to use this array for if-else conditional statement to make odd/even cells.)

  • 2
    Possible duplicate of [How to convert a DOM node list to an array in Javascript?](https://stackoverflow.com/questions/2735067/how-to-convert-a-dom-node-list-to-an-array-in-javascript) – chrisg86 Jan 08 '19 at 13:36

2 Answers2

4

You need to transform the node in an actual Array object. You can use Array.from to do that:

const nodes = document.querySelectorAll('div')
const nodesArray = Array.from(nodes)
nodesArray.forEach(console.log)

If in doubt, you can use Array.isArray to check if an object is an array:

const nodes = document.querySelectorAll('div')
console.log(Array.isArray(nodes)) // false

const nodesArray = Array.from(nodes)
console.log(Array.isArray(nodesArray)) // true
celicoo
  • 1,100
  • 8
  • 18
  • 1
    Thank you, Array.from() works greatly. I've read about this method and tried, but maybe with another code wrote after it (not systematically, checking step by step) and it didn't work. However now it's without problem. – Nela Jungmannová Jan 08 '19 at 13:51
  • @NelaJungmannová if possible, could you accept my answer as the right one? – celicoo Jan 08 '19 at 17:09
  • 1
    Of course, sorry, I have this privilege just from today so I forgot. btw. for some reason, if newly-created array is declared as parameter of forEach function, it suddenly shows not to be array (this, I think, was the mistake I had with Array.from() originally). – Nela Jungmannová Jan 08 '19 at 17:55
  • `nodeToArray.forEach (function (nodeToArray) { console.log (Array.isArray (nodeToArray))`})` In this case, Array.isArray output is false, although outside forEach function it is true. – Nela Jungmannová Jan 08 '19 at 18:53
  • 1
    The first parameter of a `.forEach` callback is the current iteration item. It will be an array only if it's an array of arrays. Does that make sense? – celicoo Jan 08 '19 at 19:01
  • Hm... as I said, I am still a beginner - so... I am afraid I don't understand. I was trying to find any tutorial or article to explain it to me, but I am still confused. I know that model syntax of forEach() is: `arr.forEach(function callback(currentValue[, index[, array]]) { }[, thisArg]);` And so the `...forEach(function (nodeToArray)...` cannot work, because nodeToArray is not the element of itself. Then it makes sense that I need Array of Arrays (am I right or am I thinking wrongly?) But to be honest, I dont know how to create Arr of Arrs from Array of 64 (number of elements in nodelist). – Nela Jungmannová Jan 09 '19 at 12:06
  • Yes, you are getting it right. Let me ask you something - why do you need an array of arrays in the first place? – celicoo Jan 09 '19 at 12:49
  • To make the `for.Each()` work - I want to divide each cell in table (made in JS, not HTML) to odd and even, and than fill odd cells with black (something like chessboard-like table, I wanted a little more advanced excercise to practise what I learned and find more about how JS really works. Guess I succeed, this nodelist to array of arrays and more is, in my current level and (un)knowledge, quite a challenging. And I thank you gratefully for explaining it to me. – Nela Jungmannová Jan 09 '19 at 13:34
  • Ok, I see where you are trying to get at. Do you think you can share what you have done so far? – celicoo Jan 09 '19 at 18:49
  • Is there any chance to send private message? I don't want to spam comment section. – Nela Jungmannová Jan 11 '19 at 09:02
1

Within my answer I thought that I'd include multiple approaches, a mixture of ES5 and ES6, here's a couple of simple ways in which you can achieve this.

As advised in the MDN docs, if you want to have any support for IE, you'd want to use the first implementation that I've provided, if you're not so worries about supporting older browsers the you can easily use either of the ES6 solutions that I've provided.

Personally I prefer using the destructuring approach, but each to their own.

// ES5
var notArray = document.querySelectorAll("input");
var array = Array.prototype.slice.call(notArray);

// ES6 
const notArray1 = document.querySelectorAll("input");
const array1 = [...notArray1];
const array2 = Array.from(notArray1);

// Tests
console.log(Array.isArray(array));
console.log(Array.isArray(array1));
console.log(Array.isArray(array2));

console.log(Array.isArray(notArray));
console.log(Array.isArray(notArray1));
<input>
<input>
<input>
<input>
<input>
<input>
JO3-W3B-D3V
  • 2,124
  • 11
  • 30