🔢 Exercice PokeCount ​
Démo ​
https://fallinov.github.io/2024-SFA-JS-EXE-PokeCount/
Objectifs ​
- Créer une application web simple pour capturer et sauvegarder des Pokémon.
- Utiliser JavaScript pour manipuler le document HTML (DOM) et ajouter des fonctionnalités interactives.
- Sauvegarder les captures dans le
localStorage
du navigateur pour les recharger entre les sessions. - Améliorer le code grâce à des écouteurs d'événements.
Mise en place ​
- Clique sur le lien suivant pour créer ton dépôt GitHub pour l'exercice : https://classroom.github.com/a/DF6YJq-Z
- Clone ton dépôt GitHub en local avec WebStorm ou un autre éditeur
- Créer une nouvelle branche qui porte ton nom
- Commence l'exercice et pense à **faire régulièrement des commits et des **push.
Étape 1 : Liaison du JavaScript au HTML ​
Comprendre les fichiers de départ ​
index.html
: Page HTML de l'exercice qui se compose de :- un titre principal (
<h1>
) - un compteur (
<h2 id="compteur-el">
) initialisĂ© Ă0
pour suivre le nombre de Pokémon capturés - deux boutons (
<button id="capturer-btn">
et<button id="sauvegarder-btn">
) pour capturer et sauvegarder les Pokémon - un paragraphe (
<p id="sauvegarde-el">
) destiné à afficher l'historique des captures.
- un titre principal (
style.css
: stylise la page avec un fond thématique Pokémon et des couleurs de boutons.pokemon-bg.webp
: Image de fond utilisée dans le CSS.
Créer un fichier JavaScript et lier au HTML : ​
- Action : Créez un nouveau fichier nommé
script.js
dans le mĂŞme dossier queindex.html
. - Action : Liez ce fichier JavaScript au fichier HTML en ajoutant la ligne suivante dans
index.html
, juste avant la fermeture de la balise</body>
:html<script src="script.js"></script>
Afficher un message "Hello World" : ​
- Action : Ouvrez
script.js
et commencez par ajouter un bloc de commentaires pour décrire le fichier :javascript/** * Fichier JavaScript pour l'application PokeCount. * @author Steve Fallet <steve.fallet@divtec.ch> * @version 0.1 (Version actuelle) * @since 2024-01-31 (Date de création) */
- Action : Toujours dans
script.js
, ajoutez le code suivant pour- Demander un interprétation stircte du code. Le mode
"use strict"
en JavaScript active un mode d'exécution plus rigoureux, interdisant certaines pratiques risquées et facilitant la détection d'erreurs dans le code. - Afficher "Hello World" dans la console du navigateur
javascript"use strict"; // Interprètation stricte du code console.log("Hello World"); // Affiche "Hello World" dans la console
- Demander un interprétation stircte du code. Le mode
- Test :
- Ouvrez
index.html
dans un navigateur web. - Ouvrez la console du navigateur (F12 ou clic droit > Inspecter > Console) pour vérifier que le message "Hello World" s'affiche correctement, ce qui confirme que le JavaScript est correctement lié à votre fichier HTML.
- Ouvrez
- Action : Remplacez
console.log
paralert
pour afficher une boîte de dialogue :javascriptalert("Hello World");
- Test :
- Ouvrez
index.html
dans un navigateur web. - Vérifiez que la boîte de dialogue s'affiche correctement.
- Ouvrez
Différence entre console.log
et alert
: ​
console.log
: Affiche des messages dans la console du navigateur, accessible via les outils de développement. Cela permet de vérifier discrètement des informations, des valeurs de variables, ou le flux d’exécution sans interrompre l’expérience utilisateur.alert
: Affiche une boîte de dialogue modale à l’utilisateur avec un message. Cette boîte bloque l’exécution du script jusqu’à ce que l’utilisateur la ferme, ce qui interrompt l’expérience utilisateur.
Pourquoi utiliser console.log
pour le débogage : ​
- Non intrusif :
console.log
permet de dĂ©boguer en arrière-plan sans gĂŞner l’utilisateur, contrairement Ăalert
qui interrompt le flux normal de l’application. - Flexibilité : Vous pouvez afficher plusieurs messages successivement, analyser des objets complexes, et garder une trace des événements dans la console, ce qui est bien plus commode pour diagnostiquer des problèmes dans votre code. En résumé,
console.log
est l’outil de choix pour le débogage, car il est discret, puissant et n’affecte pas l’expérience utilisateur.
Étape 2 : Manipulation du DOM pour modifier un élément ​
Le JavaScript peut être utilisé pour manipuler le contenu d'une page web en modifiant le Document Object Model (DOM). On peut accéder aux éléments HTML, modifier leur contenu, leur style, ou même ajouter de nouveaux éléments dynamiquement.
Récupérer le premier élément <h2>
du document HTML et modifier son contenu : ​
- Action : Utilisez
document.querySelector
pour récupérer le premier élément<h2>
du document et modifiez son contenu pour qu'il affiche20
:javascriptdocument.querySelector("h2").textContent = 20;
- Test : Actualisez la page dans le navigateur. L'élément
<h2>
doit maintenant afficher20
.
Récupérer un élément par son identifiant unique (ID) : ​
- Action : Utilisez
document.getElementById
pour récupérer l'élément avec l'IDcompteur-el
et modifiez son contenu pour qu'il affiche100
. Ajoutez cette ligne dansscript.js
:javascriptdocument.getElementById("compteur-el").textContent = 100;
- Test : Actualisez la page dans le navigateur. L'élément
<h2>
doit désormais afficher100
.
Différence entre getElementById
et querySelector
: ​
getElementById
et querySelector
sont deux méthodes pour récupérer des éléments du DOM en JavaScript.
getElementById
: Permet de récupérer un élément par son identifiant unique (ID) défini dans le HTML. C'est la méthode la plus rapide pour accéder à un élément spécifique.javascript// Sélectionner un élément <div> avec l'ID "main-content" const mainContent = document.getElementById("main-content"); // Sélectionner un élément <header> avec l'ID "site-header" const siteHeader = document.getElementById("site-header"); // Sélectionner un bouton avec l'ID "submit-btn" const submitButton = document.getElementById("submit-btn");
querySelector
: Permet de récupérer un élément grâce à un sélecteur CSS. Cela signifie que vous pouvez cibler des éléments par leur balise, classe, attribut, ou même leur position dans le DOM.javascript// Sélectionner le premier paragraphe du document const firstParagraph = document.querySelector("p"); // Sélectionner un élément par son identifiant (ID) const header = document.querySelector("#header"); // Sélectionner le premier élément avec une classe spécifique const firstButton = document.querySelector(".btn"); // Sélectionner un élément de type <div> avec une classe spécifique const specialDiv = document.querySelector("div.special"); // Sélectionner le premier élément <input> dans un formulaire avec une classe spécifique const firstInput = document.querySelector("form input.form-input");
Utilisez
getElementById
pour les éléments avec un identifiant unique, etquerySelector
pour des sélections plus complexes.
Étape 3 : Création et affichage de variables ​
Avant de commencer, mettez en commentaire ou supprimez les codes précédents pour éviter les conflits. Nous allons créer des variables pour stocker le compteur de Pokémon et l'élément
<h2 id="compteur-el">
du document.
Créer une variable pour représenter l'élément HTML <h2 id="compteur-el">
et une pour le compteur du jeu : ​
- Action : Dans
script.js
, créez deux variables :- Une variable
compteur
pour stocker la valeur du compteur (initialement0
). - Une variable
compteurEl
pour stocker la référence à l'élément<h2 id="compteur-el">
. Utilisezconst
pour cette référence puisque l'élément ne changera pas.
javascriptlet compteur = 0; const compteurEl = document.getElementById("compteur-el");
- Une variable
Pourquoi utilise-t-on const
pour compteurEl
? ​
Nous utilisons const
pour déclarer la variable compteurEl
car elle représente une référence à un élément HTML qui ne changera pas. En d'autres termes, la valeur de compteurEl
(la référence à l'élément <h2>
) restera la même tout au long du script, même si le contenu ou les attributs de cet élément peuvent être modifiés. En revanche, let
est utilisé pour compteur
car cette variable est destinée à être modifiée régulièrement, chaque fois qu'un Pokémon est capturé. L'utilisation de const
pour compteurEl
garantit que cette référence ne sera pas accidentellement réassignée à un autre élément plus tard dans le code, ce qui contribue à la stabilité et à la clarté du code.
Étape 4 : Préparation pour la capture de Pokémon ​
Créer une fonction pour capturer un Pokémon : ​
- Action : Créez une fonction
capturer()
qui incrémente le compteur et actualise le texte de<h2 id="compteur-el">
.javascriptfunction capturer() { compteur += 1; // Incrémenter le compteur de 1 compteurEl.textContent = compteur; // Actualiser le texte de l'élément <h2> }
Lier la fonction au bouton "CAPTURER" : ​
- Action : Assurez-vous que le bouton "CAPTURER" dans
index.html
appelle la fonctioncapturer()
grâce à l'attributonclick
:html<button id="capturer-btn" onclick="capturer()">CAPTURER</button>
- Test : Actualisez la page dans le navigateur. Cliquez sur le bouton "CAPTURER" et vérifiez que le compteur augmente à chaque clic.
Étape 5 : Changer la couleur du compteur toutes les cinq captures ​
Nous souhaitons modifier la couleur du texte du compteur toutes les cinq captures pour rendre le jeu plus interactif.
- Moins de 5 captures : couleur verte
- De 5 Ă 10 captures : couleur jaune
- Plus de 10 captures : couleur rouge
Modifier le code de la fonction capturer()
pour modifier la couleur du texte du compteur en fonction du nombre de captures : ​
- Action : Modifiez la fonction
capturer()
pour changer la couleur du texte du compteur selon le nombre de captures. Utilisez une conditionif...else if...else
pour déterminer la couleur :javascriptfunction capturer() { compteur += 1; // Incrémenter le compteur de 1 compteurEl.textContent = compteur; // Mettre à jour le texte de l'élément <h2> if (compteur < 5) { compteurEl.style.color = "green"; // Couleur verte pour moins de 5 captures } else if (compteur < 10) { compteurEl.style.color = "yellow"; // Couleur jaune pour 5 à 9 captures } else { compteurEl.style.color = "red"; // Couleur rouge pour 10 captures ou plus } }
- Test : Actualisez la page dans le navigateur. Capturez des Pokémon pour vérifier que la couleur du texte du compteur change correctement.
Étape 6 : Sauvegarde des captures ​
Créer une variable pour stocker les captures sauvegardées : ​
- Action : Créez une variable
sauvegardeEl
pour stocker la référence à l'élément<p id="sauvegarde-el">
:javascriptconst sauvegardeEl = document.getElementById("sauvegarde-el");
Créer une fonction pour sauvegarder les captures : ​
- Action : Créez une fonction
sauvegarder()
qui ajoute la valeur actuelle du compteur au paragraphesauvegarde-el
et rĂ©initialise le compteur Ă0
.javascriptfunction sauvegarder() { let compteurStr = compteur + " Pokémons - "; sauvegardeEl.textContent += compteurStr; // Ajouter la valeur actuelle du compteur compteur = 0; compteurEl.textContent = compteur; }
Lier la fonction au bouton "SAUVEGARDER" : ​
- Action : Assurez-vous que le bouton "SAUVEGARDER" dans
index.html
appelle la fonctionsauvegarder()
:html<button id="sauvegarder-btn" onclick="sauvegarder()">SAUVEGARDER</button>
- Test :
- Actualisez la page dans le navigateur.
- Capturez quelques Pokémon, puis cliquez sur "SAUVEGARDER".
- Vérifiez que les captures sont ajoutées à la liste et que le compteur se réinitialise.
Étape 7 : Amélioration du code avec des écouteurs d'événements ​
Les écouteurs d'événements (event listeners
) permettent de réagir à des interactions de l'utilisateur, comme un clic, sans mélanger HTML et JavaScript. Introduction aux Callbacks Avant de commencer cette étape, il est important de comprendre le concept de callback en JavaScript. Un callback est une fonction que vous passez en argument à une autre fonction, et qui sera exécutée plus tard, généralement en réponse à un événement. Les callbacks sont couramment utilisés pour diriger les interactions utilisateur de manière asynchrone, comme répondre à un clic sur un bouton. Exemple d'utilisation d'un Callback Lorsque vous utilisez un écouteur d'événement avec addEventListener
, vous passez un callback qui sera exécuté lorsque l'événement spécifié se produit. Par exemple :
const capturerBtn = document.getElementById("capturer-btn");
capturerBtn.addEventListener("click", capturer);
Dans cet exemple, la fonction capturer
est passée comme callback à addEventListener
. Elle sera appelée automatiquement chaque fois que l'utilisateur cliquera sur le bouton "CAPTURER". Les callbacks permettent ainsi de rendre votre application interactive en réagissant aux actions de l'utilisateur de manière dynamique.
Retirer les attributs onclick
du HTML : ​
- Action : Ouvrez
index.html
et retirez les attributsonclick
des boutons "CAPTURER" et "SAUVEGARDER". Les boutons devraient ressembler Ă ceci :html<button id="capturer-btn">CAPTURER</button> <button id="sauvegarder-btn">SAUVEGARDER</button>
Ajouter des écouteurs d'événements dans JavaScript : ​
- Action : Dans
script.js
, récupérez les références aux boutons et ajoutez des écouteurs d'événements pour lier les fonctionscapturer()
etsauvegarder()
:javascriptconst capturerBtn = document.getElementById("capturer-btn"); const sauvegarderBtn = document.getElementById("sauvegarder-btn"); capturerBtn.addEventListener("click", capturer); sauvegarderBtn.addEventListener("click", sauvegarder);
- Test :
- Actualisez la page dans le navigateur.
- Vérifiez que le bouton "CAPTURER" incrémente toujours le compteur et que le bouton "SAUVEGARDER" sauvegarde correctement les captures.
Pourquoi cette étape est-elle importante ? ​
L'utilisation d'écouteurs d'événements améliore la séparation entre le HTML (contenu) et le JavaScript (fonctionnalité). Cela rend le code plus modulaire, plus facile à maintenir, et extensible pour des projets plus complexes.
Étape 8 : Utiliser le localStorage
pour sauvegarder les captures ​
Actuellement, les captures sont stockées temporairement dans la page web, mais elles sont perdues si l'utilisateur recharge la page ou ferme le navigateur. Pour résoudre ce problème, nous allons utiliser le localStorage
. Le localStorage
est une fonctionnalité du navigateur qui permet de stocker des données localement sur l'ordinateur de l'utilisateur. Cela signifie que les données peuvent être conservées même après le rechargement de la page ou la fermeture du navigateur. Sauvegarder les captures dans le localStorage
:
- Action : Modifiez la fonction
sauvegarder()
pour stocker les captures dans lelocalStorage
du navigateur :javascriptfunction sauvegarder() { let compteurStr = compteur + " Pokémons - "; sauvegardeEl.textContent += compteurStr; // Ajouter la valeur actuelle du compteur localStorage.setItem("captures", sauvegardeEl.textContent); // Sauvegarder les captures dans le localStorage compteur = 0; compteurEl.textContent = compteur; }
- Test : Visualisez les données sauvegardées dans le
localStorage
en ouvrant les outils de développement du navigateur (F12 ou clic droit > Inspecter > Application > Local Storage). Charger les captures sauvegardées au chargement de la page Dans cette étape, nous allons charger les captures sauvegardées dès que la page est chargée. Pour cela, nous allons utiliser un écouteur d'événement associé à l'événementload
. Cet événement se déclenche lorsque la page a complètement fini de se charger. Au lieu de définir une fonction nommée séparée, nous allons utiliser une fonction anonyme directement dans notre écouteur d'événement. Une fonction anonyme est une fonction sans nom, utilisée ici parce qu'elle est spécifique à cette action unique et ne nécessite pas d'être réutilisée ailleurs. - Action : Ajoutez le code suivant pour charger les captures sauvegardées au chargement de la page :javascript
window.addEventListener("load", () => { // Attendre que la page soit chargée pour exécuter le code sauvegardeEl.textContent = localStorage.getItem("captures") || ""; // Charger les captures sauvegardées ou une chaîne vide });
Dans cet exemple, la fonction que nous passons Ă addEventListener
est une fonction anonyme. Elle est définie avec la syntaxe () => { ... }
et sera exécutée une seule fois lorsque l'événement load
se déclenchera. L'utilisation d'une fonction anonyme ici permet de garder le code simple et directement lié à l'événement spécifique, sans ajouter de complexité inutile.
- Test : Actualisez la page dans le navigateur. Capturez quelques Pokémon, sauvegardez-les, puis rechargez la page.
Challenges supplémentaires ​
- Ajouter un bouton "RESET" pour réinitialiser le compteur et les captures, sans oublier le localStorage.
- Afficher l'historique des captures dans une liste Ă puce.
- Gérer le stockage des captures dans un tableau JavaScript.
- Permettre Ă l'utilisateur de supprimer des captures de l'historique.
🦤 La solution du prof ​
Le site du prof ​
https://fallinov.github.io/2024-SFA-JS-EXE-PokeCount/