Reputation: 3685
What could be the problem with reversing the array of DOM objects as in the following code:
var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();
In Firefox 3, when I call the reverse()
method the script stops executing and shows the following error in the console of the Web Developer Toolbar:
imagesArr.reverse is not a function
The imagesArr
variable can be iterated through with a for loop and elements like imagesArr[i]
can be accessed, so why is it not seen as an array when calling the reverse()
method?
Upvotes: 25
Views: 22276
Reputation: 1453
I think this simpler example ;)
let arr = Array
.from(
document.querySelectorAll('your-target')
)
.reverse()
;
Upvotes: 0
Reputation: 61
This worked for me, I did a reverse for loop and allocated the nodes to an array
var Slides = document.getElementById("slideshow").querySelectorAll('li');
var TempArr = [];
for (var x = Slides.length; x--;) {
TempArr.push(Slides[x]);
}
Slides = TempArr;
Upvotes: 1
Reputation: 113
this problem can Actually be solved easily with array spread operator.
let elements = document.querySelectorAll('button');
elements = [...elements];
console.log(elements) // Before reverse
elements = elements.reverse(); // Now the reverse function will work
console.log(elements) // After reverse
<html>
<body>
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
</body>
</html>
Upvotes: 11
Reputation: 274
I know this question is old but I think it needs a bit of clarification as some of the answers here are outdated as W3C changed the definition, and consequently the return value of these methods getElementsByTagName()
and getElementsByClassName()
These methods as of the time of writing this answer return an object - empty or not - of type HTMLCollection
and not NodeList
.
It's like the difference between the properties children
which returns an object of type HTMLCollection
since it's only composed of elements and excluding text or comment nodes, and childNodes
which returns an object of type NodeList
since it could contain other node types like text and comments as well.
Note: I'd go on tangent here and express my lack of insight on why querySelectorAll()
method currently returns a NodeList
and not an HTMLCollection
since it exclusively works on element nodes in the document and nothing else.
Probably it has something to do with potential coverage of other node types in the future and they went for a more future proof solution, who knows really? :)
EDIT: I think I got the rationale behind this decision to opt for a NodeList
and not an HTMLCollection
for the querySelectorAll()
.
Since they constructed HTMLCollection
to be exclusively and entirely live and since this method doesn't need this live functionality, they decided for a NodeList
implementation instead to best serve its purpose economically and efficiently.
Upvotes: 4
Reputation: 603
getElementsByTag()
returns a NodeList instead of an Array. You need to convert the NodeList to an array then reverse it.
var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();
Upvotes: 5
Reputation: 36140
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);
Upvotes: 10
Reputation: 40798
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.
Upvotes: 1
Reputation: 49386
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.
Upvotes: 18