Tutoriel
Partie 12 — Mini-projets JavaScript : penser comme un développeur

Partie 12 — Mini-projets JavaScript : penser comme un développeur

Apprendre JavaScript, c’est bien. Construire des projets, c’est ce qui vous fait réellement progresser. Dans cette partie, vous allez réaliser trois mini-projets (to-do list, calculatrice, chargeur de contenu), comprendre les erreurs fréquentes des débutants, apprendre à les corriger, et découvrir quoi apprendre ensuite (React, Node.js) pour passer au niveau supérieur.

JAVASCRIPT 55 Mis à jour 11 hours ago
Conseil : lisez d’abord les sections clés, puis essayez un QCM lié à la même notion pour valider votre compréhension.

Si vous voulez progresser vite en JavaScript, il y a une règle simple : vous devez construire.

Les mini-projets ont un avantage énorme : ils vous obligent à relier toutes les notions que vous avez apprises (variables, conditions, fonctions, arrays, DOM, événements, asynchrone).

Dans cette partie, vous allez construire trois mini-projets réalistes. Ne cherchez pas à faire “parfait” : cherchez à faire fonctionnel, puis améliorez progressivement.

👉 Astuce : copiez le code, testez-le, puis modifiez-le. La compréhension vient par l’action.

1) Mini-projet 1 — To-do list (liste de tâches)

Objectif : ajouter des tâches, les afficher, les supprimer et marquer “fait”. C’est le projet débutant le plus utile, car il ressemble à beaucoup de fonctionnalités réelles : commentaires, panier, notes, rappels, etc.

HTML (structure)

<div style="max-width:520px; border:1px solid #e5e7eb; border-radius:14px; padding:16px;">
  <h3 style="margin:0 0 12px 0;">Ma To-do List</h3>

  <form id="todoForm" style="display:flex; gap:10px;">
    <input id="todoInput" type="text" placeholder="Ajouter une tâche..."
      style="flex:1; padding:10px; border:1px solid #ddd; border-radius:10px;">
    <button type="submit"
      style="padding:10px 14px; border:none; border-radius:10px; background:#0f172a; color:#fff; cursor:pointer;">
      Ajouter
    </button>
  </form>

  <p id="todoMsg" style="display:none; margin:12px 0 0; padding:10px; border-radius:10px;"></p>

  <ul id="todoList" style="list-style:none; padding:0; margin:14px 0 0;"></ul>
</div>
  

JavaScript (logique)

const todoForm = document.getElementById("todoForm");
const todoInput = document.getElementById("todoInput");
const todoList = document.getElementById("todoList");
const todoMsg = document.getElementById("todoMsg");

// On stocke les tâches sous forme d'objets
let todos = [];

function showTodoMessage(type, text) {
  todoMsg.style.display = "block";
  todoMsg.textContent = text;

  if (type === "error") {
    todoMsg.style.background = "#fff7ed";
    todoMsg.style.border = "1px solid #fed7aa";
    todoMsg.style.color = "#9a3412";
  } else {
    todoMsg.style.background = "#f0fdf4";
    todoMsg.style.border = "1px solid #bbf7d0";
    todoMsg.style.color = "#166534";
  }

  // Message temporaire
  setTimeout(() => {
    todoMsg.style.display = "none";
  }, 1800);
}

function renderTodos() {
  todoList.innerHTML = "";

  todos.forEach((todo) => {
    const li = document.createElement("li");
    li.style.display = "flex";
    li.style.alignItems = "center";
    li.style.justifyContent = "space-between";
    li.style.padding = "10px";
    li.style.border = "1px solid #e5e7eb";
    li.style.borderRadius = "12px";
    li.style.marginBottom = "10px";

    const left = document.createElement("div");
    left.style.display = "flex";
    left.style.alignItems = "center";
    left.style.gap = "10px";

    const checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.checked = todo.done;

    const span = document.createElement("span");
    span.textContent = todo.text;
    span.style.cursor = "pointer";
    span.style.userSelect = "none";
    span.style.textDecoration = todo.done ? "line-through" : "none";
    span.style.opacity = todo.done ? "0.6" : "1";

    // Clic sur le texte → toggle done
    span.addEventListener("click", () => {
      todo.done = !todo.done;
      renderTodos();
    });

    checkbox.addEventListener("change", () => {
      todo.done = checkbox.checked;
      renderTodos();
    });

    left.appendChild(checkbox);
    left.appendChild(span);

    const deleteBtn = document.createElement("button");
    deleteBtn.textContent = "Supprimer";
    deleteBtn.style.border = "none";
    deleteBtn.style.borderRadius = "10px";
    deleteBtn.style.padding = "8px 10px";
    deleteBtn.style.cursor = "pointer";
    deleteBtn.style.background = "#fee2e2";
    deleteBtn.style.color = "#991b1b";

    deleteBtn.addEventListener("click", () => {
      todos = todos.filter(t => t.id !== todo.id);
      renderTodos();
    });

    li.appendChild(left);
    li.appendChild(deleteBtn);
    todoList.appendChild(li);
  });
}

