Coleção Javascript de objetos DOM - por que não consigo reverter com Array.reverse()?

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

  •  09-06-2019
  •  | 
  •  

Pergunta

Qual poderia ser o problema em reverter a matriz de objetos DOM como no código a seguir:

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

No Firefox 3, quando eu chamo o reverse() método, o script para de ser executado e mostra o seguinte erro no console da Web Developer Toolbar:

imagesArr.reverse is not a function

O imagesArr variável pode ser iterada com um loop for e elementos como imagesArr[i] pode ser acessado, então por que não é visto como um array ao chamar o reverse() método?

Foi útil?

Solução

Porque getElementsByTag name na verdade retorna uma estrutura NodeList.Possui matriz semelhante, como propriedades de indexação, por conveniência sintática, mas é não uma matriz.Por exemplo, o conjunto de entradas é constantemente atualizado de forma dinâmica - se você adicionar uma nova tag img em myDivHolderId, ela aparecerá automaticamente em imagesArr.

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

Outras dicas

getElementsByTag() retorna um NodeList em vez de um Array.Você pode converter um NodeList em um Array, mas observe que o array será outro objeto, portanto, revertê-lo não afetará a posição dos nós DOM.

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

Para alterar a posição, você terá que remover os nós DOM e adicioná-los novamente na posição correta.

Array.prototype.slice.call(arrayLike, 0) é uma ótima maneira de converter um array em um array, mas se você estiver usando uma biblioteca JavaScript, ele pode fornecer uma maneira ainda melhor/mais rápida de fazer isso.Por exemplo, jQuery tem $.makeArray(arrayLike).

Você também pode usar os métodos Array diretamente no NodeList:

Array.prototype.reverse.call(listNodes);

getElementsByTag() retorna um NodeList em vez de um Array.Você precisa converter o NodeList em um array e depois revertê-lo.

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

Eu sei que esta pergunta é antiga, mas acho que precisa de um pouco de esclarecimento, pois algumas das respostas aqui estão desatualizadas, pois o W3C mudou a definição e, consequentemente, o valor de retorno desses métodos getElementsByTagName() e getElementsByClassName()

Esses métodos no momento em que escrevi esta resposta retornar um objeto - vazio ou não - do tipo HTMLCollection e não NodeList.

É como a diferença entre as propriedades children que retorna um objeto do tipo HTMLCollection já que é composto apenas de elementos e excluindo nós de texto ou comentários, e childNodes que retorna um objeto do tipo NodeList já que também pode conter outros tipos de nós, como texto e comentários.

Observação:Eu iria pela tangente aqui e expressaria minha falta de compreensão sobre o porquê querySelectorAll() método atualmente retorna um NodeList e não um HTMLCollection uma vez que funciona exclusivamente em nós de elementos do documento e nada mais.

Provavelmente tem algo a ver com a cobertura potencial de outros tipos de nós no futuro e eles optaram por uma solução mais preparada para o futuro, quem sabe?:)

EDITAR:Acho que entendi a razão por trás desta decisão de optar por um NodeList e não um HTMLCollection para o querySelectorAll().

Desde que eles construíram HTMLCollection ser exclusiva e inteiramente ao vivo e como esse método não precisa dessa funcionalidade ao vivo, eles decidiram por um NodeList implementação, em vez disso, para melhor servir o seu propósito de forma económica e eficiente.

Sua primeira linha é irrelevante, pois não força a atribuição à variável, o javascript funciona ao contrário.imagesArr, não é do tipo Array(), é qualquer que seja o tipo de retorno de getElementsByTagName("img").Neste caso, é um HtmlCollection no Firefox 3.

Os únicos métodos neste objeto são os indexadores e o comprimento.Para trabalhar ao contrário, basta iterar para trás.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top