JavaScript 节点列表

发布于 2024-07-21 18:45:19 字数 276 浏览 6 评论 0原文

有没有办法连接 2 个 document.getElementsByTagName 调用返回的 2 个 NodeList?

假设我有以下代码,

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

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

先感谢您!

is there a way to join 2 NodeLists returned by 2 calls of document.getElementsByTagName?

Say, I have the following code

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

I want to loop through the results. Is it possible in one loop?

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

坦然微笑 2024-07-28 18:45:19

似乎您可以使用相同的 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);

Seems like you can use the same Array.prototype.slice.call that makes the args array-like object become an array. (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);
哎呦我呸! 2024-07-28 18:45:19
document.querySelectorAll("input, select"); 
document.querySelectorAll("input, select"); 
多像笑话 2024-07-28 18:45:19

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

As far as I know, the NodeList type is immutable (see this article for example), which means you'll have to generate your own object.

A simple method would just be to create an array and copy all the elements into that array.

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];

The all variable then contains the union of the two sets of nodes.

っ左 2024-07-28 18:45:19

您无法加入它们,但您仍然可以在一个循环中按顺序循环它们,如下所示:

for ( var i = 0; i < inputs.length + selects.length; i++ ) {
    var element = ( i < inputs.length ) ? inputs[i] : selects[i-inputs.length];
}

或者,使用 jQuery,您可以一次性选择它们:

$('input, select')

You can't join them, but you can still loop through them sequentially in one loop like this:

for ( var i = 0; i < inputs.length + selects.length; i++ ) {
    var element = ( i < inputs.length ) ? inputs[i] : selects[i-inputs.length];
}

Alternatively, using jQuery, you could select them all in one go:

$('input, select')
迎风吟唱 2024-07-28 18:45:19
function mergeNodeLists(a, b) {
  var slice = Array.prototype.slice;
  return slice.call(a).concat(slice.call(b));
}

console.log( mergeNodeLists( 输入, 选择 ) ); // => [输入、选择]

function mergeNodeLists(a, b) {
  var slice = Array.prototype.slice;
  return slice.call(a).concat(slice.call(b));
}

console.log( mergeNodeLists( inputs, selects ) ); // => [input, select]

可可 2024-07-28 18:45:19

我把这个放在一起。 为每个循环执行 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
}

I threw this together. There might be a bit of overhead from doing an if and .length for every loop, but I think its minor unless the number of elements get extreme.

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
}
初心 2024-07-28 18:45:19

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');

Array.prototype.slice.call() fails in IE 7, use this:

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');
木森分化 2024-07-28 18:45:19

现在我肯定会使用以下版本:

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”,因为:

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

与数组访问不同,据我所知,数组访问的时间复杂度为 O(1)。

更多详细信息:

Nowadays I would definitely use the following:

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+ (with experiments enabled)

let elements = document.querySelectorAll('a');

for (let i = 0, element; (element = elements[i]); i++) {
    console.log(element);
}

"element = elements[i]" is preferred over "elements.length" since:

"Node lists are often implemented as node iterators with a filter. This means that getting a property like length is O(n), and iterating over the list by re-checking the length will be O(n^2)."

Unlike array access, which is as far as I remember O(1).

More details:

寻找一个思念的角度 2024-07-28 18:45:19

首先,我认为可以使用 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'));
    }

})();

First, I thought that this is possible to concat arrays using Array.prototype, like this:

Array.prototype.concat.call(selects, inputs);

But it doesn't work, so that I've made an arrays from node collections and concat it. Looks like that:

(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'));
    }

})();
眼波传意 2024-07-28 18:45:19

我的小书签的简短代码:

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)... }

My short code for bookmarklets:

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)... }
恬淡成诗 2024-07-28 18:45:19

试试我的方法:

 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]);
                }

try my way:

 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]);
                }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文