Manipular uma Página HTML através do JavaScript
Veremos, no decorrer do presente artigo, formas de selecionar elementos do HTML, como alterar os elementos selecionados, adicionar e remover elementos do HTML, tudo dinamicamente via JavaScript.
Não deve ser mais novidade para você, de que o client-side, lado do cliente, ou seja, a página que você está vendo aí na sua tela funciona, fundamentalmente, sobre três tecnologias: HTML, CSS e JavaScript.
O HTML serve para marcar as coisas em uma página, identificando o que é um título, parágrafo, menu, citação, lista de itens e muito mais.
Já o CSS, estiliza a página. Com ele, podemos pegar os elementos marcados no HTML e atribuir cor, tamanho e uma série de outros efeitos visuais.
E o JavaScript, principal foco deste artigo, foi desenvolvido originalmente para prover dinamismo às páginas HTML, permitindo a construção de páginas mais interativas.
Já vamos adentrar nas formas de manipular o HTML através do JavaScript, mas antes, vale ressaltar, como essas tecnologias se integram. Para que, aqueles que ainda não tenham este conhecimento, também possam acompanhar o conteúdo do artigo sem nenhum problema.
Nos projetos, o HTML, CSS e JavaScript geralmente encontram-se separados em seções distintas, por uma questão de organização. Mas, obviamente, se conversam entre si.
A reunião de todas essas tecnologias é feita na página HTML. Sendo o CSS importado no início do documento, através da metatag link
e o JavaScript ao final, com o caminho do arquivo sendo indicado no atributo Source (fonte) src
da tag script
.

Essa noção de separação dos três mundos, facilitará seu entendimento a respeito de um utilitário, nativo nos navegadores e que iremos utilizar durante o artigo para demonstrar alguns códigos, chamado Ferramentas do Desenvolvedor.
Nesta ferramenta, quando você quiser falar com o HTML, utiliza a aba Elements, o CSS é acessado na guia Stylus e o JavaScript, na seção Console.

A forma de acessar as Ferramentas do Desenvolvedor pode variar um pouco em cada navegador. Em caso de dúvidas, pesquise como localizar esta ferramenta em seu navegador e sistema operacional específico.
Em geral, nos navegadores mais populares, a ferramenta também costuma estar acessível, através do atalho de teclado F12
.
Tendo acesso ao HTML pelo JavaScript
Se pretendemos manipular os elementos de uma página HTML via JavaScript, precisamos, de alguma forma, ter acesso ao HTML no mundo do JavaScript.
Um carinha que nos ajuda nessa tarefa é o DOM, que significa Document Object Model.
O DOM é a representação do HTML em JavaScript. Você pode, por exemplo, abrir as Ferramentas do Desenvolvedor em seu navegador e, na aba Console, digitar document
. Pronto, você acaba de acessar, via JavaScript, os elementos HTML da página deste artigo.

Selecionar partes da página
A partir do DOM, você pode modificar pedaços da página, sem a necessidade de recarregá-la para que as mudanças surtam efeito. Mudar o conteúdo de uma tag, mexer na estilização, acrescentar ou remover elementos da estrutura HTML, detectar eventos de interação com a página e muito mais.
Mas tudo passa, primeiramente, pela seleção dos elementos que se deseja manipular.
Selecionar elemento pela tag
Selecionamos um elemento HTML pela tag através do método querySelector()
, informando como parâmetro, a tag de interesse. No exemplo abaixo, o h1
.
document.querySelector('h1');

Selecionar elemento pela Classe
Outra forma, é selecionar o elemento pela classe. O que é feito passando-se .
ponto, seguido pelo nome da classe, como parâmetro do método querySelector()
.
document.querySelector('.titulo');

