views:

1528

answers:

4

What would be the problem with reversing the array of DOM objects got from a command like:

var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();

When i call the reverse() method, the script stops executing with the error 'imagesArr.reverse is not a function' in Firefox 3 (can be seen in the Error console of the Web developer toolbar).

Why the variable 'imagesArr' isn't seen as an array when calling the reverse() method, but at the same time can be iterated through with a for loop and elements can be accessed like imagesArr[i]?

+1  A: 

Your first line is irrelevant, since it doesn't coerce the assignment to the variable, javascript works the other way. imagesArr, is not of Type Array(), its of whatever the return type of getElementsByTagName("img") is. In this case, its an HtmlCollection in Firefox 3.

The only methods on this object, are the indexers, and length. In order to work in reverse, just iterate backwards.

DevelopingChris
+6  A: 

Because getElementsByTag name actually returns a NodeList structure. It has similar array like indexing properties for syntactic convenience, but it is not an array. For example, the set of entries is actually constantly being dynamically updated - if you add a new img tag under myDivHolderId, it will automatically appear in imagesArr.

See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 for more.

Adam Wright
A: 

@ChanChan - thanks for the advice, i did the backwards iteration, but i wanted to know what was originally the issue. as you and adam explained, it's not an array but a NodeList.

Thank you both for the explanation.

zappan
+1  A: 

getElementsByTag() returns a NodeList instead of an Array. You can convert a NodeList to an Array but note that the array will be another object, so reversing it will not affect the DOM nodes position.

var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img");
var arrayNodes = Array.slice.call(listNodes, 0);
arrayNodes.reverse();

In order to change the position, you will have to remove the DOM nodes and add them all again at the right position.

Array.prototype.slice.call(arrayLike, 0) is a great way to convert an array-like to an array, but if you are using a JavaScript library, it may actually provide a even better/faster way to do it. For example, jQuery has $.makeArray(arrayLike).

You can also use the Array methods directly on the NodeList:

Array.prototype.reverse.call(listNodes);
Vincent Robert