2010-12-29 7 views
7

Sto avendo un momento difficile convertire un NodeList ad una matrice in IE 8. I seguenti opere perfettamente in Chrome, ma in IE 8 toArray() non è riconosciuto come valido:Converti NodeList di serie

NodeList.prototype.toArray = function() { 
    var a = []; 

    for (var i = 0, len = this.length; i < len; i++) { 
     a[i] = this[i]; 
    } 

    return a; 
} 

document.all.tags("div").toArray(); 

I ho provato ad aggiungere una funzione prototipo a un array solo per verificare il mio equilibrio e funziona correttamente. Questo mi fa pensare che IE 8 in realtà non restituisce un NodeList? Ecco un esempio completo:

http://jsfiddle.net/e4RbH/

Che cosa sto facendo di sbagliato?

+1

non esiste uno standard attuale, che dice che 'NodeList' deve essere una funzione di costruzione visibile e modificabile, o che se c'è una funzione di costruzione visibile come 'NodeList' che verrà usata come tipo di ritorno di tutti i metodi di ritorno di NodeList. (Dopo tutto, un NodeList 'childNodes' e un NodeList' getElementsByTagName' fanno cose molto diverse.) Il prototyping sugli oggetti JS nativi è specificato dallo standard ECMAScript ed è affidabile; la prototipazione su DOM Nodi e altri oggetti non definiti dallo standard di lingua non è affidabile e dovrebbe essere evitata. – bobince

risposta

3

In primo luogo, non utilizzare document.all - non è standard e deprecato. Usa document.getElementsByTagName per ottenere gli elementi DIV nel tuo caso.

In secondo luogo, non estendere gli oggetti DOM come NodeList - gli oggetti incorporati sono una razza molto strana e non sono tenuti a comportarsi come qualsiasi altro oggetto con cui generalmente lavori. Vedi questo articolo per una spiegazione approfondita di questo: What's wrong with extending the DOM.

+0

Stavo usando 'getElementByTagName', ma è passato a' document.all' durante i test. Questo era parte di un problema più grande e ho cercato di semplificarlo. Il vero problema si è rivelato essere un metodo di estensione di 'Array', che è stato implementato in modo improprio e ha influenzato altri codici. –

1

IE non supporta NodeList nel modo standard. Questo è il motivo per cui devi pubblicare il tuo spazio dei nomi e NON estendere gli oggetti principali del browser.

È possibile eseguire alert(typeof window.NodeList) e vedere se non è definito o no.

+0

In Chrome è 'function', in IE 8 è' object', non 'undefined'. Ad ogni modo, questo era il debug di un vecchio codice che ora ho rifatto in uno spazio dei nomi che avevo già. –

+0

È necessario disporre di una versione più recente di IE8 perché la mia non è definita. –

3

vecchia questione, ma qui è un provato & vero metodo:

var nodes=document.querySelectorAll("div"); // returns a node list 
nodes=Array.prototype.slice.call(nodes); // copies to an array 

Spiegazione

  • document.querySelectorAll utilizza un selettore CSS stile di trovare elementi e restituisce un elenco dei nodi. Funziona a partire da IE 8.
  • Il metodo slice copia una parte di una raccolta di tipo array (in questo caso tutto) in una nuova matrice.
  • call permette di prendere in prestito un metodo da un oggetto da utilizzare su un altro

Per trovare l'elenco dei nodi si potrebbe avere utilizzato anche `document.getElementsByTagName(), ma questo è più flessibile.