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?

1
  • 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
    Commented Dec 29, 2010 at 21:24

4 Answers 4

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);
1
  • 1
    You could also use spread operator const array = [...nodes]
    – Buzut
    Commented Jan 29, 2018 at 11:32
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.

1
  • You can't call slice on a nodeList in IE8 :\ Commented Apr 30, 2018 at 19:47
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.

2
  • 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. Commented Dec 29, 2010 at 22:07
  • Good comments but doesn't answer the question
    – zykadelic
    Commented May 14, 2019 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.

2
  • In Chrome it's function, in IE 8 it's object, not undefined. Either way, this was debugging some old code which I have now refactored into a namespace I already had. Commented Dec 29, 2010 at 22:06
  • You must have a newer version of IE8 'cause mine is undefined. Commented Dec 29, 2010 at 22:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.