有人能告诉我NodeList是什么类型的对象吗?我读到它是一个类似数组的对象,可以通过方括号表示法访问,例如var a = someNode.childNode[0];
。既然我们只能通过方括号表示法来访问对象的属性,而且我们不能有独立的索引属性,那么这怎么可能呢?
有人能告诉我NodeList是什么类型的对象吗?我读到它是一个类似数组的对象,可以通过方括号表示法访问,例如var a = someNode.childNode[0];
。既然我们只能通过方括号表示法来访问对象的属性,而且我们不能有独立的索引属性,那么这怎么可能呢?
NodeList
是一组 DOM 元素
的集合。它类似于数组(但并非如此)。要使用它,必须将其转换为常规的 JavaScript 数组。下面的代码片段可以为您完成此任务。
const nodeList = document.getElementsByClassName('.yourClass'),
nodeArray = [].slice.call(nodeList);
更新:
// newer syntax
const nodeList = Array.from(document.querySelectorAll('[selector]'))
// or
const nodeList = [...document.querySelectorAll('[selector]')]
NodeList
是一个宿主对象,不受适用于本地 JavaScript 对象的通常规则的约束。因此,您应该遵循其文档化的 API,该 API 由 length
属性和通过方括号属性访问语法访问其成员的方式组成。您可以使用此 API 创建一个包含 NodeList 成员快照的 Array
:
var nodeList = document.getElementsByTagName("div");
var nodeArray = [];
for (var i = 0; i < nodeList.length; ++i) {
nodeArray[i] = nodeList[i];
}
forEach
可以用于类型为 Array
的对象,但是不能用于 bilbo.getElementsByTagName("taggins")
。 - Ian CampbellNodeList不是JavaScript的核心对象,它是由浏览器提供的DOM。可以将其视为返回动态或实时对象接口的函数,因此forEach()方法不可用,但可以将其转换为真实数组以获得快照,例如:
// turns nodelist into an array to enable forEach
function toArray(list) {
var i, array = [];
for (i=0; i<list.length;i++) {array[i] = list[i];}
return array;
}
细节:http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-536297177
无论何时您想迭代,最好初始化第二个变量并将迭代器与该变量进行比较:
var divs = document.getElementsByTagName("div");
for (var i=0, lens=divs.length; i < len; i++){
var div = document.createElement("div");
document.body.appendChild(div);
}
NodeList是类似于数组的结构,但它实际上并不是一个数组。您可以通过方括号表示法访问数组值。
JavaScript就像酒精一样,它可以强制执行:
var links = document.getElementsByTagName('a');
Array.prototype.slice.call(links).forEach(function(anchor, index, arr) {
anchor.addEventListener('click', onClickFN, false);
});
Array.prototype.forEach.call(links, function() {})
;) - yckart[].slice.call
- Mahi现在在ES2015中,您可以使用Array.from
方法从任何类似于数组的对象创建一个数组实例,因此这应该能够正常工作:
const divList = Array.from( document.getElementsByTagName("div") );
var paragraphs = document.getElementsByTagName('p');
for (var i = 0; i < paragraphs.length; i++) {
doSomething(paragraphs[i]);
}
最好这样做:
var paragraphs = document.getElementsByTagName('p');
for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
doSomething(paragraph);
}
var parentNode = document.getElementById('foo');
for (var child = parentNode.firstChild; child; child = child.nextSibling) {
doSomething(child);
}
undefined
, null
, 0
等) 值都会... - yckartNodeList
对象是表示节点集合的数据结构。在DOM上下文中,节点可以是以下内容:
NodeList
不是数组,但NodeList
是可迭代的数据结构,这意味着我们可以使用for..of
循环遍历其值(即节点项)。此外,在NodeList
的原型上有一些不错的实用函数,使得与它们一起工作更加方便。
const parent = document.querySelector('.parent');
const myNodeList1 = parent.childNodes; // this property is a Nodelist
console.log(myNodeList1 instanceof NodeList);
const myNodeList2 = document.querySelectorAll('.foo'); // this method returns a Nodelist
console.log(myNodeList2 instanceof NodeList);
// looping over the items of a nodelist
for (let el of myNodeList2) {
el.innerHTML = 'hi';
}
// getting the length of a nodeList
console.log(myNodeList2.length);
<div class="parent">
<div class="foo"></div>
<div class="foo"></div>
</div>
Nodelist
的外观:
NodeList
的元素: myNodelist[0]; // grabs the first item of the NodeList
[].forEach.call
的范式批判在这里 - https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/ - 提供了更好的上下文。为了展示它并不像解释的那样工作,尝试运行[1, 2, 3].slice.call(nodeList)
并注意你会得到相同的结果。尝试玩弄原始数组中的条目数量,你仍然会得到相同的结果。 - romellemArray.from(nodeList).map(n => n.textContent)
这个一行代码就能搞定的例子非常优美。 - brielovArray.from(nodeList)
或[...nodeList]
都是很好的工具。然而,如果你发现自己写了[...nodeList].forEach()
,那么你可能只需遍历普通的NodeList,而不是将其展开成一个数组。如果你担心浏览器支持问题,有一个非常简单的Polyfill -if (window.NodeList && !NodeList.prototype.forEach) NodeList.prototype.forEach = Array.prototype.forEach
- romellem