9

I'm having a hard time converting a NodeList to an array in IE 8. The following works perfectly in Chrome, but in IE 8 toArray() is not recognized as valid:

NodeList.prototype.toArray = function() {
    var a = [];

    for (var i = 0, len = this.length; i < len; i++) {
        a[i] = this[i];
    }

    return a;
}

document.all.tags("div").toArray();

I tried adding a prototype function to an array just to check my sanity and it works correctly. That makes me think IE 8 doesn't actually return a NodeList? Here's a full example:

http://jsfiddle.net/e4RbH/

What am I doing wrong?

Nelson Rothermel
  • 9,436
  • 8
  • 62
  • 81
  • 1
    There is no current standard that says that `NodeList` has to be a visible and alterable constructor function, or that if there is a constructor function visible as `NodeList` that it will be used as the return type of all NodeList-returning methods. (After all, a `childNodes` NodeList and a `getElementsByTagName` NodeList do very different things.) Prototyping onto the native JS objects is specified by the ECMAScript standard and is reliable; prototyping onto DOM Nodes and other objects not defined by the language standard is unreliable and should be avoided. – bobince Dec 29 '10 at 21:24

4 Answers4

11

If you're looking for a modern answer using ES6:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

var nodes = document.querySelectorAll('div');
nodes = Array.from(nodes);
Justin Noel
  • 5,945
  • 10
  • 44
  • 59
5

Old question, but here is a tried & true method:

var nodes=document.querySelectorAll("div"); //  returns a node list
nodes=Array.prototype.slice.call(nodes);    //  copies to an array

Explanation

  • document.querySelectorAll uses a CSS-style selector to find elements and returns a node list. It works as of IE 8.
  • The slice method copies a portion of an array-like collection (in this case all of it) into a new array.
  • call allows you to borrow a method from one object to use on another

To find the node list you could also have used `document.getElementsByTagName(), but this one is more flexible.

Manngo
  • 14,066
  • 10
  • 88
  • 110
3

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.

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
casablanca
  • 69,683
  • 7
  • 133
  • 150
  • I was using `getElementByTagName`, but switched to `document.all` during testing. This was part of a bigger problem and I tried to simplify it down. The real problem ended up being an extension method to `Array` which was improperly implemented and affected other code. – Nelson Rothermel Dec 29 '10 at 22:07
  • Good comments but doesn't answer the question – zykadelic May 14 '19 at 20:59
1

IE doesn't support NodeList in the standard way. This is why you should roll your own namespace and NOT extend browser core objects.

You can do alert( typeof window.NodeList ) and see if it's undefined or not.

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434