我原本想要一种优雅的方式来模拟IE或旧浏览器中Array.concat()
函数结果的getElementsByTagName
功能,因为它似乎不支持concat
。当然只有 - 返回的对象不支持它的原因是因为它不是Array
。糟糕!
getElementsByTagName
实际上会返回NodeList
。那么真正的问题是:什么是获取文档中所有表单元素的单个列表(输入,选择,文本区域,按钮)以循环遍历它们的好方法?不需要数组......单个NodeList
也是完美的。
请注意,我使用的是IE6,因为这是用于企业内部网(尽管IE8很快)。
我想出的答案是:
它变得更简单,并且可能更好地将代码放入一个单独的函数并使用不同的节点列表调用它三次,而不是担心将它们组合成一个的好方法。
我最终转而使用MooTools(几个小时后阅读所有不同框架的比较)。所以现在,获取我想要的项目数组非常简单。我建议使用这样的javascript框架,而不是人们试图找出最好的做事方式。当然我都是为了实际学习原始语言(这就是为什么我暂时停止使用框架),但它并不总是最快速的方式,这在业务中通常很重要用语言提高编码员的能力。
更新:差不多2年后我会使用jQuery并完成它!
答案 0 :(得分:30)
要连接节点列表,请使用Array.prototype.slice.call
将它们转换为数组,然后正常连接它们。
var a = Array.prototype.slice.call(document.getElementsByTagName("p")),
b = Array.prototype.slice.call(document.getElementsByTagName("div"))
var c = a.concat(b);
修改(回复您的评论)
如果您只有几种类型的元素,这是可以的,但性能会随着您调用的DOM调用次数而减少。执行document.getElementsByTagName('*')
可能会更好更快,通过列表循环并选择具有所需nodeName
的元素。
要记住的另一件事是上面使用的Array.prototype.slice
方法可能无法在所有浏览器中使用。查看sizzle.js(jQuery背后的选择器引擎)
当然,最好使用像jQuery这样的库来解决所有问题。你可以这样做:
$("input, select, textarea, <other tags>")
答案 1 :(得分:3)
function mergeNodeLists(a, b) {
var slice = Array.prototype.slice;
return slice.call(a).concat(slice.call(b));
}
console.log( mergeNodeLists( inputs, selects ) ); // => [input, select]
答案 2 :(得分:3)
let arr = [...nodeList1, ...nodeList2];
答案 3 :(得分:1)
var a1=document.getElementsByTagName('div'),
a2=document.getElementsByTagName('button');
a1=[].slice.call(a1, 0,a1.length).concat([].slice.call(a2, 0,a2.length))
答案 4 :(得分:1)
如MDN Documentation所述,您还可以使用Array.from
将NodeList转换为支持它的浏览器中的数组。
答案 5 :(得分:0)
我以为会有比这更多的答案,无论如何我给了它一个镜头,并提出了以下功能,虽然我不得不砰的一声。
function group_elements(element, tags) {
var elements = element.getElementsByTagName('*');
var results = [];
for ( var i = 0; i < elements.length; ++i ) {
if ( tags.indexOf(elements[i].nodeName.toLowerCase()) > -1 ) {
results.push(elements[i]);
}
}
return results;
}
var form = document.getElementById('form');
var tags = ['input', 'select'];
console.log(group_elements(form, tags));