2015-06-15 28 views
7

Mozilla afferma che "for of loop eseguirà un loop su oggetti NodeList correttamente". (fonte: https://developer.mozilla.org/en-US/docs/Web/API/NodeList) Tuttavia, questo non funziona in Chrome 43. Questa documentazione non è corretta o un bug del browser?per loop querySelectorAll

Il codice di esempio copiato utilizzato su una pagina con le caselle di controllo:

var list = document.querySelectorAll('input[type=checkbox]'); 
for (var item of list) { 
    item.checked = true; 
} 
+0

Potremmo avere un po 'più di contesto? Puoi darci un esempio o qualcosa del genere? – Xufox

+0

Mi piacerebbe sapere cosa non funziona esattamente in Chrome. Invia un errore di sintassi? Controlla nessuna delle checkbox? – Xufox

+2

['for..of' loops] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) supportano solo oggetti che sono [implementati come iteratori ] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols), contenente una chiave/metodo 'Symbol.iterator'. Attualmente, in Chrome, 'console.log (Symbol.iterator in elenco); // false'. –

risposta

1

Dal momento che ho usato con successo in for..of Gecko iterare NodeList s, sembra che questo è un bug del browser, o per lo meno una mancanza del browser .

codice di lavoro effettivo da un userscript Attualmente uso:

let llnk = document.querySelectorAll("div#threadlist a.threadtitle_unread"); 
for (let lnk of llnk) { 
    //... 
} 

(Questo utilizza anche let, ma questa è un'altra storia.)

6

La documentazione sono corretti, ma non vorrei chiamare questo un bug. Piuttosto è una "caratteristica non ancora implementata".

Non c'è uno standard per questo, e c'è ancora una discussione attiva su come il DOM dovrebbe integrarsi con ES6. Si noti che è chiaro chequerySelectorAll dovrebbe restituire qualcosa iterabile che può essere utilizzato in un ciclo for of (come le richieste comuni aspettative), ma non è chiaro come che dovrebbe accadere (Let NodeList implementare l'interfaccia Iterable? Lasciate un po 'Elements collection sottoclasse Array?).

1

Prova utilizzando Array.prototype.entries()

var list = [].entries.call(document.querySelectorAll("input[type=checkbox]")); 
 

 
for (item of list) { 
 
    item[1].checked = true; 
 
};
<input type="checkbox" /><input type="checkbox" />

Si potrebbe anche usare Array.prototype.values()

var list = [].values.call(document.querySelectorAll("input[type=checkbox]")); 
 

 
for (item of list) { 
 
    item.checked = true; 
 
};
<input type="checkbox" /><input type="checkbox" />

0

È possibile utilizzare Array.from

let _list = document.querySelectorAll('input[type=checkbox]'); 

let list = Array.from(_list); 

for (let item of list) { 
    //... just like an array 
    item.checked = true 
} 

o più brevemente

let list = document.querySelectorAll('input[type=checkbox]'); 

for (let item of Array.from(list)) { 
    item.checked = true 
} 

Nota importanteArray.from è stato introdotto in Chrome 45 source.

+0

Com'è meglio? Devi chiamare Array.da ogni volta. –

+0

Sì, è vero che devi chiamare 'Array.from' ogni volta (e magari includere un polyfill per quello), ma con questo metodo non stai cercando di estendere il DOM. –

+0

Cosa c'entra questo con l'estensione del DOM? –

0

Questo è quello che faccio, per un approccio diverso

Array.prototype.forEach.call(document.querySelectorAll("input[type=checkbox]"),function(ele,idx) 
{ 
    ele.checked = true; 
} 

bene dal IE9 e soprattutto

0

nativo Symbol.iterator supporto per NodeList stato added alla WHATWG's DOM spec nel 2014.

Purtroppo, Chrome 51 è la prima versione di Chrome a supportarlo e la sua Beta è stata appena rilasciata al momento della stesura di questa risposta. Inoltre, non c'è supporto in nessuna versione di Internet Explorer o Edge.

Per aggiungere Symbol.iterator supporto per NodeList in tutti i browser per il codice, basta utilizzare il seguente polyfill:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 
1

Ecco un'altra soluzione per l'età moderna:

[...document.querySelectorAll("input[type=checkbox]")].forEach(node => { 
    node.textContent = "foo"; 
}); 

Questa sfrutta il spread operator che è supportato in Google Chrome 46+, Firefox 16+ e Edge, e solo per divertimento lo arrow function.

+0

Qual è lo scopo della ricostruzione dell'array? –

+0

Il risultato di 'querySelectorAll' è un NodeList, non un array. Convertendola possiamo facilmente iterare su di essa. –

+0

Che differenza fa ora? Sono entrambi iterabili. –

0

Ho avuto questo problema. Risulta che il mio è stato causato chiamando Promise.all() con parametri invece di un array. Per esempio:

Prima: Promise.all(p1, p2)

Dopo: Promise.all([p1, p2])

Spero che questo aiuta qualcuno.

+0

Cosa c'entra questo con NodeList? –