Colección Javascript de objetos DOM: ¿por qué no puedo revertir con Array.reverse()?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

¿Cuál podría ser el problema al invertir la matriz de objetos DOM como en el siguiente código?

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

En Firefox 3, cuando llamo al reverse() método el script deja de ejecutarse y muestra el siguiente error en la consola de la barra de herramientas del desarrollador web:

imagesArr.reverse is not a function

El imagesArr La variable se puede iterar con un bucle for y elementos como imagesArr[i] se puede acceder, entonces, ¿por qué no se ve como una matriz cuando se llama al reverse() ¿método?

¿Fue útil?

Solución

Porque el nombre getElementsByTag en realidad devuelve una estructura NodeList.Tiene una matriz similar como propiedades de indexación por conveniencia sintáctica, pero es no una matriz.Por ejemplo, el conjunto de entradas en realidad se actualiza constantemente de forma dinámica: si agrega una nueva etiqueta img en myDivHolderId, aparecerá automáticamente en imagesArr.

Ver http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 para más.

Otros consejos

getElementsByTag() devuelve una NodeList en lugar de una Array.Puede convertir una NodeList en una matriz, pero tenga en cuenta que la matriz será otro objeto, por lo que revertirla no afectará la posición de los nodos DOM.

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

Para cambiar la posición, deberá eliminar los nodos DOM y agregarlos todos nuevamente en la posición correcta.

Array.prototype.slice.call(arrayLike, 0) es una excelente manera de convertir una matriz en una matriz, pero si está utilizando una biblioteca de JavaScript, en realidad puede proporcionar una forma aún mejor y más rápida de hacerlo.Por ejemplo, jQuery tiene $.makeArray(arrayLike).

También puede utilizar los métodos Array directamente en NodeList:

Array.prototype.reverse.call(listNodes);

getElementsByTag() devuelve una NodeList en lugar de una Array.Debe convertir NodeList en una matriz y luego invertirla.

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

Sé que esta pregunta es antigua, pero creo que necesita un poco de aclaración ya que algunas de las respuestas aquí están desactualizadas ya que el W3C cambió la definición y, en consecuencia, el valor de retorno de estos métodos. getElementsByTagName() y getElementsByClassName()

Estos métodos al momento de escribir esta respuesta devolver un objeto, vacío o no, de tipo HTMLCollection y no NodeList.

Es como la diferencia entre las propiedades. children que devuelve un objeto de tipo HTMLCollection ya que solo se compone de elementos y excluye texto o nodos de comentarios, y childNodes que devuelve un objeto de tipo NodeList ya que también podría contener otros tipos de nodos como texto y comentarios.

Nota:Me iría por la tangente aquí y expresaría mi falta de comprensión sobre por qué querySelectorAll() El método actualmente devuelve un NodeList y no un HTMLCollection ya que funciona exclusivamente en nodos de elementos del documento y nada más.

Probablemente tenga algo que ver con la posible cobertura de otros tipos de nodos en el futuro y optaron por una solución más preparada para el futuro, ¿quién sabe realmente?:)

EDITAR:Creo que entendí la razón detrás de esta decisión de optar por una NodeList y no un HTMLCollection Para el querySelectorAll().

Desde que construyeron HTMLCollection ser exclusiva y completamente en vivo y dado que este método no necesita esta funcionalidad en vivo, decidieron por un NodeList implementación para cumplir mejor su propósito de manera económica y eficiente.

Su primera línea es irrelevante, ya que no obliga a la asignación a la variable, javascript funciona al revés.imagesArr, no es de Type Array(), es de cualquier tipo de retorno de getElementsByTagName("img").En este caso, es una colección Html en Firefox 3.

Los únicos métodos en este objeto son los indexadores y la longitud.Para trabajar a la inversa, simplemente itere hacia atrás.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top