DOM对象的Javascript集合-为什么我不能使用Array.reverse()进行反转?

时间:2020-03-05 18:48:09  来源:igfitidea点击:

如下面的代码所示,反转DOM对象数组可能是什么问题:

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

在Firefox 3中,当我调用reverse()方法时,脚本停止执行,并在Web Developer Toolbar的控制台中显示以下错误:

imagesArr.reverse is not a function

可以使用for循环迭代imagesArr变量,并且可以访问诸如imagesArr [i]之类的元素,那么为什么在调用reverse()方法时不将其视为数组?

解决方案

回答

第一行是无关紧要的,因为它不会强制分配给该变量,因此javascript可以采用另一种方式。 imagesArr的类型不是Array(),无论getElementsByTagName(" img")的返回类型是什么。在这种情况下,它是Firefox 3中的HtmlCollection。

此对象上唯一的方法是索引器和长度。为了反向工作,只需向后迭代。

回答

因为getElementsByTag名称实际上返回NodeList结构。为了语法上的方便,它具有类似于索引属性的数组,但它不是数组。例如,如果在myDivHolderId下添加新的img标记,则该条目集实际上会不断地动态更新,它将自动出现在imagesArr中。

有关更多信息,请参见http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177.

回答

getElementsByTag()返回一个NodeList而不是一个Array。我们可以将NodeList转换为Array,但请注意,该数组将是另一个对象,因此反转它不会影响DOM节点的位置。

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

为了更改位置,我们将必须删除DOM节点,然后将它们全部重新添加到正确的位置。

Array.prototype.slice.call(arrayLike,0)是一种将类似数组的数组转换为数组的好方法,但是如果我们使用的是JavaScript库,它实际上可能会提供一种更好/更快的方法。例如,jQuery具有$ .makeArray(arrayLike)

我们还可以直接在NodeList上使用Array方法:

Array.prototype.reverse.call(listNodes);