[PT-BR] Selecionando elementos HTML no Javascript
Tags: braziliandevs, javascript
Published: 2021-03-11 00:33:56

Olá pessoas! Já fazem algumas semanas desde que criei meu perfil, meio que na empolgação, e seguindo a recomendação da [Morganna](https://dev.to/morgiovanelli), vou escrever sobre coisas que eu estou estudando e achando interessante. Uma dessas coisas, é a utilização dos métodos seletores do Javascript, que realmente me chamaram muita atenção. Então... Vamos nessa!
## O que são seletores?
Seletores são métodos do objeto Document, que basicamente é a sua página web. Esses métodos permitem que você selecione algumas tags HTML (e seu conteúdo), permitindo depois que você manipule o conteúdo e propriedades dessas tags.
Acho que a melhor maneira de entender como isso funciona, é criando um código HTML para usarmos como exemplo.
~~~html
<div id = "primeiro-conteudo" class = "conteudo">
  <ul class = "usuarios">
   <li class = "amigo">João</li>
   <li class = "inimigo">Fernanda</li>
   <li class = "amigo">Amanda</li>
  </ul>
</div>
<div id = "segundo-conteudo" class = "conteudo">
  <p id = "descricao">Estou descrevendo alguma coisa</p>
</div>
<div id = "terceiro-conteudo" class = "conteudo">
  <input type="text" name="opiniao" />
</div>
~~~
Esse código pode não fazer muito sentido ou seguir algum tipo de regra de escrita, mas o que importa neste exemplo é como as tags estão estruturadas (suas classes, seus ids, quais tags estão dentro de quais tags, etc.). Agora, vamos utilizar os métodos seletores para selecionar diferentes trechos desse código.

## document.getElementById()
Este método é o mais simples de todos, e retorna um elemento correspondente ao id passado como parâmetro (em formato string). Caso mais de um elemento possua o id passado como parâmetro, a função retorna o primeiro elemento encontrado.Veja o código abaixo.
~~~javascript
let desc = document.getElementById("descricao");
~~~
Esse comando cria uma variável chamada desc, e armazena dessa variável o elemento cujo id é igual ao id passado como parâmetro. Caso este id não exista dentro do código HTML, o retorno da função é `null`. Agora que o elemento foi armazenado em uma variável, vamor entender o conteúdo desta variável.
`desc` é uma variável que armazena um objeto, com diversas propriedades. Se imprimissimos esta variável no console, o resultado seria:
~~~html
<p id = "descricao">
~~~
No console do navegador é possível ver as propriedades deste elemento, mas existem duas que vou pontuas aqui:
*innerText: Texto de dentro da tag;
*innetHTML: HTML de dentro da tag;
Agora que conhecemos estas duas propriedades, podemos alterar ou mostrar o conteúdo.
~~~javascript
console.log(desc.innerText);//Imprime o texto no console
desc.innerText = "Uma nova descrição atualizada";//altera o conteúdo que está dentro da tag
~~~
Claro que diversas outras operações podem ser realizadas com o objeto selecionado, mas vamos focar só nestes dois atributos por enquanto.

## document.getElementsByClassName()
Se você entendeu como a função anterior funciona, esta aqui vai ser bem simples de entender. Como o próprio nome já diz, essa função vai retornar os elementos que possuem uma mesma classe passada como parâmetro em formato string. Todos os elementos que corresponde àquela classe. Enquanto a função anterior retorna um único elemento, esta função retorna uma HTMLCollection (uma coleção) de elementos, a não ser que o seletor não seja encontrado na página HTML, então o retorno `null`. No nosso código, temos alguns itens separados nas classes "amigo" e "inimigo". Vamos selecionar esses elementos.
~~~javascript
const amigos = document.getElementsByClassName("amigo");
const inimigos = document.getElementsByClassName("inimigo");
~~~
Agora te propronho um desafio. Se eu imprimisse o valor da variável inimigos, qual seria meu resultado?
Este seletor sempre vai retornar uma coleção com todos os elementos da mesma classe. Se eu tiver apenas um elemento com esta classe, ainda será uma coleção, mas com tamanho 1 (com um único elemento). Portanto o resultado dessa impressão seria:
~~~javascript
HTMLCollection { 0: li.inimigo, length:1}
~~~
Ou seja, um objeto do tipo HTMLCollection, que possui comprimento de 1 e possui um objeto `li.inimigo` na posição 0. Essa saída, é a padrão do `console.log()`, e caso quisessemos acessar as propriedades do único objeto presente nesta coleção, podemos acessar este objeto com a notação de colchetes, e depois acessar as propriedades do objeto.
~~~javascript
console.log(inimigos[0].innetText)
~~~
Agora que você já sabe disso, qual acha que seria o output da impressão da variável amigos?
Seria assim:
~~~javascript
HTMLCollection { 0: li.amigo, 1:li.amigo, length:2}
~~~
Para acessar os elementos da variável amigos, também deve-se usar a notação de colchetes e depois de selecionado o objeto, acessar seus atributos, como foi mostrado anteriormente.

## document.getElementsByTagName()
Esta função é bem similar à anterior, com a diferença que cria uma coleção selecionando TODAS as tags com o mesmo nome, por exemplo `p`, `div`, ou `li`(lembrando que este nome deve ser passado como string).
~~~javascript
let partesDoConteudo = document.getElementsByTagName("div");
~~~
Agora vou propor novamente um desafio. Volte no nosso código no início do artigo, e me diga qual será o conteúdo da variável partesDoConteudo (uma dica, é bem similar ao conteúdo do método getElementsByClassName()).
Resultado:
~~~javascript
HTMLCollection { 0: div#primeiro-conteudo.conteudo, 1: div#segundo-conteudo.conteudo, 2: div#terceiro-conteudo.conteudo, length: 3, … }
~~~
Todos os objetos com a classe `div` foram selecionados, tendo também seus ids especificados, embora estes ids tenham sido irrelevantes na seleção.
Assim como no método getElementsByClassName(), os objetos desta coleção devem ser acessados com a notação de colchetes, para que então você consiga acessar os atributos deste objeto. 
~~~javascript
partesDoConteudo[0].innerText;
partesDoConteudo[1].innerHTML;
~~~
Mesmo que haja apenas um elemento com esta classe

## document.getElementsByName()
Assim como os outros métodos que contém plural no nome, este método também retorna uma coleção HTML, selecionando os trechos de código pelo atributo `name` das tags HTML. (Reveja o código exemplo no início do artigo)
~~~javascript
let opiniaoUsuario = document.getElementsByName("opiniao");
~~~
Como só temos um elemento com o atributo `name` selecionado, quando tentarmos imprimir a variável opiniaoUsuario, teremos uma coleção com um único objeto, que assim como nos exemplos anteriores deve ser acessado com a notação de colchetes.

## document.querySelector()
Este método é relativamente novo no Javascript, e é muito interessante de se usar. Diferentemente dos outros métodos mostrados até agora, o querySelector não recebe um atributo de uma tag HTML como parâmetro, mas recebe o mesmo seletor que seria utilizado em CSS, no formato string. É importante lembrar que como no CSS, a utilização de "." para indicar classes e de "#" para indicar ids é obrigatória.
~~~javascript
let inicio = document.querySelector("#primeiro-conteudo");
let paragrafo = document.querySelector("p");
let textoOpiniao = document.querySelector(".conteudo#terceiro-conteudo input");
let conteudoTotal = document.querySelector(".conteudo");
~~~
Todas as sintaxes utilizadas no código acima são validas. Podemos utilizar o `querySelector()` para selecionar por id, por classe, por nome de tag ou por uma combinação destes elementos. Um ponto interessante do `querySelector()`, é que essa função só retorna o primeiro elemento encontrado que tem a mesma configuração do seletor passado como parâmetro. Por exemplo, a variável `conteudoTotal` só vai receber o primeiro elemento com a classe `conteudo`, no formato de um único elemento, não de uma coleção. Se quisermos obter todos os elementos que combinam com um mesmo seletor, devemos utilizar o próximo método da lista.

## document.querySelectorAll()
O querySelectorAll é bem similar ao método querySelector, e também utiliza os seletores do CSS, com a diferença de que retorna uma NodeList (lista de nodos) com todos os elementos que correspondem ao seletor criado. Podemos pensar na NodeList como se fosse um vetor, para facilitar o entendimento, e assim como nas coleções, podemos acessar os elementos através da notação de colchetes.
~~~javascript
let paragrafo = document.querySelectorAll("p");
let conteudoTotal = document.querySelectorAll(".conteudo");
~~~
Caso um único elemento bata com o seletor passado como parâmetro, o resultado será uma NodeList com apenas um elemento, caso contrário, mais elementos estarão dentro deste objeto.


## Considerações finais
É uma boa prática guardar o resultado de um seletor em uma variável, e apartir desta variável acessar os atributos ou métodos referente ao objeto selecionado, o que facilita a utilização do objeto selecionado dentro do código. 
Existem também várias maneiras de selecionar elementos, e como programador você deve escolher qual forma melhor se adapta à sua necessidade, sendo que várias dessas são possíveis.
Espero que este artigo possa ter ajudado, e boa sorte com seus códigos!