Gostaria de saber qual é exatamente a diferença entre querySelector
e querySelectorAll
contra getElementsByClassName
e getElementById
?
A partir desta ligação que eu poderia recolher que, com querySelector
eu posso escrever document.querySelector(".myclass")
para obter elementos com classe myclass
e document.querySelector("#myid")
para obter elemento com ID myid
. Mas eu já posso fazer isso getElementsByClassName
e getElementById
. Qual deles deve ser preferido?
Também trabalho em XPages, onde o ID é gerado dinamicamente com dois pontos e se parece com isso view:_id1:inputText1
. Então, quando eu escrevo document.querySelector("#view:_id1:inputText1")
, não funciona. Mas escrever document.getElementById("view:_id1:inputText1")
funciona. Alguma idéia do porquê?
fonte
document.querySelectorAll(".myclass")
? Usardocument.querySelector(".myclass")
retornará apenas o primeiro elemento correspondente.Respostas:
A sintaxe e o suporte ao navegador.
querySelector
é mais útil quando você deseja usar seletores mais complexos.Por exemplo, todos os itens da lista descendem de um elemento que é membro da classe foo:
.foo li
O
:
personagem tem um significado especial dentro de um seletor. Você tem que escapar disso. (O caractere de escape do seletor também tem um significado especial em uma cadeia de caracteres JS, portanto, você também deve escapar disso ).fonte
getElementById
egetElementsByClassName
. A seleção className pode ser algumas centenas de vezes mais lenta semgetElementsByClassName
.coletando da Documentação Mozilla:
A interface NodeSelector Esta especificação adiciona dois novos métodos a qualquer objeto que implemente as interfaces Document, DocumentFragment ou Element:
querySelector
querySelectorAll
e
fonte
Sobre as diferenças, há uma importante nos resultados entre
querySelectorAll
egetElementsByClassName
: o valor de retorno é diferente.querySelectorAll
retornará uma coleção estática, enquantogetElementsByClassName
retorna uma coleção ao vivo. Isso pode causar confusão se você armazenar os resultados em uma variável para uso posterior:querySelectorAll
conterá os elementos que preencheram o seletor no momento em que o método foi chamado .getElementsByClassName
conterá os elementos que atenderam ao seletor quando ele for usado (que pode ser diferente do momento em que o método foi chamado).Por exemplo, observe como até mesmo se você não tiver transferido as variáveis
aux1
eaux2
, eles contêm valores diferentes depois de atualizar as classes:fonte
document.getElementsByName
,document.getElementsByTagNameNS
oudocument.getElementsByTagName
exibem o mesmo comportamento.document.getElementById()
não retorna um nó ativo . É mais rápido do quedocument.querySelector('#id_here')
provavelmente porquequerySelector
terá que analisar primeiro o seletor de CSS.Para esta resposta, refiro-me
querySelector
equerySelectorAll
como querySelector * egetElementById
,getElementsByClassName
,getElementsByTagName
, egetElementsByName
como GetElement *.Principais diferenças
querySelector
egetElementById
ambos retornam um único elemento.querySelectorAll
egetElementsByName
ambos retornam NodeLists, sendo funções mais recentes que foram adicionadas depois que o HTMLCollection saiu de moda. Os mais antigosgetElementsByClassName
e osgetElementsByTagName
dois retornam HTMLCollections. Novamente, isso é essencialmente irrelevante para saber se os elementos são vivos ou estáticos.Esses conceitos estão resumidos na tabela a seguir.
Detalhes, dicas e exemplos
As HTMLCollections não são tão parecidas com matrizes quanto as NodeLists e não suportam .forEach (). Acho o operador spread útil para contornar isso:
[...document.getElementsByClassName("someClass")].forEach()
Todos os elementos e o global
document
têm acesso a todas essas funções, excetogetElementById
egetElementsByName
, as quais são implementadas apenasdocument
.Encadear chamadas getElement * em vez de usar querySelector * melhorará o desempenho, especialmente em DOMs muito grandes. Mesmo em DOMs pequenos e / ou com cadeias muito longas, geralmente é mais rápido. No entanto, a menos que você saiba que precisa do desempenho, a legibilidade do querySelector * deve ser preferida.
querySelectorAll
geralmente é mais difícil reescrever, porque você deve selecionar elementos do NodeList ou HTMLCollection a cada etapa. Por exemplo, o código a seguir não funciona:document.getElementsByClassName("someClass").getElementsByTagName("div")
document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]
Como todos os elementos têm acesso às chamadas querySelector * e getElement *, você pode criar cadeias usando as duas chamadas, o que pode ser útil se você quiser obter algum ganho de desempenho, mas não pode evitar um querySelector que não possa ser gravado em termos das chamadas getElement * .
Embora seja geralmente fácil saber se um seletor pode ser gravado usando apenas chamadas getElement *, há um caso que pode não ser óbvio:
document.querySelectorAll(".class1.class2")
pode ser reescrito como
document.getElementsByClassName("class1 class2")
O uso de getElement * em um elemento estático buscado com querySelector * resultará em um elemento que está ativo com relação ao subconjunto estático do DOM copiado por querySelector, mas não com relação ao documento completo DOM ... é aqui que o simples a interpretação ao vivo / estática dos elementos começa a desmoronar. Você provavelmente deve evitar situações em que precisa se preocupar com isso, mas, se o fizer, lembre-se de que querySelector * chama elementos de cópia que eles encontram antes de retornar referências a eles, mas as chamadas getElement * buscam referências diretas sem copiar.
Nenhuma API especifica qual elemento deve ser selecionado primeiro se houver várias correspondências.
Como o querySelector * itera pelo DOM até encontrar uma correspondência (consulte a Diferença principal nº 2), o exposto acima também implica que você não pode confiar na posição de um elemento que está procurando no DOM para garantir que ele seja encontrado rapidamente. o navegador pode percorrer o DOM para trás, para frente, profundidade primeiro, largura primeiro ou de outra forma. O getElement * ainda encontrará elementos aproximadamente na mesma quantidade de tempo, independentemente de seu posicionamento.
fonte
Eu vim a esta página apenas para descobrir o melhor método para usar em termos de desempenho - ou seja, o que é mais rápido:
e achei o seguinte: https://jsperf.com/getelementsbyclassname-vs-queryselectorall/18
Ele executa um teste nos 2 x exemplos acima, além de incluir também um teste para o seletor equivalente do jQuery. meus resultados de teste foram os seguintes:
fonte
querySelectorAll
precisa de trabalho adicional nos bastidores (incluindo a análise da expressão do seletor, a contabilização de pseudo elementos, etc.), enquantogetElementsByClassName
é apenas um percurso de objeto recursivo.querySelector
pode ser um seletor CSS (3) completo com IDs e classes e pseudo-classes juntas assim:com
getElementByClassName
você pode apenas definir uma classecom
getElementById
você pode apenas definir um IDfonte
:first
Agora é um seletor de CSS?:first-class
, ou:first-of-type
talvez, mas achei que:first
era uma adição ao JavaScript / jQuery / Sizzle.:first
é, visivelmente, não:first-child
.querySelector
equerySelectorAll
estão relativamente novas APIs, enquantogetElementById
egetElementsByClassName
têm estado conosco por muito mais tempo. Isso significa que o que você usa dependerá principalmente de quais navegadores você precisa suportar.Quanto ao
:
, ele tem um significado especial; portanto, você deve escapar se precisar usá-lo como parte de um nome de ID / classe.fonte
querySelectorAll
está disponível no IE8, enquantogetElementsByClassName
não está.querySelectorAll
... basicamente tudo: caniuse.com/#search=querySelectorAllquerySelector
é da API do w3c SelectorgetElementBy
é da API DOM do w3cNa IMO, a diferença mais notável é que o tipo de retorno
querySelectorAll
é uma lista de nós estáticos e, porgetElementsBy
isso, é uma lista de nós ativos. Portanto, o loop na demonstração 2 nunca termina porquelis
está ativo e se atualiza a cada iteração.fonte
Diferença entre "querySelector" e "querySelectorAll"
fonte
Veja isso
getElementById mais rápido que querySelector em 25%
jquery é o mais lento
fonte
A principal diferença entre querySelector e getlementbyID (Claassname, Tagname etc) é se houver mais de um elemento que satisfaz a condição querySelector retornará apenas uma saída, enquanto getElementBy * retornará todos os elementos.
Vamos considerar um exemplo para torná-lo mais claro.
O código abaixo explicará a diferença
Por exemplo, se queremos selecionar um único elemento, vá para o queryslector ou se queremos que vários elementos, vá para getElement
fonte