在Javascript中,将NodeList转换为数组的最佳方法是什么

cc *_*ung 71 javascript arrays dom

DOM方法document.querySelectorAll()(以及其他一些方法)返回一个NodeList.

要在列表上操作,例如使用forEach(),NodeList必须先将其转换为Array.

什么是转换的最佳方式NodeList,以一个Array

san*_*rom 59

使用ES6,您可以使用Array.from(myNodeList).然后使用您最喜欢的数组方法.

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 1
Array.from(myNodeList).forEach(function(el) {
  console.log(el);
});
Run Code Online (Sandbox Code Playgroud)

使用ES6垫片也可以在旧版浏览器中使用.


如果您使用的是转换器(例如Babel),还有两种选择:

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 2
for (var el of myNodeList) {
  el.classList.add('active'); // or some other action
}

// ALT 3
[...myNodeList].forEach((el) => {
  console.log(el);
});
Run Code Online (Sandbox Code Playgroud)

  • @ccyoung但是迭代器在不兼容的ES6浏览器中不起作用,因为你不能对符号对象进行填充,因此最好使用`Array.from(myNodeList)`因为它可以被填充. (4认同)

Fre*_*tem 50

使用ES6,您可以简单地执行:

const spanList = [...document.querySelectorAll("span")];
Run Code Online (Sandbox Code Playgroud)

  • 这给了我 `Type 'NodeListOf<Element>' 必须有一个返回 iterator.ts(2488) 的 '[Symbol.iterator]()' 方法` (4认同)
  • 请注意,**您不需要将 nodeList 转换为数组来使用 forEach()** - 请参阅下面的我的答案。 (3认同)

Jos*_*ber 47

您可以使用原型中的slice方法将其转换为数组Array:

var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);
Run Code Online (Sandbox Code Playgroud)

此外,如果你需要的只是forEach,你可以从原型中调用Array,而不是先将它强制转换为数组:

var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
    console.log(el);
});
Run Code Online (Sandbox Code Playgroud)

在ES6中,您可以使用新Array.from函数将其转换为数组:

Array.from(elList).forEach(function(el) {
    console.log(el);
});
Run Code Online (Sandbox Code Playgroud)

目前这仅适用于最前沿的浏览器,但如果您使用的是polyfill服务,则可以全面访问此功能.


如果您使用的是ES6转换程序,您甚至可以使用for..of循环代替:

for (var element of document.querySelectorAll('.some .elements')) {
  // use element here
}
Run Code Online (Sandbox Code Playgroud)

  • @cc young - 注意,我使用`Array.prototype.forEach`而不是`[] .forEach`的原因是因为后者创建了一个新的Array对象,这是完全没必要的. (6认同)

c69*_*c69 21

为何转换?- call直接在元素集合上的Array函数;)

[].forEach.call( $('a'), function( v, i) {
    // do something
});
Run Code Online (Sandbox Code Playgroud)

假设$querySelectorAll的别名,当然


编辑:ES6允许更短的语法[...$('a')](仅适用于Firefox,截至2014年5月)

  • 如果你要使用jQuery,那么更多的succint解决方案是:`$('a').each(function(i,v){...});` (5认同)
  • 你的答案意味着jQuery的用法.如果是这种情况,由于[`.each()`](http://api.jquery.com/each),这个tomfoolery是完全没必要的. (3认同)
  • 哈哈哈,为什么 ?没有什么可以禁止你创建像`function $ ( s ) { return document.querySelectorAll(s); 这样的别名。}`。 (2认同)
  • offtopic:_EcmaScript 5已经是一年的标准了,所有当前的浏览器都支持Arrays的新方法,而且具体问题是在NodeList又名Element Collection上使用这些方法. (2认同)

nfe*_*ner 8

它必须是forEach吗?您可以简单地使用for循环迭代列表:

for (var i = 0; i < elementList.length; i++) {
    doSomethingWith(elementlist.item(i));
}
Run Code Online (Sandbox Code Playgroud)

  • 我个人觉得`forEach()`编程风格更好,更简洁 - ymmv (4认同)
  • +1 用于不添加不必要的数组转换的简单解决方案。仅供参考,您可以使用`elementList[i]`,而不是`elementList.item(i)`。 (2认同)

mik*_*ana 7

要在javascript中对列表进行操作,例如使用forEach(),必须将NodeList转换为Array.

这不一定是真的.您可以将.forEach()从Array添加到NodeList,它可以正常工作:

if ( ! NodeList.prototype.forEach ) {
  NodeList.prototype.forEach = Array.prototype.forEach;
}
Run Code Online (Sandbox Code Playgroud)

你现在可以运行:

myNodeList.forEach(function(node){...})
Run Code Online (Sandbox Code Playgroud)

像Arrays一样迭代NodeLists.

这会产生比.call()更短更干净的代码.

  • @DuBistKomisch这是一个polyfill,仅在标准 NodeList.foreach() 不存在时应用。 (3认同)
  • 啊,我的错,没有意识到他们实际上专门添加了“forEach”,我来这里寻找“filter” (2认同)

小智 5

嗯,这对我也有用:

const elements = Object.values( document.querySelector(your selector here) )
Run Code Online (Sandbox Code Playgroud)

Object.values()返回Array给定对象的值。NodeList是对象,就像 JS 中的一切一样。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

但它与 IE 不兼容,所以我想Array.prototype.*array_method*.call(yourNodeList)这是最好的选择。这样你就可以调用你的任何数组方法NodeList