Manipulação de Elementos e Eventos com Web APIs em JavaScript

As Web APIs representam um conjunto de interfaces fornecidas pelos navegadores, permitindo que o JavaScript interaja com o ambiente web. Elas são a ponte entre o seu código e o documento HTML renderizado, bem como as funcionalidades do próprio navegador.

Tradicionalmente, o JavaScript pode ser categorizado em três pilares:

  • ECMAScript: A linguagem base, definindo a sintaxe e a lógica fundamental.
  • DOM (Document Object Model): API para interagir e manipular a estrutura, o conteúdo e o estilo de documentos HTML e XML.
  • BOM (Browser Object Model): API para interagir com o navegador em si, como o histórico, a janela e a localização.

As Web APIs englobam tanto o DOM quanto o BOM, fornecendo ferramantas essenciais para construir interfaces de usuário dinâmicas e responsivas.

Entendendo o Document Object Model (DOM)

O DOM é uma representação estruturada de um documento HTML ou XML como uma árvore de objetos. Cada parte do documento — elementos, atributos, texto — é um nó nessa árvore. Através do DOM, o JavaScript pode acessar e modificar esses nós.

  • Documento: O HTML completo é representado pelo objeto global document.
  • Elementos: As tags HTML (como <div>, <p>, <button>) são objetos do tipo Elemento.
  • Nodos: Um conceito mais abrangente, onde tudo no documento (elementos, texto, comentários, atributos) é considerado um nodo.

Selecionando Elementos da Página

Para manipular qualquer parte do HTML, primeiro precisamos selecioná-la. As Web APIs oferecem diversos métodos para isso, com querySelector e querySelectorAll sendo opções modernas e flexíveis, que utilizam seletores CSS.

<div id="container-principal">
   <h2>Minha Seção</h2>
   <p class="info-texto">Este é um parágrafo de informação.</p>
   <ul>
       <li class="item-lista">Item 1</li>
       <li class="item-lista destaque">Item 2</li>
       <li class="item-lista">Item 3</li>
   </ul>
</div>

const container = document.querySelector('#container-principal');
console.log(container); // Seleciona o div pelo ID

const primeiroParagrafo = document.querySelector('.info-texto');
console.log(primeiroParagrafo); // Seleciona o primeiro elemento com a classe 'info-texto'

const todosItens = document.querySelectorAll('.item-lista');
console.log(todosItens); // Retorna um NodeList de todos os elementos com a classe 'item-lista'
console.log(todosItens[1].textContent); // Acessa o texto do segundo item

const itemDestaque = document.querySelector('ul .destaque');
console.log(itemDestaque); // Seleciona o item com a classe 'destaque' dentro de um 'ul'

Respondendo a Eventos do Usuário

Os eventos são a forma como o JavaScript detecta e reage às interações do usuário ou a mudanças no navegador. Cada evento possui:

  • Fonte do Evento: O elemento HTML que disparou o evento.
  • Tipo de Evento: A ação ocorrida (clique, pressionar tecla, enviar formulário, etc.).
  • Manipulador de Eventos: A função JavaScript que será executada em resposta ao evento.

Evantos de Clique

O evento de clique é um dos mais comuns, disparado quendo um usuário clica em um elemento.

<button id="botao-saudacao">Diga Olá</button>
<p id="saudacao-display"></p>

const botao = document.getElementById('botao-saudacao');
const displaySaudacao = document.getElementById('saudacao-display');

botao.addEventListener('click', () => {
   displaySaudacao.textContent = 'Olá, mundo!';
   displaySaudacao.style.color = 'blue';
});

Eventos de Teclado

Esses eventos são disparados em resposta a interações com o teclado. Os tipos mais comuns são keydown (tecla pressionada) e keyup (tecla liberada).

<input type="text" id="campo-texto-teclado" placeholder="Digite algo...">
<p id="tecla-pressionada-info"></p>

const campoTexto = document.getElementById('campo-texto-teclado');
const infoTecla = document.getElementById('tecla-pressionada-info');

campoTexto.addEventListener('keydown', (event) => {
   infoTecla.textContent = `Você pressionou a tecla: ${event.key}`;
   if (event.key === 'Enter') {
       alert('Enter foi pressionado!');
   }
});

