如何在 Javascript 中将 DOM 节点列表转换为数组?

我有一个 Javascript 函数,它接受一个 HTML 节点列表,但是它需要一个 Javascript 数组(它在这个数组上运行一些 Array 方法) ,我希望将返回 DOM 节点列表的 Document.getElementsByTagName的输出提供给它。

最初我想用一些简单的东西,比如:

Array.prototype.slice.call(list,0)

这在所有浏览器中都能正常工作,当然除了返回错误“ jScript 对象预期”的 Internet Explorer,因为显然由 Document.getElement*方法返回的 DOM 节点列表不是一个足以成为函数调用目标的 jScript 对象。

警告: 我不介意写 Internet Explorer 特定的代码,但是我不被允许使用任何 Javascript 库,比如 jQuery,因为我正在写一个嵌入到第三方网站的插件,而且我不能加载会给客户端带来冲突的外部库。

我最后的努力是迭代 DOM 节点列表并自己创建一个数组,但是有更好的方法来做到这一点吗?

135869 次浏览
var arr = new Array();
var x= ... get your nodes;


for (i=0;i<x.length;i++)
{
if (x.item(i).nodeType==1)
{
arr.push(x.item(i));
}
}

这应该可以工作,跨浏览器,让你所有的“元素”节点。

NodeList 是 一个 href = “ http://jibbering.com/faq/# hostObject”rel = “ norefrer”> host object ,在主机对象上使用 Array.prototype.slice方法不能保证工作,ECMAScript 规范说明:

切片函数是否可以成功地应用于宿主对象取决于实现。

我建议您创建一个简单的函数来遍历 NodeList并添加每个函数 existing element to an array:

function toArray(obj) {
var array = [];
// iterate backwards ensuring that length is an UInt32
for (var i = obj.length >>> 0; i--;) {
array[i] = obj[i];
}
return array;
}

更新:

正如其他答案所表明的那样,你现在可以在现代环境中使用扩展语法或者 Array.from方法:

const array = [ ...nodeList ] // or Array.from(nodeList)

但是仔细想想,我猜最常见的将 NodeList 转换成 Array 的用例是迭代它,现在 NodeList.prototype对象有了 原生 forEach,所以如果你在一个现代环境中,你可以直接使用它,或者使用 pollyfill。

While it is not really a proper shim, since there is no spec requiring working with DOM elements, I've made one to allow you to use slice() in this manner: https://gist.github.com/brettz9/6093105

更新 : 当我向 DOM4规范的编辑提出这个问题时(询问他们是否可以在 ECMAScript 规范允许实现独立性的前提下为主机对象添加自己的限制(这样规范就会要求实现者在使用数组方法时正确地转换这些对象) ,他回答说: “对于 ES6/IDL 来说,主机对象或多或少是过时的。”我看到每个 Element.attributes0规范可以使用这个 IDL 来定义“平台数组对象”,但是 Element.attributes1似乎没有为 HTMLCollection使用这个新的 IDL (尽管它看起来像是为 Element.attributes使用这个 IDL,尽管它只是明确地声明它使用 WebIDL 来定义 DOMString 和 DOMTimeStamp)。我确实看到 [ArrayClass](它继承自 Array.model)被用于 NodeList(而且 NamedNodeMap现在已经被废弃了,取而代之的是唯一仍在使用它的项目,Element.attributes)。无论如何,它看起来将成为标准。ES6 Array.from对于这样的转换可能比必须指定 Array.prototype.slice更方便,在语义上也比 [].slice()更清晰(而且据我所知,短格式 Array.slice()(一种“数组通用”)还没有成为标准行为)。

使用 传播(ES2015),就像使用 [...document.querySelectorAll('p')]一样简单

(可选: 使用 巴别塔将上述 ES6代码转换为 ES5语法)


在浏览器的控制台中尝试一下,你就会发现其中的神奇之处:

for( links of [...document.links] )
console.log(links);

Use this simple trick

<Your array> = [].map.call(<Your dom array>, function(el) {
return el;
})

第六季中,你可以这样使用:

  • 接线员

     var elements = [... nodelist]
    
  • Using Array.from

     var elements = Array.from(nodelist)
    

more reference at https://developer.mozilla.org/en-US/docs/Web/API/NodeList

今天,在2018年,我们可以使用 ECMAScript 2015(第6版)或 ES6,但不是所有的浏览器都能理解它(例如。IE 并不完全理解它)。如果你愿意,你可以使用 ES6如下: var array = [... NodeList];(Ref = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/)或 var array = Array.from(NodeList);

在其他情况下(如果你不能使用 ES6) ,你可以使用最短的方法将一个 NodeList转换成一个 Array:

var array = [].slice.call(NodeList, 0);.

例如:

var nodeList = document.querySelectorAll('input');
//we use "{}.toString.call(Object).slice(8, -1)" to find the class name of object
console.log({}.toString.call(nodeList).slice(8, -1)); //NodeList


var array = [].slice.call(nodeList, 0);
console.log({}.toString.call(array).slice(8, -1)); //Array


var result = array.filter(function(item){return item.value.length > 5});


for(var i in result)
console.log(result[i].value); //credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

但是,如果只想轻松地遍历 DOM节点列表,则不需要将 NodeList转换为 Array。可以使用以下方法循环遍历 NodeList中的项:

var nodeList = document.querySelectorAll('input');
// Calling nodeList.item(i) isn't necessary in JavaScript
for(var i = 0; i < nodeList.length; i++)
console.log(nodeList[i].value); //trust, credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

不要试图使用 < a href = “ https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statments/for.in”rel = “ noReferrer”> for...in 翻译: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校来枚举列表中的项,因为这也会枚举 NodeList的长度和项属性,并且如果脚本假设它只需要处理元素对象,就会导致错误。而且,不能保证 for..in以任何特定的顺序访问属性。< a href = “ https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statments/for.of”rel = “ noReferrer”> for...of 循环将正确地遍历 NodeList 对象。

参见: