Коллекция объектов DOM в Javascript – почему я не могу выполнить обратный ход с помощью Array.reverse()?

StackOverflow https://stackoverflow.com/questions/45613

  •  09-06-2019
  •  | 
  •  

Вопрос

В чем может быть проблема с обращением массива объектов 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() метод?

Это было полезно?

Решение

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

Видеть http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 для большего.

Другие советы

getElementsByTag() возвращает NodeList вместо массива.Вы можете преобразовать 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);

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

var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top