Concat funziona con normali array numerici e di stringa, ma non lo fa con gli array di oggetti.
In realtà, lo fa, ma NodeList
casi non hanno un metodo concat
, e Array#concat
non dispone di un mezzo di identificazione che si desidera appiattire quelle (perché non sono array).
Ma è ancora abbastanza facile fare (vedere l'avvertenza qui sotto, però). Modificare questa linea:
var allTags = allInputs.concat(allSelects);
a
var allTags = [];
allTags.push.apply(allTags, allInputs);
allTags.push.apply(allTags, allSelects);
Live Example | Source
che funziona utilizzando un piccolo trucco: Array#push
accetta un numero variabile di elementi da aggiungere alla matrice, e Function#apply
chiama la funzione utilizzando il valore espressa this
(nel nostro caso, allTags
) e ogni nell'edificio- come oggetto come gli argomenti da passare ad esso. Dal momento che le istanze NodeList
sono di tipo array, push
spinge felicemente tutti gli elementi della lista sull'array.
Questo comportamento di Function#apply
(non richiede il secondo argomento sia realmente un array) è molto chiaramente definito nella specifica, ed è ben supportato nei browser moderni.
Purtroppo, IE6 e 7 non supportano quanto sopra (penso che sia specificamente utilizzando oggetti host — NodeLists
— per Function#apply
's secondo argomento), ma poi, non dovrebbe essere di supporto loro, sia . :-) Anche IE8 no, il che è più problematico. IE9 è soddisfatto.
Se è necessario sostenere IE8 e precedenti, purtroppo, penso che sei bloccato con un vecchio ciclo noioso:
var allInputs = document.getElementsByTagName('input');
var allSelects = document.getElementsByTagName('select');
var allTags = [];
appendAll(allTags, allInputs);
appendAll(allTags, allSelects);
function appendAll(dest, src) {
var n;
for (n = 0; n < src.length; ++n) {
dest.push(src[n]);
}
return dest;
}
Live Example | Source
Questo fa funziona su IE8 e precedenti (e altri).
questo non è matrice sua matrice come oggetto (NodeList) – salexch
È, infatti, un NodeList, e quindi non ha il metodo concat. – THEtheChad