Pular para o conteúdo
murad.guide

JavaScript

Capítulo 22

Projeto galeria com lightbox

2 min de leitura 411 palavras 1 gravura

Grade de obras fictícias. Lightbox com foco no Fechar; Escape devolve a página.

Trabalhe sobre uma cópia da pasta inicio do exemplo correspondente. Leia, digite, mude uma coisa, preveja o resultado, recarregue e confira. A referência completa fica na raiz da pasta do exemplo, no pacote anexo.

O que você pratica

Diagrama: Projeto galeria com lightbox

Grade de botões

Monte um botão por obra. Ao clicar, abra o lightbox.

Tire hidden, foque Fechar. Escape também fecha.

Imagem local

SVG em data URI — sem rede externa. alt descreve a obra fictícia.

Ler o exemplo completo

A referência desta etapa usa app.js, index.html, styles.css. Abra primeiro o resultado pronto e identifique onde acontece grade de botões. Depois compare o mesmo ponto com a pasta inicio. Essa comparação mostra exatamente o que você precisa escrever, sem esconder partes indispensáveis do programa.

Diagnóstico guiado

Se o resultado não aparecer, confirme o arquivo aberto, salve a alteração e recarregue. Em seguida, abra o Console: leia a primeira mensagem de erro, confira o nome do arquivo e a linha indicada. Quando houver fetch, sirva a pasta apenas em 127.0.0.1; abrir por file:// não reproduz o pedido HTTP.

Critério de avanço

Avance quando conseguir explicar o papel de inicio, realizar uma mudança pequena e restaurar o exemplo sem copiar a resposta comentada.

Atividades

  1. Na referência, onde aparece grade de botões e qual efeito você observa?
  2. Na cópia inicio, mude apenas inicio. O que você prevê antes de executar novamente?
  3. Provoque uma falha pequena nesta etapa. Qual mensagem ou comportamento ajudou você a encontrar a causa?

Respostas comentadas

Só abra depois de tentar.

Atividade 1. A resposta deve apontar o arquivo e ligar o trecho ao efeito visível. Compare com app.js, index.html, styles.css.

Atividade 2. Registre o valor anterior, o novo valor e o resultado previsto. Depois confira; se houver diferença, explique o que o programa realmente fez.

Atividade 3. Uma boa investigação começa pela primeira mensagem do Console, pelo arquivo salvo e pelo caminho aberto. Corrija uma causa por vez e execute de novo.

Exemplo deste capítulo: pacote de exemplos/22-galeria/.

O arquivo completo

Referência do exemplo 22-galeria, reproduzida aqui para que você possa conferir sem sair da página.

index.html

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Galeria com lightbox — Ateliê do Marco Zero</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <a class="skip" href="#conteudo">Ir para o conteúdo</a>
  <header>
    <p class="tag">Ateliê do Marco Zero · Recife</p>
    <h1>Galeria com lightbox</h1>
  </header>
  <main id="conteudo">
    <div id="grade" style="display:grid;grid-template-columns:repeat(3,1fr);gap:0.5rem"></div>
    <div id="lightbox" hidden style="position:fixed;inset:0;background:rgba(0,0,0,.75);display:grid;place-items:center;padding:1rem">
      <figure style="background:#fff;padding:1rem;max-width:28rem">
        <img id="foto" alt="" style="width:100%;height:auto">
        <figcaption id="legenda"></figcaption>
        <p><button type="button" id="fechar">Fechar</button></p>
      </figure>
    </div>

  </main>
  <footer>
    <p>Material de estudo. Conteúdo fictício. Servidor só em 127.0.0.1.</p>
  </footer>
  <script src="app.js"></script>
</body>
</html>

app.js

const obras = [
  { titulo: "Marco Zero ao entardecer", cor: "#0d6e6e" },
  { titulo: "Barcos no cais", cor: "#a33b2c" },
  { titulo: "Azulejo do pátio", cor: "#0b3d91" },
];

const grade = document.querySelector("#grade");
const box = document.querySelector("#lightbox");
const foto = document.querySelector("#foto");
const legenda = document.querySelector("#legenda");

obras.forEach((obra, i) => {
  const btn = document.createElement("button");
  btn.type = "button";
  btn.style.background = obra.cor;
  btn.style.minHeight = "5rem";
  btn.textContent = obra.titulo;
  btn.addEventListener("click", () => {
    foto.alt = obra.titulo;
    foto.src = `data:image/svg+xml,${encodeURIComponent(
      `<svg xmlns='http://www.w3.org/2000/svg' width='400' height='240'><rect width='100%' height='100%' fill='${obra.cor}'/><text x='20' y='120' fill='white' font-size='22' font-family='Arial'>${obra.titulo}</text></svg>`
    )}`;
    legenda.textContent = obra.titulo;
    box.hidden = false;
    document.querySelector("#fechar").focus();
  });
  grade.appendChild(btn);
});

document.querySelector("#fechar").addEventListener("click", () => {
  box.hidden = true;
});
window.addEventListener("keydown", (e) => {
  if (e.key === "Escape") box.hidden = true;
});