проблема толчка массива javascript - PullRequest
1 голос
/ 18 июля 2011

У меня есть следующий код JavaScript:

var objectArray = [];
var allInputObjects = [];
var allSelectObjects = [];
var allTextAreaObjects = [];

//following returns 3 objects
allInputObjects = document.getElementById("divPage0").getElementsByTagName("INPUT");

//following returns 1 object
allSelectObjects = document.getElementById("divPage1").getElementsByTagName("SELECT");

//following returns 0 objects
allTextAreaObjects = document.getElementById("divPage2").getElementsByTagName("TEXTAREA");

//and following statement does not work
objectArray = allInputObjects.concat(allSelectObjects);

И моя проблема в том, что последняя строка выдает ошибку.

Я попробовал приведенный выше код в Firefox, и он говорит, что allInputObjects.concat не является функцией.

Любые подсказки, я полагаю, что скрипт не обрабатывает все объекты InputObjects как массив!

Любая помощь будет оценена.

Ответы [ 4 ]

4 голосов
/ 18 июля 2011

getElementsByTagName возвращает NodeList, что аналогично Array, за исключением того, что оно не поддерживает все эти функции-прототипы.

Для плавного преобразования такого объекта, подобного массиву, в массив,use:

var arr = Array.prototype.slice.call(somenodelist, 0);

arr будет почти идентичным, за исключением того, что теперь он поддерживает Array поддерживаемых функций-прототипов, например concat.

То, что функция на самом деле делает, возвращаетчастичное Array, содержащее элементы somenodelist, если быть точным все, начиная с индекса 0 и после.Очевидно, что это всего лишь элементы, поэтому это хитрость для преобразования объектов, подобных массивам, в реальные Array s.

4 голосов
/ 18 июля 2011

Почему вы думаете, что allSelectObjects - это массив?

Это изначально присваивается пустому массиву, конечно. Но затем он перезаписывается вызовом getElementsByTagName в строке 6 (ish). Переменные в Javascript не являются строго типизированными, поэтому первоначальное присваивание не заставляет последующие присваивания также быть массивами.

Я подозреваю, что у вас будет некоторый тип NodeList или аналогичный, а не массив, в переменной при вызове последней строки. (Это то, что возвращается методом в Firefox, по крайней мере.)

3 голосов
/ 18 июля 2011

Как отметил Андезей, вы здесь не имеете дело с массивом, вы имеете дело со своего рода списком узлов.

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

        var tags = obj.getElementsByTagName('input');
        for (var j=0;j<tags.length;j++) {
            resultArray.push(tags[j]);
        }
1 голос
/ 18 июля 2011

Еще один забавный способ конвертировать NodeList в массив:

var tags = obj.getElementsByTagName('input'),
    tags2Arr = ( 
           function toArr(i){
             return i ? toArr(i-1).concat(tags[i]) : [tags[0]];
           }(tags.length-1) 
    );

Теперь, если вы добавите метод к Array.prototype:

Array.prototype.clone = function() {
    var arr = this;
    return (function clone(i){
     return i ? clone(i-1).concat(arr[i]) : [arr[0]];
    })(this.length-1);
};

Вы можете конвертироватьNodeList в массив, используя этот oneliner:

Array.prototype.clone.call(obj.getElementsByTagName('input'));
...