campoTexto.addEventListener('keyup', (event) => {
   console.log(`Tecla ${event.key} foi liberada.`);
});

Acessando e Modificando Atributos e Propriedades

Elementos HTML possuem atributos definidos no código-fonte e propriedades que são acessíveis via JavaScript. Muitas vezes, um atributo HTML tem uma propriedade DOM correspondente que pode ser lida e modificada diretamente.

Elementos Comuns (Imagens)

<img id="imagem-dinamica" src="caminho/para/imagem1.jpg" alt="Descrição da Imagem 1" width="150">
<button id="trocar-imagem-btn">Trocar Imagem</button>

const imagem = document.getElementById('imagem-dinamica');
const btnTrocar = document.getElementById('trocar-imagem-btn');

btnTrocar.addEventListener('click', () => {
   if (imagem.src.includes('imagem1')) {
       imagem.src = 'caminho/para/imagem2.jpg'; // Altera o atributo src
       imagem.alt = 'Descrição da Imagem 2'; // Altera o atributo alt
       imagem.title = 'Nova Imagem Carregada'; // Adiciona ou altera o atributo title
   } else {
       imagem.src = 'caminho/para/imagem1.jpg';
       imagem.alt = 'Descrição da Imagem 1';
       imagem.title = 'Imagem Original';
   }
});

Elementos de Formulário

Controles de formulário como <input>, <textarea> e <select> possuem propriedades específicas (e.g., value, checked) que são frequentemente manipuladas.

Botão de Alternância (Ex: Reproduzir/Pausar)
<button id="controle-audio-btn">Reproduzir</button>

const btnAudio = document.getElementById('controle-audio-btn');

btnAudio.addEventListener('click', () => {
   if (btnAudio.textContent === 'Reproduzir') {
       btnAudio.textContent = 'Pausar';
       // Lógica para iniciar a reprodução
   } else {
       btnAudio.textContent = 'Reproduzir';
       // Lógica para pausar a reprodução
   }
});

Contador Simples
<input type="number" id="valor-contador" value="0" readonly>
<button id="incrementar-btn">+</button>
<button id="decrementar-btn">-</button>

const displayContador = document.getElementById('valor-contador');
const btnIncrementar = document.getElementById('incrementar-btn');
const btnDecrementar = document.getElementById('decrementar-btn');

btnIncrementar.addEventListener('click', () => {
   let valorAtual = parseInt(displayContador.value);
   displayContador.value = valorAtual + 1;
});

btnDecrementar.addEventListener('click', () => {
   let valorAtual = parseInt(displayContador.value);
   displayContador.value = valorAtual - 1;
});

Funcionalidade "Selecionar Todos"
<input type="checkbox" id="selecionar-tudo-master"> <label for="selecionar-tudo-master">Selecionar Tudo</label><br>
<input type="checkbox" class="item-selecionavel"> Item A<br>
<input type="checkbox" class="item-selecionavel"> Item B<br>
<input type="checkbox" class="item-selecionavel"> Item C<br>

const masterCheckbox = document.getElementById('selecionar-tudo-master');
const itemCheckboxes = document.querySelectorAll('.item-selecionavel');

masterCheckbox.addEventListener('change', () => {
   itemCheckboxes.forEach(checkbox => {
       checkbox.checked = masterCheckbox.checked;
   });
});

itemCheckboxes.forEach(checkbox => {
   checkbox.addEventListener('change', () => {
       // Verifica se todos os itens estão selecionados
       const todosMarcados = Array.from(itemCheckboxes).every(item => item.checked);
       masterCheckbox.checked = todosMarcados;
   });
});

Gerenciando Estilos de Elementos

O JavaScript pode alterar a aparência visual dos elementos de duas maneiras principais: diretamente via a propriedade style ou manipulando as classes CSS.

Estilos Inline (element.style)

Modifica as propriedades CSS diretamente no atributo style do elemento. É útil para mudanças rápidas e pontuais, mas pode ser menos gerenciável para estilos complexos.

<p id="texto-estilizavel" style="font-size: 16px; color: black;">Clique para mudar o estilo.</p>

const textoEstilo = document.getElementById('texto-estilizavel');

textoEstilo.addEventListener('click', () => {
   let tamanhoAtual = parseInt(textoEstilo.style.fontSize);
   textoEstilo.style.fontSize = (tamanhoAtual + 4) + 'px'; // Aumenta o tamanho da fonte
   textoEstilo.style.color = textoEstilo.style.color === 'black' ? 'red' : 'black'; // Alterna a cor
});

