Do Zero ao Código: Construindo Modo Escuro e Pokédex com API e JavaScript Puro

Aprender JavaScript é mais do que decorar sintaxe, é entender como o código ganha vida no navegador e transforma ideias em experiências reais. Nesta aula, vamos explorar isso na prática com dois mini-projetos que unem criatividade e fundamentos do front-end.

O primeiro é voltado para interatividade e estilo, com a criação de um seletor de tema (modo claro e escuro). O segundo foca em consumir e exibir dados de uma API real, construindo uma Pokédex divertida e funcional.

Ambos os projetos têm o mesmo propósito: mostrar como conceitos básicos de HTML, CSS e JavaScript puro podem ser combinados para criar aplicações modernas, dinâmicas e com uma ótima experiência de usuário.

Projeto 1: Crie um Seletor de Tema (Dark Mode) com JavaScript e localStorage📚

No mundo do desenvolvimento front-end, criar uma experiência de usuário agradável é fundamental. E uma das funcionalidades mais pedidas e apreciadas hoje em dia é o seletor de tema (Modo Claro e Escuro). Além de dar conforto visual, é um excelente projeto para praticar conceitos essenciais de JavaScript.

Neste tutorial, vamos construir juntos, do zero, um projeto divertido chamado “FiloDex”: uma Pokedex de Filósofos. Mas o foco principal não será a filosofia, e sim o código por trás da mágica!

Você vai aprender a:

  • Estruturar o projeto com HTML semântico.
  • Estilizar e criar temas usando variáveis CSS.
  • Manipular a página dinamicamente com JavaScript (DOM).
  • Salvar a preferência do usuário para que o tema persista, mesmo depois de fechar o navegador, usando localStorage.

BORA CODAR!!

Pré-requisitos

Para acompanhar este tutorial, é bom que você tenha um conhecimento básico de:

  • HTML: Estrutura de tags, como <div>, <h1>, <img>.
  • CSS: Seletores de classe, propriedades como background-color e color.
  • Um editor de código (como o VS Code) e um navegador.

Vamos dividir nosso projeto em três partes: a estrutura, o estilo e a interatividade.


Parte 1: A Estrutura com HTML

Primeiro, precisamos do esqueleto do nosso site. Criaremos um arquivo index.html com uma estrutura simples: um cabeçalho para o título e o botão de toggle, e uma área principal para os nossos “cards” de filósofos.

Crie o arquivo index.html e cole o código abaixo:

HTML

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FiloDex - Pokedex de Filósofos</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>📚 FiloDex</h1>
        <input type="checkbox" id="theme-toggle" class="theme-toggle-checkbox">
        <label for="theme-toggle" class="theme-toggle-label">
            <span class="sun-icon">☀️</span>
            <span class="moon-icon">🌙</span>
        </label>
    </header>

    <main class="philosopher-grid">
        <div class="card">
            <img src="https://via.placeholder.com/150" alt="Imagem de Platão">
            <h2>Platão #001</h2>
            <div class="tags">
                <span class="tag idealismo">Idealismo</span>
            </div>
            <p>Discípulo de Sócrates, sua filosofia é marcada pela Teoria das Ideias, que postula um mundo de formas perfeitas e eternas.</p>
        </div>
        </main>

    <script src="script.js"></script>
</body>
</html>

Ponto importante: Note que nosso botão de toggle é, na verdade, um input do tipo checkbox. Essa é uma técnica comum e acessível para criar botões de ligar/desligar. Nós vamos escondê-lo com CSS e usar o label (com os ícones de sol e lua) como a parte clicável.


Parte 2: A Estilização com CSS

Agora, vamos dar vida ao nosso HTML. O segredo para um seletor de tema eficiente está no uso de variáveis CSS. Definimos nossas cores principais em um lugar só e, para ativar o modo escuro, apenas trocamos os valores dessas variáveis.

Crie o arquivo style.css e adicione o seguinte:

CSS

/* 1. Definindo nossas variáveis de cor para o tema padrão (Claro) */
:root {
    --bg-color: #ffffff;
    --card-bg-color: #f0f0f0;
    --text-color: #333333;
    --shadow-color: rgba(0, 0, 0, 0.1);
}

/* 2. Definindo as mesmas variáveis, mas com valores para o tema Escuro */
body.dark {
    --bg-color: #121212;
    --card-bg-color: #2a2a2a;
    --text-color: #e0e0e0;
    --shadow-color: rgba(0, 0, 0, 0.4);
}

