以前回答的问题说这是最快的方式:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
Run Code Online (Sandbox Code Playgroud)
在我的浏览器基准测试中,我发现它比这慢3倍:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
Run Code Online (Sandbox Code Playgroud)
它们都产生相同的输出,但我发现很难相信我的第二个版本是最快的方式,特别是因为人们在这里说了不同的.
这是我浏览器中的怪癖(Chromium 6)吗?或者有更快的方法吗?
编辑:对于任何关心的人,我选择了以下内容(这似乎是我测试的每个浏览器中最快的):
//nl is a NodeList
var l = []; // Will hold the array of Node's
for(var i = 0, ll = nl.length; i != ll; l.push(nl[i++]));
Run Code Online (Sandbox Code Playgroud)
EDIT2:我发现了一种更快的方法
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
Run Code Online (Sandbox Code Playgroud) 我正在查看一些代码片段,我发现多个元素在一个节点列表上调用一个函数,并将forEach应用于一个空数组.
例如,我有类似的东西:
[].forEach.call( document.querySelectorAll('a'), function(el) {
// whatever with the current node
});
Run Code Online (Sandbox Code Playgroud)
但我无法理解它是如何工作的.任何人都可以解释我在forEach前面的空数组的行为以及它是如何call工作的?
从MDN for NodeList:
在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中.例如,Node.childNodes是实时的:
Run Code Online (Sandbox Code Playgroud)var parent = document.getElementById('parent'); var child_nodes = parent.childNodes; console.log(child_nodes.length); // let's assume "2" parent.appendChild(document.createElement('div')); console.log(child_nodes.length); // should output "3"在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容.document.querySelectorAll返回一个静态NodeList.
所以....有点烦人!对于哪些方法返回实时列表以及哪些方法返回静态列表,是否有任何中心引用,而无需单独检查DOM API的所有各个部分?这里有什么规则吗?
在ES6中过滤或映射节点列表的最有效方法是什么?
根据我的读数,我会使用以下选项之一:
[...nodelist].filter
Run Code Online (Sandbox Code Playgroud)
要么
Array.from(nodelist).filter
Run Code Online (Sandbox Code Playgroud)
你会推荐哪一个?有没有更好的方法,例如没有涉及数组?
任何人都可以告诉我NodeList是什么类型的对象.我读到它是一个类似于数组的对象,例如,它可以通过括号表示法访问var a = someNode.childNode[0];.这怎么可能,因为通过括号表示我们只能访问对象的属性,而且我知道我们不能拥有
注意:在假设此问题重复之前,此问题底部有一个部分解决了为什么一些类似的问题无法提供我正在寻找的答案.
我们都知道将NodeList转换为数组很容易,有很多方法可以做到:
[].slice.call(someNodeList)
// or
Array.from(someNodeList)
// etc...
Run Code Online (Sandbox Code Playgroud)
我所追求的是相反的; 如何将节点数组转换为静态NodeList?
在没有深入研究的情况下,我正在创建一种新方法来查询页面上的元素,即:
Document.prototype.customQueryMethod = function (...args) {...}
Run Code Online (Sandbox Code Playgroud)
为了坚持如何querySelectorAll工作,我想要返回静态集合NodeList而不是数组.
到目前为止,我已经以三种不同的方式解决了这个问题:
function createNodeList(arrayOfNodes) {
let fragment = document.createDocumentFragment();
arrayOfNodes.forEach((node) => {
fragment.appendChild(node);
});
return fragment.childNodes;
}
Run Code Online (Sandbox Code Playgroud)
虽然这确实返回了NodeList,但这不起作用,因为调用appendChild会从DOM中的当前位置(它应该保留的位置)中移除节点.
另一种变化涉及cloning节点并返回克隆.但是,现在您将返回克隆节点,这些节点没有引用DOM中的实际节点.
const FakeNodeList = (() => {
let fragment = document.createDocumentFragment();
fragment.appendChild(document.createComment('create a nodelist'));
function NodeList(nodes) {
let scope = this;
nodes.forEach((node, i) => {
scope[i] = node;
});
}
NodeList.prototype = …Run Code Online (Sandbox Code Playgroud) NodeList是否支持addEventListener.如果不是,将EventListener添加到NodeList的所有节点的最佳方法是什么.目前我使用的代码片段如下所示,有没有更好的方法来做到这一点.
var ar_coins = document.getElementsByClassName('coins');
for(var xx=0;xx < ar_coins.length;xx++)
{
ar_coins.item(xx).addEventListener('dragstart',handleDragStart,false);
}
Run Code Online (Sandbox Code Playgroud) 有没有办法加入2个调用document.getElementsByTagName返回的2个NodeLists?
说,我有以下代码
var inputs = documentElement.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');
Run Code Online (Sandbox Code Playgroud)
我想循环结果.有可能在一个循环中吗?
先感谢您!
在ES6中,iterable是一个允许的对象for... of,并且具有Symbol.iterator键.
数组是可迭代的,就像集合和地图一样.问题是:HTMLCollection和NodeList是否可迭代?他们应该是吗?
MDN文档似乎暗示a NodeList是可迭代的.
for...of循环将在支持的浏览器for...of(如Firefox 13及更高版本)中正确循环NodeList对象
这似乎证实了Firefox的行为.
我在Chrome和Firefox中测试了以下代码,并且惊讶地发现Firefox似乎认为它们是可迭代的,但Chrome却没有.此外,火狐认为,迭代器返回的HTMLCollection和NodeList是同一个.
var col = document.getElementsByClassName('test'); // Should get HTMLCollection of 2 elems
var nod = document.querySelectorAll('.test'); // Should get NodeList of 2 elems
var arr = [].slice.call(col); // Should get Array of 2 elems
console.log(col[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined
console.log(nod[Symbol.iterator]); // Firefox: iterator function, Chrome: undefined
console.log(arr[Symbol.iterator]); // Firefox & Chrome: iterator function
console.log(col[Symbol.iterator] …Run Code Online (Sandbox Code Playgroud)I am looking for a best way to iterate through NodeList excluding length. I am using:
var foo = document.querySelectorAll('[id^=foo_id]')
console.log(foo)
Run Code Online (Sandbox Code Playgroud)
Returned NodeList has all the required elements + the last entry of length:.
0: input#foo_id_...
1: input#foo_id_...
..................
n: input#foo_id_...
length: n+1
Run Code Online (Sandbox Code Playgroud)
I wonder what the most efficient way to iterate through that NodeList. I can utilize list length etc, but would like to know if there is a more "elegant" way.
javascript ×10
nodelist ×10
arrays ×3
dom ×2
ecmascript-6 ×2
concat ×1
ecmascript-5 ×1
filter ×1
foreach ×1
html ×1
loops ×1