Иногда меня раздражает тот факт, что набор элементов DOM (более формально называемый NodeList
Тем не менее, он выглядит как единое целое, и думать, что это так, является ошибкой, которую так часто совершают новички в JavaScript, что для нашей следующей ссылки на JavaScript я счел необходимым отметить этот момент для каждого отдельного объекта DOM, который является или возвращает коллекцию.
Вы можете перебирать коллекцию как массив:
for(var i=0; i<collection.length; i++)
{
//whatever
}
Но вы не можете использовать методы Array
push()
splice()
reverse()
За исключением того, что вы можете, если вы сделаете следующий шаг и преобразуете его в массив . Это на самом деле тривиально:
function collectionToArray(collection)
{
var ary = [];
for(var i=0, len = collection.length; i < len; i++)
{
ary.push(collection[i]);
}
return ary;
}
Приведенный выше код полностью кросс-браузерный и вызывается с исходной коллекцией в качестве аргумента:
var elements = collectionToArray(document.getElementsByTagName('*'));
Однако, если вам нужно иметь дело только с браузерами, которые поддерживают прототипирование нативных объектов (Opera, Firefox и Safari 3), вы можете просто создать метод toArray()
NodeList
NodeList.prototype.toArray = function()
{
var ary = [];
for(var i=0, len = this.length; i < len; i++)
{
ary.push(this[i]);
}
return ary;
};
Который затем может быть вызван как метод отдельной коллекции:
var elements = document.getElementsByTagName('*').toArray();
У этого преобразования есть один очевидный недостаток (как бы он ни был), а именно, что полученный массив больше не будет NodeList
Очевидно, да, но важно, потому что это имеет два значения:
- Он потеряет свойства и методы, унаследованные от
NodeList
. ОднакоNodeList
length
item()
Так что эта потеря совсем не значительна - Это больше не будет живая коллекция .
NodeList
ссылка на коллекцию объектов, и если эта коллекция изменяется (например, элементы добавляются или удаляются),NodeList
и наоборот, наш массив является статическим снимком коллекции в определенный момент времени, поэтому не будет обновляться в ответ на изменения в DOM . В зависимости от вашего приложения, это может быть значительным.