/* 3. Usando as variáveis para estilizar os elementos */
body {
    background-color: var(--bg-color); /* Usa a variável de cor de fundo */
    color: var(--text-color);           /* Usa a variável de cor do texto */
    font-family: sans-serif;
    transition: background-color 0.3s ease, color 0.3s ease; /* Animação suave */
}

.card {
    background-color: var(--card-bg-color);
    border-radius: 15px;
    padding: 1.5rem;
    box-shadow: 0 4px 15px var(--shadow-color);
    /* ... outros estilos ... */
}

/* ... cole o restante do seu CSS para o header, grid, etc. aqui ... */

Como funciona? Por padrão, o <body> usa as cores definidas no :root. Quando adicionarmos a classe .dark ao <body> via JavaScript, as regras dentro de body.dark terão prioridade, e os valores das variáveis serão trocados, mudando o tema do site inteiro instantaneamente!


Parte 3: A Interatividade com JavaScript

Aqui é onde a mágica acontece! Vamos capturar o clique no botão, trocar a classe do body e usar o localStorage para salvar a escolha.

Crie o arquivo script.js:

JavaScript

// 1. Selecionamos os elementos que vamos manipular
const toggle = document.getElementById('theme-toggle');
const body = document.body;

// --- LÓGICA PARA RESTAURAR O TEMA ---
// 3. Verificamos se há um tema salvo no localStorage
const savedTheme = localStorage.getItem('theme');

// Se existir um tema salvo...
if (savedTheme) {
    // ...adicionamos a classe do tema salvo ('dark') ao body
    body.classList.add(savedTheme);
    // ...e marcamos o checkbox para refletir o estado ativo
    toggle.checked = true;
}

// --- LÓGICA PARA TROCAR O TEMA ---
// 2. Adicionamos um "ouvinte" que espera por uma mudança no checkbox
toggle.addEventListener('change', () => {
    // Se o checkbox estiver MARCADO (ativado)...
    if (toggle.checked) {
        // ...adicionamos a classe 'dark' ao body
        body.classList.add('dark');
        // ...e salvamos a preferência 'dark' no localStorage
        localStorage.setItem('theme', 'dark');
    } else {
        // ...caso contrário (desmarcado), removemos a classe 'dark'
        body.classList.remove('dark');
        // ...e removemos a preferência do localStorage
        localStorage.removeItem('theme');
    }
});

O que é o localStorage? Pense nele como um pequeno “bloco de notas” que o seu navegador guarda para cada site. Com localStorage.setItem('chave', 'valor'), nós escrevemos uma nota. Com localStorage.getItem('chave'), nós lemos essa nota. Ela fica salva mesmo que você feche a aba!

É por isso que a primeira coisa que nosso script faz é verificar se existe uma nota chamada ‘theme’. Se existir, ele já aplica o tema escuro antes mesmo de você fazer qualquer coisa.


Conclusão e Próximos Passos

Parabéns! Você acabou de criar uma das funcionalidades mais modernas e úteis do desenvolvimento front-end. Você não só aprendeu a criar um seletor de tema, mas também entendeu a lógica por trás da persistência de dados com localStorage, uma habilidade que você usará em inúmeros projetos.

Desafios para você ir além:

  1. Adicione mais filósofos: Popule seu FiloDex com mais cards.
  2. Animações CSS: Adicione transições mais elaboradas quando os cards aparecem na tela.
  3. Salvar mais coisas: Crie um botão de “Favoritar” em cada card e use o localStorage para salvar quais filósofos o usuário favoritou.

🔗Projeto no github para pegar as iamgens: https://github.com/guilherme-silvam/FiloDex?tab=readme-ov-file

Projeto 2: Crie sua própria Pokédex com HTML, CSS e JavaScript do Zero 🐉

Já pensou em criar sua própria Pokédex funcional usando apenas as tecnologias web mais fundamentais? Neste tutorial, vamos embarcar em uma jornada divertida para construir um “Poké-Busca”: um pequeno aplicativo web onde você pode pesquisar por um Pokémon e ver suas informações básicas.

O melhor de tudo? Faremos isso usando apenas HTML, CSS e JavaScript puros, sem frameworks ou bibliotecas complicadas. É o projeto perfeito para você que está começando e quer entender na prática como consumir dados de uma API real.

Ao final deste guia, você terá um projeto assim:

BORA CODAR!

O que vamos aprender?

  • HTML: Estruturar a página da nossa aplicação.
  • CSS: Estilizar tudo para ficar com uma cara incrível, incluindo a fonte e as cores da logo do Pokémon.
  • JavaScript: A mágica por trás de tudo! Vamos aprender a:
    • Capturar a entrada do usuário.
    • Fazer uma requisição a uma API pública (a PokéAPI).
    • Manipular os dados recebidos (em formato JSON).
    • Exibir dinamicamente as informações na tela.

