27

有没有办法加入由 2 次 document.getElementsByTagName 调用返回的 2 个 NodeLists?

说,我有以下代码

var inputs = documentElement.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');

我想遍历结果。是否可以在一个循环中?

先感谢您!

4

11 回答 11

45

似乎您可以使用相同的 Array.prototype.slice.call 使 args 类数组对象成为数组。(见这里

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);
于 2009-05-27T10:22:11.967 回答
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')
于 2009-05-27T09:54:33.533 回答
12
document.querySelectorAll("input, select"); 
于 2010-02-23T11:36:36.883 回答
4

据我所知,该NodeList类型是不可变的(例如,参见这篇文章),这意味着您必须生成自己的对象。

一个简单的方法就是创建一个数组并将所有元素复制到该数组中。

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变量包含两组节点的并集。

于 2009-05-27T09:34:54.230 回答
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]

于 2013-06-23T15:58:03.727 回答
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
}
于 2011-04-04T22:45:30.563 回答
1

我的书签短代码:

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)... }
于 2012-10-08T07:18:13.623 回答
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'));
    }

})();
于 2009-05-27T09:53:21.400 回答
0

现在我肯定会使用以下内容:

铬、火狐 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",因为:

“节点列表通常被实现为带有过滤器的节点迭代器。这意味着获得像长度这样的属性是 O(n),并且通过重新检查长度来迭代列表将是 O(n^2)。”

与数组访问不同,据我所知,这是 O(1)。

更多细节:

于 2014-02-15T09:37:14.090 回答
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');
于 2014-04-01T15:47:36.753 回答
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]);
                }
于 2015-02-24T12:05:51.380 回答