Коллекция Javascript объектов DOM - почему я не могу вернуться с помощью Array.reverse ()? - PullRequest
10 голосов
/ 05 сентября 2008

В чем может быть проблема с обращением массива объектов DOM, как показано в следующем коде:

var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();

В Firefox 3, когда я вызываю метод reverse(), скрипт прекращает выполнение и показывает следующую ошибку в консоли панели инструментов веб-разработчика:

imagesArr.reverse is not a function

Переменная imagesArr может быть повторена с помощью цикла for, и к таким элементам, как imagesArr[i], можно получить доступ, так почему она не рассматривается как массив при вызове метода reverse()?

Ответы [ 5 ]

13 голосов
/ 05 сентября 2008

Потому что имя getElementsByTag фактически возвращает структуру NodeList. Для удобства синтаксиса он имеет аналогичный массив свойств индексации, но это , а не массив. Например, набор записей фактически постоянно обновляется динамически - если вы добавите новый тег img в myDivHolderId, он автоматически появится в imagesArr.

Подробнее см. http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177.

8 голосов
/ 05 сентября 2008

getElementsByTag() возвращает NodeList вместо Array. Вы можете преобразовать NodeList в Array, но обратите внимание, что массив будет другим объектом, поэтому его изменение не повлияет на положение узлов DOM.

var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img");
var arrayNodes = Array.slice.call(listNodes, 0);
arrayNodes.reverse();

Чтобы изменить положение, вам придется удалить узлы DOM и снова добавить их все в правильное положение.

Array.prototype.slice.call(arrayLike, 0) - отличный способ преобразовать массив, подобный массиву, но если вы используете библиотеку JavaScript, это может фактически обеспечить еще лучший / более быстрый способ сделать это. Например, jQuery имеет $.makeArray(arrayLike).

Вы также можете использовать методы Array непосредственно в NodeList:

Array.prototype.reverse.call(listNodes);
3 голосов
/ 29 января 2015

getElementsByTag() возвращает NodeList вместо Array. Вам необходимо преобразовать NodeList в массив, а затем обратить его обратно.

var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();
2 голосов
/ 20 марта 2015

Я знаю, что этот вопрос старый, но я думаю, что он нуждается в небольшом уточнении, поскольку некоторые ответы здесь устарели, так как W3C изменил определение, и, следовательно, возвращаемое значение этих методов getElementsByTagName() и getElementsByClassName()

Эти методы на момент написания этого ответа возвращают объект - пустой или нет - типа HTMLCollection и не NodeList.

Это похоже на разницу между свойствами children, которая возвращает объект типа HTMLCollection, поскольку он состоит только из элементов и исключает узлы текста или комментария, и childNodes, который возвращает объект типа NodeList, поскольку он может содержать и другие типы узлов, такие как текст и комментарии.

Примечание: я бы остановился здесь и выразил свое отсутствие понимания того, почему метод querySelectorAll() в настоящее время возвращает NodeList, а не HTMLCollection, так как он работает исключительно на узлах элементов в документе и ничего больше.

Вероятно, это как-то связано с потенциальным охватом других типов узлов в будущем, и они пошли на более перспективное решение, кто на самом деле знает? :)

РЕДАКТИРОВАТЬ: Я думаю, что я получил обоснование этого решения, чтобы выбрать NodeList, а не HTMLCollection для querySelectorAll().

Поскольку они сконструировали HTMLCollection как исключительно и полностью работоспособный, и так как этот метод не нуждается в этой оперативной функциональности, они решили использовать реализацию NodeList, чтобы наилучшим образом служить своей цели экономически и эффективно.

1 голос
/ 05 сентября 2008

Ваша первая строка не имеет значения, поскольку она не приводит к присваиванию переменной, javascript работает по-другому. imagesArr, не относится к типу Array (), это тип возвращаемого значения getElementsByTagName ("img"). В данном случае это HtmlCollection в Firefox 3.

Единственными методами для этого объекта являются индексаторы и длина. Чтобы работать в обратном порядке, просто итерируйте в обратном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...