Conteúdos da cadeira

JavaScript no cliente e DOM

Sintaxe de JavaScript, funções, DOM, eventos, propagação e validação de formulários.

Markdown

Perguntar sobre esta página

ChatGPTClaudePerplexityGeminiCopiar e abrir

Envia o link e pede à IA para ler a página. No Gemini, cola a pergunta copiada.

Ver pergunta para copiar
Nesta página

O PHP monta a página no servidor antes de a enviar. O JavaScript corre no navegador depois de a página chegar e mexe nela sem pedir nada ao servidor. Vens de funções em Python e de tipos estáticos em C++: o JavaScript tem funções parecidas com as de Python mas tipagem dinâmica ainda mais solta do que a do PHP, com conversões que surpreendem.

A miniatura vem do YouTube. O vídeo só carrega quando clicas. Abrir no YouTube

Sintaxe sem surpresas, quase

Declara variáveis com const por omissão e let quando o valor muda. O var antigo tem regras de alcance estranhas e não o deves usar em código novo:

const preco = 8.5;
let qtd = 2;
console.log('Total: ' + preco * qtd);

Isto escreve Total: 17 na consola do navegador, que abres nas ferramentas de desenvolvimento. As funções são valores como outros quaisquer, por isso passam-se como argumentos, o que vais usar em todos os eventos:

function soma(a, b) {
  return a + b;
}
const dobro = (x) => x * 2;

Quanto às conversões, decora os dois casos clássicos: '8' + 1'81' porque o + com texto concatena, mas '8' - 17 porque o - só sabe subtrair e converte. Quando um cálculo sair torto, converte explicitamente com Number() antes de culpares a lógica.

Mexer na página pelo DOM

O DOM é a página vista como uma árvore de objetos: cada etiqueta é um nó que podes ler, criar e alterar. A lista de tarefas da mercearia, com adicionar e remover, cabe nestas linhas em tarefas.js. Experimenta-a aqui: escreve um item, prime Enter, e remove-o a seguir.

HTML / CSS / JavaScript
CSS e JavaScript
const lista = document.querySelector('#tarefas');
document.querySelector('#form').addEventListener('submit', (e) => {
  e.preventDefault();
  const texto = document.querySelector('#texto').value.trim();
  if (!texto) return;
  const li = document.createElement('li');
  li.textContent = texto;
  const btn = document.createElement('button');
  btn.textContent = 'Remover';
  btn.addEventListener('click', () => li.remove());
  li.append(btn);
  lista.append(li);
});

O querySelector escolhe elementos com a mesma sintaxe do CSS. O addEventListener regista uma função que corre quando o evento acontece: aqui, submeter o formulário cria um li novo com um botão que se remove a si próprio. O preventDefault impede o comportamento normal do formulário, que seria recarregar a página e deitar fora a lista. O texto entra por textContent, nunca por innerHTML com dados do utilizador, e a diferença entre os dois é esta:

li.textContent = '<b>Queijo</b>';

O elemento mostra o texto literal <b>Queijo</b>, sem etiquetas. É o comportamento seguro para dados do utilizador: nada do que ele escreve vira código. A razão está na página de segurança.

li.innerHTML = '<b>Queijo</b>';

O elemento mostra Queijo a negrito, porque a cadeia foi interpretada como HTML. Útil para o teu próprio modelo, perigoso para dados do utilizador: uma carga com script corria. Só usa com cadeias que escreveste tu.

A propagação dos eventos

Um clique num botão dentro de um cartão dentro da página atravessa os três: primeiro desce do documento até ao botão (captura) e depois sobe de volta (bolha). Por omissão, os teus tratadores correm na subida.

Experimenta este exercício com um botão dentro de uma div:

document
  .querySelector('#caixa')
  .addEventListener('click', () => console.log('caixa'));
document.querySelector('#botao').addEventListener('click', (e) => {
  e.stopPropagation();
  console.log('botão');
});

Clicar no botão escreve só “botão”, porque o stopPropagation trava a subida e a caixa nunca fica a saber. Sem essa linha, escrevia “botão” e depois “caixa”, e um tratador na caixa que fecha um menu ou apaga uma seleção disparava sem seres tu a querer. Quando um clique fizer duas coisas em vez de uma, procura o tratador esquecido algures na subida.

Validar o formulário antes de enviar

O HTML já valida o básico com required e type, mas regras como “a data de entrega é depois de hoje” pedem JavaScript. Valida no evento de submissão e bloqueia o envio quando falhar:

document.querySelector('#encomenda').addEventListener('submit', (e) => {
  const qtd = Number(document.querySelector('#qtd').value);
  if (!(qtd >= 1)) {
    e.preventDefault();
    document.querySelector('#erro').textContent = 'A quantidade mínima é 1.';
  }
});

A mensagem aparece num elemento reservado para erros, junto ao campo, em vez de numa caixa de alerta que interrompe tudo. E lembra-te do limite desta validação: ela ajuda o utilizador honesto, mas o servidor volta a validar tudo, porque um pedido pode ser forjado sem passar pelo teu formulário. A validação do cliente é cortesia; a do servidor é segurança.

Ver o ficheiro no GitHub

À tua maneira

Escolhe como preferes ler.

Aparência
Ajustar cores e largura
Cor de destaque do tema FEUP
Tipo de letra

Álgebra, lógica e uma ideia de cada vez.

As tuas escolhas ficam guardadas neste navegador.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.