todoForm.addEventListener("submit", (e) => {
  e.preventDefault();

  const text = todoInput.value.trim();

  if (text === "") {
    showTodoMessage("error", "Veuillez saisir une tâche.");
    return;
  }

  todos.push({
    id: Date.now(),
    text: text,
    done: false
  });

  todoInput.value = "";
  showTodoMessage("success", "Tâche ajoutée.");
  renderTodos();
});
  

✅ Ce projet vous apprend : arrays d’objets, DOM, événements, fonctions et état (state).

2) Mini-projet 2 — Calculatrice simple

Objectif : deux champs (nombre A et nombre B), un choix d’opération, et un résultat. C’est petit, mais très instructif : conversion de types, validations, conditions.

HTML

<div style="max-width:520px; border:1px solid #e5e7eb; border-radius:14px; padding:16px; margin-top:14px;">
  <h3 style="margin:0 0 12px 0;">Calculatrice</h3>

  <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
    <input id="numA" type="number" placeholder="Nombre A"
      style="padding:10px; border:1px solid #ddd; border-radius:10px;">

    <input id="numB" type="number" placeholder="Nombre B"
      style="padding:10px; border:1px solid #ddd; border-radius:10px;">
  </div>

  <select id="op"
    style="width:100%; padding:10px; border:1px solid #ddd; border-radius:10px; margin-top:10px;">
    <option value="add">Addition (+)</option>
    <option value="sub">Soustraction (-)</option>
    <option value="mul">Multiplication (×)</option>
    <option value="div">Division (÷)</option>
  </select>

  <button id="calcBtn"
    style="width:100%; padding:12px; border:none; border-radius:10px; background:#0f172a; color:#fff; cursor:pointer; margin-top:10px;">
    Calculer
  </button>

  <p id="calcMsg" style="display:none; margin:12px 0 0; padding:10px; border-radius:10px;"></p>
  <h4 id="result" style="margin:12px 0 0;">Résultat : —</h4>
</div>
  

JavaScript

const numA = document.getElementById("numA");
const numB = document.getElementById("numB");
const op = document.getElementById("op");
const calcBtn = document.getElementById("calcBtn");
const calcMsg = document.getElementById("calcMsg");
const result = document.getElementById("result");

function showCalcMessage(type, text) {
  calcMsg.style.display = "block";
  calcMsg.textContent = text;

  if (type === "error") {
    calcMsg.style.background = "#fff7ed";
    calcMsg.style.border = "1px solid #fed7aa";
    calcMsg.style.color = "#9a3412";
  } else {
    calcMsg.style.background = "#f0fdf4";
    calcMsg.style.border = "1px solid #bbf7d0";
    calcMsg.style.color = "#166534";
  }

  setTimeout(() => (calcMsg.style.display = "none"), 1800);
}

function toNumber(value) {
  // Convertir proprement
  return Number(value);
}

calcBtn.addEventListener("click", () => {
  const a = toNumber(numA.value);
  const b = toNumber(numB.value);

  if (Number.isNaN(a) || Number.isNaN(b)) {
    showCalcMessage("error", "Veuillez entrer deux nombres valides.");
    return;
  }

  let res;

  if (op.value === "add") res = a + b;
  else if (op.value === "sub") res = a - b;
  else if (op.value === "mul") res = a * b;
  else if (op.value === "div") {
    if (b === 0) {
      showCalcMessage("error", "Division par zéro impossible.");
      return;
    }
    res = a / b;
  }

  result.textContent = "Résultat : " + res;
  showCalcMessage("success", "Calcul effectué.");
});
  

✅ Ce projet vous apprend : types, validations, conditions, UX (messages).

3) Mini-projet 3 — Chargement dynamique de contenu (API)

Objectif : cliquer sur un bouton pour charger des données depuis une API et les afficher. C’est un mini-projet très proche des dashboards, blogs, listes d’utilisateurs, et pages “chargement plus”.

Nous utilisons une API de test (JSONPlaceholder) utilisée pour l’apprentissage.

