有没有办法加入2个调用document.getElementsByTagName返回的2个NodeLists?
说,我有以下代码
var inputs = documentElement.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');
我想循环结果。有可能在一个循环中吗?
提前谢谢!
答案 0 :(得分:46)
好像你可以使用相同的Array.prototype.slice.call,它使args数组类对象成为一个数组。 (See here)
var inputs = document.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');
inputs = Array.prototype.slice.call(inputs);
selects = Array.prototype.slice.call(selects);
var res = inputs.concat(selects);
alert(res.length);
答案 1 :(得分:20)
你不能加入它们,但你仍然可以在一个循环中顺序循环它们:
for ( var i = 0; i < inputs.length + selects.length; i++ ) {
var element = ( i < inputs.length ) ? inputs[i] : selects[i-inputs.length];
}
或者,使用jQuery,您可以一次性选择它们:
$('input, select')
答案 2 :(得分:12)
document.querySelectorAll("input, select");
答案 3 :(得分:4)
据我所知,NodeList
类型是不可变的(例如参见this article),这意味着您必须生成自己的对象。
一个简单的方法就是创建一个数组并将所有元素复制到该数组中。
var inputs = documentElement.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');
var all = new Array(inputs.length + selects.length);
var index = 0;
for (i = 0; i < inputs.length; i++)
all[index++] = inputs[i];
for (i = 0; i < selects.length; i++)
all[index++] = selects[i];
all
变量则包含两组节点的并集。
答案 4 :(得分:2)
function mergeNodeLists(a, b) {
var slice = Array.prototype.slice;
return slice.call(a).concat(slice.call(b));
}
console.log( mergeNodeLists( inputs, selects ) ); // => [input, select]
答案 5 :(得分:1)
我把它扔在了一起。对每个循环执行 if 和 .length 可能会有一些开销,但我认为除非元素数量极端,否则它会很小。
inputs = div.getElementsByTagName('input');
selects = div.getElementsByTagName('select');
for (i=0; i<inputs.length+selects.length; i++) {
element = (i<inputs.length ? inputs[i] : selects[i-inputs.length]);
// do whatever with element
}
答案 6 :(得分:1)
我的bookmarklet短代码:
var e, t = d.getElementsByTagName('textarea'), u = d.getElementsByTagName('input'), i = t.length;
while(e = (i > 0) ? t[--i] : u[-i--]){ if(e.offsetHeight > 0)... }
答案 7 :(得分:0)
首先,我认为可以使用Array.prototype来连接数组,如下所示:
Array.prototype.concat.call(selects, inputs);
但它不起作用,所以我从节点集合中创建了一个数组并将它连接起来。看起来像这样:
(function () {
var inputs = document.getElementsByTagName('input'),
selects = document.getElementsByTagName('select'),
result,
i,
node;
function convert (collection) {
var a = [];
for (var i = 0, length = collection.length; i < length; i++) {
a.push(collection[i]);
}
return a;
}
// concatenation && convertation
result = Array.prototype.concat(convert(inputs), convert(selects));
// traversing
i = result.length;
while(node = result[--i]) {
alert(node.getAttribute('name'));
}
})();
答案 8 :(得分:0)
现在我肯定会使用以下内容:
Chrome,Firefox 3.5 +,IE8 +
var elements = document.querySelectorAll('a');
for (var i = 0, element; (element = elements[i]); i++) {
console.log(element);
}
IE11 +,Firefox 24 +,Chrome 30+(已启用实验)
let elements = document.querySelectorAll('a');
for (let i = 0, element; (element = elements[i]); i++) {
console.log(element);
}
“element = elements [i]”优于“elements.length”,因为:
“节点列表通常被实现为带有过滤器的节点迭代器。这意味着获取像length这样的属性是O(n),并且通过重新检查长度来迭代列表将是O(n ^ 2)。 “
与数组访问不同,就我记得O(1)而言。
更多详情:
答案 9 :(得分:0)
Array.prototype.slice.call()在IE 7中失败,请使用:
Object.prototype.getMyElements = function(tags){
tags = tags.split(',');
var i, j, col=[], ci=0;
for(i=0; i<tags.length; i++) {
var objs = this.getElementsByTagName(tags[i]);
for(j=0; j<objs.length; j++) col[ci++] = objs[j];
}
return col;
}
var objs = document.getMyElements('INPUT,TEXTAREA');
var objs = document.getElementById('myform').getMyElements('INPUT,TEXTAREA');
答案 10 :(得分:0)
试试我的方式:
var allES = [];
var inputs = document.getElementsByTagName("input");
for (i = 0; i < inputs.length; i++) {
allES.push(inputs[i]);
}
// gather SELECT elements
var selects = document.getElementsByTagName("select");
for ( i=0; i < selects.length; i++){
allES.push(selects[i]);
}