Alterar conteúdo de texto de um elemento
Aproveitando o conhecimento que temos agora de seleção, vamos avançar um pouco e alterar o conteúdo de texto em um elemento. Nesse sentido, primeiro iremos guardar o elemento selecionado numa variável, que irei chamar de título.
let titulo = document.querySelector('.titulo');
Podemos até imprimir o conteúdo da variável. Aliás, é sempre uma boa prática certificar-se de cada passo que você faz.
console.log(titulo);
Porém, não estamos interessados no elemento como um todo, e sim, no seu conteúdo. Temos acesso ao conteúdo de um elemento através da propriedade textContent
.
console.log(titulo.textContent);

Agora que temos acesso, podemos atribuir um novo conteúdo ao elemento. E ele será, imediatamente, renderizado na página.
titulo.textContent = 'Novo Título';

Mas calma, você não hackeou a página. Apenas alterou localmente o código que foi entregue a você pelos nossos servidores. Ao recarregar o navegador, tudo volta ao normal.
Selecionar Elementos pelo ID
Considere a tabela abaixo com o identificador tabela-clientes
.

Selecionamos elementos pelo identificador passando o caractere cerquilha #
antes do id, como parâmetro do método querySelector()
.
let tabelaClientes = document.querySelector('#tabela-clientes');

Selecionar Várias Ocorrências de um Mesmo Elemento
Quando você precisa selecionar várias ocorrências de um mesmo elemento, pode utilizar o método querySelectorAll()
, que lhe retornará um array com todos os elementos de interesse.
Abaixo, para ilustrar, selecionamos todos os elementos dentro da tabela, que possuem a classe cliente.
let clientes = tabelaClientes.querySelectorAll('.cliente');

Listar, Adicionar e Remover Classes CSS no HTML via JavaScript
Para manipular Classes CSS dinamicamente através do JavaScript, vamos utilizar como exemplo, novamente, o site atual. Onde você está lendo este artigo.
Ao rolar a página para baixo, a partir de certo ponto você deve notar o surgimento, no canto inferior direito, de um botão que, ao ser clicado, te levará novamente para o topo.
Isso foi feito simplesmente pela adição, dinamicamente via JavaScript, de uma classe CSS ao HTML, que torna o botão visível.
Se você tiver curiosidade, pode novamente lançar mão das Ferramentas do Desenvolvedor para analisar o código. Para isso, basta posicionar o ponteiro do mouse sobre a área específica do site que se deseja inspecionar, clicar com o botão direito e, no menu de acesso rápido, escolher "Inspecionar".

Você verá, através da aba Elements, uma âncora (a famosa tag para fazer links) com as classes icone-arrow-up
e icone-arrow-up--ativo
. Este é, justamente, o elemento que corresponde ao botão.
Escolha a aba Console na Ferramenta do Desenvolvedor e, utilizando os conhecimentos adquiridos acima, selecione o elemento e guarde-o em uma variável. Por exemplo:
let voltarAoTopo = document.querySelector('.icone-arrow-up');
Em seguida, chame a variável declarada na linha anterior e execute a propriedade classList
, a qual, deve listar todas as classes do referido elemento.
voltarAoTopo.classList;

O classList
também nos disponibiliza alguns métodos. Dois que podem ser úteis aqui, são o add()
e o remove()
que adicionam ou removem classes CSS.
Se você pegar a variável que contém o elemento, chamar a propriedade classList
e invocar o método remove()
, passando como parâmetro a classe icone-arrow-up--ativo
, irá observar que o botão desaparece.
voltarAoTopo.classList.remove("icone-arrow-up--ativo");
Agora listando novamente as classes do elemento, a que foi removida não estará mais presente.
Se você rolar a página, o evento de scroll será detectado e a classe novamente adicionada. Mas experimente removê-la, não rolar a página, e inserir a classe manualmente. Você verá que o botão ressurge.
voltarAoTopo.classList.add("icone-arrow-up--ativo");
Montando Elementos HTML via JavaScript
O método disponível pelo DOM para criação de um elemento HTML é o createElement()
.
Voltando ao exemplo da nossa tabela clientes, vamos adicionar um novo cliente a ela via Javascript.
Adicionar um cliente, nada mais é do que criar uma nova linha tr
na tabela.
let cliente = document.createElement("tr");
Agora que já temos a linha, vamos criar as células td
para esta linha.
let nomeCliente = document.createElement("td");
let idadeCliente = document.createElement("td");
Se você imprimir o resultado, verá que os elementos foram criados separadamente. Mas, queremos que as células estejam dentro da linha.

