反转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>
答案 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>