HTML

<div style="max-width:520px; border:1px solid #e5e7eb; border-radius:14px; padding:16px; margin-top:14px;">
  <h3 style="margin:0 0 12px 0;">Chargement dynamique</h3>

  <button id="loadBtn"
    style="padding:12px 14px; border:none; border-radius:10px; background:#0f172a; color:#fff; cursor:pointer;">
    Charger des utilisateurs
  </button>

  <p id="loaderMsg" style="margin:12px 0 0; color:#555;"></p>

  <ul id="usersList" style="list-style:none; padding:0; margin:14px 0 0;"></ul>
</div>
  

JavaScript (fetch + async/await)

const loadBtn = document.getElementById("loadBtn");
const loaderMsg = document.getElementById("loaderMsg");
const usersList = document.getElementById("usersList");

function renderUsers(users) {
  usersList.innerHTML = "";

  users.forEach(user => {
    const li = document.createElement("li");
    li.style.padding = "10px";
    li.style.border = "1px solid #e5e7eb";
    li.style.borderRadius = "12px";
    li.style.marginBottom = "10px";

    li.innerHTML = "<strong>" + user.name + "</strong><br>" +
                   "<span style='color:#555'>" + user.email + "</span>";

    usersList.appendChild(li);
  });
}

async function loadUsers() {
  loaderMsg.textContent = "Chargement...";
  loadBtn.disabled = true;
  loadBtn.style.opacity = "0.7";

  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    const users = await response.json();
    renderUsers(users);
    loaderMsg.textContent = "Utilisateurs chargés avec succès.";
  } catch (error) {
    loaderMsg.textContent = "Erreur lors du chargement. Vérifiez votre connexion.";
  } finally {
    loadBtn.disabled = false;
    loadBtn.style.opacity = "1";
  }
}

loadBtn.addEventListener("click", loadUsers);
  

✅ Ce projet vous apprend : asynchrone, fetch, DOM dynamique, gestion d’erreurs.

4) Erreurs classiques des débutants (et comment les corriger)

Erreur 1 — Tout écrire dans un seul bloc

Beaucoup de débutants écrivent tout dans un seul addEventListener. Résultat : code long, difficile à relire, difficile à corriger.

✅ Solution : découpez en fonctions (ex: renderTodos(), showMessage(), etc.)

Erreur 2 — Oublier les conversions (String vs Number)

Les inputs HTML renvoient souvent des chaînes de caractères. Si vous ne convertissez pas, vous obtenez des résultats étranges.

✅ Solution : utilisez Number() et vérifiez avec Number.isNaN().

Erreur 3 — Modifier le DOM sans stratégie

Si vous ajoutez et supprimez des éléments sans logique claire, l’interface devient incohérente.

✅ Solution : utilisez une fonction de rendu (render) qui reconstruit l’affichage à partir des données.

Erreur 4 — Oublier la gestion d’erreurs en asynchrone

Une API peut échouer. Une connexion peut être lente. Un serveur peut être indisponible.

✅ Solution : utilisez try/catch et affichez un message utile à l’utilisateur.

5) Quoi apprendre ensuite (React, Node.js) : le chemin logique

Maintenant que vous avez une base solide, voici une progression naturelle :

Étape 1 — JavaScript moderne (niveau intermédiaire)

  • map, filter, reduce
  • Modules (import, export)
  • LocalStorage (sauvegarder les données côté navigateur)
  • Gestion d’état plus propre (patterns)

Étape 2 — React (front-end moderne)

React vous permet de construire des interfaces plus grandes avec une logique plus propre. Si votre objectif est de créer des applications web modernes, React est un excellent choix.

  • Composants
  • Props & State
  • Hooks (useState, useEffect)
  • Routing

Étape 3 — Node.js (back-end JavaScript)

Node.js vous permet d’utiliser JavaScript côté serveur. C’est très utile si vous voulez faire des APIs, gérer l’authentification, et connecter une base de données.

  • Express.js
  • API REST
  • MongoDB / MySQL
  • Auth (JWT)

✅ Si votre objectif est de construire un vrai produit : React + API (Node.js ou Laravel) est un duo puissant.


Félicitations : si vous avez suivi toutes les parties jusqu’ici, vous avez une base solide en JavaScript. Les mini-projets que vous venez de faire sont exactement le type d’exercices qui accélèrent votre progression.

Prochaine étape : choisissez un projet réel (même simple), construisez-le, puis améliorez-le chaque semaine. C’est ainsi qu’on devient développeur.