9

First thing's first: this isn't asking to how to turn a NodeList into an Array. This is the opposite.

For consistency's sake, I would like to create a function that returns a NodeList, just like document.querySelectorAll() does.

Here's my current code:

var toNodeList = function(arrayOfNodes){
  var fragment = document.createDocumentFragment();
  arrayOfNodes.forEach(function(item){
    fragment.appendChild(item);
  });
  return fragment.childNodes;
};

However this removes the original elements from the DOM!

How can I make a NodeList in a non-destructive fashion?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • Hi @DominicTobias, I mean the nodes inside arrayOfNodes (generated previously) are being removed from the DOM. – mikemaccana Jul 21 '14 at 16:17
  • 1
    Not sure why you would need a nodeList, but here you go -> **http://jsfiddle.net/dzu2m/** – adeneo Jul 21 '14 at 17:28
  • @adeneo Hrm, adding a temporary class to each element, running querySelectorAll() and then removing the class. It works, but it's obviously a little hacky. – mikemaccana Jul 22 '14 at 08:23
  • You can't really create a nodeList, only native methods can, so the only way to get a nodeList with DOM elements is to select them, and adding something unique to the elements is the easiest way to do that. – adeneo Jul 22 '14 at 08:27
  • @adeneo do you have a citation for that? If so add it as an answer. – mikemaccana Jul 22 '14 at 17:55
  • @adeneo `console.log( isNodeList( toNodeList(arr) ) )` is giving false!! Also, if I add another div with a class of `custom_class` but not in the array, I get that element too, so ... – Angshu31 Mar 07 '20 at 17:31

1 Answers1

5

You would need to clone the node.

var toNodeList = function(arrayOfNodes){
  var fragment = document.createDocumentFragment();
  arrayOfNodes.forEach(function(item){
    fragment.appendChild(item.cloneNode());
  });
  return fragment.childNodes;
};

Note pass true to cloneNode to make a deep clone.

Dominic
  • 62,658
  • 20
  • 139
  • 163
  • 1
    Just just discovered `cloneNode()` at the same time you answered that. Thanks! – mikemaccana Jul 21 '14 at 16:20
  • 1
    Note that this returns clones, so you're no longer working with the elements in the DOM – adeneo Jul 21 '14 at 16:25
  • Ah @adeneo you're right. Since the purpose of this is to have a reference to the original elements to manipulate later, `.cloneNode` won't work. Going to leave this open to see if there's a way I can have a NodeList that has a reference to the original nodes (eg, like what `document.querySelectorAll()` returns). – mikemaccana Jul 21 '14 at 16:34
  • @mikemaccana I was wondering if you wanted that but then what is the purpose of not using `querySelectorAll`? – Dominic Jul 21 '14 at 21:23
  • @dominic I don't wish to return a NodeList with every node in the DOM that matches a selector, just return a NodeList (based on other criteria). – mikemaccana Jul 22 '14 at 08:20
  • @mikemaccana NodeList's are readonly but check this workaround: http://stackoverflow.com/questions/20075234/is-it-possible-to-append-an-element-to-a-javascript-nodelist – Dominic Jul 22 '14 at 08:39
  • 1
    lol @Dominic I forgot to accept this answer 8 years ago. – mikemaccana Nov 16 '22 at 14:59