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

zap*_*pan 10 javascript arrays

反转DOM对象数组可能会出现问题,如下面的代码所示:

var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();
Run Code Online (Sandbox Code Playgroud)

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

imagesArr.reverse is not a function
Run Code Online (Sandbox Code Playgroud)

所述imagesArr变量可以通过与一个for循环和元件等被迭代imagesArr[i]可以被访问,那么,为什么不调用时视为一个阵列reverse()的方法?

Ada*_*ght 14

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

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


Muh*_*him 10

这个问题实际上可以通过数组扩展运算符轻松解决。

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
Run Code Online (Sandbox Code Playgroud)
<html>
<body>
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)


Vin*_*ert 9

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

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

要更改位置,您必须删除DOM节点并在正确的位置再次添加它们.

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

您也可以直接在NodeList上使用Array方法:

Array.prototype.reverse.call(listNodes);
Run Code Online (Sandbox Code Playgroud)

  • 不,你不能直接在`NodeList`上调用该方法,因为它的索引是不可写的.它应该抛出一个错误. (3认同)
  • ES6:`arrayNodes = Array.from(listNodes)` (2认同)

小智 5

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

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