Это прослушивает меня, что я не могу просто сделать document.querySelectorAll(...).map(...)
даже в Firefox 3.6, и я все еще не могу найти ответ, таким образом, я думал, что осуществлю кросспостинг по ТАК вопросу из этого блога:
http://blowery.org/2008/08/29/yay-for-queryselectorall-boo-for-staticnodelist/
Кто-либо знает о технической причине, почему Вы не получаете Массив? Или почему StaticNodeList не наследовался Массиву таким способом, которым Вы могли использовать map
, concat
, и т.д.?
(BTW, если это - всего одна функция, Вы хотите, можно сделать что-то как NodeList.prototype.map = Array.prototype.map;
... но снова, почему эта функциональность (намеренно?) заблокированный во-первых?)
Я считаю, что это философское решение W3C. Дизайн W3C DOM [spec] довольно ортогонален дизайну JavaScript, поскольку DOM означает нейтральную платформу и язык.
Решения типа « getElementsByFoo ()
возвращает упорядоченный NodeList
» или « querySelectorAll ()
возвращает StaticNodeList
» очень много преднамеренно, так что реализациям не нужно беспокоиться о выравнивании своей возвращаемой структуры данных на основе зависимых от языка реализаций (например, .map
доступен для массивов в JavaScript и Ruby, но не в списках на C #).
W3C стремятся к низкому уровню: они скажут, что NodeList
должен содержать свойство только для чтения .length
типа unsigned long , потому что они считают, что каждая реализация может минимум поддерживают , что , но они не будут явно говорить, что оператор индекса []
должен быть перегружен для поддержки получения позиционных элементов, потому что они не хотят заглушать какой-нибудь бедный маленький язык, который приходит вместе, который хочет для реализации getElementsByFoo ()
, но не может поддерживать перегрузку оператора.Это преобладающая философия, присутствующая в большей части спецификации.
Джон Ресиг озвучил аналогичный вариант , что и ваш, к которому он добавляет :
Мои аргументы не столько в том, что
NodeIterator
не очень похож на DOM, он не очень похож на JavaScript. Он не использует возможности языка JavaScript, а использует их в меру своих возможностей ...
Я немного сочувствую. Если бы модель DOM была написана специально с учетом функций JavaScript, она была бы намного менее неудобной и более интуитивно понятной в использовании. В то же время я понимаю дизайнерские решения W3C.
Я не знаю, почему он возвращает список узлов вместо массива, возможно, потому что, как и getElementsByTagName, он обновляет результат при обновлении DOM. В любом случае очень простой метод преобразования этого результата в простой массив:
Array.prototype.slice.call(document.querySelectorAll(...));
, а затем вы можете сделать:
Array.prototype.slice.call(document.querySelectorAll(...)).map(...);
Просто добавьте к тому, что сказал Полумесяц,
если это всего одна функция, которую вы хотите, вы можете сделать что-нибудь вроде NodeList.prototype.map = Array.prototype.map
Не делайте этого! Это совсем не гарантирует работу.
Ни один из стандартов JavaScript или DOM / BOM не указывает, что функция-конструктор NodeList
существует даже как глобальное свойство / window
, или что NodeList
, возвращенный querySelectorAll
унаследует от него, или что его прототип доступен для записи, или что функция Array.prototype.map
действительно будет работать с NodeList.
NodeList может быть «объектом-хостом» (и является одним из них в IE и некоторых старых браузерах). Методы Array
определены как разрешенные для работы с любым «собственным объектом» JavaScript, который предоставляет числовые свойства и свойства length
, но они не обязательны для работы с объектами хоста (и в IE, они этого не делают).
Досадно, что вы не получаете все методы массива в списках DOM (все они, а не только StaticNodeList), но надежного способа обойти это нет. Вам придется вручную преобразовать каждый возвращаемый список DOM в массив:
Array.fromList= function(list) {
var array= new Array(list.length);
for (var i= 0, n= list.length; i<n; i++)
array[i]= list[i];
return array;
};
Array.fromList(element.childNodes).forEach(function() {
...
});