我有一个Javascript函数,它接受一个HTML节点列表,但它需要一个Javascript数组(它在上面运行一些Array方法),我想把Document.getElementsByTagName
的输出提供给它,它返回一个DOM节点列表。
最初,我想用一些简单的东西,比如:
Array.prototype.slice.call(list,0)
这在所有浏览器中都可以正常工作,当然除了Internet Explorer,它返回错误“JScript object expected”,因为显然Document.getElement*
方法返回的DOM节点列表不是一个JScript对象,不足以成为函数调用的目标。
警告:我不介意编写Internet Explorer特定的代码,但我不允许使用任何Javascript库,如JQuery,因为我正在编写一个嵌入到第三方网站的小部件,我不能加载外部库,这将为客户端创建冲突。
我最后的努力是迭代DOM节点列表并自己创建一个数组,但是有更好的方法吗?
7条答案
按热度按时间tvmytwxo1#
在es6中,您可以使用如下命令:
Array.from
更多参考资料在https://developer.mozilla.org/en-US/docs/Web/API/NodeList
ghhaqwfi2#
NodeList是 host objects,在host objects上使用
Array.prototype.slice
方法不能保证工作,ECMAScript规范规定:slice函数能否成功应用于宿主对象取决于实现。
我建议你编写一个简单的函数来迭代
NodeList
,并将每个现有元素添加到数组中:更新:
正如其他答案所建议的那样,您现在可以在现代环境中使用spread语法或
Array.from
方法:但是仔细想想,我想将NodeList转换为Array最常见的用例是迭代它,现在
NodeList.prototype
对象有forEach
method natively,所以如果你在现代环境中,你可以直接使用它,或者使用pollyfill。niknxzdl3#
使用spread (ES2015)非常简单:
[...document.querySelectorAll('p')]
(可选:使用Babel将上述ES6代码转换为ES5语法)
zte4gxcn4#
使用这个简单的技巧
jdzmm42g5#
今天,在2018年,我们可以使用ECMAScript 2015(第6版)或ES6,但并非所有浏览器都能理解它(例如,ECMAScript 2015)。我不明白所有的一切)。如果你愿意,你可以使用ES6如下:
var array = [... NodeList];
(as spread operator)或**var array = Array.from(NodeList);
**。在其他情况下(如果你不能使用ES6),你可以使用最短的方法将
NodeList
转换为Array
:var array = [].slice.call(NodeList, 0);
。例如:
但是,如果您只想简单地迭代
DOM
节点列表,则不需要将NodeList
转换为Array
。可以使用以下命令循环NodeList
中的项目:不要尝试使用**
for...in
或for each...in
来枚举列表中的项,因为这也会枚举NodeList
的长度和项属性,如果脚本假定它只需要处理元素对象,则会导致错误。此外,for..in
不保证以任何特定的顺序访问这些属性。for...of
**循环将正确循环NodeList对象。请参见:
8e2ybdfx6#
虽然它不是一个真正合适的shim,因为没有规范要求使用DOM元素,但我已经做了一个,允许您以这种方式使用
slice()
:https://gist.github.com/brettz9/6093105更新:当我向DOM 4规范的编辑提出这个问题时(询问他们是否可以在ECMAScript规范允许实现独立性的基础上,为主机对象添加自己的限制(以便规范要求实现者在与数组方法一起使用时正确转换这些对象)),他回答说“主机对象在ES6 / IDL中或多或少已经过时了。”我在www.example.com上看到http://www.w3.org/TR/WebIDL/#es-arrayspecs可以使用这个IDL来定义“平台数组对象”,但是http://www.w3.org/TR/domcore/似乎没有为
HTMLCollection
使用新的IDL(尽管它看起来可能会为Element.attributes
这样做,尽管它只显式地声明它正在为DOMString和DOMTimeStamp使用WebIDL)。我确实看到[ArrayClass]
(继承自Array.prototype)被用于NodeList
(而NamedNodeMap
现在被弃用,以支持唯一仍在使用它的项目Element.attributes
)。无论如何,它看起来都将成为标准。ES6Array.from
也可能比指定Array.prototype.slice
更方便进行此类转换,并且比[].slice()
在语义上更清晰(据我所知,更短的形式Array.slice()
(“数组泛型”)尚未成为标准行为)。xqnpmsa87#
这应该工作,跨浏览器,并得到你所有的“元素”节点。