Para isso, iremos usar o método appendChild()
, ou seja, coloque como filho. Designando as células como filhas da linha.
cliente.appendChild(nomeCliente); cliente.appendChild(idadeCliente);
Agora já temos um resultado mais próximo do que desejamos.

O próximo passo, é colocar o nome do cliente e idade nas células. Já vimos acima como fazer isso, basta setar o textContent
, atribuindo o valor desejado a cada elemento.
nomeCliente.textContent = "João"; idadeCliente.textContent = "35";
E, por último, colocamos o novo cliente como filho da tabela de clientes.
tabelaClientes.appendChild(cliente);

Escrevendo Menos Código e Melhorando a Legibilidade
Você deve ter notado que repetimos diversas vezes a sintaxe document.querySelector
, todas as vezes que precisamos selecionar partes da nossa página html. Que tal criarmos um apelido (alias), copiando um pouco o JQuery, e assim, escrever menos código?
Em JavaScript temos as First Class Functions, isso significa que funções são tratadas como qualquer outra variável. Consequência, as funções podem ser atribuídas como um valor à uma variável, passadas como argumentos para outras funções e retornadas por outra função.
Sabendo disso, vamos definir uma variável denominada cifrão $
e carregar o método querySelector
nela.
let $ = document.querySelector;
E agora, para chamar a função que está na variável $
, utilizamos o abre e fecha parêntese ()
. A partir daí, toda vez que quisermos selecionar algum elemento da nossa página html, escreveremos algo como:
let titulo = $('.titulo');
Acabamos de selecionar o elemento html da página, que possui a classe título. Até aqui, tranquilo. Nada novo em relação ao que já vimos acima.
Por que então o alias que criamos com o cifrão $
não está funcionando? Vamos entender!
No JavaScript, e demais linguagens que suportam o paradigma de Orientação a Objetos, tudo é um objeto.
Um objeto é uma instância de uma classe. Mas calma, eu não sei o que é classe. Tudo bem. Se fossemos usar uma metáfora, a receita de um bolo seria a classe e o bolo físico, a instância. Em outras palavras, a materialização.
Uma classe possui métodos. Aliás, em JavaScript, quando um procedimento de programação está declarado fora de uma classe, é chamado de função. E, quando está dentro de uma classe, de método.
Em nosso exemplo, querySelector
é um método da classe document
. Mas quando carregado na váriável cifrão $
, passa a ser uma função.
Para ficar mais claro, criamos abaixo uma classe denominada Pessoa
, com as propriedades nome
e idade
.

Ao olhar para dentro da classe, você verá a palavra reservada this
. Ela representa, entre outras coisas, o contexto de execução.
O contexto é todo o escopo que determinada função, método, objeto ou variável está inserida.
Em algumas linguagens, o this
possui um contexto fixo e definido. Mas este não é o caso do JavaScript.
Se colocarmos um console.log
dentro da classe Pessoa
para imprimir o this
, veremos que seu valor é Pessoa.

Já o this
fora da classe, tem outro valor. Ao imprimi-lo no console do navegador, por exemplo, é Window
.

Então é isso que está ocorrendo. Estamos tentando executar o método querySelector
fora de seu contexto que é document
e isso não vai funcionar.
O ES5 introduziu o método bind
para estabelecer o valor this
da função, independente de como ela for chamada.
Bind significa ligado. Nesse caso, queremos executar o querySelector
fora do contexto de document
, mas mantê-lo ligado ao document
. Então vamos utilizar o bind
para manter essa ligação.
let $ = document.querySelector.bind(document);
Agora sim, podemos selecionar qualquer elemento do nosso html usando o cifrão $
e, entre parêntesis, informar a tag, classe ou id de interesse.
let titulo = $('.titulo');
