Quero iterar sobre alguns elementos DOM, estou fazendo o seguinte:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
mas eu recebo um erro:
document.getElementsByClassName ("myclass"). forEach não é uma função
Eu estou usando o Firefox 3, então eu sei que ambos getElementsByClassName
e Array.forEach
estão presentes. Isso funciona bem:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
O resultado de getElementsByClassName
uma matriz? se não, o que é?
fonte
[].forEach.call(elsArray, function () {...})
.querySelectorAll
O método retorna um NodeList.document.getElementsByClassName()
deve retornar umHTMLCollection
(que é muito semelhante, mas não um NodeList). Obrigado por apontar o erro.HTMLCollection
dica. Agora finalmente posso usarHTMLCollection.prototype.forEach = Array.prototype.forEach;
no meu código.Você pode usar
Array.from
para converter coleção em matriz, o que é muito mais limpo queArray.prototype.forEach.call
:Em navegadores antigos que não suportam
Array.from
, você precisa usar algo como o Babel.O ES6 também adiciona esta sintaxe:
Após a reestruturação com
...
obras em todos os objetos do tipo matriz, não apenas as próprias matrizes, é usada uma boa sintaxe antiga de matriz para construir uma matriz a partir dos valores.Enquanto a função alternativa
querySelectorAll
(que meio que tornagetElementsByClassName
obsoleta) retorna uma coleção que possuiforEach
nativamente, outros métodos gostammap
oufilter
estão faltando, então essa sintaxe ainda é útil:fonte
Ou você pode usar o
querySelectorAll
que retorna NodeList :Compatível com navegadores modernos (incluindo Edge, mas não o IE):
Posso usar querySelectorAll
NodeList.prototype.forEach ()
MDN: Document.querySelectorAll ()
fonte
Editar: embora o tipo de retorno tenha sido alterado nas novas versões do HTML (consulte a resposta atualizada de Tim Down), o código abaixo ainda funciona.
Como outros já disseram, é um NodeList. Aqui está um exemplo completo e prático que você pode tentar:
Isso funciona no IE 9, FF 5, Safari 5 e Chrome 12 no Win 7.
fonte
O resultado de
getElementsByClassName()
não é uma matriz, mas um objeto semelhante a uma matriz . Especificamente, é chamado de anHTMLCollection
, para não ser confundidoNodeList
( que possui seu próprioforEach()
método ).Uma maneira simples com o ES2015 de converter um objeto do tipo matriz para uso
Array.prototype.forEach()
que ainda não foi mencionado é usar o operador de propagação ou a sintaxe de propagação :fonte
Não
Como em todos os métodos DOM que retornam vários elementos, é um NodeList, consulte https://developer.mozilla.org/en/DOM/document.getElementsByClassName
fonte
Como já foi dito,
getElementsByClassName
retorna um HTMLCollection , que é definido comoAnteriormente, alguns navegadores retornavam um NodeList .
A diferença é importante, porque agora o DOM4 define os NodeList como iteráveis.
De acordo com o rascunho do IDL da Web ,
Isso significa que, se você quiser usar
forEach
, poderá usar um método DOM que retorne um NodeList , comoquerySelectorAll
.Observe que isso ainda não é amplamente suportado. Veja também o método forEach de Node.childNodes?
fonte
forEach in not a function
document.querySelectorAll(...).forEach is not a function
Ele não retorna um
Array
, ele retorna um NodeList .fonte
Esta é a maneira mais segura:
fonte
getElementsByClassName
retorna HTMLCollection em navegadores modernos.que é um objeto semelhante a um array semelhante aos argumentos iteráveis por
for...of
loop, veja abaixo o que o documento MDN está dizendo sobre ele:exemplo
fonte
error TS2488: Type 'HTMLCollectionOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.
Aqui está um teste que eu criei no jsperf: https://jsperf.com/vanillajs-loop-through-elements-of-class
A versão mais aperfeiçoada no Chrome e no Firefox é o bom e velho loop for combinado com document.getElementsByClassName:
No Safari, esta variante é a vencedora:
Se você deseja a variante mais aperfeiçoada para todos os navegadores, pode ser esta:
fonte