Raccolta Javascript di oggetti DOM: perché non posso invertire con Array.reverse()?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Quale potrebbe essere il problema con l'inversione dell'array di oggetti DOM come nel seguente codice:

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

In Firefox 3, quando chiamo il file reverse() metodo lo script interrompe l'esecuzione e mostra il seguente errore nella console della barra degli strumenti per sviluppatori Web:

imagesArr.reverse is not a function

IL imagesArr la variabile può essere ripetuta con un ciclo for ed elementi come imagesArr[i] è possibile accedere, quindi perché non viene visto come un array quando si chiama il file reverse() metodo?

È stato utile?

Soluzione

Perché getElementsByTag name restituisce effettivamente una struttura NodeList.Ha un array simile come proprietà di indicizzazione per comodità sintattica, ma lo è non un array.Ad esempio, l'insieme di voci viene in realtà costantemente aggiornato dinamicamente: se aggiungi un nuovo tag img sotto myDivHolderId, apparirà automaticamente in imagesArr.

Vedere http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 per più.

Altri suggerimenti

getElementsByTag() restituisce un NodeList invece di un Array.Puoi convertire una NodeList in un Array ma tieni presente che l'array sarà un altro oggetto, quindi invertirlo non influirà sulla posizione dei nodi DOM.

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

Per modificare la posizione, dovrai rimuovere i nodi DOM e aggiungerli nuovamente tutti nella posizione corretta.

Array.prototype.slice.call(arrayLike, 0) è un ottimo modo per convertire un array simile a un array, ma se stai utilizzando una libreria JavaScript, potrebbe effettivamente fornire un modo ancora migliore/più veloce per farlo.Ad esempio, jQuery ha $.makeArray(arrayLike).

Puoi anche utilizzare i metodi Array direttamente sulla NodeList:

Array.prototype.reverse.call(listNodes);

getElementsByTag() restituisce un NodeList invece di un Array.È necessario convertire NodeList in un array e quindi invertirlo.

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

So che questa domanda è vecchia ma penso che abbia bisogno di un po' di chiarimenti poiché alcune delle risposte qui sono obsolete poiché il W3C ha cambiato la definizione e di conseguenza il valore restituito di questi metodi getElementsByTagName() E getElementsByClassName()

Questi metodi al momento della stesura di questa risposta restituisce un oggetto - vuoto o meno - di tipo HTMLCollection E non NodeList.

È come la differenza tra le proprietà children che restituisce un oggetto di tipo HTMLCollection poiché è composto solo da elementi ed esclude nodi di testo o commenti, e childNodes che restituisce un oggetto di tipo NodeList poiché potrebbe contenere anche altri tipi di nodi come testo e commenti.

Nota:Qui andrei per la tangente ed esprimerei la mia mancanza di intuizione sul perché querySelectorAll() Il metodo attualmente restituisce a NodeList e non un HTMLCollection poiché funziona esclusivamente sui nodi degli elementi nel documento e nient'altro.

Probabilmente ha qualcosa a che fare con la potenziale copertura di altri tipi di nodi in futuro e hanno optato per una soluzione più a prova di futuro, chi lo sa davvero?:)

MODIFICARE:Penso di aver capito la logica dietro questa decisione di optare per a NodeList e non un HTMLCollection per il querySelectorAll().

Da quando hanno costruito HTMLCollection essere esclusivamente ed interamente live e poiché questo metodo non necessita di questa funzionalità live, hanno deciso per a NodeList implementazione invece per servire al meglio il suo scopo in modo economico ed efficiente.

La tua prima riga è irrilevante, poiché non forza l'assegnazione alla variabile, javascript funziona al contrario.imagesArr, non è di Type Array(), è di qualunque sia il tipo restituito di getElementsByTagName("img").In questo caso, si tratta di una HtmlCollection in Firefox 3.

Gli unici metodi su questo oggetto sono gli indicizzatori e length.Per lavorare al contrario, basta ripetere all'indietro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top