JavaScript NodeList - PullRequest
       18

JavaScript NodeList

27 голосов
/ 27 мая 2009

есть ли способ присоединиться к 2 спискам NodeList, возвращаемым 2 вызовами document.getElementsByTagName?

Скажи, у меня есть следующий код

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

Я хочу просмотреть результаты. Возможно ли это за один цикл?

Заранее спасибо!

Ответы [ 11 ]

46 голосов
/ 27 мая 2009

Похоже, вы можете использовать тот же 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);
20 голосов
/ 27 мая 2009

Вы не можете присоединиться к ним, но вы все равно можете последовательно проходить через них в одном цикле, как это:

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

В качестве альтернативы, используя jQuery, вы можете выбрать их все сразу:

$('input, select')
12 голосов
/ 23 февраля 2010
document.querySelectorAll("input, select"); 
4 голосов
/ 27 мая 2009

Насколько я знаю, тип 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 содержит объединение двух наборов узлов.

2 голосов
/ 23 июня 2013
function mergeNodeLists(a, b) {
  var slice = Array.prototype.slice;
  return slice.call(a).concat(slice.call(b));
}

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

1 голос
/ 08 октября 2012

Мой короткий код для букмарклетов:

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)... }
1 голос
/ 05 апреля 2011

Я бросил это вместе. Выполнение 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
}
0 голосов
/ 24 февраля 2015

попробуй мой путь:

 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]);
                }
0 голосов
/ 01 апреля 2014

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');
0 голосов
/ 15 февраля 2014

В настоящее время я бы определенно использовал следующее:

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

Подробнее:

...