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

时间:2008-09-05 12:05:43

标签: javascript arrays

反转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()方法时它不被视为数组? / p>

6 个答案:

答案 0 :(得分:13)

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

有关详情,请参阅http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177

答案 1 :(得分:8)

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);

答案 2 :(得分:3)

getElementsByTag()返回NodeList而不是Array。您需要将NodeList转换为数组,然后将其反转。

var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();

答案 3 :(得分:2)

我知道这个问题已经过时但我认为需要一些澄清,因为W3C更改了定义,因此这些方法的回复值getElementsByTagName()和{{1} }

这些方法截至撰写此答案的时候会返回一个类型为getElementsByClassName() HTMLCollection的对象 - 空或不 - 。

它类似于返回类型为NodeList的对象的属性children之间的区别,因为它只包含元素并排除了文本或注释节点,并且{{ 1}}返回类型为HTMLCollection的对象,因为它可以包含其他节点类型,如文本和注释。

注意:我在这里继续说切,并表示我对childNodes方法当前返回NodeList而不是querySelectorAll()的原因缺乏洞察力,因为它专门用于元素文档中的节点,没有别的。

可能它与未来其他节点类型的潜在覆盖范围有关,他们寻求更加面向未来的解决方案,谁知道呢? :)

编辑:我认为我得到了这个决定背后的理由,即为NodeList选择HTMLCollection而不是NodeList

由于他们将HTMLCollection构建为完全和完全生活,并且由于此方法不需要此实时功能,因此他们决定实施querySelectorAll(),以便经济有效地实现其目的。

答案 4 :(得分:1)

你的第一行是无关紧要的,因为它没有强制赋值变量,javascript以另一种方式工作。 imagesArr,不是Type Array(),它的类型是getElementsByTagName(“img”)的返回类型。在这种情况下,它是Firefox 3中的HtmlCollection。

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

答案 5 :(得分:0)

这个问题其实可以用数组展开运算符轻松解决。

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>