Aula 10 - Manipulação do DOM
Uma visão geral do modelo objeto-documento (DOM) e suas formas de manipulação com javascript
Exemplos de aula
Operações no DOM

Cada documento HTML lido pelo navegador precisa ser estruturado pelo navegador de forma a permitir a manipulação dos elementos HTML e também sua renderização na tela. O DOM (Document Object Model) é uma interface usada pelos navegadores para representar e dar acesso aos elementos de uma página web.
Podemos utilizar javascript para manipular diretamente os objetos de uma página e, dessa forma, serão adequadamente atualizados pelo navegador. Essa manipulação através do javascript é feita utilizando o objeto document.
Com o acesso aos objetos (que são os elementos HTML), também podemos acessar seus respectivos atributos, textos (conteúdo de um elemento) e eventos.
Para recuperar um elemento já presente no DOM, vamos utilizar a função:
var umaVariavel = document.querySelector("seletor")
Repare que no lugar de "seletor", vamos inserir um seletor no mesmo formato que já utilizamos no CSS (ex.: #id, .classe, input). Esse método sempre retorna o primeiro elemento encontrado na árvore DOM. Para encontrar todos os elementos, podemos utilizar:
var umaLista = document.querySelectorAll("seletor")
Esse método retorna sempre um vetor, independente do número de ocorrências encontradas, contendo cada um dos elementos. Para acessá-los, podemos usar este for:
for(var umElemento of umaLista){
console.log(umElemento)
}
O chamado for of é um atalho de repetição que pode ser utilizado para qualquer tipo de variável iterável, que é o caso de um vetor. Ele percorre automaticamente todas as posições do vetor e finaliza quando este termina. Em cada iteração, a primeira variável assume o valor de um elemento. A alternativa clássica para a estrutura acima seria:
for(var i = 0; i < umaLista.length(); i++){
var umElemento = umaLista[i]
}
Em determinado momento, surge a necessidade de adicionar um novo elemento à uma página em tempo de execução. Por exemplo, ao clicar em um botão, você deseja adicionar um novo títuloh1 à página.
Apesar de ser possível inserir um novo elemento no DOM apenas alterando o conteúdo de texto, devemos criá-lo usando a interface DOM disponibilizada pelo navegador. Para isso, usaremos a seguinte sintaxe:
var novoTitulo = document.createElement("h1")
Isso faz com que o DOM crie um novo elemento e armazene-o na variável novoTitulo. No entanto, ele não sera renderizado na tela. A razão é que ele foi criado apenas na memória e ainda não foi anexado à árvore do DOM. Faremos isso usando essa operação para acessar obody e adicionar o elemento:
var novoTitulo = document.createElement("h1")
document.body.appendChild(novoTitulo)
Repare que passamos como parâmetro da função appendChild nosso novo títuloh1 recem criado. O novo título será anexado na árvore exatamente dentro do nó do qual a função appendChild foi chamada, ou seja, o nó body. No entanto, ainda não damos nenhum conteúdo de texto para nosso título, vamos fazer isso usando:
var novoTitulo = document.createElement("h1")
document.body.appendChild(novoTitulo)
novoTitulo.textContent = "Meu novo título"
Substituímos o conteúdo da variável novoTitulo, mas como está é apenas um "apontador" para o elemento que foi anexado na árvore, ele será atualizado instantaneamente na página. É possível alterar qualquer atributo de um elemento HTML. Vamos alterar, por exemplo, o iddesse elemento:
novoTitulo.id = "titulo-novo"
Para alterar a classe de um elemento, também podemos usar as funções abaixo:
document.body.classList.add("umaClasse") // adiciona a classe umaClasse ao elemento
document.body.classList.remove("umaClasse") // adiciona a classe umaClasse ao elemento
Para remover um elemento pré-existente na árvore do DOM, podemos utilizar a funçãoremoveChild. Observe este exemplo:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
var pai = document.querySelector("ul")
var filho = pai.querySelector("li")
pai.removeChild(filho)
O código acima remove o primeiro elemento da lista ul. Repare que é necessário recuperar, além do elemento que queremos deletar, o seu pai, pois é ele quem renderiza os elementos filhos (assim como precisamos dele para adicionar um novo nó). No entanto, podemos usar a seguinte sintaxe para encontrar o elemento pai de um nó filho:
var filho = document.querySelector("li")
var pai = filho.parentNode
Dessa forma, o atributo parentNode sempre retorna o elemento pai.
Outros tópicos
Uma variável no javascript é um container para armazenar dados. Assim como podemos armazenar tipos de dados primitivos do javascript, como strings, number e arrays, também temos um tipo de dado chamado object.
Um objeto pode conter vários tipos de valores, e sua utilização é caracterizada pelo uso de pares de chaves e valores. Por isso, um objeto no javascript tem uma sintaxe básica parecida com essa:
var meuObjeto = {
"chave": "valor"
}
Para deixar mais claro, vamos criar um objeto que representa uma fruta:
var fruta = {
"nome": "maçã",
"peso": 180,
"cor": "vermelha",
"mordida": true
}
Repare que podemos armazenar, separados por virgula, vários pares de dados, demarcados com uma chave para representação. Essa chave é usada para acessar cada um dos dados do objeto:
console.log(fruta.nome) // imprime maçã
console.log(fruta.peso) // imprime 180
console.log(fruta.mordida) // imprime true
Outra característica importante de um objeto no javascript é que o tipo de dado aceito para cada chave é exatamente o mesmo que para qualquer variável. Ou seja, podemos usar como valor strings, number, arrays e outros objects:
var sistemas = {
"maçã": {
"nome": "maçã",
"peso": 180,
"cor": "vermelha",
"mordida": true
},
"janela": {
"nome": "janela",
"peso": 10000,
"quebrada": true
}
}
Repare que cada objeto interno maçã e janela são totalmente independentes, possuindo diferentes nomes para suas chaves.
Um problema pode ocorrer para acessar a chave maça, já que não podemos utilizar caracteres especiais. Por isso, podemos utilizar também a seguinte sintaxe:
sistemas["maçã"].nome // retorna maçã
Mão na Massa
Crie uma página que permita ao usuário gerenciar uma lista com filmes/jogos. O formulário de inserção deve conter nome, estilo/gênero e URL de imagem (local ou remota).
Cada filme/jogo adicionado deve estar dentro de uma div, e deve apresentar os dados de entrada de forma estilizada (Ex.: a foto deve ser exibida com a tag img).
Crie uma página que contenha um formulário para cadastro de atores com os seguintes items:
- Nome
- Nacionalidade
- URL de Imagem
Na mesma página, crie uma seção contendo um select (documentação) e um espaço para os mesmos campos listados no formulário anterior. Implemente uma função que insira um novo item no select a cada novo cadastro no objeto. Além disso, cada vez que o select é alterado, as informações devem ser atualizadas na seção.
Para atualizar as informações quando o usuário seleciona um novo item no select, utilize o evento onChange (documentação)
Utilizando um javascript, crie três listas drop-down (elemento select) para apresentar ano, meses e dias.
Apenas anos entre 1990 e 1999 devem ser apresentados. Os meses devem estar entre Fevereiro e Agosto. E os dias do mês devem estar entre 05 e 25.
Todos os elementos devem ser gerados dinamicamente através do javascript (Dica: use estruturas de repetição)
Exercícios Complementares
Crie um função que gera de números de um sorteio de mega-sena. Como referência, o gerador deve apresentar um conjunto de 6 números de 1 a 60, sendo que cada número é único na sequência e não há possibilidade de repetir estes números em uma mesma jogada (amodal).
Em seguida, crie um formulário onde seja possível ao usuário "comprar tickets", definindo uma sequência amodal e registrando o ticket comprado na tela.
Por fim, a interface deve conter um botão de sorteio, que chama a função de sorteio e identifica se houve algum ticket ganhador
Ex.: O botão de sorteio pode ser implementado com algum tipo de timeout para exibir o ganhador