Estilos Baseados em Classes (element.classList)

A abordagem preferida para gerenciar estilos complexos é alternar classes CSS. Isso mantém a separação de responsabilidades (HTML para estrutura, CSS para estilo, JS para comportamento) e facilita a manutenção.

<style>
   body {
       transition: background-color 0.3s, color 0.3s;
       margin: 0;
       padding: 20px;
       min-height: 100vh;
   }
   .tema-claro {
       background-color: #f0f8ff;
       color: #333;
   }
   .tema-escuro {
       background-color: #222;
       color: #eee;
   }
</style>
<body class="tema-claro">
   <p>Este é um parágrafo de exemplo para alternar o tema.</p>
   <button id="alternar-tema-btn">Alternar Tema</button>
</body>

const bodyElement = document.body;
const btnAlternarTema = document.getElementById('alternar-tema-btn');

btnAlternarTema.addEventListener('click', () => {
   bodyElement.classList.toggle('tema-escuro');
   bodyElement.classList.toggle('tema-claro');
});

Manipulação Dinâmica de Nodos

As Web APIs permitem não apenas modificar elementos existentes, mas também criar novos, inseri-los ou removê-los do documento.

Inserindo Nodos

Para adicionar novos elementos ao DOM:

  1. Crie o novo elemento usando document.createElement().
  2. Defina seu conteúdo e atributos, se necessário.
  3. Anexe-o a um elemento pai existente usando appendChild() (no final) ou insertBefore() (antes de um nó de referência).
<div id="lista-dinamica">
   <p class="item-existente">Item Base 1</p>
   <p>Item Base 2</p>
</div>
<button id="adicionar-item-btn">Adicionar Item</button>

const containerLista = document.getElementById('lista-dinamica');
const btnAdicionar = document.getElementById('adicionar-item-btn');

btnAdicionar.addEventListener('click', () => {
   // 1. Criar um novo elemento
   const novoParagrafo = document.createElement('p');
   novoParagrafo.textContent = `Novo Item ${containerLista.children.length + 1}`;
   novoParagrafo.style.color = 'green';

   // 2. Inserir no final
   containerLista.appendChild(novoParagrafo);

   // Exemplo de insertBefore: Inserir um h3 antes do primeiro p
   const tituloExtra = document.createElement('h3');
   tituloExtra.textContent = 'Seção Dinâmica';
   const primeiroP = containerLista.querySelector('.item-existente');
   if (!document.querySelector('#lista-dinamica h3')) { // Adiciona apenas uma vez
       containerLista.insertBefore(tituloExtra, primeiroP);
   }
});

Removendo Nodos

Para remover um elemento do DOM, use parentNode.removeChild(childElement). O elemento removido ainda existe na memória e pode ser reanexado se necessário.

<div id="lista-remocao">
   <span>Item 1</span><br>
   <span id="item-para-remover">Item 2 (para remover)</span><br>
   <span>Item 3</span>
</div>
<button id="remover-elemento-btn">Remover Item 2</button>
<button id="restaurar-elemento-btn" disabled>Restaurar Item 2</button>

const listaRemocao = document.getElementById('lista-remocao');
const itemARemover = document.getElementById('item-para-remover');
const btnRemover = document.getElementById('remover-elemento-btn');
const btnRestaurar = document.getElementById('restaurar-elemento-btn');

let elementoRemovido = null;

btnRemover.addEventListener('click', () => {
   if (itemARemover && itemARemover.parentNode) {
       elementoRemovido = listaRemocao.removeChild(itemARemover);
       console.log("Elemento removido do DOM:", elementoRemovido);
       btnRemover.disabled = true;
       btnRestaurar.disabled = false;
   }
});

btnRestaurar.addEventListener('click', () => {
   if (elementoRemovido) {
       listaRemocao.appendChild(elementoRemovido); // Reinsere o elemento removido
       console.log("Elemento restaurado no DOM.");
       btnRemover.disabled = false;
       btnRestaurar.disabled = true;
   }
});

Tags: javascript DOM WebAPI Eventos ManipulacaoDOM

Publicado em 6-15 00:42 por Thomas