Concat współpracuje ze zwykłych tablic numerycznych i łańcuchowych, ale nie robi z tablicami obiektów.
Właściwie to robi, ale NodeList
przypadki nie mają metodę concat
i Array#concat
nie posiada środki identyfikacji, które chcesz spłaszczyć tych (bo nie jesteś tablic).
Ale nadal jest dość łatwo zrobić (zobacz poniżej zastrzeżenie). Zmień tę linię:
var allTags = allInputs.concat(allSelects);
do
var allTags = [];
allTags.push.apply(allTags, allInputs);
allTags.push.apply(allTags, allSelects);
Live Example | Source
To działa przy użyciu trochę trick: Array#push
akceptuje zmienną liczbę elementów, aby dodać do tablicy, a Function#apply
wywołuje funkcję korzystając z daną wartość dla this
(w naszym przypadku allTags
) oraz wszelkie array- jak obiekt jako argumenty do przekazania. Ponieważ instancje NodeList
są podobne do tablic, push
z przyjemnością przenosi wszystkie elementy listy do tablicy.
Takie zachowanie Function#apply
(nie wymaga drugiego argumentu naprawdę tablicy) jest bardzo jasno określone w opisie, jest dobrze obsługiwane przeglądarkami.
Niestety, IE6 i 7 nie obsługują powyżej (myślę, że to konkretnie za pomocą gospodarz obiektów — NodeLists
— dla Function#apply
jest drugi argument), ale potem, nie powinno być wspieranie im, albo . :-) IE8 też nie jest bardziej problematyczne. IE9 jest z tego zadowolony.
Jeśli trzeba wspierać IE8 i wcześniej, niestety, myślę, że utkniesz z nudnej starej pętli:
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
To ma działa na IE8 i wcześniejszych (i innych).
nie jest tablica jego tablicą jak przedmiotu (NodeList) – salexch
Jest to w rzeczywistości NodeList, a więc nie ma sposobu concat. – THEtheChad