Меня беспокоит то, что я не могу просто сделать это document.querySelectorAll(...).map(...)
даже в Firefox 3.6, и я все еще не могу найти ответ, поэтому я подумал, что я отправлю кросс-пост на SO вопрос из этого блога:
http://blowery.org/2008/08/29/yay-for-queryselectorall-boo-for-staticnodelist/
Кто-нибудь знает техническую причину, по которой вы не получаете массив? Или почему StaticNodeList не наследует от массива таким образом , что вы могли бы использовать map
, concat
и т.д.?
(Кстати, если вам нужна только одна функция, вы можете сделать что-то вроде NodeList.prototype.map = Array.prototype.map;
... но опять же, почему эта функция (намеренно?) Заблокирована в первую очередь?)
Ответы:
Я считаю, что это философское решение W3C. Дизайн W3C DOM [spec] полностью ортогонален дизайну JavaScript, поскольку DOM должен быть нейтральным к платформе и языку.
Такие решения, как «
getElementsByFoo()
возвращает упорядоченныйNodeList
» или «querySelectorAll()
возвращаетStaticNodeList
», в значительной степени преднамеренные, поэтому реализациям не нужно беспокоиться о выравнивании структуры возвращаемых данных на основе языковых реализаций (например.map
, доступность в массивах в JavaScript и Ruby, но нет в списках в C #).W3C стремятся к низкому уровню: они скажут, что a
NodeList
должно содержать свойство readonly.length
типа unsigned long, потому что они считают, что каждая реализация может хотя бы поддерживать это , но они не будут явно говорить, что[]
оператор индекса должен быть перегружен для поддержки получения позиционных элементов, потому что они не хотят заглушать какой-нибудь бедный маленький язык, который хотят реализовать,getElementsByFoo()
но не могут поддерживать перегрузку операторов. Это преобладающая философия, присутствующая в большей части спецификации.Джон Ресиг озвучил аналогичный вариант, как и ваш, к которому он добавляет :
Я немного сочувствую. Если бы модель DOM была написана специально с учетом функций JavaScript, она была бы намного менее неудобной и более интуитивной в использовании. В то же время я понимаю дизайнерские решения W3C.
источник
StaticNodeList
объект в массив. Я бы поддержал ответ @mck89 как способ преобразования aNodeList
/StaticNodeList
в собственный массив, но это не сработает в IE (8 obv) с ошибкой JScript, поскольку эти объекты размещены / "специальные".document
,window
и т. Д. IE часто реализует эти «специально» (например, как объекты COM), которые иногда не соответствуют нормальному использованию, маленькими и тонкими способами, такими какArray.prototype.slice.call
бомбардировка при заданииStaticNodeList
;)Вы можете использовать оператор распространения ES2015 (ES6) :
[...document.querySelectorAll('div')]
преобразует StaticNodeList в массив элементов.
Вот пример того, как его использовать.
источник
Array.from(document.querySelectorAll('div')).map(x => console.log(x.innerHTML))
Я не знаю, почему он возвращает список узлов вместо массива, возможно, потому, что, как и getElementsByTagName, он обновит результат при обновлении DOM. В любом случае очень простой метод преобразования этого результата в простой массив:
а затем вы можете сделать:
источник
slice
линию хоть.Просто чтобы добавить к тому, что сказал Полумесяц,
Не делай этого! Это вовсе не обязательно сработает.
Ни один из стандартов JavaScript или DOM / BOM не указывает, что
NodeList
функция-конструктор даже существует как глобальное /window
свойство, или чтоNodeList
возвращаемый объектquerySelectorAll
будет наследовать от него, или что ее прототип доступен для записи, или что функцияArray.prototype.map
действительно будет работать с NodeList.NodeList может быть «объектом-хостом» (и таковым является в IE и некоторых старых браузерах). Эти
Array
методы определяются как будет разрешено работать на «родной» объект любого в JavaScript , который предоставляет числовые иlength
свойства, но они не требуются для работы на объектах хозяевах (и в IE, они не делают).Раздражает то, что вы не получаете все методы массива в списках DOM (все они, а не только StaticNodeList), но надежного способа обойти это невозможно. Вам придется вручную преобразовать каждый возвращаемый список DOM в массив:
источник
new Array(n)
просто дает JS-терминалу подсказку о том, как долго будет работать массив. Это могло бы позволить ему заранее выделить это количество места, что потенциально могло бы привести к ускорению, так как некоторых перераспределений памяти можно было бы избежать по мере роста массива. Я не знаю, действительно ли это помогает в современных браузерах ... Я подозреваю, что это не заметно.Я думаю, вы можете просто сделать следующее
Это работает идеально для меня
источник
Это вариант, который я хотел добавить к ряду других возможностей, предложенных здесь другими. Это предназначено только для интеллектуального развлечения и не рекомендуется .
Просто для удовольствия , вот способ «заставить»
querySelectorAll
встать на колени и поклониться вам:Теперь приятно переступить через эту функцию, показывая, кто здесь главный. Теперь я не знаю, что лучше, создать целую новую оболочку именованной функции, а затем заставить весь ваш код использовать это странное имя (в значительной степени в стиле jQuery) или один раз переопределить функцию, как указано выше, чтобы остальная часть вашего кода все еще могла использовать исходное имя метода DOM
querySelectorAll
.источник