Ferramentas Necessárias

  1. Um editor de código (como o Visual Studio Code).
  2. Um navegador web (Google Chrome, Firefox, etc.).
  3. Um pouco de curiosidade e vontade de aprender!

Passo 1: A Estrutura (HTML)

Todo projeto web começa com o esqueleto: o HTML. Ele define quais elementos estarão na nossa página, como o título, os campos de texto e os botões.

Crie um arquivo chamado index.html e cole o código abaixo:

HTML

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Poké-Busca</title>
    
    <link rel="icon" type="image/png" href="pokeball-icon.png"> 
    
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <main class="container">
        <h1>Poké-Busca</h1>
        <div class="search-box">
            <input type="text" id="pokemonInput" placeholder="Digite o nome ou ID">
            <button id="searchButton">Buscar</button>
            <button id="resetButton">Limpar</button> 
        </div>

        <div id="pokemonDisplay" class="pokemon-display-area"></div>
    </main>

    <script src="script.js"></script>
</body>
</html>

O que fizemos aqui?

  • Criamos a estrutura básica com um título <h1>.
  • Adicionamos um input para o usuário digitar, e dois button, um para buscar e outro para limpar.
  • Definimos uma div com o id pokemonDisplay. É aqui que as informações do Pokémon aparecerão.
  • Linkamos nossos futuros arquivos style.css e script.js.

Não se esqueça: Você precisará de uma imagem de pokébola chamada pokeball-icon.png na mesma pasta para o ícone da aba funcionar!

Passo 2: Dando Estilo e Personalidade (CSS)

Um esqueleto não é nada sem músculos e pele, certo? O CSS vai dar vida e cor ao nosso projeto.

Crie um arquivo chamado style.css e adicione o código a seguir. Os comentários explicam o que cada parte faz!

CSS

/* Importa a fonte personalizada que imita a da logo do Pokémon */
@import url('https://fonts.cdnfonts.com/css/pokemon-solid');

body {
    font-family: Arial, sans-serif;
    /* Imagem de fundo temática */
    background-image: url('pokemon_wallpaper.jpg');
    background-size: cover;
    background-position: center;
    background-attachment: fixed; /* A imagem fica fixa durante o scroll */
    
    /* Centraliza todo o conteúdo na página */
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container {
    background-color: rgba(255, 255, 255, 0.9); /* Fundo branco semi-transparente */
    padding: 20px 40px;
    border-radius: 10px;
    box-shadow: 0 8px 16px rgba(0,0,0,0.3); /* Sombra para destacar */
    text-align: center;
    width: 400px;
}

/* O título com o estilo da logo do Pokémon! */
h1 {
    font-family: 'Pokemon Solid', sans-serif;
    color: #FFCB05; /* Amarelo Pokémon */
    font-size: 3.5rem;
    letter-spacing: 4px;
    /* O truque do contorno azul com text-shadow */
    -webkit-text-stroke: 2px #3D7DCA; /* Azul Pokémon */
    text-shadow: 3px 3px 0 #3D7DCA;
}

.search-box {
    display: flex;
    justify-content: center;
    gap: 10px; /* Espaçamento entre os botões e o input */
    margin-bottom: 20px;
}

#pokemonInput {
    padding: 12px;
    border: 1px solid #ccc;
    border-radius: 5px;
    width: 200px;
    font-size: 1rem;
}

/* Botão de Busca (Vermelho) */
#searchButton {
    padding: 12px 20px;
    border: none;
    background-color: #e74c3c;
    color: white;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s ease;
}

#searchButton:hover {
    background-color: #c0392b;
}

/* Botão de Limpar (Cinza) */
#resetButton {
    padding: 12px 20px;
    border: none;
    background-color: #7f8c8d;
    color: white;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s ease;
}

#resetButton:hover {
    background-color: #95a5a6;
}

/* Área onde o Pokémon será exibido */
.pokemon-display-area {
    margin-top: 20px;
    padding: 15px;
    min-height: 250px; /* Altura mínima para o layout não "quebrar" */
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.pokemon-display-area img {
    width: 120px;
    height: 120px;
}

.error {
    color: #c0392b;
    font-weight: bold;
}

Atenção: Para o fundo funcionar, você precisará de uma imagem chamada pokemon_wallpaper.jpg na pasta do projeto.

Passo 3: A Mágica da Interatividade (JavaScript)

Agora vem a parte mais emocionante! O JavaScript vai conectar nosso site à internet para buscar os dados dos Pokémon.

Crie um arquivo chamado script.js e cole este código:

JavaScript

// Primeiro, pegamos as referências dos elementos HTML com os quais vamos interagir
const pokemonInput = document.getElementById('pokemonInput');
const searchButton = document.getElementById('searchButton');
const resetButton = document.getElementById('resetButton');
const pokemonDisplay = document.getElementById('pokemonDisplay');

// --- Função de Busca ---
const fetchPokemon = () => {
    // Pegamos o valor que o usuário digitou (e convertemos para minúsculas)
    const pokemonNameOrId = pokemonInput.value.toLowerCase();

    // Se o campo estiver vazio, não fazemos nada
    if (!pokemonNameOrId) {
        alert('Por favor, digite o nome ou ID de um Pokémon.');
        return;
    }

    // Exibe uma mensagem de "Buscando..."
    pokemonDisplay.innerHTML = '<p>Buscando...</p>';

    // A MÁGICA DO FETCH: fazendo a chamada para a PokéAPI
    fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonNameOrId}`)
        .then(response => {
            // Se a resposta não for bem-sucedida (ex: erro 404), nós lançamos um erro
            if (!response.ok) {
                throw new Error('Pokémon não encontrado!');
            }
            // Se deu tudo certo, convertemos a resposta para o formato JSON
            return response.json();
        })
        .then(data => {
            // Com os dados em mãos, criamos o HTML para exibir o Pokémon
            pokemonDisplay.innerHTML = `
                <h2>${data.name.charAt(0).toUpperCase() + data.name.slice(1)}</h2>
                <img src="${data.sprites.front_default}" alt="Imagem do ${data.name}">
                <p><strong>ID:</strong> ${data.id}</p>
                <p><strong>Tipo:</strong> ${data.types[0].type.name}</p>
                <p><strong>Altura:</strong> ${data.height / 10} m</p>
                <p><strong>Peso:</strong> ${data.weight / 10} kg</p>
            `;
        })
        .catch(error => {
            // Se qualquer etapa acima der erro, exibimos a mensagem de erro
            pokemonDisplay.innerHTML = `<p class="error">${error.message}</p>`;
        });
};

// --- Função de Limpar ---
const resetSearch = () => {
    pokemonDisplay.innerHTML = ''; // Limpa a área de exibição
    pokemonInput.value = ''; // Limpa o campo de texto
    pokemonInput.focus(); // Coloca o cursor de volta no campo de texto
};

// Adicionamos os "ouvintes de evento" para os botões
searchButton.addEventListener('click', fetchPokemon);
resetButton.addEventListener('click', resetSearch);

Como a mágica funciona?

  1. getElementById: Usamos isso para “capturar” os elementos do HTML e poder manipulá-los com o JS.
  2. addEventListener: Dizemos aos botões para “escutarem” por um clique. Quando o clique acontece, eles executam uma função (fetchPokemon ou resetSearch).
  3. fetch(): Essa é a função mais importante aqui. Ela faz uma “requisição” para o endereço da PokéAPI. É como se o nosso código pedisse ao servidor da API: “Ei, me dê os dados do Pokémon ‘pikachu’!”.
  4. .then() e .catch(): Como a internet pode demorar, o fetch trabalha com “Promessas” (Promises). O .then() executa somente quando a resposta chega com sucesso. O .catch() é o nosso plano B, executado se algo der errado (como um Pokémon que não existe).
  5. innerHTML: Depois de obter e organizar os dados, usamos o innerHTML para injetar o novo conteúdo HTML diretamente na nossa página.

Passo Final: Juntando Tudo!

Certifique-se de que os três arquivos (index.html, style.css, script.js) e as duas imagens (pokeball-icon.png e pokemon_wallpaper.jpg) estejam todos na mesma pasta.

Agora, basta abrir o arquivo index.html no seu navegador.

Digite “pikachu”, “ditto” ou o seu número da sorte (de 1 a 1025) e veja a mágica acontecer!

Desafios para você ir além

Gostou do resultado? Que tal tentar alguns desafios para aprimorar o projeto e seus conhecimentos?

  1. Exiba mais informações: A API fornece muito mais dados! Tente mostrar os status base do Pokémon (HP, ataque, defesa).
  2. Mostre todos os tipos: Alguns Pokémon têm dois tipos. Modifique o código para exibir ambos.
  3. Botões de Navegação: Adicione botões de “Anterior” e “Próximo” para navegar pela Pokédex usando os IDs.

🔗Projeto no github para pegar as iamgens: https://github.com/guilherme-silvam/Pok-dex–API

Publicar comentário