parent
f1d1fc9e7a
commit
978b213ed7
@ -0,0 +1,214 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
|
||||
"translation_date": "2025-08-23T23:29:00+00:00",
|
||||
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Introduction aux langages de programmation et outils du métier
|
||||
|
||||
Cette leçon couvre les bases des langages de programmation. Les sujets abordés ici s'appliquent à la plupart des langages de programmation modernes. Dans la section "Outils du métier", vous découvrirez des logiciels utiles pour vous en tant que développeur.
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz avant la leçon
|
||||
[Quiz avant la leçon](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
|
||||
|
||||
## Introduction
|
||||
|
||||
Dans cette leçon, nous aborderons :
|
||||
|
||||
- Qu'est-ce que la programmation ?
|
||||
- Les types de langages de programmation
|
||||
- Les éléments de base d'un programme
|
||||
- Les logiciels et outils utiles pour le développeur professionnel
|
||||
|
||||
> Vous pouvez suivre cette leçon sur [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon) !
|
||||
|
||||
## Qu'est-ce que la programmation ?
|
||||
|
||||
La programmation (également appelée codage) est le processus d'écriture d'instructions pour un appareil tel qu'un ordinateur ou un appareil mobile. Nous écrivons ces instructions avec un langage de programmation, qui est ensuite interprété par l'appareil. Ces ensembles d'instructions peuvent être appelés de différentes manières, mais *programme*, *programme informatique*, *application (app)* et *exécutable* sont quelques noms courants.
|
||||
|
||||
Un *programme* peut être tout ce qui est écrit avec du code : sites web, jeux, applications mobiles, etc. Bien qu'il soit possible de créer un programme sans écrire de code, la logique sous-jacente est interprétée par l'appareil, et cette logique a très probablement été écrite avec du code. Un programme qui *s'exécute* ou *interprète* du code exécute des instructions. L'appareil que vous utilisez pour lire cette leçon exécute un programme pour l'afficher sur votre écran.
|
||||
|
||||
✅ Faites une petite recherche : qui est considéré comme le premier programmeur informatique au monde ?
|
||||
|
||||
## Les langages de programmation
|
||||
|
||||
Les langages de programmation permettent aux développeurs d'écrire des instructions pour un appareil. Les appareils ne comprennent que le binaire (1 et 0), et pour *la plupart* des développeurs, ce n'est pas une manière très efficace de communiquer. Les langages de programmation servent de moyen de communication entre les humains et les ordinateurs.
|
||||
|
||||
Les langages de programmation existent sous différents formats et peuvent avoir des objectifs variés. Par exemple, JavaScript est principalement utilisé pour les applications web, tandis que Bash est principalement utilisé pour les systèmes d'exploitation.
|
||||
|
||||
Les *langages de bas niveau* nécessitent généralement moins d'étapes que les *langages de haut niveau* pour qu'un appareil interprète les instructions. Cependant, ce qui rend les langages de haut niveau populaires, c'est leur lisibilité et leur support. JavaScript est considéré comme un langage de haut niveau.
|
||||
|
||||
Le code suivant illustre la différence entre un langage de haut niveau avec JavaScript et un langage de bas niveau avec le code assembleur ARM.
|
||||
|
||||
```javascript
|
||||
let number = 10
|
||||
let n1 = 0, n2 = 1, nextTerm;
|
||||
|
||||
for (let i = 1; i <= number; i++) {
|
||||
console.log(n1);
|
||||
nextTerm = n1 + n2;
|
||||
n1 = n2;
|
||||
n2 = nextTerm;
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
area ascen,code,readonly
|
||||
entry
|
||||
code32
|
||||
adr r0,thumb+1
|
||||
bx r0
|
||||
code16
|
||||
thumb
|
||||
mov r0,#00
|
||||
sub r0,r0,#01
|
||||
mov r1,#01
|
||||
mov r4,#10
|
||||
ldr r2,=0x40000000
|
||||
back add r0,r1
|
||||
str r0,[r2]
|
||||
add r2,#04
|
||||
mov r3,r0
|
||||
mov r0,r1
|
||||
mov r1,r3
|
||||
sub r4,#01
|
||||
cmp r4,#00
|
||||
bne back
|
||||
end
|
||||
```
|
||||
|
||||
Croyez-le ou non, *ils font exactement la même chose* : afficher une séquence de Fibonacci jusqu'à 10.
|
||||
|
||||
✅ Une séquence de Fibonacci est [définie](https://en.wikipedia.org/wiki/Fibonacci_number) comme un ensemble de nombres où chaque nombre est la somme des deux précédents, en commençant par 0 et 1. Les 10 premiers nombres de la séquence de Fibonacci sont 0, 1, 1, 2, 3, 5, 8, 13, 21 et 34.
|
||||
|
||||
## Les éléments d'un programme
|
||||
|
||||
Une seule instruction dans un programme est appelée une *instruction* (*statement*) et comporte généralement un caractère ou un espacement de ligne qui marque où l'instruction se termine, ou *se termine*. La manière dont un programme se termine varie selon le langage.
|
||||
|
||||
Les instructions dans un programme peuvent dépendre de données fournies par un utilisateur ou provenant d'ailleurs pour exécuter des instructions. Les données peuvent modifier le comportement d'un programme, c'est pourquoi les langages de programmation incluent un moyen de stocker temporairement des données pour une utilisation ultérieure. Ces moyens sont appelés *variables*. Les variables sont des instructions qui demandent à un appareil de sauvegarder des données dans sa mémoire. Les variables dans les programmes sont similaires aux variables en algèbre, où elles ont un nom unique et leur valeur peut changer au fil du temps.
|
||||
|
||||
Il est possible que certaines instructions ne soient pas exécutées par un appareil. Cela se produit généralement par conception lorsqu'elles sont écrites par le développeur ou par accident lorsqu'une erreur inattendue survient. Ce type de contrôle sur une application la rend plus robuste et maintenable. En général, ces changements de contrôle se produisent lorsque certaines conditions sont remplies. Une instruction courante utilisée dans la programmation moderne pour contrôler l'exécution d'un programme est l'instruction `if..else`.
|
||||
|
||||
✅ Vous en apprendrez davantage sur ce type d'instruction dans les leçons suivantes.
|
||||
|
||||
## Outils du métier
|
||||
|
||||
[](https://youtube.com/watch?v=69WJeXGBdxg "Outils du métier")
|
||||
|
||||
> 🎥 Cliquez sur l'image ci-dessus pour une vidéo sur les outils
|
||||
|
||||
Dans cette section, vous découvrirez des logiciels que vous pourriez trouver très utiles au début de votre parcours de développement professionnel.
|
||||
|
||||
Un **environnement de développement** est un ensemble unique d'outils et de fonctionnalités qu'un développeur utilise fréquemment lorsqu'il écrit des logiciels. Certains de ces outils ont été personnalisés pour répondre aux besoins spécifiques d'un développeur et peuvent évoluer avec le temps si ce développeur change de priorités dans son travail, ses projets personnels ou lorsqu'il utilise un autre langage de programmation. Les environnements de développement sont aussi uniques que les développeurs qui les utilisent.
|
||||
|
||||
### Éditeurs
|
||||
|
||||
L'un des outils les plus cruciaux pour le développement logiciel est l'éditeur. Les éditeurs sont l'endroit où vous écrivez votre code et parfois où vous l'exécutez.
|
||||
|
||||
Les développeurs s'appuient sur les éditeurs pour plusieurs raisons supplémentaires :
|
||||
|
||||
- Le *débogage* permet de découvrir des bogues et des erreurs en parcourant le code, ligne par ligne. Certains éditeurs disposent de capacités de débogage ; ils peuvent être personnalisés et ajoutés pour des langages de programmation spécifiques.
|
||||
- La *coloration syntaxique* ajoute des couleurs et des formats de texte au code, ce qui le rend plus facile à lire. La plupart des éditeurs permettent une coloration syntaxique personnalisée.
|
||||
- Les *extensions et intégrations* sont des outils spécialisés pour les développeurs, créés par des développeurs. Ces outils ne sont pas intégrés à l'éditeur de base. Par exemple, de nombreux développeurs documentent leur code pour expliquer son fonctionnement. Ils peuvent installer une extension de vérification orthographique pour repérer les fautes de frappe dans la documentation. La plupart des extensions sont conçues pour être utilisées dans un éditeur spécifique, et la plupart des éditeurs permettent de rechercher les extensions disponibles.
|
||||
- La *personnalisation* permet aux développeurs de créer un environnement de développement unique adapté à leurs besoins. La plupart des éditeurs sont extrêmement personnalisables et peuvent également permettre aux développeurs de créer des extensions personnalisées.
|
||||
|
||||
#### Éditeurs populaires et extensions pour le développement web
|
||||
|
||||
- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)
|
||||
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
|
||||
- [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare)
|
||||
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
|
||||
- [Atom](https://atom.io/)
|
||||
- [spell-check](https://atom.io/packages/spell-check)
|
||||
- [teletype](https://atom.io/packages/teletype)
|
||||
- [atom-beautify](https://atom.io/packages/atom-beautify)
|
||||
- [Sublimetext](https://www.sublimetext.com/)
|
||||
- [emmet](https://emmet.io/)
|
||||
- [SublimeLinter](http://www.sublimelinter.com/en/stable/)
|
||||
|
||||
### Navigateurs
|
||||
|
||||
Un autre outil crucial est le navigateur. Les développeurs web s'appuient sur le navigateur pour voir comment leur code s'exécute sur le web. Il est également utilisé pour afficher les éléments visuels d'une page web écrits dans l'éditeur, comme le HTML.
|
||||
|
||||
De nombreux navigateurs sont équipés d'*outils de développement* (DevTools) qui contiennent un ensemble de fonctionnalités utiles et d'informations pour aider les développeurs à collecter et capturer des informations importantes sur leur application. Par exemple : si une page web contient des erreurs, il est parfois utile de savoir quand elles se sont produites. Les DevTools d'un navigateur peuvent être configurés pour capturer ces informations.
|
||||
|
||||
#### Navigateurs populaires et DevTools
|
||||
|
||||
- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium/?WT.mc_id=academic-77807-sagibbon)
|
||||
- [Chrome](https://developers.google.com/web/tools/chrome-devtools/)
|
||||
- [Firefox](https://developer.mozilla.org/docs/Tools)
|
||||
|
||||
### Outils en ligne de commande
|
||||
|
||||
Certains développeurs préfèrent une vue moins graphique pour leurs tâches quotidiennes et s'appuient sur la ligne de commande pour y parvenir. Écrire du code nécessite une quantité importante de saisie, et certains développeurs préfèrent ne pas interrompre leur flux sur le clavier. Ils utiliseront des raccourcis clavier pour basculer entre les fenêtres du bureau, travailler sur différents fichiers et utiliser des outils. La plupart des tâches peuvent être effectuées avec une souris, mais un avantage de la ligne de commande est qu'il est possible d'accomplir beaucoup de choses avec des outils en ligne de commande sans avoir à alterner entre la souris et le clavier. Un autre avantage de la ligne de commande est qu'elle est configurable : vous pouvez enregistrer une configuration personnalisée, la modifier plus tard et l'importer sur d'autres machines de développement. Étant donné que les environnements de développement sont si uniques à chaque développeur, certains éviteront d'utiliser la ligne de commande, d'autres s'y fieront entièrement, et certains préféreront un mélange des deux.
|
||||
|
||||
### Options populaires pour la ligne de commande
|
||||
|
||||
Les options pour la ligne de commande diffèrent selon le système d'exploitation que vous utilisez.
|
||||
|
||||
*💻 = préinstallé sur le système d'exploitation.*
|
||||
|
||||
#### Windows
|
||||
|
||||
- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7/?WT.mc_id=academic-77807-sagibbon) 💻
|
||||
- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands/?WT.mc_id=academic-77807-sagibbon) (également connu sous le nom de CMD) 💻
|
||||
- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-77807-sagibbon)
|
||||
- [mintty](https://mintty.github.io/)
|
||||
|
||||
#### MacOS
|
||||
|
||||
- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻
|
||||
- [iTerm](https://iterm2.com/)
|
||||
- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7/?WT.mc_id=academic-77807-sagibbon)
|
||||
|
||||
#### Linux
|
||||
|
||||
- [Bash](https://www.gnu.org/software/bash/manual/html_node/index.html) 💻
|
||||
- [KDE Konsole](https://docs.kde.org/trunk5/en/konsole/konsole/index.html)
|
||||
- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7/?WT.mc_id=academic-77807-sagibbon)
|
||||
|
||||
#### Outils populaires en ligne de commande
|
||||
|
||||
- [Git](https://git-scm.com/) (💻 sur la plupart des systèmes d'exploitation)
|
||||
- [NPM](https://www.npmjs.com/)
|
||||
- [Yarn](https://classic.yarnpkg.com/en/docs/cli/)
|
||||
|
||||
### Documentation
|
||||
|
||||
Lorsqu'un développeur souhaite apprendre quelque chose de nouveau, il se tourne souvent vers la documentation pour comprendre comment l'utiliser. Les développeurs s'appuient souvent sur la documentation pour les guider dans l'utilisation correcte des outils et des langages, et aussi pour approfondir leur compréhension de leur fonctionnement.
|
||||
|
||||
#### Documentation populaire sur le développement web
|
||||
|
||||
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), par Mozilla, les éditeurs du navigateur [Firefox](https://www.mozilla.org/firefox/)
|
||||
- [Frontend Masters](https://frontendmasters.com/learn/)
|
||||
- [Web.dev](https://web.dev), par Google, éditeurs de [Chrome](https://www.google.com/chrome/)
|
||||
- [Documentation pour développeurs de Microsoft](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), pour [Microsoft Edge](https://www.microsoft.com/edge)
|
||||
- [W3 Schools](https://www.w3schools.com/where_to_start.asp)
|
||||
|
||||
✅ Faites des recherches : Maintenant que vous connaissez les bases de l'environnement d'un développeur web, comparez-le avec celui d'un designer web.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Comparez quelques langages de programmation. Quelles sont les caractéristiques uniques de JavaScript par rapport à Java ? Et de COBOL par rapport à Go ?
|
||||
|
||||
## Quiz après la leçon
|
||||
[Quiz après la leçon](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/2)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
Étudiez un peu les différents langages disponibles pour le programmeur. Essayez d'écrire une ligne dans un langage, puis réécrivez-la dans deux autres. Qu'avez-vous appris ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Lire la documentation](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "1ce4deaec80130d3a0a3c906568459fc",
|
||||
"translation_date": "2025-08-23T23:31:21+00:00",
|
||||
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Lire la documentation
|
||||
|
||||
## Instructions
|
||||
|
||||
Il existe de nombreux outils dont un développeur web peut avoir besoin, disponibles sur la [documentation MDN sur les outils côté client](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Sélectionnez 3 outils qui ne sont pas abordés dans la leçon, expliquez pourquoi un développeur web les utiliserait, et recherchez un outil qui appartient à cette catégorie en partageant sa documentation. Ne choisissez pas le même exemple d'outil mentionné dans la documentation MDN.
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
Exemplaire | Adéquat | À améliorer
|
||||
--- | --- | -- |
|
||||
| Expliqué pourquoi un développeur web utiliserait l'outil | Expliqué comment, mais pas pourquoi un développeur utiliserait l'outil | N'a pas mentionné comment ou pourquoi un développeur utiliserait l'outil |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,337 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
|
||||
"translation_date": "2025-08-23T23:18:46+00:00",
|
||||
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Introduction à GitHub
|
||||
|
||||
Cette leçon couvre les bases de GitHub, une plateforme pour héberger et gérer les modifications de votre code.
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz Pré-Leçon
|
||||
[Quiz pré-leçon](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/3)
|
||||
|
||||
## Introduction
|
||||
|
||||
Dans cette leçon, nous aborderons :
|
||||
|
||||
- le suivi du travail effectué sur votre machine
|
||||
- le travail sur des projets avec d'autres personnes
|
||||
- comment contribuer aux logiciels open source
|
||||
|
||||
### Prérequis
|
||||
|
||||
Avant de commencer, vérifiez si Git est installé. Dans le terminal, tapez :
|
||||
`git --version`
|
||||
|
||||
Si Git n'est pas installé, [téléchargez Git](https://git-scm.com/downloads). Ensuite, configurez votre profil Git local dans le terminal :
|
||||
* `git config --global user.name "votre-nom"`
|
||||
* `git config --global user.email "votre-email"`
|
||||
|
||||
Pour vérifier si Git est déjà configuré, vous pouvez taper :
|
||||
`git config --list`
|
||||
|
||||
Vous aurez également besoin d'un compte GitHub, d'un éditeur de code (comme Visual Studio Code) et d'ouvrir votre terminal (ou : invite de commande).
|
||||
|
||||
Rendez-vous sur [github.com](https://github.com/) pour créer un compte si ce n'est pas déjà fait, ou connectez-vous et complétez votre profil.
|
||||
|
||||
✅ GitHub n'est pas le seul dépôt de code au monde ; il en existe d'autres, mais GitHub est le plus connu.
|
||||
|
||||
### Préparation
|
||||
|
||||
Vous aurez besoin d'un dossier contenant un projet de code sur votre machine locale (ordinateur portable ou PC) et d'un dépôt public sur GitHub, qui servira d'exemple pour apprendre à contribuer aux projets des autres.
|
||||
|
||||
---
|
||||
|
||||
## Gestion du code
|
||||
|
||||
Supposons que vous avez un dossier localement avec un projet de code et que vous souhaitez commencer à suivre vos progrès en utilisant git - le système de contrôle de version. Certaines personnes comparent l'utilisation de git à l'écriture d'une lettre d'amour à votre futur vous-même. En lisant vos messages de commit des jours, semaines ou mois plus tard, vous pourrez vous rappeler pourquoi vous avez pris une décision ou "revenir en arrière" sur une modification - à condition d'écrire de bons "messages de commit".
|
||||
|
||||
### Tâche : Créer un dépôt et commettre du code
|
||||
|
||||
> Regardez la vidéo
|
||||
>
|
||||
> [](https://www.youtube.com/watch?v=9R31OUPpxU4)
|
||||
|
||||
1. **Créer un dépôt sur GitHub**. Sur GitHub.com, dans l'onglet des dépôts ou depuis la barre de navigation en haut à droite, trouvez le bouton **nouveau dépôt**.
|
||||
|
||||
1. Donnez un nom à votre dépôt (dossier).
|
||||
1. Sélectionnez **créer un dépôt**.
|
||||
|
||||
1. **Naviguer vers votre dossier de travail**. Dans votre terminal, passez au dossier (également appelé répertoire) que vous souhaitez commencer à suivre. Tapez :
|
||||
|
||||
```bash
|
||||
cd [name of your folder]
|
||||
```
|
||||
|
||||
1. **Initialiser un dépôt git**. Dans votre projet, tapez :
|
||||
|
||||
```bash
|
||||
git init
|
||||
```
|
||||
|
||||
1. **Vérifier le statut**. Pour vérifier le statut de votre dépôt, tapez :
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
La sortie peut ressembler à ceci :
|
||||
|
||||
```output
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git checkout -- <file>..." to discard changes in working directory)
|
||||
|
||||
modified: file.txt
|
||||
modified: file2.txt
|
||||
```
|
||||
|
||||
Typiquement, une commande `git status` vous indique des informations comme les fichiers prêts à être _enregistrés_ dans le dépôt ou ceux qui ont des modifications que vous pourriez vouloir conserver.
|
||||
|
||||
1. **Ajouter tous les fichiers pour le suivi**
|
||||
Cela s'appelle également mettre en scène les fichiers / ajouter des fichiers à la zone de staging.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
```
|
||||
|
||||
L'argument `git add` suivi de `.` indique que tous vos fichiers et modifications sont prêts pour le suivi.
|
||||
|
||||
1. **Ajouter des fichiers sélectionnés pour le suivi**
|
||||
|
||||
```bash
|
||||
git add [file or folder name]
|
||||
```
|
||||
|
||||
Cela permet d'ajouter uniquement des fichiers sélectionnés à la zone de staging lorsque vous ne souhaitez pas tout commettre en une seule fois.
|
||||
|
||||
1. **Désépingler tous les fichiers**
|
||||
|
||||
```bash
|
||||
git reset
|
||||
```
|
||||
|
||||
Cette commande permet de désépingler tous les fichiers en une seule fois.
|
||||
|
||||
1. **Désépingler un fichier particulier**
|
||||
|
||||
```bash
|
||||
git reset [file or folder name]
|
||||
```
|
||||
|
||||
Cette commande permet de désépingler uniquement un fichier particulier que vous ne souhaitez pas inclure dans le prochain commit.
|
||||
|
||||
1. **Conserver votre travail**. À ce stade, vous avez ajouté les fichiers dans une zone appelée _staging area_. Un endroit où Git suit vos fichiers. Pour rendre la modification permanente, vous devez _commettre_ les fichiers. Pour ce faire, créez un _commit_ avec la commande `git commit`. Un _commit_ représente un point de sauvegarde dans l'historique de votre dépôt. Tapez la commande suivante pour créer un _commit_ :
|
||||
|
||||
```bash
|
||||
git commit -m "first commit"
|
||||
```
|
||||
|
||||
Cela commet tous vos fichiers, en ajoutant le message "premier commit". Pour les futurs messages de commit, vous voudrez être plus descriptif pour indiquer le type de modification que vous avez apportée.
|
||||
|
||||
1. **Connecter votre dépôt Git local à GitHub**. Un dépôt Git est utile sur votre machine, mais à un moment donné, vous voudrez sauvegarder vos fichiers quelque part et inviter d'autres personnes à travailler avec vous sur votre dépôt. Un excellent endroit pour cela est GitHub. Rappelez-vous que nous avons déjà créé un dépôt sur GitHub, donc la seule chose à faire est de connecter notre dépôt Git local à GitHub. La commande `git remote add` fera cela. Tapez la commande suivante :
|
||||
|
||||
> Notez, avant de taper la commande, allez sur la page de votre dépôt GitHub pour trouver l'URL du dépôt. Vous l'utiliserez dans la commande ci-dessous. Remplacez ```https://github.com/username/repository_name.git``` par votre URL GitHub.
|
||||
|
||||
```bash
|
||||
git remote add origin https://github.com/username/repository_name.git
|
||||
```
|
||||
|
||||
Cela crée un _remote_, ou connexion, nommé "origin" pointant vers le dépôt GitHub que vous avez créé précédemment.
|
||||
|
||||
1. **Envoyer les fichiers locaux à GitHub**. Jusqu'à présent, vous avez créé une _connexion_ entre le dépôt local et le dépôt GitHub. Envoyons ces fichiers à GitHub avec la commande suivante `git push`, comme suit :
|
||||
|
||||
> Notez, le nom de votre branche peut être différent par défaut de ```main```.
|
||||
|
||||
```bash
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
Cela envoie vos commits dans votre branche "main" à GitHub.
|
||||
|
||||
2. **Ajouter d'autres modifications**. Si vous souhaitez continuer à apporter des modifications et les envoyer à GitHub, vous n'aurez besoin que des trois commandes suivantes :
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "type your commit message here"
|
||||
git push
|
||||
```
|
||||
|
||||
> Astuce, vous pourriez également vouloir adopter un fichier `.gitignore` pour empêcher les fichiers que vous ne voulez pas suivre d'apparaître sur GitHub - comme ce fichier de notes que vous stockez dans le même dossier mais qui n'a pas sa place dans un dépôt public. Vous pouvez trouver des modèles pour les fichiers `.gitignore` sur [.gitignore templates](https://github.com/github/gitignore).
|
||||
|
||||
#### Messages de commit
|
||||
|
||||
Un excellent sujet de message de commit complète la phrase suivante :
|
||||
Si appliqué, ce commit va <votre sujet ici>
|
||||
|
||||
Pour le sujet, utilisez l'impératif au présent : "modifier" et non "modifié" ni "modifie".
|
||||
Comme pour le sujet, dans le corps (facultatif), utilisez également l'impératif au présent. Le corps doit inclure la motivation du changement et contraster cela avec le comportement précédent. Vous expliquez le `pourquoi`, pas le `comment`.
|
||||
|
||||
✅ Prenez quelques minutes pour explorer GitHub. Pouvez-vous trouver un message de commit vraiment excellent ? Pouvez-vous en trouver un vraiment minimaliste ? Quelles informations pensez-vous être les plus importantes et utiles à transmettre dans un message de commit ?
|
||||
|
||||
### Tâche : Collaborer
|
||||
|
||||
La principale raison de mettre des choses sur GitHub était de rendre possible la collaboration avec d'autres développeurs.
|
||||
|
||||
## Travailler sur des projets avec d'autres
|
||||
|
||||
> Regardez la vidéo
|
||||
>
|
||||
> [](https://www.youtube.com/watch?v=bFCM-PC3cu8)
|
||||
|
||||
Dans votre dépôt, naviguez vers `Insights > Community` pour voir comment votre projet se compare aux standards communautaires recommandés.
|
||||
|
||||
Voici quelques éléments qui peuvent améliorer votre dépôt GitHub :
|
||||
- **Description**. Avez-vous ajouté une description pour votre projet ?
|
||||
- **README**. Avez-vous ajouté un README ? GitHub fournit des conseils pour rédiger un [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
|
||||
- **Lignes directrices pour contribuer**. Votre projet a-t-il des [lignes directrices pour contribuer](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon) ?
|
||||
- **Code de conduite**. Un [Code de conduite](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/) ?
|
||||
- **Licence**. Peut-être le plus important, une [licence](https://docs.github.com/articles/adding-a-license-to-a-repository/) ?
|
||||
|
||||
Toutes ces ressources faciliteront l'intégration de nouveaux membres dans l'équipe. Et ce sont généralement les choses que les nouveaux contributeurs regardent avant même de consulter votre code, pour savoir si votre projet est le bon endroit où investir leur temps.
|
||||
|
||||
✅ Les fichiers README, bien qu'ils prennent du temps à préparer, sont souvent négligés par les mainteneurs occupés. Pouvez-vous trouver un exemple particulièrement descriptif ? Note : il existe des [outils pour aider à créer de bons README](https://www.makeareadme.com/) que vous pourriez essayer.
|
||||
|
||||
### Tâche : Fusionner du code
|
||||
|
||||
Les documents de contribution aident les gens à contribuer au projet. Ils expliquent quels types de contributions vous recherchez et comment le processus fonctionne. Les contributeurs devront suivre une série d'étapes pour pouvoir contribuer à votre dépôt sur GitHub :
|
||||
|
||||
1. **Forker votre dépôt**. Vous voudrez probablement que les gens _forkent_ votre projet. Forker signifie créer une réplique de votre dépôt sur leur profil GitHub.
|
||||
1. **Cloner**. À partir de là, ils cloneront le projet sur leur machine locale.
|
||||
1. **Créer une branche**. Vous voudrez leur demander de créer une _branche_ pour leur travail.
|
||||
1. **Concentrer leur modification sur une seule zone**. Demandez aux contributeurs de concentrer leurs contributions sur une seule chose à la fois - de cette façon, les chances que vous puissiez _fusionner_ leur travail sont plus élevées. Imaginez qu'ils corrigent un bug, ajoutent une nouvelle fonctionnalité et mettent à jour plusieurs tests - que faire si vous voulez, ou ne pouvez implémenter que 2 sur 3, ou 1 sur 3 modifications ?
|
||||
|
||||
✅ Imaginez une situation où les branches sont particulièrement critiques pour écrire et livrer du bon code. À quels cas d'utilisation pouvez-vous penser ?
|
||||
|
||||
> Note, soyez le changement que vous voulez voir dans le monde, et créez des branches pour votre propre travail également. Tous les commits que vous faites seront effectués sur la branche sur laquelle vous êtes actuellement "checkout". Utilisez `git status` pour voir sur quelle branche vous êtes.
|
||||
|
||||
Passons en revue un flux de travail de contributeur. Supposons que le contributeur a déjà _forké_ et _cloné_ le dépôt afin qu'il ait un dépôt Git prêt à être travaillé sur sa machine locale :
|
||||
|
||||
1. **Créer une branche**. Utilisez la commande `git branch` pour créer une branche qui contiendra les modifications qu'ils souhaitent contribuer :
|
||||
|
||||
```bash
|
||||
git branch [branch-name]
|
||||
```
|
||||
|
||||
1. **Passer à la branche de travail**. Passez à la branche spécifiée et mettez à jour le répertoire de travail avec `git switch` :
|
||||
|
||||
```bash
|
||||
git switch [branch-name]
|
||||
```
|
||||
|
||||
1. **Travailler**. À ce stade, vous voulez ajouter vos modifications. N'oubliez pas d'en informer Git avec les commandes suivantes :
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "my changes"
|
||||
```
|
||||
|
||||
Assurez-vous de donner un bon nom à votre commit, pour votre bien ainsi que pour le mainteneur du dépôt que vous aidez.
|
||||
|
||||
1. **Combiner votre travail avec la branche `main`**. À un moment donné, vous avez terminé de travailler et vous voulez combiner votre travail avec celui de la branche `main`. La branche `main` a peut-être changé entre-temps, alors assurez-vous de la mettre d'abord à jour avec les commandes suivantes :
|
||||
|
||||
```bash
|
||||
git switch main
|
||||
git pull
|
||||
```
|
||||
|
||||
À ce stade, vous voulez vous assurer que tous les _conflits_, situations où Git ne peut pas facilement _combiner_ les modifications, se produisent dans votre branche de travail. Par conséquent, exécutez les commandes suivantes :
|
||||
|
||||
```bash
|
||||
git switch [branch_name]
|
||||
git merge main
|
||||
```
|
||||
|
||||
Cela intégrera toutes les modifications de `main` dans votre branche et, espérons-le, vous pourrez simplement continuer. Sinon, VS Code vous indiquera où Git est _confus_ et vous modifierez les fichiers concernés pour indiquer quel contenu est le plus précis.
|
||||
|
||||
1. **Envoyer votre travail à GitHub**. Envoyer votre travail à GitHub signifie deux choses : pousser votre branche vers votre dépôt et ensuite ouvrir une PR (Pull Request).
|
||||
|
||||
```bash
|
||||
git push --set-upstream origin [branch-name]
|
||||
```
|
||||
|
||||
La commande ci-dessus crée la branche sur votre dépôt forké.
|
||||
|
||||
1. **Ouvrir une PR**. Ensuite, vous voulez ouvrir une PR. Pour ce faire, naviguez vers le dépôt forké sur GitHub. Vous verrez une indication sur GitHub vous demandant si vous souhaitez créer une nouvelle PR, cliquez dessus et vous serez dirigé vers une interface où vous pourrez modifier le titre du message de commit, lui donner une description plus appropriée. Maintenant, le mainteneur du dépôt que vous avez forké verra cette PR et _croisons les doigts_ il appréciera et _fusionnera_ votre PR. Vous êtes maintenant un contributeur, yay :)
|
||||
|
||||
1. **Nettoyer**. Il est considéré comme une bonne pratique de _nettoyer_ après avoir fusionné avec succès une PR. Vous voulez nettoyer à la fois votre branche locale et la branche que vous avez poussée sur GitHub. Supprimons-la d'abord localement avec la commande suivante :
|
||||
|
||||
```bash
|
||||
git branch -d [branch-name]
|
||||
```
|
||||
Assurez-vous d'aller sur la page GitHub du dépôt forké ensuite et de supprimer la branche distante que vous venez d'y pousser.
|
||||
|
||||
`Pull request` semble être un terme étrange, car en réalité, vous voulez pousser vos modifications au projet. Mais le mainteneur (propriétaire du projet) ou l'équipe principale doit examiner vos modifications avant de les fusionner avec la branche "main" du projet. Vous demandez donc une décision de modification à un mainteneur.
|
||||
|
||||
Une pull request est l'endroit où comparer et discuter des différences introduites sur une branche avec des revues, des commentaires, des tests intégrés, et plus encore. Une bonne pull request suit à peu près les mêmes règles qu'un message de commit. Vous pouvez ajouter une référence à un problème dans le gestionnaire de problèmes, par exemple lorsque votre travail corrige un problème. Cela se fait en utilisant un `#` suivi du numéro de votre problème. Par exemple `#97`.
|
||||
|
||||
🤞Croisons les doigts pour que tous les contrôles passent et que le(s) propriétaire(s) du projet fusionne(nt) vos modifications dans le projet🤞
|
||||
|
||||
Mettez à jour votre branche de travail locale actuelle avec tous les nouveaux commits de la branche distante correspondante sur GitHub :
|
||||
|
||||
`git pull`
|
||||
|
||||
## Comment contribuer à l'open source
|
||||
|
||||
Tout d'abord, trouvons un dépôt (ou **repo**) sur GitHub qui vous intéresse et auquel vous souhaitez apporter une modification. Vous voudrez copier son contenu sur votre machine.
|
||||
|
||||
✅ Une bonne façon de trouver des dépôts adaptés aux débutants est de [rechercher par le tag 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/).
|
||||
|
||||

|
||||
|
||||
Il existe plusieurs façons de copier du code. Une méthode consiste à "cloner" le contenu du dépôt, en utilisant HTTPS, SSH, ou en utilisant l'interface en ligne de commande GitHub CLI.
|
||||
|
||||
Ouvrez votre terminal et clonez le dépôt comme ceci :
|
||||
`git clone https://github.com/ProjectURL`
|
||||
|
||||
Pour travailler sur le projet, passez au bon dossier :
|
||||
`cd ProjectURL`
|
||||
|
||||
Vous pouvez également ouvrir l'ensemble du projet en utilisant [Codespaces](https://github.com/features/codespaces), l'éditeur de code intégré / environnement de développement cloud de GitHub, ou [GitHub Desktop](https://desktop.github.com/).
|
||||
|
||||
Enfin, vous pouvez télécharger le code dans un dossier compressé.
|
||||
|
||||
### Quelques informations intéressantes sur GitHub
|
||||
|
||||
Vous pouvez étoiler, surveiller et/ou "forker" tout dépôt public sur GitHub. Vous pouvez retrouver vos dépôts étoilés dans le menu déroulant en haut à droite. C'est comme ajouter un favori, mais pour du code.
|
||||
|
||||
Les projets ont un gestionnaire de problèmes, généralement sur GitHub dans l'onglet "Issues" sauf indication contraire, où les gens discutent des problèmes liés au projet. Et l'onglet Pull Requests est l'endroit où les gens discutent et examinent les modifications en cours.
|
||||
|
||||
Les projets peuvent également avoir des discussions dans des forums, des listes de diffusion ou des canaux de chat comme Slack, Discord ou IRC.
|
||||
|
||||
✅ Explorez votre nouveau dépôt GitHub et essayez quelques fonctionnalités, comme modifier les paramètres, ajouter des informations à votre dépôt, et créer un projet (comme un tableau Kanban). Il y a beaucoup à découvrir !
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Associez-vous à un ami pour travailler sur le code de chacun. Créez un projet collaboratif, forkez du code, créez des branches, et fusionnez des modifications.
|
||||
|
||||
## Quiz post-lecture
|
||||
[Quiz post-lecture](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/4)
|
||||
|
||||
## Révision & Auto-apprentissage
|
||||
|
||||
Lisez davantage sur [comment contribuer à un logiciel open source](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution).
|
||||
|
||||
[Cheatsheet Git](https://training.github.com/downloads/github-git-cheat-sheet/).
|
||||
|
||||
Pratiquez, pratiquez, pratiquez. GitHub propose d'excellents parcours d'apprentissage via [skills.github.com](https://skills.github.com) :
|
||||
|
||||
- [Première semaine sur GitHub](https://skills.github.com/#first-week-on-github)
|
||||
|
||||
Vous trouverez également des cours plus avancés.
|
||||
|
||||
## Devoir
|
||||
|
||||
Complétez [le cours Première semaine sur GitHub](https://skills.github.com/#first-week-on-github).
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,242 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
|
||||
"translation_date": "2025-08-23T23:23:25+00:00",
|
||||
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer des pages web accessibles
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz avant le cours
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/5)
|
||||
|
||||
> La puissance du Web réside dans son universalité. L'accès pour tous, indépendamment des handicaps, est un aspect essentiel.
|
||||
>
|
||||
> \- Sir Timothy Berners-Lee, directeur du W3C et inventeur du World Wide Web
|
||||
|
||||
Cette citation illustre parfaitement l'importance de créer des sites web accessibles. Une application qui ne peut pas être utilisée par tous est, par définition, exclusive. En tant que développeurs web, nous devons toujours garder l'accessibilité à l'esprit. En adoptant cette approche dès le début, vous serez bien préparé pour garantir que tout le monde puisse accéder aux pages que vous créez. Dans cette leçon, vous apprendrez à utiliser des outils pour garantir l'accessibilité de vos ressources web et à concevoir en tenant compte de l'accessibilité.
|
||||
|
||||
> Vous pouvez suivre cette leçon sur [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon) !
|
||||
|
||||
## Outils à utiliser
|
||||
|
||||
### Lecteurs d'écran
|
||||
|
||||
Les lecteurs d'écran sont parmi les outils d'accessibilité les plus connus.
|
||||
|
||||
[Les lecteurs d'écran](https://fr.wikipedia.org/wiki/Lecteur_d%27%C3%A9cran) sont des outils couramment utilisés par les personnes ayant des déficiences visuelles. Tout comme nous nous assurons qu'un navigateur transmet correctement les informations que nous souhaitons partager, nous devons également veiller à ce qu'un lecteur d'écran fasse de même.
|
||||
|
||||
Dans sa forme la plus basique, un lecteur d'écran lit une page de haut en bas de manière audible. Si votre page est entièrement composée de texte, le lecteur transmettra les informations de manière similaire à un navigateur. Bien sûr, les pages web ne sont que rarement composées uniquement de texte ; elles contiennent des liens, des images, des couleurs et d'autres éléments visuels. Il est donc essentiel de s'assurer que ces informations sont correctement interprétées par un lecteur d'écran.
|
||||
|
||||
Chaque développeur web devrait se familiariser avec un lecteur d'écran. Comme mentionné précédemment, c'est l'outil que vos utilisateurs utiliseront. De la même manière que vous connaissez le fonctionnement d'un navigateur, vous devriez apprendre à utiliser un lecteur d'écran. Heureusement, la plupart des systèmes d'exploitation intègrent des lecteurs d'écran.
|
||||
|
||||
Certains navigateurs disposent également d'outils intégrés et d'extensions capables de lire le texte à haute voix ou de fournir des fonctionnalités de navigation de base, comme [ces outils d'accessibilité pour le navigateur Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Bien qu'importants, ces outils fonctionnent différemment des lecteurs d'écran et ne doivent pas être confondus avec des outils de test pour lecteurs d'écran.
|
||||
|
||||
✅ Essayez un lecteur d'écran et un outil de lecture de texte dans un navigateur. Sous Windows, [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) est inclus par défaut, et [JAWS](https://webaim.org/articles/jaws/) et [NVDA](https://www.nvaccess.org/about-nvda/) peuvent également être installés. Sous macOS et iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) est installé par défaut.
|
||||
|
||||
### Zoom
|
||||
|
||||
Un autre outil couramment utilisé par les personnes ayant des déficiences visuelles est le zoom. Le type de zoom le plus basique est le zoom statique, contrôlé via `Control + signe plus (+)` ou en diminuant la résolution de l'écran. Ce type de zoom redimensionne l'ensemble de la page, il est donc important d'utiliser un [design responsive](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) pour offrir une bonne expérience utilisateur à des niveaux de zoom élevés.
|
||||
|
||||
Un autre type de zoom repose sur des logiciels spécialisés qui agrandissent une zone spécifique de l'écran et permettent de se déplacer, un peu comme avec une loupe. Sous Windows, [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) est intégré, et [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) est un logiciel tiers de grossissement avec plus de fonctionnalités et une base d'utilisateurs plus large. macOS et iOS disposent également d'un logiciel de grossissement intégré appelé [Zoom](https://www.apple.com/accessibility/mac/vision/).
|
||||
|
||||
### Vérificateurs de contraste
|
||||
|
||||
Les couleurs des sites web doivent être soigneusement choisies pour répondre aux besoins des utilisateurs daltoniens ou de ceux ayant des difficultés à percevoir les couleurs à faible contraste.
|
||||
|
||||
✅ Testez un site web que vous aimez avec une extension de navigateur comme [le vérificateur de contraste WCAG](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). Qu'avez-vous appris ?
|
||||
|
||||
### Lighthouse
|
||||
|
||||
Dans la section des outils de développement de votre navigateur, vous trouverez l'outil Lighthouse. Cet outil est important pour obtenir une première analyse de l'accessibilité (ainsi que d'autres aspects) d'un site web. Bien qu'il ne faille pas se fier exclusivement à Lighthouse, un score de 100 % est un bon point de départ.
|
||||
|
||||
✅ Trouvez Lighthouse dans le panneau des outils de développement de votre navigateur et analysez un site. Qu'avez-vous découvert ?
|
||||
|
||||
## Concevoir pour l'accessibilité
|
||||
|
||||
L'accessibilité est un sujet relativement vaste. Pour vous aider, de nombreuses ressources sont disponibles.
|
||||
|
||||
- [Accessible U - Université du Minnesota](https://accessibility.umn.edu/your-role/web-developers)
|
||||
|
||||
Bien que nous ne puissions pas couvrir tous les aspects de la création de sites accessibles, voici quelques principes de base que vous voudrez mettre en œuvre. Concevoir une page accessible dès le départ est **toujours** plus facile que de revenir sur une page existante pour la rendre accessible.
|
||||
|
||||
## Bonnes pratiques d'affichage
|
||||
|
||||
### Palettes de couleurs sûres
|
||||
|
||||
Les gens perçoivent le monde différemment, y compris les couleurs. Lorsque vous choisissez un schéma de couleurs pour votre site, assurez-vous qu'il soit accessible à tous. Un excellent [outil pour générer des palettes de couleurs est Color Safe](http://colorsafe.co/).
|
||||
|
||||
✅ Identifiez un site web qui pose problème dans son utilisation des couleurs. Pourquoi ?
|
||||
|
||||
### Utilisez le bon HTML
|
||||
|
||||
Avec CSS et JavaScript, il est possible de faire ressembler n'importe quel élément à n'importe quel type de contrôle. `<span>` pourrait être utilisé pour créer un `<button>`, et `<b>` pourrait devenir un lien hypertexte. Bien que cela puisse sembler plus facile à styliser, cela ne transmet rien à un lecteur d'écran. Utilisez le HTML approprié lorsque vous créez des contrôles sur une page. Si vous voulez un lien hypertexte, utilisez `<a>`. Utiliser le bon HTML pour le bon contrôle s'appelle utiliser du HTML sémantique.
|
||||
|
||||
✅ Allez sur un site web et vérifiez si les concepteurs et développeurs utilisent correctement le HTML. Pouvez-vous trouver un bouton qui devrait être un lien ? Astuce : faites un clic droit et choisissez "Afficher le code source de la page" dans votre navigateur pour examiner le code sous-jacent.
|
||||
|
||||
### Créez une hiérarchie de titres descriptive
|
||||
|
||||
Les utilisateurs de lecteurs d'écran [s'appuient fortement sur les titres](https://webaim.org/projects/screenreadersurvey8/#finding) pour trouver des informations et naviguer sur une page. Rédiger un contenu de titre descriptif et utiliser des balises de titre sémantiques sont essentiels pour créer un site facilement navigable pour les utilisateurs de lecteurs d'écran.
|
||||
|
||||
### Utilisez de bons indices visuels
|
||||
|
||||
CSS offre un contrôle total sur l'apparence de tout élément d'une page. Vous pouvez créer des zones de texte sans contour ou des liens hypertexte sans soulignement. Malheureusement, supprimer ces indices peut rendre plus difficile pour quelqu'un qui en dépend de reconnaître le type de contrôle.
|
||||
|
||||
## L'importance du texte des liens
|
||||
|
||||
Les liens hypertexte sont essentiels pour naviguer sur le web. Par conséquent, s'assurer qu'un lecteur d'écran peut correctement lire les liens permet à tous les utilisateurs de naviguer sur votre site.
|
||||
|
||||
### Lecteurs d'écran et liens
|
||||
|
||||
Comme on pourrait s'y attendre, les lecteurs d'écran lisent le texte des liens de la même manière qu'ils lisent tout autre texte sur la page. Avec cela en tête, le texte démontré ci-dessous pourrait sembler parfaitement acceptable.
|
||||
|
||||
> Le petit manchot, parfois appelé manchot féerique, est le plus petit manchot du monde. [Cliquez ici](https://fr.wikipedia.org/wiki/Manchot_bleu) pour plus d'informations.
|
||||
|
||||
> Le petit manchot, parfois appelé manchot féerique, est le plus petit manchot du monde. Visitez https://fr.wikipedia.org/wiki/Manchot_bleu pour plus d'informations.
|
||||
|
||||
> **NOTE** Comme vous êtes sur le point de le lire, vous ne devriez **jamais** créer de liens ressemblant à ceux ci-dessus.
|
||||
|
||||
Rappelez-vous, les lecteurs d'écran sont une interface différente des navigateurs avec un ensemble de fonctionnalités différent.
|
||||
|
||||
### Le problème avec l'utilisation de l'URL
|
||||
|
||||
Les lecteurs d'écran lisent le texte. Si une URL apparaît dans le texte, le lecteur d'écran lira l'URL. En général, l'URL ne transmet pas d'informations significatives et peut être agaçante. Vous avez peut-être déjà vécu cela si votre téléphone a lu à haute voix un message texte contenant une URL.
|
||||
|
||||
### Le problème avec "cliquez ici"
|
||||
|
||||
Les lecteurs d'écran ont également la capacité de lire uniquement les liens hypertexte d'une page, un peu comme une personne voyante scannerait une page à la recherche de liens. Si le texte des liens est toujours "cliquez ici", tout ce que l'utilisateur entendra sera "cliquez ici, cliquez ici, cliquez ici, cliquez ici, cliquez ici, ..." Tous les liens deviennent alors indiscernables les uns des autres.
|
||||
|
||||
### Bon texte de lien
|
||||
|
||||
Un bon texte de lien décrit brièvement ce qui se trouve de l'autre côté du lien. Dans l'exemple ci-dessus parlant des petits manchots, le lien mène à la page Wikipédia sur l'espèce. L'expression *petit manchot* serait un excellent texte de lien car elle indique clairement ce que quelqu'un apprendra en cliquant sur le lien - les petits manchots.
|
||||
|
||||
> Le [petit manchot](https://fr.wikipedia.org/wiki/Manchot_bleu), parfois appelé manchot féerique, est le plus petit manchot du monde.
|
||||
|
||||
✅ Naviguez sur le web pendant quelques minutes pour trouver des pages utilisant des stratégies de lien obscures. Comparez-les avec d'autres sites mieux conçus. Qu'avez-vous appris ?
|
||||
|
||||
#### Notes pour les moteurs de recherche
|
||||
|
||||
En bonus, en veillant à ce que votre site soit accessible à tous, vous aiderez également les moteurs de recherche à naviguer sur votre site. Les moteurs de recherche utilisent le texte des liens pour comprendre les sujets des pages. Ainsi, utiliser un bon texte de lien aide tout le monde !
|
||||
|
||||
### ARIA
|
||||
|
||||
Imaginez la page suivante :
|
||||
|
||||
| Produit | Description | Commander |
|
||||
| ------------ | ------------------ | ------------ |
|
||||
| Widget | [Description](../../../../1-getting-started-lessons/3-accessibility/') | [Commander](../../../../1-getting-started-lessons/3-accessibility/') |
|
||||
| Super widget | [Description](../../../../1-getting-started-lessons/3-accessibility/') | [Commander](../../../../1-getting-started-lessons/3-accessibility/') |
|
||||
|
||||
Dans cet exemple, dupliquer le texte de description et commander a du sens pour quelqu'un utilisant un navigateur. Cependant, une personne utilisant un lecteur d'écran n'entendrait que les mots *description* et *commander* répétés sans contexte.
|
||||
|
||||
Pour prendre en charge ces types de scénarios, le HTML prend en charge un ensemble d'attributs appelés [Applications Internet Riches Accessibles (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Ces attributs permettent de fournir des informations supplémentaires aux lecteurs d'écran.
|
||||
|
||||
> **NOTE** : Comme pour de nombreux aspects du HTML, la prise en charge par les navigateurs et les lecteurs d'écran peut varier. Cependant, la plupart des clients principaux prennent en charge les attributs ARIA.
|
||||
|
||||
Vous pouvez utiliser `aria-label` pour décrire le lien lorsque le format de la page ne le permet pas. La description pour widget pourrait être définie comme :
|
||||
|
||||
``` html
|
||||
<a href="#" aria-label="Widget description">description</a>
|
||||
```
|
||||
|
||||
✅ En général, utiliser un balisage sémantique comme décrit ci-dessus remplace l'utilisation d'ARIA, mais parfois il n'existe pas d'équivalent sémantique pour certains widgets HTML. Un bon exemple est un arbre. Il n'existe pas d'équivalent HTML pour un arbre, donc vous identifiez le `<div>` générique pour cet élément avec un rôle et des valeurs ARIA appropriés. La [documentation MDN sur ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) contient plus d'informations utiles.
|
||||
|
||||
```html
|
||||
<h2 id="tree-label">File Viewer</h2>
|
||||
<div role="tree" aria-labelledby="tree-label">
|
||||
<div role="treeitem" aria-expanded="false" tabindex="0">Uploads</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Images
|
||||
|
||||
Il va sans dire que les lecteurs d'écran ne peuvent pas lire automatiquement ce qu'il y a dans une image. Rendre les images accessibles ne demande pas beaucoup de travail - c'est tout l'intérêt de l'attribut `alt`. Toutes les images significatives doivent avoir un `alt` pour décrire ce qu'elles représentent.
|
||||
Les images purement décoratives doivent avoir leur attribut `alt` défini sur une chaîne vide : `alt=""`. Cela empêche les lecteurs d'écran d'annoncer inutilement l'image décorative.
|
||||
|
||||
✅ Comme vous pouvez vous y attendre, les moteurs de recherche ne peuvent pas non plus comprendre ce qu'il y a dans une image. Ils utilisent également le texte alternatif. Ainsi, une fois de plus, rendre votre page accessible offre des avantages supplémentaires !
|
||||
|
||||
## Le clavier
|
||||
|
||||
Certains utilisateurs ne peuvent pas utiliser une souris ou un pavé tactile et dépendent des interactions au clavier pour naviguer d'un élément à l'autre. Il est important que votre site web présente votre contenu dans un ordre logique afin qu'un utilisateur de clavier puisse accéder à chaque élément interactif en parcourant le document. Si vous construisez vos pages web avec un balisage sémantique et utilisez CSS pour styliser leur mise en page visuelle, votre site devrait être navigable au clavier, mais il est important de tester cet aspect manuellement. Apprenez-en plus sur les [stratégies de navigation au clavier](https://webaim.org/techniques/keyboard/).
|
||||
|
||||
✅ Allez sur un site web et essayez de naviguer uniquement avec votre clavier. Qu'est-ce qui fonctionne, qu'est-ce qui ne fonctionne pas ? Pourquoi ?
|
||||
|
||||
## Résumé
|
||||
|
||||
Un web accessible à certains n'est pas un véritable "web mondial". La meilleure façon de garantir que les sites que vous créez soient accessibles est d'intégrer les bonnes pratiques d'accessibilité dès le départ. Bien qu'il y ait des étapes supplémentaires à suivre, intégrer ces compétences dans votre flux de travail dès maintenant garantira que toutes les pages que vous créez seront accessibles.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Prenez ce HTML et réécrivez-le pour qu'il soit aussi accessible que possible, en utilisant les stratégies que vous avez apprises.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Example
|
||||
</title>
|
||||
<link href='../assets/style.css' rel='stylesheet' type='text/css'>
|
||||
</head>
|
||||
<body>
|
||||
<div class="site-header">
|
||||
<p class="site-title">Turtle Ipsum</p>
|
||||
<p class="site-subtitle">The World's Premier Turtle Fan Club</p>
|
||||
</div>
|
||||
<div class="main-nav">
|
||||
<p class="nav-header">Resources</p>
|
||||
<div class="nav-list">
|
||||
<p class="nav-item nav-item-bull"><a href="https://www.youtube.com/watch?v=CMNry4PE93Y">"I like turtles"</a></p>
|
||||
<p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtle">Basic Turtle Info</a></p>
|
||||
<p class="nav-item nav-item-bull"><a href="https://en.wikipedia.org/wiki/Turtles_(chocolate)">Chocolate Turtles</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<div>
|
||||
<p class="page-title">Welcome to Turtle Ipsum.
|
||||
<a href="">Click here</a> to learn more.
|
||||
</p>
|
||||
<p class="article-text">
|
||||
Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="footer-section">
|
||||
<span class="button">Sign up for turtle news</span>
|
||||
</div><div class="footer-section">
|
||||
<p class="nav-header footer-title">
|
||||
Internal Pages
|
||||
</p>
|
||||
<div class="nav-list">
|
||||
<p class="nav-item nav-item-bull"><a href="../">Index</a></p>
|
||||
<p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="footer-copyright">© 2016 Instrument</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Quiz après le cours
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/6)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
De nombreux gouvernements ont des lois concernant les exigences en matière d'accessibilité. Informez-vous sur les lois d'accessibilité de votre pays. Qu'est-ce qui est couvert, et qu'est-ce qui ne l'est pas ? Un exemple est [ce site web gouvernemental](https://accessibility.blog.gov.uk/).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Analysez un site web non accessible](assignment.md)
|
||||
|
||||
Crédits : [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) par Instrument
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,27 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "a258597a194e77d4fd469b3cd976b29e",
|
||||
"translation_date": "2025-08-23T23:26:44+00:00",
|
||||
"source_file": "1-getting-started-lessons/3-accessibility/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Analyser un site inaccessible
|
||||
|
||||
## Instructions
|
||||
|
||||
Identifiez un site web que vous pensez être NON accessible et créez un plan d'action pour améliorer son accessibilité.
|
||||
Votre première tâche sera d'identifier ce site, de détailler les raisons pour lesquelles vous pensez qu'il est inaccessible sans utiliser d'outils d'analyse, puis de le soumettre à une analyse Lighthouse. Capturez un PDF des résultats de cette analyse et élaborez un plan détaillé comprenant au minimum dix points expliquant comment le site pourrait être amélioré.
|
||||
|
||||
## Tableau pour tester l'accessibilité du site
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
|----------|------------|---------|-------------|
|
||||
| | manque <10 % de ce qui est requis | manque 20 % de ce qui est requis | manque 50 % de ce qui est requis |
|
||||
|
||||
----
|
||||
Rapport étudiant : inclut des paragraphes sur l'inaccessibilité du site, le rapport Lighthouse capturé en PDF, une liste de dix points pour l'amélioration, avec des détails sur la manière de les mettre en œuvre
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,29 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "04683f4cfa46004179b0404b89a3065c",
|
||||
"translation_date": "2025-08-23T23:16:17+00:00",
|
||||
"source_file": "1-getting-started-lessons/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Premiers Pas avec le Développement Web
|
||||
|
||||
Dans cette section du programme, vous serez introduit à des concepts non basés sur des projets, mais essentiels pour devenir un développeur professionnel.
|
||||
|
||||
### Sujets
|
||||
|
||||
1. [Introduction aux Langages de Programmation et Outils du Métier](1-intro-to-programming-languages/README.md)
|
||||
2. [Introduction à GitHub](2-github-basics/README.md)
|
||||
3. [Notions de Base sur l'Accessibilité](3-accessibility/README.md)
|
||||
|
||||
### Crédits
|
||||
|
||||
L'Introduction aux Langages de Programmation et Outils du Métier a été écrite avec ♥️ par [Jasmine Greenaway](https://twitter.com/paladique)
|
||||
|
||||
L'Introduction à GitHub a été écrite avec ♥️ par [Floor Drees](https://twitter.com/floordrees)
|
||||
|
||||
Les Notions de Base sur l'Accessibilité ont été écrites avec ♥️ par [Christopher Harrison](https://twitter.com/geektrainer)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,213 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
|
||||
"translation_date": "2025-08-23T22:47:26+00:00",
|
||||
"source_file": "2-js-basics/1-data-types/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Bases de JavaScript : Types de données
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz avant le cours
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/7)
|
||||
|
||||
Cette leçon couvre les bases de JavaScript, le langage qui permet d'ajouter de l'interactivité sur le web.
|
||||
|
||||
> Vous pouvez suivre cette leçon sur [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)!
|
||||
|
||||
[](https://youtube.com/watch?v=JNIXfGiDWM8 "Variables en JavaScript")
|
||||
|
||||
[](https://youtube.com/watch?v=AWfA95eLdq8 "Types de données en JavaScript")
|
||||
|
||||
> 🎥 Cliquez sur les images ci-dessus pour des vidéos sur les variables et les types de données.
|
||||
|
||||
Commençons par les variables et les types de données qui les composent !
|
||||
|
||||
## Variables
|
||||
|
||||
Les variables stockent des valeurs qui peuvent être utilisées et modifiées dans votre code.
|
||||
|
||||
Créer et **déclarer** une variable suit la syntaxe suivante : **[mot-clé] [nom]**. Cela se compose de deux parties :
|
||||
|
||||
- **Mot-clé**. Les mots-clés peuvent être `let` ou `var`.
|
||||
|
||||
✅ Le mot-clé `let` a été introduit dans ES6 et donne à votre variable une portée dite _de bloc_. Il est recommandé d'utiliser `let` plutôt que `var`. Nous aborderons les portées de bloc plus en détail dans les prochaines parties.
|
||||
- **Le nom de la variable**, c'est un nom que vous choisissez vous-même.
|
||||
|
||||
### Tâche - Travailler avec des variables
|
||||
|
||||
1. **Déclarez une variable**. Déclarons une variable en utilisant le mot-clé `let` :
|
||||
|
||||
```javascript
|
||||
let myVariable;
|
||||
```
|
||||
|
||||
`myVariable` a maintenant été déclarée en utilisant le mot-clé `let`. Elle n'a actuellement pas de valeur.
|
||||
|
||||
1. **Attribuez une valeur**. Stockez une valeur dans une variable avec l'opérateur `=` suivi de la valeur attendue.
|
||||
|
||||
```javascript
|
||||
myVariable = 123;
|
||||
```
|
||||
|
||||
> Remarque : l'utilisation de `=` dans cette leçon signifie que nous utilisons un "opérateur d'affectation", utilisé pour attribuer une valeur à une variable. Cela ne signifie pas égalité.
|
||||
|
||||
`myVariable` a maintenant été *initialisée* avec la valeur 123.
|
||||
|
||||
1. **Refactorisez**. Remplacez votre code par l'instruction suivante.
|
||||
|
||||
```javascript
|
||||
let myVariable = 123;
|
||||
```
|
||||
|
||||
Ce qui précède est appelé une _initialisation explicite_ lorsqu'une variable est déclarée et qu'une valeur lui est attribuée en même temps.
|
||||
|
||||
1. **Changez la valeur de la variable**. Modifiez la valeur de la variable de la manière suivante :
|
||||
|
||||
```javascript
|
||||
myVariable = 321;
|
||||
```
|
||||
|
||||
Une fois qu'une variable est déclarée, vous pouvez modifier sa valeur à tout moment dans votre code avec l'opérateur `=` et la nouvelle valeur.
|
||||
|
||||
✅ Essayez-le ! Vous pouvez écrire du JavaScript directement dans votre navigateur. Ouvrez une fenêtre de navigateur et accédez aux outils de développement. Dans la console, vous trouverez une invite ; tapez `let myVariable = 123`, appuyez sur Entrée, puis tapez `myVariable`. Que se passe-t-il ? Notez que vous en apprendrez davantage sur ces concepts dans les leçons suivantes.
|
||||
|
||||
## Constantes
|
||||
|
||||
La déclaration et l'initialisation d'une constante suivent les mêmes concepts qu'une variable, à l'exception du mot-clé `const`. Les constantes sont généralement déclarées avec des lettres majuscules.
|
||||
|
||||
```javascript
|
||||
const MY_VARIABLE = 123;
|
||||
```
|
||||
|
||||
Les constantes sont similaires aux variables, avec deux exceptions :
|
||||
|
||||
- **Doit avoir une valeur**. Les constantes doivent être initialisées, sinon une erreur se produira lors de l'exécution du code.
|
||||
- **La référence ne peut pas être modifiée**. La référence d'une constante ne peut pas être modifiée une fois initialisée, sinon une erreur se produira lors de l'exécution du code. Regardons deux exemples :
|
||||
- **Valeur simple**. Ce qui suit n'est PAS autorisé :
|
||||
|
||||
```javascript
|
||||
const PI = 3;
|
||||
PI = 4; // not allowed
|
||||
```
|
||||
|
||||
- **La référence d'un objet est protégée**. Ce qui suit n'est PAS autorisé.
|
||||
|
||||
```javascript
|
||||
const obj = { a: 3 };
|
||||
obj = { b: 5 } // not allowed
|
||||
```
|
||||
|
||||
- **La valeur d'un objet n'est pas protégée**. Ce qui suit EST autorisé :
|
||||
|
||||
```javascript
|
||||
const obj = { a: 3 };
|
||||
obj.a = 5; // allowed
|
||||
```
|
||||
|
||||
Ci-dessus, vous modifiez la valeur de l'objet mais pas la référence elle-même, ce qui est autorisé.
|
||||
|
||||
> Remarque, un `const` signifie que la référence est protégée contre la réaffectation. La valeur n'est pas _immuable_ et peut changer, surtout si c'est une structure complexe comme un objet.
|
||||
|
||||
## Types de données
|
||||
|
||||
Les variables peuvent stocker différents types de valeurs, comme des nombres et du texte. Ces différents types de valeurs sont appelés **types de données**. Les types de données sont une partie importante du développement logiciel car ils aident les développeurs à prendre des décisions sur la manière dont le code doit être écrit et comment le logiciel doit fonctionner. De plus, certains types de données ont des caractéristiques uniques qui permettent de transformer ou d'extraire des informations supplémentaires d'une valeur.
|
||||
|
||||
✅ Les types de données sont également appelés primitives de données JavaScript, car ce sont les types de données de plus bas niveau fournis par le langage. Il existe 7 types de données primitifs : string, number, bigint, boolean, undefined, null et symbol. Prenez un moment pour visualiser ce que chacun de ces primitifs pourrait représenter. Qu'est-ce qu'un `zebra` ? Et `0` ? `true` ?
|
||||
|
||||
### Nombres
|
||||
|
||||
Dans la section précédente, la valeur de `myVariable` était un type de données numérique.
|
||||
|
||||
`let myVariable = 123;`
|
||||
|
||||
Les variables peuvent stocker tous types de nombres, y compris les décimaux ou les nombres négatifs. Les nombres peuvent également être utilisés avec des opérateurs arithmétiques, abordés dans la [section suivante](../../../../2-js-basics/1-data-types).
|
||||
|
||||
### Opérateurs arithmétiques
|
||||
|
||||
Il existe plusieurs types d'opérateurs à utiliser pour effectuer des fonctions arithmétiques, et certains sont listés ici :
|
||||
|
||||
| Symbole | Description | Exemple |
|
||||
| ------- | ------------------------------------------------------------------------ | -------------------------------- |
|
||||
| `+` | **Addition** : Calcule la somme de deux nombres | `1 + 2 //réponse attendue est 3` |
|
||||
| `-` | **Soustraction** : Calcule la différence entre deux nombres | `1 - 2 //réponse attendue est -1` |
|
||||
| `*` | **Multiplication** : Calcule le produit de deux nombres | `1 * 2 //réponse attendue est 2` |
|
||||
| `/` | **Division** : Calcule le quotient de deux nombres | `1 / 2 //réponse attendue est 0.5` |
|
||||
| `%` | **Reste** : Calcule le reste de la division de deux nombres | `1 % 2 //réponse attendue est 1` |
|
||||
|
||||
✅ Essayez-le ! Essayez une opération arithmétique dans la console de votre navigateur. Les résultats vous surprennent-ils ?
|
||||
|
||||
### Chaînes de caractères
|
||||
|
||||
Les chaînes de caractères sont des ensembles de caractères qui se trouvent entre des guillemets simples ou doubles.
|
||||
|
||||
- `'Ceci est une chaîne de caractères'`
|
||||
- `"Ceci est aussi une chaîne de caractères"`
|
||||
- `let myString = 'Ceci est une valeur de chaîne stockée dans une variable';`
|
||||
|
||||
N'oubliez pas d'utiliser des guillemets lorsque vous écrivez une chaîne, sinon JavaScript supposera qu'il s'agit d'un nom de variable.
|
||||
|
||||
### Formatage des chaînes
|
||||
|
||||
Les chaînes sont textuelles et nécessiteront parfois un formatage.
|
||||
|
||||
Pour **concaténer** deux ou plusieurs chaînes, ou les joindre ensemble, utilisez l'opérateur `+`.
|
||||
|
||||
```javascript
|
||||
let myString1 = "Hello";
|
||||
let myString2 = "World";
|
||||
|
||||
myString1 + myString2 + "!"; //HelloWorld!
|
||||
myString1 + " " + myString2 + "!"; //Hello World!
|
||||
myString1 + ", " + myString2 + "!"; //Hello, World!
|
||||
|
||||
```
|
||||
|
||||
✅ Pourquoi `1 + 1 = 2` en JavaScript, mais `'1' + '1' = 11` ? Réfléchissez-y. Et `'1' + 1` ?
|
||||
|
||||
**Les littéraux de modèle** sont une autre façon de formater les chaînes, sauf qu'au lieu de guillemets, on utilise l'accent grave. Tout ce qui n'est pas du texte brut doit être placé dans des espaces réservés `${ }`. Cela inclut toutes les variables qui peuvent être des chaînes.
|
||||
|
||||
```javascript
|
||||
let myString1 = "Hello";
|
||||
let myString2 = "World";
|
||||
|
||||
`${myString1} ${myString2}!` //Hello World!
|
||||
`${myString1}, ${myString2}!` //Hello, World!
|
||||
```
|
||||
|
||||
Vous pouvez atteindre vos objectifs de formatage avec l'une ou l'autre méthode, mais les littéraux de modèle respecteront les espaces et les sauts de ligne.
|
||||
|
||||
✅ Quand utiliseriez-vous un littéral de modèle plutôt qu'une chaîne simple ?
|
||||
|
||||
### Booléens
|
||||
|
||||
Les booléens ne peuvent avoir que deux valeurs : `true` ou `false`. Les booléens peuvent aider à décider quelles lignes de code doivent s'exécuter lorsque certaines conditions sont remplies. Dans de nombreux cas, les [opérateurs](../../../../2-js-basics/1-data-types) aident à définir la valeur d'un booléen, et vous remarquerez souvent des variables initialisées ou leurs valeurs mises à jour avec un opérateur.
|
||||
|
||||
- `let myTrueBool = true`
|
||||
- `let myFalseBool = false`
|
||||
|
||||
✅ Une variable peut être considérée comme 'vraie' si elle évalue à un booléen `true`. Fait intéressant, en JavaScript, [toutes les valeurs sont vraies sauf si elles sont définies comme fausses](https://developer.mozilla.org/docs/Glossary/Truthy).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
JavaScript est connu pour ses façons surprenantes de gérer les types de données à l'occasion. Faites quelques recherches sur ces 'pièges'. Par exemple : la sensibilité à la casse peut poser problème ! Essayez ceci dans votre console : `let age = 1; let Age = 2; age == Age` (résout `false` -- pourquoi ?). Quels autres pièges pouvez-vous trouver ?
|
||||
|
||||
## Quiz après le cours
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/8)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Consultez [cette liste d'exercices JavaScript](https://css-tricks.com/snippets/javascript/) et essayez-en un. Qu'avez-vous appris ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Pratique des types de données](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "3869244ceda606c4969d8cdd82679867",
|
||||
"translation_date": "2025-08-23T22:49:06+00:00",
|
||||
"source_file": "2-js-basics/1-data-types/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Pratique des types de données
|
||||
|
||||
## Instructions
|
||||
|
||||
Imaginez que vous construisez un panier d'achat. Rédigez une documentation sur les types de données dont vous auriez besoin pour compléter votre expérience d'achat. Comment avez-vous fait vos choix ?
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
Critères | Exemplaire | Adéquat | À améliorer
|
||||
--- | --- | --- | --- |
|
||||
||Les six types de données sont listés et explorés en détail, avec une documentation sur leur utilisation|Quatre types de données sont explorés|Deux types de données sont explorés|
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "8973f96157680a13e9446e4bb540ee57",
|
||||
"translation_date": "2025-08-23T22:43:02+00:00",
|
||||
"source_file": "2-js-basics/2-functions-methods/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Amusement avec les Fonctions
|
||||
|
||||
## Instructions
|
||||
|
||||
Créez différentes fonctions, à la fois des fonctions qui retournent quelque chose et des fonctions qui ne retournent rien.
|
||||
|
||||
Essayez de créer une fonction qui combine des paramètres et des paramètres avec des valeurs par défaut.
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ----------------- |
|
||||
| | Une solution est proposée avec deux fonctions ou plus bien conçues et des paramètres variés | Une solution fonctionnelle est proposée avec une fonction et quelques paramètres | La solution contient des erreurs |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,52 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "bf62b82567e6f9bdf4abda9ae0ccb64a",
|
||||
"translation_date": "2025-08-23T22:39:43+00:00",
|
||||
"source_file": "2-js-basics/3-making-decisions/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Opérateurs
|
||||
|
||||
## Instructions
|
||||
|
||||
Expérimentez avec les opérateurs. Voici une suggestion pour un programme que vous pouvez implémenter :
|
||||
|
||||
Vous avez un ensemble d'étudiants provenant de deux systèmes de notation différents.
|
||||
|
||||
### Premier système de notation
|
||||
|
||||
Un système de notation où les notes vont de 1 à 5, et où 3 et au-dessus signifient que vous réussissez le cours.
|
||||
|
||||
### Deuxième système de notation
|
||||
|
||||
L'autre système de notation utilise les notes suivantes : `A, A-, B, B-, C, C-`, où `A` est la meilleure note et `C` est la note minimale pour réussir.
|
||||
|
||||
### La tâche
|
||||
|
||||
Étant donné le tableau suivant `allStudents` représentant tous les étudiants et leurs notes, construisez un nouveau tableau `studentsWhoPass` contenant tous les étudiants qui réussissent.
|
||||
|
||||
> TIP, utilisez une boucle for, des instructions if...else et des opérateurs de comparaison :
|
||||
|
||||
```javascript
|
||||
let allStudents = [
|
||||
'A',
|
||||
'B-',
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
2
|
||||
]
|
||||
|
||||
let studentsWhoPass = [];
|
||||
```
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------ | ----------------------------- | ------------------------------- |
|
||||
| | Une solution complète est présentée | Une solution partielle est présentée | Une solution avec des erreurs est présentée |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,145 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "3f7f87871312cf6cc12662da7d973182",
|
||||
"translation_date": "2025-08-23T22:44:23+00:00",
|
||||
"source_file": "2-js-basics/4-arrays-loops/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Notions de base en JavaScript : Tableaux et Boucles
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz avant le cours
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/13)
|
||||
|
||||
Cette leçon couvre les bases de JavaScript, le langage qui permet d'ajouter de l'interactivité sur le web. Dans cette leçon, vous apprendrez à utiliser les tableaux et les boucles, qui servent à manipuler des données.
|
||||
|
||||
[](https://youtube.com/watch?v=1U4qTyq02Xw "Tableaux")
|
||||
|
||||
[](https://www.youtube.com/watch?v=Eeh7pxtTZ3k "Boucles")
|
||||
|
||||
> 🎥 Cliquez sur les images ci-dessus pour visionner des vidéos sur les tableaux et les boucles.
|
||||
|
||||
> Vous pouvez suivre cette leçon sur [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-arrays/?WT.mc_id=academic-77807-sagibbon) !
|
||||
|
||||
## Tableaux
|
||||
|
||||
Travailler avec des données est une tâche courante dans n'importe quel langage, et cela devient beaucoup plus simple lorsque les données sont organisées dans un format structuré, comme les tableaux. Avec les tableaux, les données sont stockées dans une structure similaire à une liste. Un des grands avantages des tableaux est qu'ils peuvent contenir différents types de données dans un même tableau.
|
||||
|
||||
✅ Les tableaux sont partout autour de nous ! Pouvez-vous penser à un exemple concret de tableau, comme un ensemble de panneaux solaires ?
|
||||
|
||||
La syntaxe d'un tableau utilise une paire de crochets.
|
||||
|
||||
```javascript
|
||||
let myArray = [];
|
||||
```
|
||||
|
||||
Ceci est un tableau vide, mais les tableaux peuvent être déclarés déjà remplis de données. Les différentes valeurs d'un tableau sont séparées par une virgule.
|
||||
|
||||
```javascript
|
||||
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
|
||||
```
|
||||
|
||||
Les valeurs d'un tableau se voient attribuer un identifiant unique appelé **index**, un nombre entier qui est déterminé en fonction de leur position à partir du début du tableau. Dans l'exemple ci-dessus, la chaîne de caractères "Chocolate" a un index de 0, et l'index de "Rocky Road" est 4. Utilisez l'index avec des crochets pour récupérer, modifier ou insérer des valeurs dans le tableau.
|
||||
|
||||
✅ Cela vous surprend-il que les tableaux commencent à l'index zéro ? Dans certains langages de programmation, les index commencent à 1. Il y a une histoire intéressante à ce sujet, que vous pouvez [lire sur Wikipédia](https://en.wikipedia.org/wiki/Zero-based_numbering).
|
||||
|
||||
```javascript
|
||||
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
|
||||
iceCreamFlavors[2]; //"Vanilla"
|
||||
```
|
||||
|
||||
Vous pouvez utiliser l'index pour modifier une valeur, comme ceci :
|
||||
|
||||
```javascript
|
||||
iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan"
|
||||
```
|
||||
|
||||
Et vous pouvez insérer une nouvelle valeur à un index donné comme ceci :
|
||||
|
||||
```javascript
|
||||
iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough"
|
||||
```
|
||||
|
||||
✅ Une méthode plus courante pour ajouter des valeurs à un tableau est d'utiliser des opérateurs comme array.push().
|
||||
|
||||
Pour savoir combien d'éléments se trouvent dans un tableau, utilisez la propriété `length`.
|
||||
|
||||
```javascript
|
||||
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
|
||||
iceCreamFlavors.length; //5
|
||||
```
|
||||
|
||||
✅ Essayez par vous-même ! Utilisez la console de votre navigateur pour créer et manipuler un tableau de votre propre création.
|
||||
|
||||
## Boucles
|
||||
|
||||
Les boucles permettent d'effectuer des tâches répétitives ou **itératives**, et elles peuvent faire gagner beaucoup de temps et de lignes de code. Chaque itération peut varier en termes de variables, de valeurs et de conditions. Il existe différents types de boucles en JavaScript, qui ont toutes de petites différences, mais qui accomplissent essentiellement la même chose : parcourir des données.
|
||||
|
||||
### Boucle For
|
||||
|
||||
La boucle `for` nécessite 3 éléments pour itérer :
|
||||
- `compteur` Une variable généralement initialisée avec un nombre qui compte le nombre d'itérations
|
||||
- `condition` Une expression utilisant des opérateurs de comparaison pour arrêter la boucle lorsque la condition devient `false`
|
||||
- `expression d'itération` Exécutée à la fin de chaque itération, généralement utilisée pour modifier la valeur du compteur
|
||||
|
||||
```javascript
|
||||
// Counting up to 10
|
||||
for (let i = 0; i < 10; i++) {
|
||||
console.log(i);
|
||||
}
|
||||
```
|
||||
|
||||
✅ Exécutez ce code dans la console de votre navigateur. Que se passe-t-il lorsque vous modifiez légèrement le compteur, la condition ou l'expression d'itération ? Pouvez-vous le faire fonctionner à l'envers, en créant un compte à rebours ?
|
||||
|
||||
### Boucle While
|
||||
|
||||
Contrairement à la syntaxe de la boucle `for`, les boucles `while` nécessitent uniquement une condition qui arrêtera la boucle lorsque la condition deviendra `false`. Les conditions dans les boucles dépendent généralement d'autres valeurs comme des compteurs, et doivent être gérées pendant la boucle. Les valeurs initiales des compteurs doivent être créées en dehors de la boucle, et toutes les expressions nécessaires pour répondre à une condition, y compris la modification du compteur, doivent être maintenues à l'intérieur de la boucle.
|
||||
|
||||
```javascript
|
||||
//Counting up to 10
|
||||
let i = 0;
|
||||
while (i < 10) {
|
||||
console.log(i);
|
||||
i++;
|
||||
}
|
||||
```
|
||||
|
||||
✅ Pourquoi choisiriez-vous une boucle for plutôt qu'une boucle while ? 17 000 utilisateurs se sont posé la même question sur StackOverflow, et certaines des opinions [pourraient vous intéresser](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript).
|
||||
|
||||
## Boucles et Tableaux
|
||||
|
||||
Les tableaux sont souvent utilisés avec des boucles, car la plupart des conditions nécessitent la longueur du tableau pour arrêter la boucle, et l'index peut également servir de valeur de compteur.
|
||||
|
||||
```javascript
|
||||
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
|
||||
|
||||
for (let i = 0; i < iceCreamFlavors.length; i++) {
|
||||
console.log(iceCreamFlavors[i]);
|
||||
} //Ends when all flavors are printed
|
||||
```
|
||||
|
||||
✅ Expérimentez en parcourant un tableau de votre propre création dans la console de votre navigateur.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Il existe d'autres façons de parcourir des tableaux en dehors des boucles for et while. Découvrez [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of), et [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Réécrivez votre boucle de tableau en utilisant l'une de ces techniques.
|
||||
|
||||
## Quiz après le cours
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/14)
|
||||
|
||||
## Révision et Étude personnelle
|
||||
|
||||
Les tableaux en JavaScript possèdent de nombreuses méthodes qui sont extrêmement utiles pour manipuler des données. [Renseignez-vous sur ces méthodes](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) et essayez-en quelques-unes (comme push, pop, slice et splice) sur un tableau de votre création.
|
||||
|
||||
## Devoir
|
||||
|
||||
[Parcourir un tableau](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "8b2381170bd0fd2870f5889bb8620f02",
|
||||
"translation_date": "2025-08-23T22:45:42+00:00",
|
||||
"source_file": "2-js-basics/4-arrays-loops/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Parcourir un tableau
|
||||
|
||||
## Instructions
|
||||
|
||||
Créez un programme qui liste chaque 3ᵉ nombre entre 1 et 20 et l'affiche dans la console.
|
||||
|
||||
> ASTUCE : utilisez une boucle for et modifiez l'expression d'itération.
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| --------- | --------------------------------------- | ------------------------ | -------------------------------- |
|
||||
| | Le programme fonctionne correctement et est commenté | Le programme n'est pas commenté | Le programme est incomplet ou contient des bugs |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,26 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "cc9e70a2f096c67389c8acff1521fc27",
|
||||
"translation_date": "2025-08-23T22:36:58+00:00",
|
||||
"source_file": "2-js-basics/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Introduction à JavaScript
|
||||
|
||||
JavaScript est la langue du web. Dans ces quatre leçons, vous apprendrez ses bases.
|
||||
|
||||
### Sujets
|
||||
|
||||
1. [Variables et Types de Données](1-data-types/README.md)
|
||||
2. [Fonctions et Méthodes](2-functions-methods/README.md)
|
||||
3. [Prendre des Décisions avec JavaScript](3-making-decisions/README.md)
|
||||
4. [Tableaux et Boucles](4-arrays-loops/README.md)
|
||||
|
||||
### Crédits
|
||||
|
||||
Ces leçons ont été écrites avec ♥️ par [Jasmine Greenaway](https://twitter.com/paladique), [Christopher Harrison](https://twitter.com/geektrainer) et [Chris Noring](https://twitter.com/chris_noring)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,249 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
|
||||
"translation_date": "2025-08-23T22:25:11+00:00",
|
||||
"source_file": "3-terrarium/1-intro-to-html/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet Terrarium Partie 1 : Introduction à HTML
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/15)
|
||||
|
||||
|
||||
> Regardez la vidéo
|
||||
|
||||
>
|
||||
> [](https://www.youtube.com/watch?v=1TvxJKBzhyQ)
|
||||
|
||||
### Introduction
|
||||
|
||||
HTML, ou HyperText Markup Language, est le 'squelette' du web. Si CSS 'habille' votre HTML et que JavaScript lui donne vie, HTML est le corps de votre application web. La syntaxe de HTML reflète même cette idée, puisqu'elle inclut des balises "head", "body" et "footer".
|
||||
|
||||
Dans cette leçon, nous allons utiliser HTML pour structurer le 'squelette' de l'interface de notre terrarium virtuel. Il comportera un titre et trois colonnes : une colonne à gauche et une à droite où se trouveront les plantes déplaçables, et une zone centrale qui représentera le terrarium en verre. À la fin de cette leçon, vous pourrez voir les plantes dans les colonnes, mais l'interface aura un aspect un peu étrange ; ne vous inquiétez pas, dans la section suivante, vous ajouterez des styles CSS pour améliorer l'apparence de l'interface.
|
||||
|
||||
### Tâche
|
||||
|
||||
Sur votre ordinateur, créez un dossier appelé 'terrarium' et, à l'intérieur, un fichier nommé 'index.html'. Vous pouvez le faire dans Visual Studio Code après avoir créé votre dossier terrarium en ouvrant une nouvelle fenêtre VS Code, en cliquant sur 'ouvrir un dossier', et en naviguant vers votre nouveau dossier. Cliquez sur le petit bouton 'fichier' dans le volet Explorateur et créez le nouveau fichier :
|
||||
|
||||

|
||||
|
||||
Ou
|
||||
|
||||
Utilisez ces commandes dans votre terminal git bash :
|
||||
* `mkdir terrarium`
|
||||
* `cd terrarium`
|
||||
* `touch index.html`
|
||||
* `code index.html` ou `nano index.html`
|
||||
|
||||
> Les fichiers index.html indiquent à un navigateur qu'il s'agit du fichier par défaut dans un dossier ; des URL comme `https://anysite.com/test` peuvent être construites à partir d'une structure de dossier incluant un dossier appelé `test` avec `index.html` à l'intérieur ; `index.html` n'a pas besoin d'apparaître dans l'URL.
|
||||
|
||||
---
|
||||
|
||||
## Le DocType et les balises html
|
||||
|
||||
La première ligne d'un fichier HTML est son doctype. Il est un peu surprenant de devoir inclure cette ligne tout en haut du fichier, mais elle indique aux anciens navigateurs qu'ils doivent rendre la page en mode standard, en suivant la spécification HTML actuelle.
|
||||
|
||||
> Astuce : dans VS Code, vous pouvez survoler une balise pour obtenir des informations sur son utilisation à partir des guides de référence MDN.
|
||||
|
||||
La deuxième ligne doit être la balise d'ouverture `<html>`, suivie immédiatement de sa balise de fermeture `</html>`. Ces balises sont les éléments racines de votre interface.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez ces lignes en haut de votre fichier `index.html` :
|
||||
|
||||
```HTML
|
||||
<!DOCTYPE html>
|
||||
<html></html>
|
||||
```
|
||||
|
||||
✅ Il existe plusieurs modes qui peuvent être déterminés en définissant le DocType avec une chaîne de requête : [Mode Quirks et Mode Standards](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Ces modes étaient utilisés pour prendre en charge des navigateurs très anciens qui ne sont généralement plus utilisés aujourd'hui (Netscape Navigator 4 et Internet Explorer 5). Vous pouvez vous en tenir à la déclaration standard du doctype.
|
||||
|
||||
---
|
||||
|
||||
## Le 'head' du document
|
||||
|
||||
La zone 'head' du document HTML inclut des informations cruciales sur votre page web, également appelées [métadonnées](https://developer.mozilla.org/docs/Web/HTML/Element/meta). Dans notre cas, nous indiquons au serveur web auquel cette page sera envoyée pour être rendue, ces quatre éléments :
|
||||
|
||||
- le titre de la page
|
||||
- les métadonnées de la page, y compris :
|
||||
- le 'jeu de caractères', qui indique quel encodage de caractères est utilisé dans la page
|
||||
- des informations sur le navigateur, y compris `x-ua-compatible` qui indique que le navigateur IE=edge est pris en charge
|
||||
- des informations sur le comportement du viewport lorsqu'il est chargé. Définir le viewport avec une échelle initiale de 1 contrôle le niveau de zoom lorsque la page est chargée pour la première fois.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez un bloc 'head' à votre document entre les balises d'ouverture et de fermeture `<html>`.
|
||||
|
||||
```html
|
||||
<head>
|
||||
<title>Welcome to my Virtual Terrarium</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
```
|
||||
|
||||
✅ Que se passerait-il si vous définissiez une balise meta viewport comme ceci : `<meta name="viewport" content="width=600">` ? Lisez-en plus sur le [viewport](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag).
|
||||
|
||||
---
|
||||
|
||||
## Le `body` du document
|
||||
|
||||
### Balises HTML
|
||||
|
||||
En HTML, vous ajoutez des balises à votre fichier .html pour créer des éléments d'une page web. Chaque balise a généralement une balise d'ouverture et de fermeture, comme ceci : `<p>bonjour</p>` pour indiquer un paragraphe. Créez le corps de votre interface en ajoutant un ensemble de balises `<body>` à l'intérieur de la paire de balises `<html>` ; votre balisage ressemble maintenant à ceci :
|
||||
|
||||
### Tâche
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to my Virtual Terrarium</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Maintenant, vous pouvez commencer à construire votre page. Normalement, vous utilisez des balises `<div>` pour créer les différents éléments d'une page. Nous allons créer une série d'éléments `<div>` qui contiendront des images.
|
||||
|
||||
### Images
|
||||
|
||||
Une balise HTML qui n'a pas besoin de balise de fermeture est la balise `<img>`, car elle possède un élément `src` qui contient toutes les informations nécessaires à la page pour rendre l'élément.
|
||||
|
||||
Créez un dossier dans votre application appelé `images` et ajoutez-y toutes les images du [dossier source](../../../../3-terrarium/solution/images) ; (il y a 14 images de plantes).
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez ces images de plantes dans deux colonnes entre les balises `<body></body>` :
|
||||
|
||||
```html
|
||||
<div id="page">
|
||||
<div id="left-container" class="container">
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant2" src="./images/plant2.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant3" src="./images/plant3.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant4" src="./images/plant4.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant5" src="./images/plant5.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant6" src="./images/plant6.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant7" src="./images/plant7.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="right-container" class="container">
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant8" src="./images/plant8.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant9" src="./images/plant9.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant10" src="./images/plant10.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant11" src="./images/plant11.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant12" src="./images/plant12.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant13" src="./images/plant13.png" />
|
||||
</div>
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant14" src="./images/plant14.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
> Note : Spans vs. Divs. Les Divs sont considérés comme des éléments 'block', et les Spans comme des éléments 'inline'. Que se passerait-il si vous transformiez ces divs en spans ?
|
||||
|
||||
Avec ce balisage, les plantes apparaissent maintenant à l'écran. Cela a un aspect assez mauvais, car elles ne sont pas encore stylées avec CSS, ce que nous ferons dans la prochaine leçon.
|
||||
|
||||
Chaque image possède un texte alternatif qui apparaîtra même si vous ne pouvez pas voir ou rendre une image. C'est un attribut important à inclure pour l'accessibilité. Vous en apprendrez davantage sur l'accessibilité dans les leçons futures ; pour l'instant, rappelez-vous que l'attribut alt fournit des informations alternatives pour une image si un utilisateur ne peut pas la voir (en raison d'une connexion lente, d'une erreur dans l'attribut src, ou si l'utilisateur utilise un lecteur d'écran).
|
||||
|
||||
✅ Avez-vous remarqué que chaque image a le même texte alternatif ? Est-ce une bonne pratique ? Pourquoi ou pourquoi pas ? Pouvez-vous améliorer ce code ?
|
||||
|
||||
---
|
||||
|
||||
## Balisage sémantique
|
||||
|
||||
En général, il est préférable d'utiliser des 'sémantiques' significatives lors de l'écriture de HTML. Qu'est-ce que cela signifie ? Cela signifie que vous utilisez des balises HTML pour représenter le type de données ou d'interaction pour lequel elles ont été conçues. Par exemple, le texte principal d'un titre sur une page devrait utiliser une balise `<h1>`.
|
||||
|
||||
Ajoutez la ligne suivante juste en dessous de votre balise d'ouverture `<body>` :
|
||||
|
||||
```html
|
||||
<h1>My Terrarium</h1>
|
||||
```
|
||||
|
||||
Utiliser un balisage sémantique, comme avoir des en-têtes en `<h1>` et des listes non ordonnées rendues en `<ul>`, aide les lecteurs d'écran à naviguer sur une page. En général, les boutons devraient être écrits comme `<button>` et les listes comme `<li>`. Bien qu'il soit _possible_ d'utiliser des éléments `<span>` spécialement stylés avec des gestionnaires de clics pour imiter des boutons, il est préférable pour les utilisateurs handicapés d'utiliser des technologies pour déterminer où se trouve un bouton sur une page et interagir avec lui, si l'élément apparaît comme un bouton. Pour cette raison, essayez d'utiliser autant que possible un balisage sémantique.
|
||||
|
||||
✅ Regardez un lecteur d'écran et [comment il interagit avec une page web](https://www.youtube.com/watch?v=OUDV1gqs9GA). Pouvez-vous comprendre pourquoi un balisage non sémantique pourrait frustrer l'utilisateur ?
|
||||
|
||||
## Le terrarium
|
||||
|
||||
La dernière partie de cette interface consiste à créer un balisage qui sera stylé pour créer un terrarium.
|
||||
|
||||
### Tâche :
|
||||
|
||||
Ajoutez ce balisage au-dessus de la dernière balise `</div>` :
|
||||
|
||||
```html
|
||||
<div id="terrarium">
|
||||
<div class="jar-top"></div>
|
||||
<div class="jar-walls">
|
||||
<div class="jar-glossy-long"></div>
|
||||
<div class="jar-glossy-short"></div>
|
||||
</div>
|
||||
<div class="dirt"></div>
|
||||
<div class="jar-bottom"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
✅ Même si vous avez ajouté ce balisage à l'écran, vous ne voyez absolument rien s'afficher. Pourquoi ?
|
||||
|
||||
---
|
||||
|
||||
## 🚀Défi
|
||||
|
||||
Il existe des balises 'anciennes' amusantes en HTML qui sont encore intéressantes à expérimenter, bien que vous ne devriez pas utiliser des balises obsolètes comme [ces balises](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) dans votre balisage. Cependant, pouvez-vous utiliser l'ancienne balise `<marquee>` pour faire défiler horizontalement le titre h1 ? (si vous le faites, n'oubliez pas de la supprimer ensuite)
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/16)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
HTML est le système de construction 'éprouvé' qui a aidé à construire le web tel qu'il est aujourd'hui. Apprenez un peu sur son histoire en étudiant des balises anciennes et nouvelles. Pouvez-vous comprendre pourquoi certaines balises ont été abandonnées et d'autres ajoutées ? Quelles balises pourraient être introduites à l'avenir ?
|
||||
|
||||
Apprenez-en davantage sur la création de sites pour le web et les appareils mobiles sur [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
|
||||
## Devoir
|
||||
|
||||
[Pratiquez votre HTML : Créez une maquette de blog](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "970776c81401c9aacb34f365edac6b53",
|
||||
"translation_date": "2025-08-23T22:26:43+00:00",
|
||||
"source_file": "3-terrarium/1-intro-to-html/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Pratiquez votre HTML : Créez une maquette de blog
|
||||
|
||||
## Instructions
|
||||
|
||||
Imaginez que vous concevez ou redessinez votre site web personnel. Créez une maquette graphique de votre site, puis écrivez le code HTML que vous utiliseriez pour construire les différents éléments du site. Vous pouvez le faire sur papier et le scanner, ou utiliser le logiciel de votre choix, mais assurez-vous de coder manuellement le HTML.
|
||||
|
||||
## Barème
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| | Une mise en page de blog est représentée visuellement avec au moins 10 éléments de balisage affichés | Une mise en page de blog est représentée visuellement avec environ 5 éléments de balisage affichés | Une mise en page de blog est représentée visuellement avec au maximum 3 éléments de balisage affichés |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,282 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
|
||||
"translation_date": "2025-08-23T22:33:33+00:00",
|
||||
"source_file": "3-terrarium/2-intro-to-css/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet Terrarium Partie 2 : Introduction au CSS
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz Pré-Conférence
|
||||
|
||||
[Quiz pré-conférence](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/17)
|
||||
|
||||
### Introduction
|
||||
|
||||
Le CSS, ou Cascading Style Sheets, résout un problème important du développement web : comment rendre votre site web attrayant. Styliser vos applications les rend plus utilisables et esthétiques ; vous pouvez également utiliser le CSS pour créer un design web réactif (Responsive Web Design - RWD), permettant à vos applications d'avoir une belle apparence quel que soit la taille de l'écran. Le CSS ne se limite pas à embellir votre application ; ses spécifications incluent des animations et des transformations qui permettent des interactions sophistiquées pour vos applications. Le CSS Working Group aide à maintenir les spécifications actuelles du CSS ; vous pouvez suivre leur travail sur le [site du World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
|
||||
|
||||
> Notez que le CSS est un langage qui évolue, comme tout sur le web, et que tous les navigateurs ne prennent pas en charge les parties les plus récentes des spécifications. Vérifiez toujours vos implémentations en consultant [CanIUse.com](https://caniuse.com).
|
||||
|
||||
Dans cette leçon, nous allons ajouter des styles à notre terrarium en ligne et en apprendre davantage sur plusieurs concepts CSS : la cascade, l'héritage, l'utilisation des sélecteurs, le positionnement et l'utilisation du CSS pour construire des mises en page. Au cours de ce processus, nous allons organiser le terrarium et créer le terrarium lui-même.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous devez avoir construit le HTML de votre terrarium et être prêt à le styliser.
|
||||
|
||||
> Regardez la vidéo
|
||||
|
||||
>
|
||||
> [](https://www.youtube.com/watch?v=6yIdOIV9p1I)
|
||||
|
||||
### Tâche
|
||||
|
||||
Dans votre dossier terrarium, créez un nouveau fichier appelé `style.css`. Importez ce fichier dans la section `<head>` :
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## La Cascade
|
||||
|
||||
Les feuilles de style en cascade (CSS) intègrent l'idée que les styles "cascadent", de sorte que l'application d'un style est guidée par sa priorité. Les styles définis par un auteur de site web ont priorité sur ceux définis par un navigateur. Les styles définis "inline" ont priorité sur ceux définis dans une feuille de style externe.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez le style inline "color: red" à votre balise `<h1>` :
|
||||
|
||||
```HTML
|
||||
<h1 style="color: red">My Terrarium</h1>
|
||||
```
|
||||
|
||||
Ensuite, ajoutez le code suivant à votre fichier `style.css` :
|
||||
|
||||
```CSS
|
||||
h1 {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
✅ Quelle couleur s'affiche dans votre application web ? Pourquoi ? Pouvez-vous trouver un moyen de remplacer les styles ? Quand voudriez-vous faire cela, ou pourquoi pas ?
|
||||
|
||||
---
|
||||
|
||||
## L'Héritage
|
||||
|
||||
Les styles sont hérités d'un style ancêtre vers un descendant, de sorte que les éléments imbriqués héritent des styles de leurs parents.
|
||||
|
||||
### Tâche
|
||||
|
||||
Définissez la police du corps (`body`) sur une police donnée et vérifiez la police d'un élément imbriqué :
|
||||
|
||||
```CSS
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
Ouvrez la console de votre navigateur dans l'onglet 'Éléments' et observez la police du H1. Elle hérite de la police du corps, comme indiqué dans le navigateur :
|
||||
|
||||

|
||||
|
||||
✅ Pouvez-vous faire en sorte qu'un style imbriqué hérite d'une propriété différente ?
|
||||
|
||||
---
|
||||
|
||||
## Sélecteurs CSS
|
||||
|
||||
### Balises
|
||||
|
||||
Jusqu'à présent, votre fichier `style.css` ne contient que quelques balises stylisées, et l'application semble assez étrange :
|
||||
|
||||
```CSS
|
||||
body {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #3a241d;
|
||||
text-align: center;
|
||||
}
|
||||
```
|
||||
|
||||
Cette manière de styliser une balise vous donne le contrôle sur des éléments uniques, mais vous devez contrôler les styles de nombreuses plantes dans votre terrarium. Pour cela, vous devez utiliser les sélecteurs CSS.
|
||||
|
||||
### Ids
|
||||
|
||||
Ajoutez un style pour organiser les conteneurs gauche et droit. Comme il n'y a qu'un seul conteneur gauche et un seul conteneur droit, ils ont des ids dans le balisage. Pour les styliser, utilisez `#` :
|
||||
|
||||
```CSS
|
||||
#left-container {
|
||||
background-color: #eee;
|
||||
width: 15%;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#right-container {
|
||||
background-color: #eee;
|
||||
width: 15%;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
Ici, vous avez positionné ces conteneurs avec un positionnement absolu à l'extrême gauche et droite de l'écran, et utilisé des pourcentages pour leur largeur afin qu'ils puissent s'adapter aux petits écrans mobiles.
|
||||
|
||||
✅ Ce code est assez répétitif, donc pas "DRY" (Don't Repeat Yourself) ; pouvez-vous trouver une meilleure façon de styliser ces ids, peut-être avec un id et une classe ? Vous devrez modifier le balisage et refactoriser le CSS :
|
||||
|
||||
```html
|
||||
<div id="left-container" class="container"></div>
|
||||
```
|
||||
|
||||
### Classes
|
||||
|
||||
Dans l'exemple ci-dessus, vous avez stylisé deux éléments uniques à l'écran. Si vous voulez que des styles s'appliquent à plusieurs éléments à l'écran, vous pouvez utiliser des classes CSS. Faites cela pour organiser les plantes dans les conteneurs gauche et droit.
|
||||
|
||||
Notez que chaque plante dans le balisage HTML a une combinaison d'ids et de classes. Les ids ici sont utilisés par le JavaScript que vous ajouterez plus tard pour manipuler le placement des plantes dans le terrarium. Les classes, cependant, donnent à toutes les plantes un style donné.
|
||||
|
||||
```html
|
||||
<div class="plant-holder">
|
||||
<img class="plant" alt="plant" id="plant1" src="./images/plant1.png" />
|
||||
</div>
|
||||
```
|
||||
|
||||
Ajoutez le code suivant à votre fichier `style.css` :
|
||||
|
||||
```CSS
|
||||
.plant-holder {
|
||||
position: relative;
|
||||
height: 13%;
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
.plant {
|
||||
position: absolute;
|
||||
max-width: 150%;
|
||||
max-height: 150%;
|
||||
z-index: 2;
|
||||
}
|
||||
```
|
||||
|
||||
Ce qui est notable dans cet extrait, c'est le mélange de positionnement relatif et absolu, que nous aborderons dans la section suivante. Regardez la façon dont les hauteurs sont gérées par pourcentages :
|
||||
|
||||
Vous définissez la hauteur du support de plante à 13 %, un bon chiffre pour garantir que toutes les plantes s'affichent dans chaque conteneur vertical sans besoin de défilement.
|
||||
|
||||
Vous déplacez le support de plante vers la gauche pour permettre aux plantes d'être plus centrées dans leur conteneur. Les images ont une grande quantité d'arrière-plan transparent pour les rendre plus faciles à déplacer, donc elles doivent être poussées vers la gauche pour mieux s'adapter à l'écran.
|
||||
|
||||
Ensuite, la plante elle-même reçoit une largeur maximale de 150 %. Cela lui permet de se réduire à mesure que le navigateur se réduit. Essayez de redimensionner votre navigateur ; les plantes restent dans leurs conteneurs mais se réduisent pour s'adapter.
|
||||
|
||||
Un autre point notable est l'utilisation de z-index, qui contrôle l'altitude relative d'un élément (de sorte que les plantes se trouvent au-dessus du conteneur et semblent être à l'intérieur du terrarium).
|
||||
|
||||
✅ Pourquoi avez-vous besoin à la fois d'un sélecteur CSS pour le support de plante et pour la plante ?
|
||||
|
||||
## Positionnement CSS
|
||||
|
||||
Mélanger les propriétés de positionnement (il existe des positions statiques, relatives, fixes, absolues et collantes) peut être un peu délicat, mais lorsqu'il est bien fait, cela vous donne un bon contrôle sur les éléments de vos pages.
|
||||
|
||||
Les éléments positionnés en absolu sont positionnés par rapport à leurs ancêtres positionnés les plus proches, et s'il n'y en a pas, ils sont positionnés par rapport au corps du document.
|
||||
|
||||
Les éléments positionnés en relatif sont positionnés en fonction des instructions CSS pour ajuster leur placement par rapport à leur position initiale.
|
||||
|
||||
Dans notre exemple, le `plant-holder` est un élément positionné en relatif qui est positionné dans un conteneur positionné en absolu. Le comportement résultant est que les conteneurs latéraux sont fixés à gauche et à droite, et le `plant-holder` est imbriqué, s'ajustant dans les barres latérales, laissant de l'espace pour que les plantes soient placées en colonne verticale.
|
||||
|
||||
> La `plant` elle-même a également un positionnement absolu, nécessaire pour la rendre déplaçable, comme vous le découvrirez dans la prochaine leçon.
|
||||
|
||||
✅ Expérimentez en changeant les types de positionnement des conteneurs latéraux et du `plant-holder`. Que se passe-t-il ?
|
||||
|
||||
## Mises en page CSS
|
||||
|
||||
Vous allez maintenant utiliser ce que vous avez appris pour construire le terrarium lui-même, uniquement avec du CSS !
|
||||
|
||||
Tout d'abord, stylisez les enfants de la div `.terrarium` comme un rectangle arrondi en utilisant le CSS :
|
||||
|
||||
```CSS
|
||||
.jar-walls {
|
||||
height: 80%;
|
||||
width: 60%;
|
||||
background: #d1e1df;
|
||||
border-radius: 1rem;
|
||||
position: absolute;
|
||||
bottom: 0.5%;
|
||||
left: 20%;
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.jar-top {
|
||||
width: 50%;
|
||||
height: 5%;
|
||||
background: #d1e1df;
|
||||
position: absolute;
|
||||
bottom: 80.5%;
|
||||
left: 25%;
|
||||
opacity: 0.7;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.jar-bottom {
|
||||
width: 50%;
|
||||
height: 1%;
|
||||
background: #d1e1df;
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
left: 25%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.dirt {
|
||||
width: 60%;
|
||||
height: 5%;
|
||||
background: #3a241d;
|
||||
position: absolute;
|
||||
border-radius: 0 0 1rem 1rem;
|
||||
bottom: 1%;
|
||||
left: 20%;
|
||||
opacity: 0.7;
|
||||
z-index: -1;
|
||||
}
|
||||
```
|
||||
|
||||
Notez l'utilisation des pourcentages ici. Si vous réduisez votre navigateur, vous pouvez voir comment le bocal s'adapte également. Notez également les pourcentages de largeur et de hauteur pour les éléments du bocal et comment chaque élément est positionné en absolu au centre, fixé en bas de la fenêtre.
|
||||
|
||||
Nous utilisons également `rem` pour le rayon de bordure, une longueur relative à la police. Lisez-en plus sur ce type de mesure relative dans les [spécifications CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
|
||||
|
||||
✅ Essayez de changer les couleurs et l'opacité du bocal par rapport à celles de la terre. Que se passe-t-il ? Pourquoi ?
|
||||
|
||||
---
|
||||
|
||||
## 🚀Défi
|
||||
|
||||
Ajoutez un éclat "bulle" dans la zone inférieure gauche du bocal pour le rendre plus semblable à du verre. Vous styliserez les `.jar-glossy-long` et `.jar-glossy-short` pour ressembler à un reflet brillant. Voici à quoi cela ressemblerait :
|
||||
|
||||

|
||||
|
||||
Pour compléter le quiz post-conférence, parcourez ce module Learn : [Stylisez votre application HTML avec CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
|
||||
|
||||
## Quiz Post-Conférence
|
||||
|
||||
[Quiz post-conférence](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/18)
|
||||
|
||||
## Révision & Auto-Étude
|
||||
|
||||
Le CSS semble trompeusement simple, mais il y a de nombreux défis lorsqu'il s'agit de styliser une application parfaitement pour tous les navigateurs et toutes les tailles d'écran. CSS-Grid et Flexbox sont des outils développés pour rendre le travail un peu plus structuré et fiable. Apprenez-en plus sur ces outils en jouant à [Flexbox Froggy](https://flexboxfroggy.com/) et [Grid Garden](https://codepip.com/games/grid-garden/).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Refactorisation CSS](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "9d4d75af51aaccfe9af778f792c62919",
|
||||
"translation_date": "2025-08-23T22:35:31+00:00",
|
||||
"source_file": "3-terrarium/2-intro-to-css/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Réorganisation CSS
|
||||
|
||||
## Instructions
|
||||
|
||||
Redonnez du style au terrarium en utilisant soit Flexbox, soit CSS Grid, et prenez des captures d'écran pour montrer que vous l'avez testé sur plusieurs navigateurs. Vous pourriez avoir besoin de modifier le balisage, alors créez une nouvelle version de l'application avec l'art en place pour votre refonte. Ne vous inquiétez pas de rendre les éléments déplaçables ; concentrez-vous uniquement sur la refonte du HTML et du CSS pour l'instant.
|
||||
|
||||
## Critères
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ----------------------------------------------------------------- | ----------------------------- | ------------------------------------ |
|
||||
| | Présenter un terrarium complètement restylé en utilisant Flexbox ou CSS Grid | Restyler quelques éléments | Ne pas réussir à restyler le terrarium du tout |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,228 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
|
||||
"translation_date": "2025-08-23T22:29:10+00:00",
|
||||
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet Terrarium Partie 3 : Manipulation du DOM et une Closure
|
||||
|
||||

|
||||
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||
|
||||
## Quiz Pré-Conférence
|
||||
|
||||
[Quiz pré-conférence](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/19)
|
||||
|
||||
### Introduction
|
||||
|
||||
Manipuler le DOM, ou "Document Object Model", est un aspect clé du développement web. Selon [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "Le Document Object Model (DOM) est la représentation des données des objets qui composent la structure et le contenu d'un document sur le web." Les défis liés à la manipulation du DOM sur le web ont souvent conduit à l'utilisation de frameworks JavaScript plutôt que du JavaScript pur pour gérer le DOM, mais nous allons nous débrouiller seuls !
|
||||
|
||||
De plus, cette leçon introduira l'idée d'une [closure JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), que vous pouvez considérer comme une fonction incluse dans une autre fonction, permettant ainsi à la fonction interne d'accéder au scope de la fonction externe.
|
||||
|
||||
> Les closures en JavaScript sont un sujet vaste et complexe. Cette leçon aborde l'idée la plus basique : dans le code de ce terrarium, vous trouverez une closure : une fonction interne et une fonction externe construites de manière à permettre à la fonction interne d'accéder au scope de la fonction externe. Pour beaucoup plus d'informations sur le fonctionnement de cela, veuillez consulter la [documentation détaillée](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
|
||||
|
||||
Nous utiliserons une closure pour manipuler le DOM.
|
||||
|
||||
Pensez au DOM comme à un arbre, représentant toutes les façons dont un document de page web peut être manipulé. Diverses API (Interfaces de Programmation d'Applications) ont été écrites pour que les programmeurs, utilisant leur langage de programmation préféré, puissent accéder au DOM et le modifier, le changer, le réorganiser et le gérer autrement.
|
||||
|
||||

|
||||
|
||||
> Une représentation du DOM et du balisage HTML qui y fait référence. De [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
|
||||
|
||||
Dans cette leçon, nous terminerons notre projet de terrarium interactif en créant le JavaScript qui permettra à un utilisateur de manipuler les plantes sur la page.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous devriez avoir construit le HTML et le CSS de votre terrarium. À la fin de cette leçon, vous serez capable de déplacer les plantes dans et hors du terrarium en les faisant glisser.
|
||||
|
||||
### Tâche
|
||||
|
||||
Dans votre dossier terrarium, créez un nouveau fichier appelé `script.js`. Importez ce fichier dans la section `<head>` :
|
||||
|
||||
```html
|
||||
<script src="./script.js" defer></script>
|
||||
```
|
||||
|
||||
> Note : utilisez `defer` lors de l'importation d'un fichier JavaScript externe dans le fichier HTML afin de permettre au JavaScript de s'exécuter uniquement après que le fichier HTML a été entièrement chargé. Vous pourriez également utiliser l'attribut `async`, qui permet au script de s'exécuter pendant que le fichier HTML est en cours de traitement, mais dans notre cas, il est important que les éléments HTML soient entièrement disponibles pour le glissement avant que nous permettions au script de glissement de s'exécuter.
|
||||
---
|
||||
|
||||
## Les éléments du DOM
|
||||
|
||||
La première chose à faire est de créer des références aux éléments que vous souhaitez manipuler dans le DOM. Dans notre cas, ce sont les 14 plantes actuellement en attente dans les barres latérales.
|
||||
|
||||
### Tâche
|
||||
|
||||
```html
|
||||
dragElement(document.getElementById('plant1'));
|
||||
dragElement(document.getElementById('plant2'));
|
||||
dragElement(document.getElementById('plant3'));
|
||||
dragElement(document.getElementById('plant4'));
|
||||
dragElement(document.getElementById('plant5'));
|
||||
dragElement(document.getElementById('plant6'));
|
||||
dragElement(document.getElementById('plant7'));
|
||||
dragElement(document.getElementById('plant8'));
|
||||
dragElement(document.getElementById('plant9'));
|
||||
dragElement(document.getElementById('plant10'));
|
||||
dragElement(document.getElementById('plant11'));
|
||||
dragElement(document.getElementById('plant12'));
|
||||
dragElement(document.getElementById('plant13'));
|
||||
dragElement(document.getElementById('plant14'));
|
||||
```
|
||||
|
||||
Que se passe-t-il ici ? Vous faites référence au document et parcourez son DOM pour trouver un élément avec un Id particulier. Rappelez-vous dans la première leçon sur le HTML que vous avez donné des Ids individuels à chaque image de plante (`id="plant1"`). Maintenant, vous allez utiliser cet effort. Après avoir identifié chaque élément, vous passez cet élément à une fonction appelée `dragElement` que vous allez construire dans un instant. Ainsi, l'élément dans le HTML est maintenant activé pour le glissement, ou le sera bientôt.
|
||||
|
||||
✅ Pourquoi fait-on référence aux éléments par Id ? Pourquoi pas par leur classe CSS ? Vous pourriez vous référer à la leçon précédente sur le CSS pour répondre à cette question.
|
||||
|
||||
---
|
||||
|
||||
## La Closure
|
||||
|
||||
Vous êtes maintenant prêt à créer la closure `dragElement`, qui est une fonction externe qui inclut une ou plusieurs fonctions internes (dans notre cas, nous en aurons trois).
|
||||
|
||||
Les closures sont utiles lorsque une ou plusieurs fonctions doivent accéder au scope de la fonction externe. Voici un exemple :
|
||||
|
||||
```javascript
|
||||
function displayCandy(){
|
||||
let candy = ['jellybeans'];
|
||||
function addCandy(candyType) {
|
||||
candy.push(candyType)
|
||||
}
|
||||
addCandy('gumdrops');
|
||||
}
|
||||
displayCandy();
|
||||
console.log(candy)
|
||||
```
|
||||
|
||||
Dans cet exemple, la fonction `displayCandy` entoure une fonction qui ajoute un nouveau type de bonbon à un tableau qui existe déjà dans la fonction. Si vous exécutez ce code, le tableau `candy` serait indéfini, car il est une variable locale (locale à la closure).
|
||||
|
||||
✅ Comment pouvez-vous rendre le tableau `candy` accessible ? Essayez de le déplacer en dehors de la closure. De cette façon, le tableau devient global, plutôt que de rester uniquement disponible dans le scope local de la closure.
|
||||
|
||||
### Tâche
|
||||
|
||||
Sous les déclarations d'éléments dans `script.js`, créez une fonction :
|
||||
|
||||
```javascript
|
||||
function dragElement(terrariumElement) {
|
||||
//set 4 positions for positioning on the screen
|
||||
let pos1 = 0,
|
||||
pos2 = 0,
|
||||
pos3 = 0,
|
||||
pos4 = 0;
|
||||
terrariumElement.onpointerdown = pointerDrag;
|
||||
}
|
||||
```
|
||||
|
||||
`dragElement` obtient son objet `terrariumElement` à partir des déclarations en haut du script. Ensuite, vous définissez certaines positions locales à `0` pour l'objet passé à la fonction. Ce sont les variables locales qui seront manipulées pour chaque élément lorsque vous ajoutez la fonctionnalité de glisser-déposer dans la closure à chaque élément. Le terrarium sera peuplé par ces éléments glissés, donc l'application doit garder une trace de leur emplacement.
|
||||
|
||||
De plus, l'élément `terrariumElement` qui est passé à cette fonction est assigné à un événement `pointerdown`, qui fait partie des [API web](https://developer.mozilla.org/docs/Web/API) conçues pour aider à la gestion du DOM. `onpointerdown` se déclenche lorsqu'un bouton est pressé, ou dans notre cas, lorsqu'un élément glissable est touché. Ce gestionnaire d'événements fonctionne à la fois sur les [navigateurs web et mobiles](https://caniuse.com/?search=onpointerdown), avec quelques exceptions.
|
||||
|
||||
✅ Le [gestionnaire d'événements `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) a beaucoup plus de support inter-navigateurs ; pourquoi ne pas l'utiliser ici ? Réfléchissez au type exact d'interaction écran que vous essayez de créer ici.
|
||||
|
||||
---
|
||||
|
||||
## La fonction Pointerdrag
|
||||
|
||||
L'élément `terrariumElement` est prêt à être déplacé ; lorsque l'événement `onpointerdown` est déclenché, la fonction `pointerDrag` est invoquée. Ajoutez cette fonction juste sous cette ligne : `terrariumElement.onpointerdown = pointerDrag;` :
|
||||
|
||||
### Tâche
|
||||
|
||||
```javascript
|
||||
function pointerDrag(e) {
|
||||
e.preventDefault();
|
||||
console.log(e);
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
}
|
||||
```
|
||||
|
||||
Plusieurs choses se produisent. Tout d'abord, vous empêchez les événements par défaut qui se produisent normalement sur pointerdown en utilisant `e.preventDefault();`. De cette façon, vous avez plus de contrôle sur le comportement de l'interface.
|
||||
|
||||
> Revenez à cette ligne lorsque vous aurez complètement construit le fichier script et essayez sans `e.preventDefault()` - que se passe-t-il ?
|
||||
|
||||
Ensuite, ouvrez `index.html` dans une fenêtre de navigateur et inspectez l'interface. Lorsque vous cliquez sur une plante, vous pouvez voir comment l'événement 'e' est capturé. Explorez l'événement pour voir combien d'informations sont collectées par un seul événement pointerdown !
|
||||
|
||||
Ensuite, notez comment les variables locales `pos3` et `pos4` sont définies sur e.clientX. Vous pouvez trouver les valeurs `e` dans le panneau d'inspection. Ces valeurs capturent les coordonnées x et y de la plante au moment où vous cliquez dessus ou la touchez. Vous aurez besoin d'un contrôle précis sur le comportement des plantes lorsque vous cliquez et les faites glisser, donc vous gardez une trace de leurs coordonnées.
|
||||
|
||||
✅ Cela devient-il plus clair pourquoi toute cette application est construite avec une grande closure ? Si ce n'était pas le cas, comment maintiendriez-vous le scope pour chacune des 14 plantes glissables ?
|
||||
|
||||
Complétez la fonction initiale en ajoutant deux autres manipulations d'événements pointer sous `pos4 = e.clientY` :
|
||||
|
||||
```html
|
||||
document.onpointermove = elementDrag;
|
||||
document.onpointerup = stopElementDrag;
|
||||
```
|
||||
Vous indiquez maintenant que vous souhaitez que la plante soit déplacée avec le pointeur lorsque vous le déplacez, et que le geste de glissement s'arrête lorsque vous désélectionnez la plante. `onpointermove` et `onpointerup` font tous partie de la même API que `onpointerdown`. L'interface générera des erreurs maintenant car vous n'avez pas encore défini les fonctions `elementDrag` et `stopElementDrag`, alors construisez-les ensuite.
|
||||
|
||||
## Les fonctions elementDrag et stopElementDrag
|
||||
|
||||
Vous allez compléter votre closure en ajoutant deux autres fonctions internes qui géreront ce qui se passe lorsque vous faites glisser une plante et arrêtez de la faire glisser. Le comportement souhaité est que vous puissiez déplacer n'importe quelle plante à tout moment et la placer n'importe où sur l'écran. Cette interface est assez flexible (il n'y a pas de zone de dépôt par exemple) pour vous permettre de concevoir votre terrarium exactement comme vous le souhaitez en ajoutant, supprimant et repositionnant des plantes.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez la fonction `elementDrag` juste après l'accolade fermante de `pointerDrag` :
|
||||
|
||||
```javascript
|
||||
function elementDrag(e) {
|
||||
pos1 = pos3 - e.clientX;
|
||||
pos2 = pos4 - e.clientY;
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
console.log(pos1, pos2, pos3, pos4);
|
||||
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
|
||||
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
|
||||
}
|
||||
```
|
||||
Dans cette fonction, vous modifiez beaucoup les positions initiales 1-4 que vous avez définies comme variables locales dans la fonction externe. Que se passe-t-il ici ?
|
||||
|
||||
Pendant que vous faites glisser, vous réattribuez `pos1` en le rendant égal à `pos3` (que vous avez défini plus tôt comme `e.clientX`) moins la valeur actuelle de `e.clientX`. Vous effectuez une opération similaire sur `pos2`. Ensuite, vous réinitialisez `pos3` et `pos4` aux nouvelles coordonnées X et Y de l'élément. Vous pouvez observer ces changements dans la console pendant que vous faites glisser. Ensuite, vous modifiez le style CSS de la plante pour définir sa nouvelle position en fonction des nouvelles positions de `pos1` et `pos2`, en calculant les coordonnées X et Y de la plante en haut et à gauche en comparant son décalage avec ces nouvelles positions.
|
||||
|
||||
> `offsetTop` et `offsetLeft` sont des propriétés CSS qui définissent la position d'un élément en fonction de celle de son parent ; son parent peut être n'importe quel élément qui n'est pas positionné comme `static`.
|
||||
|
||||
Tous ces recalculs de positionnement vous permettent d'affiner le comportement du terrarium et de ses plantes.
|
||||
|
||||
### Tâche
|
||||
|
||||
La tâche finale pour compléter l'interface est d'ajouter la fonction `stopElementDrag` après l'accolade fermante de `elementDrag` :
|
||||
|
||||
```javascript
|
||||
function stopElementDrag() {
|
||||
document.onpointerup = null;
|
||||
document.onpointermove = null;
|
||||
}
|
||||
```
|
||||
|
||||
Cette petite fonction réinitialise les événements `onpointerup` et `onpointermove` afin que vous puissiez soit redémarrer le déplacement de votre plante en commençant à la faire glisser à nouveau, soit commencer à déplacer une nouvelle plante.
|
||||
|
||||
✅ Que se passe-t-il si vous ne définissez pas ces événements sur null ?
|
||||
|
||||
Vous avez maintenant terminé votre projet !
|
||||
|
||||
🥇Félicitations ! Vous avez terminé votre magnifique terrarium. 
|
||||
|
||||
---
|
||||
|
||||
## 🚀Défi
|
||||
|
||||
Ajoutez un nouveau gestionnaire d'événements à votre closure pour faire quelque chose de plus avec les plantes ; par exemple, double-cliquez sur une plante pour la mettre au premier plan. Soyez créatif !
|
||||
|
||||
## Quiz Post-Conférence
|
||||
|
||||
[Quiz post-conférence](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/20)
|
||||
|
||||
## Révision & Auto-Étude
|
||||
|
||||
Bien que déplacer des éléments sur l'écran semble trivial, il existe de nombreuses façons de le faire et de nombreux pièges, selon l'effet que vous recherchez. En fait, il existe une [API de glisser-déposer](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) entière que vous pouvez essayer. Nous ne l'avons pas utilisée dans ce module car l'effet que nous voulions était quelque peu différent, mais essayez cette API sur votre propre projet et voyez ce que vous pouvez accomplir.
|
||||
|
||||
Trouvez plus d'informations sur les événements de pointeur dans les [docs W3C](https://www.w3.org/TR/pointerevents1/) et sur les [docs web MDN](https://developer.mozilla.org/docs/Web/API/Pointer_events).
|
||||
|
||||
Vérifiez toujours les capacités des navigateurs en utilisant [CanIUse.com](https://caniuse.com/).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Travaillez un peu plus avec le DOM](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "22fb6c3cb570c47f1ac65048393941fa",
|
||||
"translation_date": "2025-08-23T22:31:57+00:00",
|
||||
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Travaillez un peu plus avec le DOM
|
||||
|
||||
## Instructions
|
||||
|
||||
Explorez davantage le DOM en 'adoptant' un élément du DOM. Consultez la [liste des interfaces DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) sur MDN et choisissez-en une. Trouvez un exemple de son utilisation sur un site web, et rédigez une explication sur la manière dont elle est utilisée.
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- |
|
||||
| | Un paragraphe explicatif est présenté, avec un exemple | Un paragraphe explicatif est présenté, sans exemple | Aucun paragraphe n'est présenté |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "7965cd2bc5dc92ad888dc4c6ab2ab70a",
|
||||
"translation_date": "2025-08-23T22:23:34+00:00",
|
||||
"source_file": "3-terrarium/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Mon Terrarium : Un projet pour apprendre HTML, CSS et la manipulation du DOM avec JavaScript 🌵🌱
|
||||
|
||||
Un petit exercice de méditation par glisser-déposer. Avec un peu de HTML, JS et CSS, vous pourrez créer une interface web, la styliser et même ajouter plusieurs interactions de votre choix.
|
||||
|
||||

|
||||
|
||||
# Leçons
|
||||
|
||||
1. [Introduction au HTML](./1-intro-to-html/README.md)
|
||||
2. [Introduction au CSS](./2-intro-to-css/README.md)
|
||||
3. [Introduction au DOM et aux closures en JS](./3-intro-to-DOM-and-closures/README.md)
|
||||
|
||||
## Crédits
|
||||
|
||||
Écrit avec ♥️ par [Jen Looper](https://www.twitter.com/jenlooper)
|
||||
|
||||
Le terrarium créé via CSS a été inspiré par le bocal en verre de Jakub Mandra sur [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY).
|
||||
|
||||
Les illustrations sont dessinées à la main par [Jen Looper](http://jenlooper.com) avec l'aide de Procreate.
|
||||
|
||||
## Déployez votre Terrarium
|
||||
|
||||
Vous pouvez déployer, ou publier votre terrarium sur le web en utilisant Azure Static Web Apps.
|
||||
|
||||
1. Forkez ce dépôt
|
||||
|
||||
2. Appuyez sur ce bouton
|
||||
|
||||
[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-77807-sagibbon#create/Microsoft.StaticApp)
|
||||
|
||||
3. Suivez l'assistant pour créer votre application. Assurez-vous de définir la racine de l'application sur `/solution` ou sur la racine de votre code. Il n'y a pas d'API dans cette application, donc inutile d'en ajouter une. Un dossier GitHub sera créé dans votre dépôt forké pour aider les services de build d'Azure Static Web Apps à construire et publier votre application sur une nouvelle URL.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "6329fbe8bd936068debd78cca6f09c0a",
|
||||
"translation_date": "2025-08-23T22:36:17+00:00",
|
||||
"source_file": "3-terrarium/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Mon Terrarium : Un projet pour apprendre HTML, CSS et la manipulation du DOM avec JavaScript 🌵🌱
|
||||
|
||||
Un petit exercice de code avec glisser-déposer. Avec un peu de HTML, JS et CSS, vous pouvez créer une interface web, la styliser et y ajouter des interactions.
|
||||
|
||||

|
||||
|
||||
## Crédits
|
||||
|
||||
Écrit avec ♥️ par [Jen Looper](https://www.twitter.com/jenlooper)
|
||||
|
||||
Le terrarium créé via CSS a été inspiré par le bocal en verre de Jakub Mandra sur [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY).
|
||||
|
||||
Les illustrations ont été dessinées à la main par [Jen Looper](http://jenlooper.com) en utilisant Procreate.
|
||||
|
||||
## Déployez votre Terrarium
|
||||
|
||||
Vous pouvez déployer, ou publier, votre terrarium sur le web en utilisant Azure Static Web Apps.
|
||||
|
||||
1. Forkez ce dépôt
|
||||
|
||||
2. Appuyez sur ce bouton
|
||||
|
||||
[](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-77807-sagibbon#create/Microsoft.StaticApp)
|
||||
|
||||
3. Suivez l'assistant pour créer votre application. Assurez-vous de définir la racine de l'application sur `/solution` ou sur la racine de votre code. Il n'y a pas d'API dans cette application, donc inutile de vous en préoccuper. Un dossier .github sera créé dans votre dépôt forké pour aider le service de build d'Azure Static Web Apps à construire et publier votre application sur une nouvelle URL.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,42 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "957547b822c40042e07d591c4fbfde4f",
|
||||
"translation_date": "2025-08-24T00:17:16+00:00",
|
||||
"source_file": "4-typing-game/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Programmation Événementielle - Créer un Jeu de Dactylographie
|
||||
|
||||
## Introduction
|
||||
|
||||
La dactylographie est l'une des compétences les plus sous-estimées des développeurs. La capacité à transférer rapidement vos pensées de votre tête à votre éditeur permet à la créativité de s'exprimer librement. L'un des meilleurs moyens d'apprendre est de jouer à un jeu !
|
||||
|
||||
> Alors, créons un jeu de dactylographie !
|
||||
|
||||
Vous allez utiliser les compétences en JavaScript, HTML et CSS que vous avez acquises jusqu'à présent pour créer un jeu de dactylographie. Le jeu présentera au joueur une citation aléatoire (nous utilisons des citations de [Sherlock Holmes](https://en.wikipedia.org/wiki/Sherlock_Holmes)) et chronométrera le temps que le joueur met pour la taper correctement. Vous allez utiliser les compétences en JavaScript, HTML et CSS que vous avez acquises jusqu'à présent pour créer un jeu de dactylographie.
|
||||
|
||||

|
||||
|
||||
## Prérequis
|
||||
|
||||
Cette leçon suppose que vous êtes familier avec les concepts suivants :
|
||||
|
||||
- Création de champs de saisie de texte et de boutons
|
||||
- CSS et application de styles à l'aide de classes
|
||||
- Bases de JavaScript
|
||||
- Création d'un tableau
|
||||
- Génération d'un nombre aléatoire
|
||||
- Obtention de l'heure actuelle
|
||||
|
||||
## Leçon
|
||||
|
||||
[Créer un jeu de dactylographie en utilisant la programmation événementielle](./typing-game/README.md)
|
||||
|
||||
## Crédits
|
||||
|
||||
Écrit avec ♥️ par [Christopher Harrison](http://www.twitter.com/geektrainer)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-24T00:17:53+00:00",
|
||||
"source_file": "4-typing-game/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de faire appel à une traduction professionnelle humaine. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,351 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
|
||||
"translation_date": "2025-08-24T00:20:02+00:00",
|
||||
"source_file": "4-typing-game/typing-game/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer un jeu en utilisant des événements
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/21)
|
||||
|
||||
## Programmation pilotée par les événements
|
||||
|
||||
Lors de la création d'une application basée sur un navigateur, nous fournissons une interface utilisateur graphique (GUI) pour permettre à l'utilisateur d'interagir avec ce que nous avons construit. Le moyen le plus courant d'interagir avec le navigateur est de cliquer et de taper dans divers éléments. Le défi auquel nous sommes confrontés en tant que développeurs est que nous ne savons pas quand ils vont effectuer ces opérations !
|
||||
|
||||
La [programmation pilotée par les événements](https://fr.wikipedia.org/wiki/Programmation_événementielle) est le type de programmation dont nous avons besoin pour créer notre GUI. Si nous décomposons un peu cette expression, nous voyons que le mot clé ici est **événement**. Un [événement](https://www.merriam-webster.com/dictionary/event), selon Merriam-Webster, est défini comme "quelque chose qui se produit". Cela décrit parfaitement notre situation. Nous savons que quelque chose va se produire pour lequel nous voulons exécuter du code en réponse, mais nous ne savons pas quand cela aura lieu.
|
||||
|
||||
La manière dont nous marquons une section de code que nous voulons exécuter est en créant une fonction. Lorsque nous pensons à la [programmation procédurale](https://fr.wikipedia.org/wiki/Programmation_procédurale), les fonctions sont appelées dans un ordre spécifique. Cela reste vrai avec la programmation pilotée par les événements. La différence réside dans **comment** les fonctions seront appelées.
|
||||
|
||||
Pour gérer les événements (clics sur des boutons, saisie, etc.), nous enregistrons des **écouteurs d'événements**. Un écouteur d'événement est une fonction qui attend qu'un événement se produise et s'exécute en réponse. Les écouteurs d'événements peuvent mettre à jour l'interface utilisateur, effectuer des appels au serveur ou tout autre traitement nécessaire en réponse à l'action de l'utilisateur. Nous ajoutons un écouteur d'événement en utilisant [addEventListener](https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener) et en fournissant une fonction à exécuter.
|
||||
|
||||
> **NOTE :** Il est important de souligner qu'il existe de nombreuses façons de créer des écouteurs d'événements. Vous pouvez utiliser des fonctions anonymes ou en créer des nommées. Vous pouvez également utiliser divers raccourcis, comme définir la propriété `click` ou utiliser `addEventListener`. Dans notre exercice, nous allons nous concentrer sur `addEventListener` et les fonctions anonymes, car c'est probablement la technique la plus courante utilisée par les développeurs web. C'est aussi la plus flexible, car `addEventListener` fonctionne pour tous les événements, et le nom de l'événement peut être fourni en tant que paramètre.
|
||||
|
||||
### Événements courants
|
||||
|
||||
Il existe [des dizaines d'événements](https://developer.mozilla.org/fr/docs/Web/Events) que vous pouvez écouter lors de la création d'une application. Pratiquement tout ce qu'un utilisateur fait sur une page déclenche un événement, ce qui vous donne beaucoup de pouvoir pour leur offrir l'expérience que vous souhaitez. Heureusement, vous n'aurez généralement besoin que d'une poignée d'événements. Voici quelques-uns des plus courants (y compris les deux que nous utiliserons pour créer notre jeu) :
|
||||
|
||||
- [click](https://developer.mozilla.org/fr/docs/Web/API/Element/click_event) : L'utilisateur a cliqué sur quelque chose, généralement un bouton ou un lien hypertexte
|
||||
- [contextmenu](https://developer.mozilla.org/fr/docs/Web/API/Element/contextmenu_event) : L'utilisateur a cliqué avec le bouton droit de la souris
|
||||
- [select](https://developer.mozilla.org/fr/docs/Web/API/Element/select_event) : L'utilisateur a sélectionné du texte
|
||||
- [input](https://developer.mozilla.org/fr/docs/Web/API/Element/input_event) : L'utilisateur a saisi du texte
|
||||
|
||||
## Création du jeu
|
||||
|
||||
Nous allons créer un jeu pour explorer le fonctionnement des événements en JavaScript. Notre jeu testera les compétences de frappe d'un joueur, une compétence souvent sous-estimée mais essentielle pour tous les développeurs. Nous devrions tous pratiquer notre frappe ! Voici le déroulement général du jeu :
|
||||
|
||||
- Le joueur clique sur un bouton "Démarrer" et voit une citation à taper
|
||||
- Le joueur tape la citation aussi vite que possible dans une zone de texte
|
||||
- À mesure que chaque mot est complété, le suivant est mis en surbrillance
|
||||
- Si le joueur fait une faute de frappe, la zone de texte devient rouge
|
||||
- Lorsque le joueur termine la citation, un message de succès s'affiche avec le temps écoulé
|
||||
|
||||
Construisons notre jeu et apprenons à utiliser les événements !
|
||||
|
||||
### Structure des fichiers
|
||||
|
||||
Nous aurons besoin de trois fichiers : **index.html**, **script.js** et **style.css**. Commençons par les configurer pour nous faciliter la tâche.
|
||||
|
||||
- Créez un nouveau dossier pour votre travail en ouvrant une console ou une fenêtre de terminal et en exécutant la commande suivante :
|
||||
|
||||
```bash
|
||||
# Linux or macOS
|
||||
mkdir typing-game && cd typing-game
|
||||
|
||||
# Windows
|
||||
md typing-game && cd typing-game
|
||||
```
|
||||
|
||||
- Ouvrez Visual Studio Code
|
||||
|
||||
```bash
|
||||
code .
|
||||
```
|
||||
|
||||
- Ajoutez trois fichiers au dossier dans Visual Studio Code avec les noms suivants :
|
||||
- index.html
|
||||
- script.js
|
||||
- style.css
|
||||
|
||||
## Créer l'interface utilisateur
|
||||
|
||||
En examinant les exigences, nous savons que nous aurons besoin de quelques éléments sur notre page HTML. C'est un peu comme une recette, où nous avons besoin d'ingrédients :
|
||||
|
||||
- Un endroit pour afficher la citation que l'utilisateur doit taper
|
||||
- Un endroit pour afficher les messages, comme un message de succès
|
||||
- Une zone de texte pour taper
|
||||
- Un bouton "Démarrer"
|
||||
|
||||
Chacun de ces éléments aura besoin d'IDs pour que nous puissions les manipuler dans notre JavaScript. Nous ajouterons également des références aux fichiers CSS et JavaScript que nous allons créer.
|
||||
|
||||
Créez un nouveau fichier nommé **index.html**. Ajoutez le HTML suivant :
|
||||
|
||||
```html
|
||||
<!-- inside index.html -->
|
||||
<html>
|
||||
<head>
|
||||
<title>Typing game</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Typing game!</h1>
|
||||
<p>Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!</p>
|
||||
<p id="quote"></p> <!-- This will display our quote -->
|
||||
<p id="message"></p> <!-- This will display any status messages -->
|
||||
<div>
|
||||
<input type="text" aria-label="current word" id="typed-value" /> <!-- The textbox for typing -->
|
||||
<button type="button" id="start">Start</button> <!-- To start the game -->
|
||||
</div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Lancer l'application
|
||||
|
||||
Il est toujours préférable de développer de manière itérative pour voir à quoi ressemblent les choses. Lançons notre application. Il existe une excellente extension pour Visual Studio Code appelée [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) qui hébergera votre application localement et actualisera le navigateur à chaque sauvegarde.
|
||||
|
||||
- Installez [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) en suivant le lien et en cliquant sur **Installer**
|
||||
- Le navigateur vous demandera d'ouvrir Visual Studio Code, puis Visual Studio Code vous demandera de procéder à l'installation
|
||||
- Redémarrez Visual Studio Code si nécessaire
|
||||
- Une fois installé, dans Visual Studio Code, appuyez sur Ctrl-Shift-P (ou Cmd-Shift-P) pour ouvrir la palette de commandes
|
||||
- Tapez **Live Server: Open with Live Server**
|
||||
- Live Server commencera à héberger votre application
|
||||
- Ouvrez un navigateur et accédez à **https://localhost:5500**
|
||||
- Vous devriez maintenant voir la page que vous avez créée !
|
||||
|
||||
Ajoutons un peu de fonctionnalité.
|
||||
|
||||
## Ajouter le CSS
|
||||
|
||||
Avec notre HTML créé, ajoutons le CSS pour le style de base. Nous devons mettre en surbrillance le mot que le joueur doit taper et colorer la zone de texte si ce qu'il a tapé est incorrect. Nous ferons cela avec deux classes.
|
||||
|
||||
Créez un nouveau fichier nommé **style.css** et ajoutez la syntaxe suivante.
|
||||
|
||||
```css
|
||||
/* inside style.css */
|
||||
.highlight {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: lightcoral;
|
||||
border: red;
|
||||
}
|
||||
```
|
||||
|
||||
✅ En ce qui concerne le CSS, vous pouvez organiser votre page comme vous le souhaitez. Prenez un peu de temps pour rendre la page plus attrayante :
|
||||
|
||||
- Choisissez une police différente
|
||||
- Ajoutez des couleurs aux titres
|
||||
- Redimensionnez les éléments
|
||||
|
||||
## JavaScript
|
||||
|
||||
Avec notre interface utilisateur créée, concentrons-nous sur le JavaScript qui fournira la logique. Nous allons décomposer cela en plusieurs étapes :
|
||||
|
||||
- [Créer les constantes](../../../../4-typing-game/typing-game)
|
||||
- [Écouteur d'événement pour démarrer le jeu](../../../../4-typing-game/typing-game)
|
||||
- [Écouteur d'événement pour la saisie](../../../../4-typing-game/typing-game)
|
||||
|
||||
Mais d'abord, créez un nouveau fichier nommé **script.js**.
|
||||
|
||||
### Ajouter les constantes
|
||||
|
||||
Nous aurons besoin de quelques éléments pour nous faciliter la programmation. Encore une fois, comme une recette, voici ce dont nous aurons besoin :
|
||||
|
||||
- Un tableau contenant la liste de toutes les citations
|
||||
- Un tableau vide pour stocker tous les mots de la citation actuelle
|
||||
- Un espace pour stocker l'index du mot que le joueur tape actuellement
|
||||
- L'heure à laquelle le joueur a cliqué sur "Démarrer"
|
||||
|
||||
Nous aurons également besoin de références aux éléments de l'interface utilisateur :
|
||||
|
||||
- La zone de texte (**typed-value**)
|
||||
- L'affichage de la citation (**quote**)
|
||||
- Le message (**message**)
|
||||
|
||||
```javascript
|
||||
// inside script.js
|
||||
// all of our quotes
|
||||
const quotes = [
|
||||
'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
|
||||
'There is nothing more deceptive than an obvious fact.',
|
||||
'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
|
||||
'I never make exceptions. An exception disproves the rule.',
|
||||
'What one man can invent another can discover.',
|
||||
'Nothing clears up a case so much as stating it to another person.',
|
||||
'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
|
||||
];
|
||||
// store the list of words and the index of the word the player is currently typing
|
||||
let words = [];
|
||||
let wordIndex = 0;
|
||||
// the starting time
|
||||
let startTime = Date.now();
|
||||
// page elements
|
||||
const quoteElement = document.getElementById('quote');
|
||||
const messageElement = document.getElementById('message');
|
||||
const typedValueElement = document.getElementById('typed-value');
|
||||
```
|
||||
|
||||
✅ Ajoutez d'autres citations à votre jeu
|
||||
|
||||
> **NOTE :** Nous pouvons récupérer les éléments à tout moment dans le code en utilisant `document.getElementById`. Étant donné que nous allons nous référer régulièrement à ces éléments, nous allons éviter les fautes de frappe avec des littéraux de chaîne en utilisant des constantes. Des frameworks comme [Vue.js](https://vuejs.org/) ou [React](https://reactjs.org/) peuvent vous aider à mieux centraliser votre code.
|
||||
|
||||
Prenez une minute pour regarder une vidéo sur l'utilisation de `const`, `let` et `var`
|
||||
|
||||
[](https://youtube.com/watch?v=JNIXfGiDWM8 "Types de variables")
|
||||
|
||||
> 🎥 Cliquez sur l'image ci-dessus pour une vidéo sur les variables.
|
||||
|
||||
### Ajouter la logique de démarrage
|
||||
|
||||
Pour commencer le jeu, le joueur cliquera sur "Démarrer". Bien sûr, nous ne savons pas quand il va cliquer sur "Démarrer". C'est là qu'un [écouteur d'événement](https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener) entre en jeu. Un écouteur d'événement nous permettra d'écouter un événement (comme un clic) et d'exécuter du code en réponse. Dans notre cas, nous voulons exécuter du code lorsque l'utilisateur clique sur "Démarrer".
|
||||
|
||||
Lorsque l'utilisateur clique sur **Démarrer**, nous devons sélectionner une citation, configurer l'interface utilisateur et initialiser le suivi du mot actuel et du chronométrage. Voici le JavaScript que vous devez ajouter ; nous le décomposerons juste après le bloc de script.
|
||||
|
||||
```javascript
|
||||
// at the end of script.js
|
||||
document.getElementById('start').addEventListener('click', () => {
|
||||
// get a quote
|
||||
const quoteIndex = Math.floor(Math.random() * quotes.length);
|
||||
const quote = quotes[quoteIndex];
|
||||
// Put the quote into an array of words
|
||||
words = quote.split(' ');
|
||||
// reset the word index for tracking
|
||||
wordIndex = 0;
|
||||
|
||||
// UI updates
|
||||
// Create an array of span elements so we can set a class
|
||||
const spanWords = words.map(function(word) { return `<span>${word} </span>`});
|
||||
// Convert into string and set as innerHTML on quote display
|
||||
quoteElement.innerHTML = spanWords.join('');
|
||||
// Highlight the first word
|
||||
quoteElement.childNodes[0].className = 'highlight';
|
||||
// Clear any prior messages
|
||||
messageElement.innerText = '';
|
||||
|
||||
// Setup the textbox
|
||||
// Clear the textbox
|
||||
typedValueElement.value = '';
|
||||
// set focus
|
||||
typedValueElement.focus();
|
||||
// set the event handler
|
||||
|
||||
// Start the timer
|
||||
startTime = new Date().getTime();
|
||||
});
|
||||
```
|
||||
|
||||
Décomposons le code !
|
||||
|
||||
- Initialisation du suivi des mots
|
||||
- L'utilisation de [Math.floor](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) et [Math.random](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Math/random) nous permet de sélectionner aléatoirement une citation dans le tableau `quotes`
|
||||
- Nous convertissons la `quote` en un tableau de `words` pour suivre le mot que le joueur tape actuellement
|
||||
- `wordIndex` est initialisé à 0, car le joueur commence par le premier mot
|
||||
- Configuration de l'interface utilisateur
|
||||
- Création d'un tableau `spanWords`, contenant chaque mot dans un élément `span`
|
||||
- Cela nous permettra de mettre en surbrillance le mot à afficher
|
||||
- Utilisation de `join` pour créer une chaîne que nous pouvons utiliser pour mettre à jour le `innerHTML` de `quoteElement`
|
||||
- Cela affichera la citation au joueur
|
||||
- Définition de la `className` du premier élément `span` sur `highlight` pour le mettre en surbrillance en jaune
|
||||
- Nettoyage de `messageElement` en définissant `innerText` sur `''`
|
||||
- Configuration de la zone de texte
|
||||
- Effacement de la valeur actuelle de `typedValueElement`
|
||||
- Mise au point sur `typedValueElement`
|
||||
- Démarrage du chronomètre en appelant `getTime`
|
||||
|
||||
### Ajouter la logique de saisie
|
||||
|
||||
Lorsque le joueur tape, un événement `input` sera déclenché. Cet écouteur d'événement vérifiera si le joueur tape correctement le mot et gérera l'état actuel du jeu. Revenons à **script.js** et ajoutons le code suivant à la fin. Nous le décomposerons ensuite.
|
||||
|
||||
```javascript
|
||||
// at the end of script.js
|
||||
typedValueElement.addEventListener('input', () => {
|
||||
// Get the current word
|
||||
const currentWord = words[wordIndex];
|
||||
// get the current value
|
||||
const typedValue = typedValueElement.value;
|
||||
|
||||
if (typedValue === currentWord && wordIndex === words.length - 1) {
|
||||
// end of sentence
|
||||
// Display success
|
||||
const elapsedTime = new Date().getTime() - startTime;
|
||||
const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
|
||||
messageElement.innerText = message;
|
||||
} else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {
|
||||
// end of word
|
||||
// clear the typedValueElement for the new word
|
||||
typedValueElement.value = '';
|
||||
// move to the next word
|
||||
wordIndex++;
|
||||
// reset the class name for all elements in quote
|
||||
for (const wordElement of quoteElement.childNodes) {
|
||||
wordElement.className = '';
|
||||
}
|
||||
// highlight the new word
|
||||
quoteElement.childNodes[wordIndex].className = 'highlight';
|
||||
} else if (currentWord.startsWith(typedValue)) {
|
||||
// currently correct
|
||||
// highlight the next word
|
||||
typedValueElement.className = '';
|
||||
} else {
|
||||
// error state
|
||||
typedValueElement.className = 'error';
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Décomposons le code ! Nous commençons par récupérer le mot actuel et la valeur que le joueur a tapée jusqu'à présent. Ensuite, nous avons une logique en cascade, où nous vérifions si la citation est complète, si le mot est complet, si le mot est correct ou (en dernier recours) s'il y a une erreur.
|
||||
|
||||
- La citation est complète, indiquée par `typedValue` égal à `currentWord` et `wordIndex` égal à un de moins que la `length` de `words`
|
||||
- Calcul de `elapsedTime` en soustrayant `startTime` de l'heure actuelle
|
||||
- Division de `elapsedTime` par 1 000 pour convertir les millisecondes en secondes
|
||||
- Affichage d'un message de succès
|
||||
- Le mot est complet, indiqué par `typedValue` se terminant par un espace (fin d'un mot) et `typedValue` égal à `currentWord`
|
||||
- Réinitialisation de la `value` de `typedElement` à `''` pour permettre la saisie du mot suivant
|
||||
- Incrémentation de `wordIndex` pour passer au mot suivant
|
||||
- Boucle à travers tous les `childNodes` de `quoteElement` pour définir `className` sur `''` et revenir à l'affichage par défaut
|
||||
- Définition de `className` du mot actuel sur `highlight` pour le marquer comme le prochain mot à taper
|
||||
- Le mot est actuellement correctement tapé (mais pas complet), indiqué par `currentWord` commençant par `typedValue`
|
||||
- Réinitialisation de l'affichage de `typedValueElement` en effaçant `className`
|
||||
- Si nous arrivons ici, il y a une erreur
|
||||
- Définition de `className` de `typedValueElement` sur `error`
|
||||
|
||||
## Tester votre application
|
||||
|
||||
Vous êtes arrivé à la fin ! La dernière étape consiste à vérifier que notre application fonctionne. Essayez-la ! Ne vous inquiétez pas s'il y a des erreurs ; **tous les développeurs** rencontrent des erreurs. Examinez les messages et déboguez si nécessaire.
|
||||
|
||||
Cliquez sur **Démarrer** et commencez à taper ! Cela devrait ressembler un peu à l'animation que nous avons vue auparavant.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Ajoutez plus de fonctionnalités :
|
||||
|
||||
- Désactivez l'écouteur d'événement `input` à la fin du jeu, et réactivez-le lorsque le bouton est cliqué
|
||||
- Désactivez la zone de texte lorsque le joueur termine la citation
|
||||
- Affichez une boîte de dialogue modale avec le message de succès
|
||||
- Stockez les meilleurs scores en utilisant [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/22)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
Lisez sur [tous les événements disponibles](https://developer.mozilla.org/docs/Web/Events) pour le développeur via le navigateur web, et réfléchissez aux scénarios dans lesquels vous utiliseriez chacun d'eux.
|
||||
|
||||
## Devoir
|
||||
|
||||
[Créez un nouveau jeu de clavier](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,24 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "de5384c118e15e4d1d0eaa00fc01b112",
|
||||
"translation_date": "2025-08-24T00:22:27+00:00",
|
||||
"source_file": "4-typing-game/typing-game/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer un nouveau jeu de clavier
|
||||
|
||||
## Instructions
|
||||
|
||||
Créez un petit jeu qui utilise les événements du clavier pour accomplir des tâches. Cela peut être un type de jeu de dactylographie différent, ou un jeu artistique qui peint des pixels à l'écran en fonction des frappes. Faites preuve de créativité !
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------ | ------------------------ | ------------------ |
|
||||
| | Un jeu complet est présenté | Le jeu est très minimal | Le jeu contient des bugs |
|
||||
| | | | |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,180 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "0bb55e0b98600afab801eea115228873",
|
||||
"translation_date": "2025-08-23T23:43:29+00:00",
|
||||
"source_file": "5-browser-extension/1-about-browsers/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet d'extension de navigateur Partie 1 : Tout sur les navigateurs
|
||||
|
||||

|
||||
> Croquis par [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/23)
|
||||
|
||||
### Introduction
|
||||
|
||||
Les extensions de navigateur ajoutent des fonctionnalités supplémentaires à un navigateur. Mais avant d'en créer une, il est utile de comprendre un peu comment les navigateurs fonctionnent.
|
||||
|
||||
### À propos du navigateur
|
||||
|
||||
Dans cette série de leçons, vous apprendrez à créer une extension de navigateur qui fonctionnera sur les navigateurs Chrome, Firefox et Edge. Dans cette partie, vous découvrirez comment les navigateurs fonctionnent et vous préparerez les éléments de l'extension de navigateur.
|
||||
|
||||
Mais qu'est-ce qu'un navigateur exactement ? C'est une application logicielle qui permet à un utilisateur d'accéder à du contenu depuis un serveur et de l'afficher sur des pages web.
|
||||
|
||||
✅ Un peu d'histoire : le premier navigateur s'appelait 'WorldWideWeb' et a été créé par Sir Timothy Berners-Lee en 1990.
|
||||
|
||||

|
||||
> Quelques premiers navigateurs, via [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
|
||||
|
||||
Lorsqu'un utilisateur se connecte à Internet en utilisant une adresse URL (Uniform Resource Locator), généralement via le protocole Hypertext Transfer Protocol avec une adresse `http` ou `https`, le navigateur communique avec un serveur web et récupère une page web.
|
||||
|
||||
À ce stade, le moteur de rendu du navigateur l'affiche sur l'appareil de l'utilisateur, qui peut être un téléphone mobile, un ordinateur de bureau ou un ordinateur portable.
|
||||
|
||||
Les navigateurs ont également la capacité de mettre en cache du contenu afin qu'il n'ait pas besoin d'être récupéré depuis le serveur à chaque fois. Ils peuvent enregistrer l'historique de navigation d'un utilisateur, stocker des 'cookies', qui sont de petits morceaux de données contenant des informations utilisées pour enregistrer l'activité d'un utilisateur, et bien plus encore.
|
||||
|
||||
Un point très important à retenir sur les navigateurs est qu'ils ne sont pas tous identiques ! Chaque navigateur a ses forces et ses faiblesses, et un développeur web professionnel doit comprendre comment rendre les pages web performantes sur différents navigateurs. Cela inclut la gestion des petits écrans comme ceux des téléphones mobiles, ainsi que des utilisateurs hors ligne.
|
||||
|
||||
Un site web très utile que vous devriez probablement ajouter à vos favoris dans le navigateur que vous préférez utiliser est [caniuse.com](https://www.caniuse.com). Lorsque vous créez des pages web, il est très utile d'utiliser les listes de technologies prises en charge par caniuse pour mieux répondre aux besoins de vos utilisateurs.
|
||||
|
||||
✅ Comment savoir quels navigateurs sont les plus populaires auprès des utilisateurs de votre site web ? Consultez vos analyses - vous pouvez installer divers outils d'analyse dans le cadre de votre processus de développement web, et ils vous indiqueront quels navigateurs sont les plus utilisés.
|
||||
|
||||
## Extensions de navigateur
|
||||
|
||||
Pourquoi voudriez-vous créer une extension de navigateur ? C'est un outil pratique à ajouter à votre navigateur lorsque vous avez besoin d'un accès rapide à des tâches que vous effectuez souvent. Par exemple, si vous avez besoin de vérifier les couleurs sur les différentes pages web que vous consultez, vous pourriez installer une extension de navigateur pour choisir les couleurs. Si vous avez du mal à vous souvenir de vos mots de passe, vous pourriez utiliser une extension de gestion des mots de passe.
|
||||
|
||||
Les extensions de navigateur sont également amusantes à développer. Elles ont tendance à gérer un nombre limité de tâches qu'elles exécutent efficacement.
|
||||
|
||||
✅ Quelles sont vos extensions de navigateur préférées ? Quelles tâches accomplissent-elles ?
|
||||
|
||||
### Installer des extensions
|
||||
|
||||
Avant de commencer à créer, examinez le processus de création et de déploiement d'une extension de navigateur. Bien que chaque navigateur varie légèrement dans la gestion de cette tâche, le processus est similaire sur Chrome et Firefox à cet exemple sur Edge :
|
||||
|
||||

|
||||
|
||||
> Note : Assurez-vous d'activer le mode développeur et de permettre les extensions provenant d'autres magasins.
|
||||
|
||||
En essence, le processus sera :
|
||||
|
||||
- créer votre extension en utilisant `npm run build`
|
||||
- naviguer dans le navigateur vers le panneau des extensions en utilisant le bouton "Paramètres et plus" (l'icône `...`) en haut à droite
|
||||
- si c'est une nouvelle installation, choisir `load unpacked` pour télécharger une nouvelle extension depuis son dossier de construction (dans notre cas, il s'agit de `/dist`)
|
||||
- ou, cliquer sur `reload` si vous rechargez l'extension déjà installée
|
||||
|
||||
✅ Ces instructions concernent les extensions que vous créez vous-même ; pour installer des extensions qui ont été publiées dans le magasin d'extensions de navigateur associé à chaque navigateur, vous devez naviguer vers ces [magasins](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) et installer l'extension de votre choix.
|
||||
|
||||
### Commencer
|
||||
|
||||
Vous allez créer une extension de navigateur qui affiche l'empreinte carbone de votre région, montrant la consommation d'énergie de votre région et la source de cette énergie. L'extension comportera un formulaire qui collecte une clé API afin que vous puissiez accéder à l'API de CO2 Signal.
|
||||
|
||||
**Vous avez besoin de :**
|
||||
|
||||
- [une clé API](https://www.co2signal.com/) ; entrez votre email dans la boîte sur cette page et une clé vous sera envoyée
|
||||
- le [code de votre région](http://api.electricitymap.org/v3/zones) correspondant à la [Electricity Map](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
- le [code de départ](../../../../5-browser-extension/start). Téléchargez le dossier `start` ; vous compléterez le code dans ce dossier.
|
||||
- [NPM](https://www.npmjs.com) - NPM est un outil de gestion de paquets ; installez-le localement et les paquets listés dans votre fichier `package.json` seront installés pour être utilisés par votre projet web.
|
||||
|
||||
✅ Apprenez-en plus sur la gestion des paquets dans ce [module d'apprentissage excellent](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
|
||||
|
||||
Prenez un moment pour parcourir la base de code :
|
||||
|
||||
dist
|
||||
-|manifest.json (les paramètres par défaut sont ici)
|
||||
-|index.html (le balisage HTML du front-end est ici)
|
||||
-|background.js (le JS de fond est ici)
|
||||
-|main.js (JS compilé)
|
||||
src
|
||||
-|index.js (votre code JS va ici)
|
||||
|
||||
✅ Une fois que vous avez votre clé API et le code de votre région à portée de main, conservez-les quelque part dans une note pour une utilisation future.
|
||||
|
||||
### Construire le HTML pour l'extension
|
||||
|
||||
Cette extension a deux vues. Une pour recueillir la clé API et le code de région :
|
||||
|
||||

|
||||
|
||||
Et la seconde pour afficher la consommation de carbone de la région :
|
||||
|
||||

|
||||
|
||||
Commençons par construire le HTML pour le formulaire et le styliser avec du CSS.
|
||||
|
||||
Dans le dossier `/dist`, vous allez construire un formulaire et une zone de résultats. Dans le fichier `index.html`, remplissez la zone de formulaire délimitée :
|
||||
|
||||
```HTML
|
||||
<form class="form-data" autocomplete="on">
|
||||
<div>
|
||||
<h2>New? Add your Information</h2>
|
||||
</div>
|
||||
<div>
|
||||
<label for="region">Region Name</label>
|
||||
<input type="text" id="region" required class="region-name" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="api">Your API Key from tmrow</label>
|
||||
<input type="text" id="api" required class="api-key" />
|
||||
</div>
|
||||
<button class="search-btn">Submit</button>
|
||||
</form>
|
||||
```
|
||||
C'est le formulaire où vos informations enregistrées seront saisies et sauvegardées dans le stockage local.
|
||||
|
||||
Ensuite, créez la zone de résultats ; sous la balise finale du formulaire, ajoutez quelques divs :
|
||||
|
||||
```HTML
|
||||
<div class="result">
|
||||
<div class="loading">loading...</div>
|
||||
<div class="errors"></div>
|
||||
<div class="data"></div>
|
||||
<div class="result-container">
|
||||
<p><strong>Region: </strong><span class="my-region"></span></p>
|
||||
<p><strong>Carbon Usage: </strong><span class="carbon-usage"></span></p>
|
||||
<p><strong>Fossil Fuel Percentage: </strong><span class="fossil-fuel"></span></p>
|
||||
</div>
|
||||
<button class="clear-btn">Change region</button>
|
||||
</div>
|
||||
```
|
||||
À ce stade, vous pouvez essayer une construction. Assurez-vous d'installer les dépendances du paquet de cette extension :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Cette commande utilisera npm, le gestionnaire de paquets Node, pour installer webpack pour le processus de construction de votre extension. Webpack est un outil de regroupement qui gère la compilation du code. Vous pouvez voir le résultat de ce processus en regardant dans `/dist/main.js` - vous verrez que le code a été regroupé.
|
||||
|
||||
Pour l'instant, l'extension devrait se construire et, si vous la déployez dans Edge en tant qu'extension, vous verrez un formulaire affiché proprement.
|
||||
|
||||
Félicitations, vous avez fait les premiers pas vers la création d'une extension de navigateur. Dans les leçons suivantes, vous la rendrez plus fonctionnelle et utile.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Explorez un magasin d'extensions de navigateur et installez-en une dans votre navigateur. Vous pouvez examiner ses fichiers de manière intéressante. Qu'avez-vous découvert ?
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/24)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Dans cette leçon, vous avez appris un peu sur l'histoire du navigateur web ; profitez de cette occasion pour en apprendre davantage sur la façon dont les inventeurs du World Wide Web ont envisagé son utilisation en lisant davantage sur son histoire. Quelques sites utiles incluent :
|
||||
|
||||
[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/)
|
||||
|
||||
[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/)
|
||||
|
||||
[Une interview avec Tim Berners-Lee](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
|
||||
|
||||
## Devoir
|
||||
|
||||
[Re-stylisez votre extension](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "e3c6f2a03c2336e60412612d870af547",
|
||||
"translation_date": "2025-08-23T23:44:58+00:00",
|
||||
"source_file": "5-browser-extension/1-about-browsers/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Redéfinir le style de votre extension
|
||||
|
||||
## Instructions
|
||||
|
||||
La base de code de cette extension est fournie avec des styles, mais vous n'êtes pas obligé de les utiliser ; personnalisez votre extension en modifiant son fichier CSS.
|
||||
|
||||
## Critères
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | -------------------------------------------- | --------------------- | ------------------ |
|
||||
| | Le code est soumis avec de nouveaux styles fonctionnels | Le style est incomplet | Les styles sont défectueux |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,238 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
|
||||
"translation_date": "2025-08-23T23:39:20+00:00",
|
||||
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet d'extension de navigateur Partie 2 : Appeler une API, utiliser le stockage local
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/25)
|
||||
|
||||
### Introduction
|
||||
|
||||
Dans cette leçon, vous allez appeler une API en soumettant le formulaire de votre extension de navigateur et afficher les résultats dans votre extension. De plus, vous apprendrez à stocker des données dans le stockage local de votre navigateur pour une utilisation future.
|
||||
|
||||
✅ Suivez les segments numérotés dans les fichiers appropriés pour savoir où placer votre code.
|
||||
|
||||
### Configurez les éléments à manipuler dans l'extension :
|
||||
|
||||
À ce stade, vous avez construit le HTML pour le formulaire et la `<div>` des résultats de votre extension de navigateur. Désormais, vous devrez travailler dans le fichier `/src/index.js` et construire votre extension étape par étape. Référez-vous à la [leçon précédente](../1-about-browsers/README.md) pour configurer votre projet et comprendre le processus de construction.
|
||||
|
||||
En travaillant dans votre fichier `index.js`, commencez par créer quelques variables `const` pour contenir les valeurs associées à différents champs :
|
||||
|
||||
```JavaScript
|
||||
// form fields
|
||||
const form = document.querySelector('.form-data');
|
||||
const region = document.querySelector('.region-name');
|
||||
const apiKey = document.querySelector('.api-key');
|
||||
|
||||
// results
|
||||
const errors = document.querySelector('.errors');
|
||||
const loading = document.querySelector('.loading');
|
||||
const results = document.querySelector('.result-container');
|
||||
const usage = document.querySelector('.carbon-usage');
|
||||
const fossilfuel = document.querySelector('.fossil-fuel');
|
||||
const myregion = document.querySelector('.my-region');
|
||||
const clearBtn = document.querySelector('.clear-btn');
|
||||
```
|
||||
|
||||
Tous ces champs sont référencés par leur classe CSS, comme vous les avez configurés dans le HTML lors de la leçon précédente.
|
||||
|
||||
### Ajoutez des écouteurs d'événements
|
||||
|
||||
Ensuite, ajoutez des écouteurs d'événements au formulaire et au bouton de réinitialisation qui remet le formulaire à zéro, afin que si un utilisateur soumet le formulaire ou clique sur ce bouton, une action se produise. Ajoutez également l'appel pour initialiser l'application en bas du fichier :
|
||||
|
||||
```JavaScript
|
||||
form.addEventListener('submit', (e) => handleSubmit(e));
|
||||
clearBtn.addEventListener('click', (e) => reset(e));
|
||||
init();
|
||||
```
|
||||
|
||||
✅ Remarquez la syntaxe abrégée utilisée pour écouter un événement de soumission ou de clic, et comment l'événement est transmis aux fonctions `handleSubmit` ou `reset`. Pouvez-vous écrire l'équivalent de cette syntaxe abrégée dans un format plus long ? Lequel préférez-vous ?
|
||||
|
||||
### Construisez les fonctions `init()` et `reset()` :
|
||||
|
||||
Vous allez maintenant construire la fonction qui initialise l'extension, appelée `init()` :
|
||||
|
||||
```JavaScript
|
||||
function init() {
|
||||
//if anything is in localStorage, pick it up
|
||||
const storedApiKey = localStorage.getItem('apiKey');
|
||||
const storedRegion = localStorage.getItem('regionName');
|
||||
|
||||
//set icon to be generic green
|
||||
//todo
|
||||
|
||||
if (storedApiKey === null || storedRegion === null) {
|
||||
//if we don't have the keys, show the form
|
||||
form.style.display = 'block';
|
||||
results.style.display = 'none';
|
||||
loading.style.display = 'none';
|
||||
clearBtn.style.display = 'none';
|
||||
errors.textContent = '';
|
||||
} else {
|
||||
//if we have saved keys/regions in localStorage, show results when they load
|
||||
displayCarbonUsage(storedApiKey, storedRegion);
|
||||
results.style.display = 'none';
|
||||
form.style.display = 'none';
|
||||
clearBtn.style.display = 'block';
|
||||
}
|
||||
};
|
||||
|
||||
function reset(e) {
|
||||
e.preventDefault();
|
||||
//clear local storage for region only
|
||||
localStorage.removeItem('regionName');
|
||||
init();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Dans cette fonction, il y a une logique intéressante. En la lisant, pouvez-vous voir ce qui se passe ?
|
||||
|
||||
- Deux constantes `const` sont définies pour vérifier si l'utilisateur a stocké une clé API (`APIKey`) et un code de région dans le stockage local.
|
||||
- Si l'une de ces valeurs est nulle, affichez le formulaire en modifiant son style pour qu'il s'affiche en mode 'block'.
|
||||
- Masquez les résultats, le chargement et le bouton de réinitialisation, et définissez tout texte d'erreur sur une chaîne vide.
|
||||
- Si une clé et une région existent, lancez une routine pour :
|
||||
- Appeler l'API pour obtenir des données sur l'utilisation du carbone.
|
||||
- Masquer la zone des résultats.
|
||||
- Masquer le formulaire.
|
||||
- Afficher le bouton de réinitialisation.
|
||||
|
||||
Avant de continuer, il est utile d'apprendre un concept très important disponible dans les navigateurs : [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage est un moyen pratique de stocker des chaînes de caractères dans le navigateur sous forme de paires `clé-valeur`. Ce type de stockage web peut être manipulé par JavaScript pour gérer des données dans le navigateur. LocalStorage ne s'expire pas, tandis que SessionStorage, un autre type de stockage web, est effacé lorsque le navigateur est fermé. Les différents types de stockage ont leurs avantages et inconvénients.
|
||||
|
||||
> Note - votre extension de navigateur a son propre stockage local ; la fenêtre principale du navigateur est une instance différente et se comporte séparément.
|
||||
|
||||
Vous définissez votre clé API (`APIKey`) avec une valeur de chaîne, par exemple, et vous pouvez voir qu'elle est définie dans Edge en "inspectant" une page web (vous pouvez faire un clic droit sur un navigateur pour inspecter) et en allant dans l'onglet Applications pour voir le stockage.
|
||||
|
||||

|
||||
|
||||
✅ Réfléchissez à des situations où vous NE voudriez PAS stocker certaines données dans LocalStorage. En général, placer des clés API dans LocalStorage est une mauvaise idée ! Pouvez-vous comprendre pourquoi ? Dans notre cas, puisque notre application est purement éducative et ne sera pas déployée dans un magasin d'applications, nous utiliserons cette méthode.
|
||||
|
||||
Remarquez que vous utilisez l'API Web pour manipuler LocalStorage, soit en utilisant `getItem()`, `setItem()`, ou `removeItem()`. C'est largement pris en charge par les navigateurs.
|
||||
|
||||
Avant de construire la fonction `displayCarbonUsage()` appelée dans `init()`, construisons la fonctionnalité pour gérer la soumission initiale du formulaire.
|
||||
|
||||
### Gérez la soumission du formulaire
|
||||
|
||||
Créez une fonction appelée `handleSubmit` qui accepte un argument événementiel `(e)`. Empêchez l'événement de se propager (dans ce cas, nous voulons empêcher le navigateur de se rafraîchir) et appelez une nouvelle fonction, `setUpUser`, en passant les arguments `apiKey.value` et `region.value`. De cette manière, vous utilisez les deux valeurs saisies via le formulaire initial lorsque les champs appropriés sont remplis.
|
||||
|
||||
```JavaScript
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
setUpUser(apiKey.value, region.value);
|
||||
}
|
||||
```
|
||||
|
||||
✅ Rafraîchissez votre mémoire - le HTML que vous avez configuré dans la dernière leçon contient deux champs de saisie dont les `values` sont capturées via les constantes que vous avez définies en haut du fichier, et ils sont tous deux `required`, donc le navigateur empêche les utilisateurs de saisir des valeurs nulles.
|
||||
|
||||
### Configurez l'utilisateur
|
||||
|
||||
Passons à la fonction `setUpUser`, où vous définissez les valeurs de stockage local pour `apiKey` et `regionName`. Ajoutez une nouvelle fonction :
|
||||
|
||||
```JavaScript
|
||||
function setUpUser(apiKey, regionName) {
|
||||
localStorage.setItem('apiKey', apiKey);
|
||||
localStorage.setItem('regionName', regionName);
|
||||
loading.style.display = 'block';
|
||||
errors.textContent = '';
|
||||
clearBtn.style.display = 'block';
|
||||
//make initial call
|
||||
displayCarbonUsage(apiKey, regionName);
|
||||
}
|
||||
```
|
||||
|
||||
Cette fonction affiche un message de chargement pendant que l'API est appelée. À ce stade, vous êtes arrivé à la création de la fonction la plus importante de cette extension de navigateur !
|
||||
|
||||
### Affichez l'utilisation du carbone
|
||||
|
||||
Enfin, il est temps d'interroger l'API !
|
||||
|
||||
Avant d'aller plus loin, nous devrions discuter des API. Les API, ou [Interfaces de Programmation d'Applications](https://www.webopedia.com/TERM/A/API.html), sont un élément essentiel de la boîte à outils d'un développeur web. Elles fournissent des moyens standardisés pour que les programmes interagissent et communiquent entre eux. Par exemple, si vous construisez un site web qui doit interroger une base de données, quelqu'un pourrait avoir créé une API pour vous permettre de l'utiliser. Bien qu'il existe de nombreux types d'API, l'un des plus populaires est une [API REST](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
|
||||
|
||||
✅ Le terme 'REST' signifie 'Transfert d'État Représentationnel' et repose sur l'utilisation d'URL configurées de différentes manières pour récupérer des données. Faites quelques recherches sur les différents types d'API disponibles pour les développeurs. Quel format vous semble le plus intéressant ?
|
||||
|
||||
Il y a des points importants à noter à propos de cette fonction. Tout d'abord, remarquez le mot-clé [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Écrire vos fonctions pour qu'elles s'exécutent de manière asynchrone signifie qu'elles attendent qu'une action, comme le retour de données, soit terminée avant de continuer.
|
||||
|
||||
Voici une courte vidéo sur `async` :
|
||||
|
||||
[](https://youtube.com/watch?v=YwmlRkrxvkk "Async et Await pour gérer les promesses")
|
||||
|
||||
> 🎥 Cliquez sur l'image ci-dessus pour une vidéo sur async/await.
|
||||
|
||||
Créez une nouvelle fonction pour interroger l'API C02Signal :
|
||||
|
||||
```JavaScript
|
||||
import axios from '../node_modules/axios';
|
||||
|
||||
async function displayCarbonUsage(apiKey, region) {
|
||||
try {
|
||||
await axios
|
||||
.get('https://api.co2signal.com/v1/latest', {
|
||||
params: {
|
||||
countryCode: region,
|
||||
},
|
||||
headers: {
|
||||
'auth-token': apiKey,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
let CO2 = Math.floor(response.data.data.carbonIntensity);
|
||||
|
||||
//calculateColor(CO2);
|
||||
|
||||
loading.style.display = 'none';
|
||||
form.style.display = 'none';
|
||||
myregion.textContent = region;
|
||||
usage.textContent =
|
||||
Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)';
|
||||
fossilfuel.textContent =
|
||||
response.data.data.fossilFuelPercentage.toFixed(2) +
|
||||
'% (percentage of fossil fuels used to generate electricity)';
|
||||
results.style.display = 'block';
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
loading.style.display = 'none';
|
||||
results.style.display = 'none';
|
||||
errors.textContent = 'Sorry, we have no data for the region you have requested.';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
C'est une grande fonction. Que se passe-t-il ici ?
|
||||
|
||||
- En suivant les bonnes pratiques, vous utilisez le mot-clé `async` pour que cette fonction se comporte de manière asynchrone. La fonction contient un bloc `try/catch` car elle retournera une promesse lorsque l'API renverra des données. Comme vous n'avez pas de contrôle sur la vitesse de réponse de l'API (elle peut ne pas répondre du tout !), vous devez gérer cette incertitude en l'appelant de manière asynchrone.
|
||||
- Vous interrogez l'API co2signal pour obtenir les données de votre région, en utilisant votre clé API. Pour utiliser cette clé, vous devez utiliser un type d'authentification dans les paramètres d'en-tête.
|
||||
- Une fois que l'API répond, vous assignez divers éléments de ses données de réponse aux parties de votre écran que vous avez configurées pour afficher ces données.
|
||||
- S'il y a une erreur ou s'il n'y a pas de résultat, vous affichez un message d'erreur.
|
||||
|
||||
✅ Utiliser des modèles de programmation asynchrone est un autre outil très utile dans votre boîte à outils. Lisez [à propos des différentes manières](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) de configurer ce type de code.
|
||||
|
||||
Félicitations ! Si vous construisez votre extension (`npm run build`) et la rafraîchissez dans votre panneau d'extensions, vous avez une extension fonctionnelle ! La seule chose qui ne fonctionne pas est l'icône, et vous corrigerez cela dans la prochaine leçon.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Nous avons discuté de plusieurs types d'API jusqu'à présent dans ces leçons. Choisissez une API web et recherchez en profondeur ce qu'elle offre. Par exemple, examinez les API disponibles dans les navigateurs comme l'[API HTML Drag and Drop](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). Qu'est-ce qui fait une excellente API selon vous ?
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/26)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
Vous avez appris à propos de LocalStorage et des API dans cette leçon, deux outils très utiles pour le développeur web professionnel. Pouvez-vous réfléchir à la manière dont ces deux éléments fonctionnent ensemble ? Pensez à la façon dont vous architectureriez un site web qui stockerait des éléments à utiliser par une API.
|
||||
|
||||
## Devoir
|
||||
|
||||
[Adoptez une API](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "a0c78d1dd9d1acdbf7f52e7cc3ebe1a7",
|
||||
"translation_date": "2025-08-23T23:40:55+00:00",
|
||||
"source_file": "5-browser-extension/2-forms-browsers-local-storage/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Adoptez une API
|
||||
|
||||
## Instructions
|
||||
|
||||
Les APIs peuvent être très amusantes à utiliser. Voici une [liste de nombreuses APIs gratuites](https://github.com/public-apis/public-apis). Choisissez une API et créez une extension de navigateur qui résout un problème. Cela peut être un problème aussi simple que de ne pas avoir assez de photos d'animaux (dans ce cas, essayez l'[API Dog CEO](https://dog.ceo/dog-api/)) ou quelque chose de plus complexe - amusez-vous !
|
||||
|
||||
## Critères d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | -------------------------------------------------------------------------- | --------------------------------------- | ----------------------- |
|
||||
| | Une extension de navigateur complète est soumise en utilisant une API de la liste ci-dessus | Une extension de navigateur partielle est soumise | La soumission contient des bugs |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,174 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
|
||||
"translation_date": "2025-08-23T23:46:32+00:00",
|
||||
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Projet d'extension de navigateur Partie 3 : Découvrez les tâches en arrière-plan et les performances
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/27)
|
||||
|
||||
### Introduction
|
||||
|
||||
Dans les deux dernières leçons de ce module, vous avez appris à créer un formulaire et une zone d'affichage pour les données récupérées depuis une API. C'est une méthode très classique pour créer une présence sur le web. Vous avez même appris à gérer la récupération de données de manière asynchrone. Votre extension de navigateur est presque terminée.
|
||||
|
||||
Il reste à gérer certaines tâches en arrière-plan, notamment la mise à jour de la couleur de l'icône de l'extension. C'est donc le moment idéal pour parler de la manière dont le navigateur gère ce type de tâche. Réfléchissons à ces tâches du navigateur dans le contexte des performances de vos ressources web pendant leur développement.
|
||||
|
||||
## Bases des performances web
|
||||
|
||||
> "Les performances d'un site web concernent deux choses : la vitesse de chargement de la page et la rapidité d'exécution du code." -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
|
||||
|
||||
Le sujet de la création de sites web extrêmement rapides sur tous types d'appareils, pour tous types d'utilisateurs, dans toutes sortes de situations, est, sans surprise, vaste. Voici quelques points à garder à l'esprit lorsque vous développez un projet web classique ou une extension de navigateur.
|
||||
|
||||
La première chose à faire pour garantir l'efficacité de votre site est de collecter des données sur ses performances. Le premier endroit pour le faire est dans les outils de développement de votre navigateur web. Dans Edge, vous pouvez sélectionner le bouton "Paramètres et plus" (l'icône des trois points en haut à droite du navigateur), puis naviguer vers Plus d'outils > Outils de développement et ouvrir l'onglet Performances. Vous pouvez également utiliser les raccourcis clavier `Ctrl` + `Shift` + `I` sur Windows ou `Option` + `Command` + `I` sur Mac pour ouvrir les outils de développement.
|
||||
|
||||
L'onglet Performances contient un outil de profilage. Ouvrez un site web (essayez, par exemple, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) et cliquez sur le bouton 'Enregistrer', puis actualisez le site. Arrêtez l'enregistrement à tout moment, et vous pourrez voir les routines générées pour 'script', 'render' et 'paint' le site :
|
||||
|
||||

|
||||
|
||||
✅ Consultez la [documentation Microsoft](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) sur le panneau Performances dans Edge.
|
||||
|
||||
> Astuce : pour obtenir une lecture précise du temps de démarrage de votre site web, videz le cache de votre navigateur.
|
||||
|
||||
Sélectionnez des éléments de la chronologie du profil pour zoomer sur les événements qui se produisent pendant le chargement de votre page.
|
||||
|
||||
Obtenez un aperçu des performances de votre page en sélectionnant une partie de la chronologie du profil et en regardant le panneau de résumé :
|
||||
|
||||

|
||||
|
||||
Vérifiez le panneau du journal des événements pour voir si un événement a pris plus de 15 ms :
|
||||
|
||||

|
||||
|
||||
✅ Familiarisez-vous avec votre profiler ! Ouvrez les outils de développement sur ce site et voyez s'il y a des goulots d'étranglement. Quel est l'actif qui se charge le plus lentement ? Le plus rapidement ?
|
||||
|
||||
## Vérifications de profilage
|
||||
|
||||
En général, il existe certains "points problématiques" que chaque développeur web devrait surveiller lors de la création d'un site pour éviter les mauvaises surprises au moment de le déployer en production.
|
||||
|
||||
**Tailles des ressources** : Le web est devenu plus "lourd", et donc plus lent, ces dernières années. Une partie de ce poids est liée à l'utilisation des images.
|
||||
|
||||
✅ Parcourez l'[Internet Archive](https://httparchive.org/reports/page-weight) pour une vue historique du poids des pages et plus encore.
|
||||
|
||||
Une bonne pratique consiste à s'assurer que vos images sont optimisées et livrées à la bonne taille et résolution pour vos utilisateurs.
|
||||
|
||||
**Traversées du DOM** : Le navigateur doit construire son modèle d'objet de document (DOM) en fonction du code que vous écrivez. Il est donc dans l'intérêt de bonnes performances de page de garder vos balises minimales, en utilisant et en stylisant uniquement ce dont la page a besoin. À ce propos, le CSS excessif associé à une page pourrait être optimisé ; les styles qui doivent être utilisés uniquement sur une page n'ont pas besoin d'être inclus dans la feuille de style principale, par exemple.
|
||||
|
||||
**JavaScript** : Chaque développeur JavaScript devrait surveiller les scripts "bloquant le rendu" qui doivent être chargés avant que le reste du DOM puisse être traversé et peint dans le navigateur. Envisagez d'utiliser `defer` avec vos scripts en ligne (comme cela est fait dans le module Terrarium).
|
||||
|
||||
✅ Essayez quelques sites sur un [site de test de vitesse](https://www.webpagetest.org/) pour en savoir plus sur les vérifications courantes effectuées pour déterminer les performances d'un site.
|
||||
|
||||
Maintenant que vous avez une idée de la manière dont le navigateur rend les ressources que vous lui envoyez, examinons les dernières étapes nécessaires pour terminer votre extension :
|
||||
|
||||
### Créer une fonction pour calculer la couleur
|
||||
|
||||
Dans `/src/index.js`, ajoutez une fonction appelée `calculateColor()` après la série de variables `const` que vous avez définies pour accéder au DOM :
|
||||
|
||||
```JavaScript
|
||||
function calculateColor(value) {
|
||||
let co2Scale = [0, 150, 600, 750, 800];
|
||||
let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02'];
|
||||
|
||||
let closestNum = co2Scale.sort((a, b) => {
|
||||
return Math.abs(a - value) - Math.abs(b - value);
|
||||
})[0];
|
||||
console.log(value + ' is closest to ' + closestNum);
|
||||
let num = (element) => element > closestNum;
|
||||
let scaleIndex = co2Scale.findIndex(num);
|
||||
|
||||
let closestColor = colors[scaleIndex];
|
||||
console.log(scaleIndex, closestColor);
|
||||
|
||||
chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } });
|
||||
}
|
||||
```
|
||||
|
||||
Que se passe-t-il ici ? Vous passez une valeur (l'intensité carbone) issue de l'appel API que vous avez complété dans la dernière leçon, puis vous calculez à quel point sa valeur est proche de l'indice présenté dans le tableau des couleurs. Ensuite, vous envoyez cette valeur de couleur la plus proche au runtime de Chrome.
|
||||
|
||||
Le chrome.runtime dispose [d'une API](https://developer.chrome.com/extensions/runtime) qui gère toutes sortes de tâches en arrière-plan, et votre extension en tire parti :
|
||||
|
||||
> "Utilisez l'API chrome.runtime pour récupérer la page d'arrière-plan, retourner les détails du manifeste et écouter et répondre aux événements du cycle de vie de l'application ou de l'extension. Vous pouvez également utiliser cette API pour convertir le chemin relatif des URL en URL entièrement qualifiées."
|
||||
|
||||
✅ Si vous développez cette extension de navigateur pour Edge, cela pourrait vous surprendre d'utiliser une API Chrome. Les versions plus récentes du navigateur Edge fonctionnent sur le moteur de navigateur Chromium, ce qui vous permet de tirer parti de ces outils.
|
||||
|
||||
> Notez que si vous souhaitez profiler une extension de navigateur, lancez les outils de développement depuis l'extension elle-même, car elle constitue une instance de navigateur distincte.
|
||||
|
||||
### Définir une couleur d'icône par défaut
|
||||
|
||||
Maintenant, dans la fonction `init()`, définissez l'icône sur une couleur verte générique pour commencer en appelant à nouveau l'action `updateIcon` de Chrome :
|
||||
|
||||
```JavaScript
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'updateIcon',
|
||||
value: {
|
||||
color: 'green',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Appeler la fonction, exécuter l'appel
|
||||
|
||||
Ensuite, appelez cette fonction que vous venez de créer en l'ajoutant à la promesse retournée par l'API C02Signal :
|
||||
|
||||
```JavaScript
|
||||
//let CO2...
|
||||
calculateColor(CO2);
|
||||
```
|
||||
|
||||
Et enfin, dans `/dist/background.js`, ajoutez l'écouteur pour ces appels d'action en arrière-plan :
|
||||
|
||||
```JavaScript
|
||||
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
||||
if (msg.action === 'updateIcon') {
|
||||
chrome.browserAction.setIcon({ imageData: drawIcon(msg.value) });
|
||||
}
|
||||
});
|
||||
//borrowed from energy lollipop extension, nice feature!
|
||||
function drawIcon(value) {
|
||||
let canvas = document.createElement('canvas');
|
||||
let context = canvas.getContext('2d');
|
||||
|
||||
context.beginPath();
|
||||
context.fillStyle = value.color;
|
||||
context.arc(100, 100, 50, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
|
||||
return context.getImageData(50, 50, 100, 100);
|
||||
}
|
||||
```
|
||||
|
||||
Dans ce code, vous ajoutez un écouteur pour tout message envoyé au gestionnaire de tâches en arrière-plan. Si le message est appelé 'updateIcon', alors le code suivant est exécuté pour dessiner une icône de la couleur appropriée en utilisant l'API Canvas.
|
||||
|
||||
✅ Vous en apprendrez davantage sur l'API Canvas dans les [leçons du jeu spatial](../../6-space-game/2-drawing-to-canvas/README.md).
|
||||
|
||||
Maintenant, reconstruisez votre extension (`npm run build`), actualisez et lancez votre extension, et observez le changement de couleur. Est-ce le bon moment pour faire une course ou laver la vaisselle ? Maintenant, vous le savez !
|
||||
|
||||
Félicitations, vous avez créé une extension de navigateur utile et appris davantage sur le fonctionnement du navigateur et sur la manière de profiler ses performances.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Explorez certains sites web open source qui existent depuis longtemps et, en vous basant sur leur historique GitHub, essayez de déterminer comment ils ont été optimisés au fil des années pour les performances, si cela a été fait. Quel est le point de douleur le plus courant ?
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/28)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Envisagez de vous inscrire à une [newsletter sur les performances](https://perf.email/).
|
||||
|
||||
Explorez certaines des façons dont les navigateurs évaluent les performances web en examinant les onglets de performances dans leurs outils web. Trouvez-vous des différences majeures ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Analyser un site pour ses performances](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,21 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "fc09b0fb314a5ab0507ba99216e6a843",
|
||||
"translation_date": "2025-08-23T23:47:56+00:00",
|
||||
"source_file": "5-browser-extension/3-background-tasks-and-performance/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Analyser un site pour ses performances
|
||||
|
||||
Fournissez un rapport détaillé sur un site web, en mettant en évidence les zones où les performances posent problème. Analysez pourquoi le site est lent et ce que vous pourriez faire pour l'accélérer. Ne vous limitez pas aux outils du navigateur, mais faites des recherches sur d'autres outils qui pourraient enrichir votre rapport.
|
||||
|
||||
## Critères d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ---------------------------------------------------------------------------------------------------------- | --------------------------- | ----------------------------- |
|
||||
| | Un rapport est présenté avec des détails provenant non seulement des outils du navigateur mais aussi d'outils tiers si disponibles | Un rapport basique est présenté | Un rapport minimal est présenté |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "b121a279a6ab39878491f3e572673515",
|
||||
"translation_date": "2025-08-23T23:37:32+00:00",
|
||||
"source_file": "5-browser-extension/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une extension de navigateur
|
||||
|
||||
Créer des extensions de navigateur est une manière amusante et intéressante de réfléchir à la performance de vos applications tout en développant un type différent de ressource web. Ce module comprend des leçons sur le fonctionnement des navigateurs, le déploiement d'une extension de navigateur, la création d'un formulaire, l'appel d'une API, l'utilisation du stockage local, ainsi que l'évaluation et l'amélioration des performances de votre site web.
|
||||
|
||||
Vous allez créer une extension de navigateur qui fonctionne sur Edge, Chrome et Firefox. Cette extension, qui ressemble à un mini site web conçu pour une tâche très spécifique, interroge l'[API CO2 Signal](https://www.co2signal.com) pour obtenir les données sur l'utilisation de l'électricité et l'intensité carbone d'une région donnée, et fournit une lecture de l'empreinte carbone de cette région.
|
||||
|
||||
Cette extension peut être utilisée ponctuellement par un utilisateur après avoir saisi une clé API et un code de région dans un formulaire, afin de déterminer l'utilisation locale de l'électricité et ainsi fournir des données pouvant influencer les décisions énergétiques de l'utilisateur. Par exemple, il pourrait être préférable de retarder l'utilisation d'un sèche-linge (une activité à forte intensité carbone) pendant une période de forte consommation d'électricité dans votre région.
|
||||
|
||||
### Sujets
|
||||
|
||||
1. [À propos des navigateurs](1-about-browsers/README.md)
|
||||
2. [Formulaires et stockage local](2-forms-browsers-local-storage/README.md)
|
||||
3. [Tâches en arrière-plan et performance](3-background-tasks-and-performance/README.md)
|
||||
|
||||
### Crédits
|
||||
|
||||

|
||||
|
||||
## Crédits
|
||||
|
||||
L'idée de ce déclencheur carbone web a été proposée par Asim Hussain, responsable chez Microsoft de l'équipe Green Cloud Advocacy et auteur des [Green Principles](https://principles.green/). À l'origine, il s'agissait d'un [projet de site web](https://github.com/jlooper/green).
|
||||
|
||||
La structure de l'extension de navigateur a été influencée par l'[extension COVID d'Adebola Adeniran](https://github.com/onedebos/covtension).
|
||||
|
||||
Le concept derrière le système d'icônes en "point" a été suggéré par la structure d'icônes de l'extension de navigateur [Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
Ces leçons ont été écrites avec ♥️ par [Jen Looper](https://www.twitter.com/jenlooper)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "fab4e6b4f0efcd587a9029d82991f597",
|
||||
"translation_date": "2025-08-23T23:48:39+00:00",
|
||||
"source_file": "5-browser-extension/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code terminé
|
||||
|
||||
En utilisant l'API C02 Signal de tmrow pour suivre la consommation d'électricité, créez une extension de navigateur afin d'avoir un rappel directement dans votre navigateur sur l'intensité de la consommation électrique de votre région. Utiliser cette extension de manière ponctuelle vous aidera à prendre des décisions sur vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Premiers pas
|
||||
|
||||
Vous devrez avoir [npm](https://npmjs.com) installé. Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les packages nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu 'trois points' en haut à droite du navigateur pour accéder au panneau Extensions. À partir de là, sélectionnez 'Charger un module non empaqueté' pour charger une nouvelle extension. Ouvrez le dossier 'dist' lorsque cela est demandé, et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API de CO2 Signal ([obtenez-en une ici par email](https://www.co2signal.com/) - entrez votre email dans la boîte sur cette page) ainsi que du [code de votre région](http://api.electricitymap.org/v3/zones) correspondant à la [Electricity Map](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois la clé API et la région saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter la consommation énergétique de votre région et vous donner une indication sur les activités énergivores qui seraient appropriées à réaliser. Le concept derrière ce système de 'point' m'a été inspiré par l'extension [Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "cbaf73f94a9ab4c680a10ef871e92948",
|
||||
"translation_date": "2025-08-23T23:49:34+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.es.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code complet
|
||||
|
||||
En utilisant l'API CO2 Signal de tmrow pour suivre la consommation d'électricité, créez une extension de navigateur afin d'avoir un rappel directement dans votre navigateur sur la consommation électrique de votre région. L'utilisation de cette extension ad hoc vous aidera à prendre des décisions concernant vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Pour commencer
|
||||
|
||||
Vous devrez avoir [npm](https://npmjs.com) installé. Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les paquets nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu des 'trois points' dans le coin supérieur droit du navigateur pour accéder au panneau Extensions. De là, sélectionnez 'Charger sans empaquetage' pour ajouter une nouvelle extension. Ouvrez le dossier 'dist' lorsque cela vous est demandé, et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API CO2 Signal ([obtenez-en une ici par e-mail](https://www.co2signal.com/) - entrez votre adresse e-mail dans le champ sur cette page) ainsi que du [code de votre région](http://api.electricitymap.org/v3/zones) correspondant à la [carte de l'électricité](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois que la clé API et la région sont saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter la consommation d'énergie de votre région et vous donner une indication sur les activités à forte consommation d'énergie qui seraient appropriées pour vous. Le concept derrière ce système de "points" m'a été inspiré par l'[extension Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "9361268ca430b2579375009e1eceb5e5",
|
||||
"translation_date": "2025-08-23T23:52:15+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.fr.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code Complété
|
||||
|
||||
En utilisant l'API CO2 Signal de tmrow pour suivre la consommation d'électricité, créez une extension de navigateur afin d'avoir un rappel directement dans votre navigateur sur la consommation d'électricité de votre région. L'utilisation de cette extension vous aidera à prendre des décisions éclairées sur vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Pour commencer
|
||||
|
||||
Vous devrez avoir [npm](https://npmjs.com) installé. Téléchargez une copie de ce code dans un dossier de votre ordinateur.
|
||||
|
||||
Installez tous les packages requis :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour installer sur Edge, utilisez le menu 'trois points' dans le coin supérieur droit du navigateur pour accéder au panneau Extensions. À partir de là, sélectionnez 'Charger l'extension décompressée' pour ajouter une nouvelle extension. Ouvrez le dossier 'dist' lorsque vous y êtes invité, et l'extension se chargera. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API CO2 Signal ([obtenez-en une ici par e-mail](https://www.co2signal.com/) - entrez votre e-mail dans la case sur cette page) et du [code pour votre région](http://api.electricitymap.org/v3/zones) correspondant à la [Carte de l'électricité](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois que la clé API et la région sont saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter la consommation d'énergie de votre région. Cela vous donnera un indicateur sur les activités énergivores qu'il serait pertinent d'effectuer. Le concept derrière ce système de 'points' m'a été inspiré par l'[extension Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "dd58ae1b7707034f055718c1b68bc8de",
|
||||
"translation_date": "2025-08-23T23:50:29+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.hi.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code complet
|
||||
|
||||
Utilisation de l'API CO2 Signal de tmrow pour suivre la consommation d'électricité, création d'une extension de navigateur qui vous rappelle à quel point l'utilisation de l'électricité est intense dans votre région via votre navigateur. En utilisant cette extension de manière ad hoc, vous pourrez prendre des décisions basées sur ces informations pour ajuster vos activités.
|
||||
|
||||

|
||||
|
||||
## Commencer
|
||||
|
||||
Vous devez installer [npm](https://npmjs.com). Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les packages nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Créez l'extension avec Webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu 'trois points' en haut à droite du navigateur pour trouver le panneau des extensions. À partir de là, sélectionnez 'Charger sans empaquetage' pour charger une nouvelle extension. Dans l'invite, ouvrez le dossier 'dist' et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour CO2 Signal ([obtenez-la ici par email](https://www.co2signal.com/) - entrez votre email dans la boîte sur cette page) et [le code de votre région](http://api.electricitymap.org/v3/zones) sur [Electricity Map](https://www.electricitymap.org/map) (par exemple, à Boston, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois la clé API et le code de région saisis dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter la consommation énergétique de votre région et vous donner un indicateur des activités énergivores qui seraient appropriées. Le concept derrière ce système de 'point' m'a été inspiré par l'extension [Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "9a6b22a2eff0f499b66236be973b24ad",
|
||||
"translation_date": "2025-08-23T23:53:06+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.it.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension du navigateur Carbon Trigger : code pour commencer
|
||||
|
||||
Vous utiliserez l'API Signal CO2 de tmrow pour surveiller l'utilisation de l'électricité et créer une extension de navigateur afin d'avoir un rappel directement dans votre navigateur sur l'impact de l'utilisation de l'électricité dans votre région. L'utilisation de cette extension sur mesure vous aidera à évaluer vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Pour commencer
|
||||
|
||||
Assurez-vous que [npm](https://npmjs.com) est installé. Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les paquets nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Créez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu "trois points" dans le coin supérieur droit du navigateur pour accéder au panneau Extensions. Si ce n'est pas déjà activé, activez le Mode développeur (en bas à gauche). Sélectionnez "Charger non empaqueté" pour ajouter une nouvelle extension. Ouvrez le dossier "dist" lorsque le prompt s'affiche, et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API CO2 Signal (vous pouvez [l'obtenir ici par e-mail](https://www.co2signal.com/) - entrez votre adresse e-mail dans la case sur cette page) ainsi que du [code de votre région](http://api.electricitymap.org/v3/zones) correspondant à la [carte électrique](https://www.electricitymap.org/map) (à Boston, par exemple, "US-NEISO").
|
||||
|
||||

|
||||
|
||||
Une fois que la clé API et la région ont été saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter l'utilisation énergétique de la région et fournir une indication sur les activités à forte consommation énergétique qui seraient appropriées à réaliser. Le concept derrière ce système de "points" a été inspiré par l' [extension Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "3f5e6821e0febccfc5d05e7c944d9e3d",
|
||||
"translation_date": "2025-08-23T23:53:59+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.ja.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code final
|
||||
|
||||
Construisez une extension de navigateur qui utilise l'API CO2 Signal de tmrow pour suivre la consommation d'électricité dans votre région et afficher un rappel sur votre navigateur indiquant à quel point l'utilisation d'énergie est élevée. En utilisant cette extension de manière ad hoc, vous pouvez prendre des décisions basées sur ces informations pour vos activités.
|
||||
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
Vous devez avoir [npm](https://npmjs.com) installé. Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les packages nécessaires.
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack.
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, trouvez le panneau "Extensions" via le menu "trois points" en haut à droite du navigateur. À partir de là, sélectionnez "Load Unpacked" pour charger la nouvelle extension. Lorsque vous êtes invité, ouvrez le dossier "dist" et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API de l'API CO2 Signal ([obtenez-en une ici par email](https://www.co2signal.com/) - entrez votre email dans la boîte sur cette page) et du [code correspondant à votre région](http://api.electricitymap.org/v3/zones) sur [Electricity Map](https://www.electricitymap.org/map) (par exemple, pour Boston, utilisez 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois que vous avez entré la clé API et la région dans l'interface de l'extension, un point coloré apparaîtra dans la barre d'extensions de votre navigateur. Ce point reflète la consommation d'énergie de votre région et vous indique quelles activités nécessitant de l'énergie sont appropriées. Le concept de ce système de "point" m'a été inspiré par l'extension [Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "21b364c158c8e4f698de65eeac16c9fe",
|
||||
"translation_date": "2025-08-23T23:51:23+00:00",
|
||||
"source_file": "5-browser-extension/solution/translation/README.ms.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de Navigateur Carbon Trigger : Code Complet
|
||||
|
||||
En utilisant l'API CO2 Signal de tmrow pour surveiller la consommation d'électricité, créez une extension de navigateur qui vous alerte sur l'impact énergétique de votre région. Cette extension vous aidera à prendre des décisions éclairées sur vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Commencez ici
|
||||
|
||||
Vous devez installer [npm](https://npmjs.com). Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les packages nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu 'trois points' dans le coin supérieur droit du navigateur pour accéder au panneau Extensions. De là, sélectionnez 'Charger un package non empaqueté' pour ajouter une nouvelle extension. Ouvrez le dossier 'dist' lorsque demandé, et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API CO2 Signal ([obtenez-en une ici par e-mail](https://www.co2signal.com/) - entrez votre e-mail dans la boîte sur cette page) et [le code de votre région](http://api.electricitymap.org/v3/zones) correspondant à [Electricity Map](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois la clé API et la région saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur changera pour refléter la consommation énergétique de votre région et vous donnera des indications sur les activités énergivores adaptées à ce moment. Le concept derrière ce système de 'point' m'a été inspiré par [l'extension de navigateur Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,39 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "26fd39046d264ba185dcb086d3a8cf3e",
|
||||
"translation_date": "2025-08-23T23:41:42+00:00",
|
||||
"source_file": "5-browser-extension/start/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Extension de navigateur Carbon Trigger : Code de démarrage
|
||||
|
||||
En utilisant l'API CO2 Signal de tmrow pour suivre la consommation d'électricité, créez une extension de navigateur afin d'avoir un rappel directement dans votre navigateur sur l'intensité de la consommation d'électricité dans votre région. Utiliser cette extension de manière ponctuelle vous aidera à prendre des décisions sur vos activités en fonction de ces informations.
|
||||
|
||||

|
||||
|
||||
## Premiers pas
|
||||
|
||||
Vous devrez avoir [npm](https://npmjs.com) installé. Téléchargez une copie de ce code dans un dossier sur votre ordinateur.
|
||||
|
||||
Installez tous les packages nécessaires :
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construisez l'extension avec webpack :
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Pour l'installer sur Edge, utilisez le menu 'trois points' en haut à droite du navigateur pour accéder au panneau Extensions. À partir de là, sélectionnez 'Charger un pack non empaqueté' pour charger une nouvelle extension. Ouvrez le dossier 'dist' lorsque vous y êtes invité, et l'extension sera chargée. Pour l'utiliser, vous aurez besoin d'une clé API pour l'API CO2 Signal ([obtenez-en une ici par email](https://www.co2signal.com/) - entrez votre email dans la boîte sur cette page) et du [code de votre région](http://api.electricitymap.org/v3/zones) correspondant à la [Electricity Map](https://www.electricitymap.org/map) (à Boston, par exemple, j'utilise 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Une fois la clé API et la région saisies dans l'interface de l'extension, le point coloré dans la barre d'extension du navigateur devrait changer pour refléter la consommation énergétique de votre région et vous donner une indication sur les activités énergivores qui seraient appropriées à réaliser. Le concept derrière ce système de 'point' m'a été inspiré par l'extension [Energy Lollipop](https://energylollipop.com/) pour les émissions en Californie.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,236 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
|
||||
"translation_date": "2025-08-23T23:05:15+00:00",
|
||||
"source_file": "6-space-game/1-introduction/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 1 : Introduction
|
||||
|
||||

|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/29)
|
||||
|
||||
### Héritage et composition dans le développement de jeux
|
||||
|
||||
Dans les leçons précédentes, il n'était pas nécessaire de se préoccuper de l'architecture des applications que vous avez créées, car les projets étaient de petite envergure. Cependant, lorsque vos applications prennent de l'ampleur, les décisions architecturales deviennent plus importantes. Il existe deux approches principales pour créer des applications plus complexes en JavaScript : *composition* ou *héritage*. Ces deux approches ont leurs avantages et inconvénients, mais expliquons-les dans le contexte d'un jeu.
|
||||
|
||||
✅ L'un des livres les plus célèbres sur la programmation traite des [design patterns](https://en.wikipedia.org/wiki/Design_Patterns).
|
||||
|
||||
Dans un jeu, vous avez des `objets de jeu`, qui sont des objets présents à l'écran. Cela signifie qu'ils ont une position dans un système de coordonnées cartésiennes, caractérisée par des coordonnées `x` et `y`. En développant un jeu, vous remarquerez que tous vos objets de jeu ont des propriétés standard, communes à chaque jeu que vous créez, notamment des éléments qui sont :
|
||||
|
||||
- **basés sur la localisation** La plupart, sinon tous, les éléments de jeu sont basés sur la localisation. Cela signifie qu'ils ont une position, un `x` et un `y`.
|
||||
- **mobiles** Ce sont des objets qui peuvent se déplacer vers une nouvelle position. Il s'agit généralement d'un héros, d'un monstre ou d'un PNJ (personnage non joueur), mais pas, par exemple, d'un objet statique comme un arbre.
|
||||
- **auto-destructeurs** Ces objets n'existent que pendant une période définie avant de se préparer à être supprimés. Cela est généralement représenté par un booléen `mort` ou `détruit` qui indique au moteur de jeu que cet objet ne doit plus être affiché.
|
||||
- **temps de recharge** Le 'temps de recharge' est une propriété typique des objets de courte durée. Un exemple typique est un morceau de texte ou un effet graphique comme une explosion qui ne doit être visible que pendant quelques millisecondes.
|
||||
|
||||
✅ Pensez à un jeu comme Pac-Man. Pouvez-vous identifier les quatre types d'objets mentionnés ci-dessus dans ce jeu ?
|
||||
|
||||
### Exprimer des comportements
|
||||
|
||||
Tout ce que nous avons décrit ci-dessus représente des comportements que les objets de jeu peuvent avoir. Alors, comment les coder ? Nous pouvons exprimer ces comportements sous forme de méthodes associées à des classes ou des objets.
|
||||
|
||||
**Classes**
|
||||
|
||||
L'idée est d'utiliser des `classes` en combinaison avec l'`héritage` pour ajouter un certain comportement à une classe.
|
||||
|
||||
✅ L'héritage est un concept important à comprendre. Apprenez-en davantage grâce à [l'article de MDN sur l'héritage](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
|
||||
|
||||
Exprimé en code, un objet de jeu peut ressembler à ceci :
|
||||
|
||||
```javascript
|
||||
|
||||
//set up the class GameObject
|
||||
class GameObject {
|
||||
constructor(x, y, type) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
//this class will extend the GameObject's inherent class properties
|
||||
class Movable extends GameObject {
|
||||
constructor(x,y, type) {
|
||||
super(x,y, type)
|
||||
}
|
||||
|
||||
//this movable object can be moved on the screen
|
||||
moveTo(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
//this is a specific class that extends the Movable class, so it can take advantage of all the properties that it inherits
|
||||
class Hero extends Movable {
|
||||
constructor(x,y) {
|
||||
super(x,y, 'Hero')
|
||||
}
|
||||
}
|
||||
|
||||
//this class, on the other hand, only inherits the GameObject properties
|
||||
class Tree extends GameObject {
|
||||
constructor(x,y) {
|
||||
super(x,y, 'Tree')
|
||||
}
|
||||
}
|
||||
|
||||
//a hero can move...
|
||||
const hero = new Hero();
|
||||
hero.moveTo(5,5);
|
||||
|
||||
//but a tree cannot
|
||||
const tree = new Tree();
|
||||
```
|
||||
|
||||
✅ Prenez quelques minutes pour imaginer un héros de Pac-Man (Inky, Pinky ou Blinky, par exemple) et comment il serait écrit en JavaScript.
|
||||
|
||||
**Composition**
|
||||
|
||||
Une autre façon de gérer l'héritage des objets est d'utiliser la *composition*. Les objets expriment alors leur comportement comme ceci :
|
||||
|
||||
```javascript
|
||||
//create a constant gameObject
|
||||
const gameObject = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
type: ''
|
||||
};
|
||||
|
||||
//...and a constant movable
|
||||
const movable = {
|
||||
moveTo(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
//then the constant movableObject is composed of the gameObject and movable constants
|
||||
const movableObject = {...gameObject, ...movable};
|
||||
|
||||
//then create a function to create a new Hero who inherits the movableObject properties
|
||||
function createHero(x, y) {
|
||||
return {
|
||||
...movableObject,
|
||||
x,
|
||||
y,
|
||||
type: 'Hero'
|
||||
}
|
||||
}
|
||||
//...and a static object that inherits only the gameObject properties
|
||||
function createStatic(x, y, type) {
|
||||
return {
|
||||
...gameObject
|
||||
x,
|
||||
y,
|
||||
type
|
||||
}
|
||||
}
|
||||
//create the hero and move it
|
||||
const hero = createHero(10,10);
|
||||
hero.moveTo(5,5);
|
||||
//and create a static tree which only stands around
|
||||
const tree = createStatic(0,0, 'Tree');
|
||||
```
|
||||
|
||||
**Quel modèle devrais-je utiliser ?**
|
||||
|
||||
C'est à vous de choisir le modèle que vous préférez. JavaScript prend en charge ces deux paradigmes.
|
||||
|
||||
--
|
||||
|
||||
Un autre modèle courant dans le développement de jeux traite du problème de gestion de l'expérience utilisateur et des performances du jeu.
|
||||
|
||||
## Modèle Pub/Sub
|
||||
|
||||
✅ Pub/Sub signifie 'publish-subscribe' (publier-s'abonner)
|
||||
|
||||
Ce modèle repose sur l'idée que les différentes parties de votre application ne devraient pas se connaître entre elles. Pourquoi cela ? Cela facilite la compréhension globale de ce qui se passe lorsque les différentes parties sont séparées. Cela permet également de modifier soudainement un comportement si nécessaire. Comment y parvenir ? En établissant certains concepts :
|
||||
|
||||
- **message** : Un message est généralement une chaîne de texte accompagnée d'une charge utile optionnelle (un morceau de données qui clarifie le contenu du message). Un message typique dans un jeu peut être `KEY_PRESSED_ENTER`.
|
||||
- **éditeur** : Cet élément *publie* un message et l'envoie à tous les abonnés.
|
||||
- **abonné** : Cet élément *écoute* des messages spécifiques et exécute une tâche en réponse à la réception de ce message, comme tirer un laser.
|
||||
|
||||
L'implémentation est assez petite en taille mais c'est un modèle très puissant. Voici comment il peut être implémenté :
|
||||
|
||||
```javascript
|
||||
//set up an EventEmitter class that contains listeners
|
||||
class EventEmitter {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
}
|
||||
//when a message is received, let the listener to handle its payload
|
||||
on(message, listener) {
|
||||
if (!this.listeners[message]) {
|
||||
this.listeners[message] = [];
|
||||
}
|
||||
this.listeners[message].push(listener);
|
||||
}
|
||||
//when a message is sent, send it to a listener with some payload
|
||||
emit(message, payload = null) {
|
||||
if (this.listeners[message]) {
|
||||
this.listeners[message].forEach(l => l(message, payload))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Pour utiliser le code ci-dessus, nous pouvons créer une implémentation très simple :
|
||||
|
||||
```javascript
|
||||
//set up a message structure
|
||||
const Messages = {
|
||||
HERO_MOVE_LEFT: 'HERO_MOVE_LEFT'
|
||||
};
|
||||
//invoke the eventEmitter you set up above
|
||||
const eventEmitter = new EventEmitter();
|
||||
//set up a hero
|
||||
const hero = createHero(0,0);
|
||||
//let the eventEmitter know to watch for messages pertaining to the hero moving left, and act on it
|
||||
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
|
||||
hero.move(5,0);
|
||||
});
|
||||
|
||||
//set up the window to listen for the keyup event, specifically if the left arrow is hit, emit a message to move the hero left
|
||||
window.addEventListener('keyup', (evt) => {
|
||||
if (evt.key === 'ArrowLeft') {
|
||||
eventEmitter.emit(Messages.HERO_MOVE_LEFT)
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Dans l'exemple ci-dessus, nous connectons un événement clavier, `ArrowLeft`, et envoyons le message `HERO_MOVE_LEFT`. Nous écoutons ce message et déplaçons le `hero` en conséquence. La force de ce modèle réside dans le fait que l'écouteur d'événements et le héros ne se connaissent pas. Vous pouvez remapper la touche `ArrowLeft` à la touche `A`. De plus, il serait possible de faire quelque chose de complètement différent sur `ArrowLeft` en modifiant légèrement la fonction `on` de l'eventEmitter :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
|
||||
hero.move(5,0);
|
||||
});
|
||||
```
|
||||
|
||||
À mesure que les choses deviennent plus complexes lorsque votre jeu grandit, ce modèle reste constant en termes de complexité et votre code reste propre. Il est fortement recommandé d'adopter ce modèle.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Réfléchissez à la manière dont le modèle pub-sub peut améliorer un jeu. Quelles parties devraient émettre des événements, et comment le jeu devrait-il y réagir ? C'est le moment de faire preuve de créativité en imaginant un nouveau jeu et le comportement de ses différentes parties.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/30)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Apprenez-en davantage sur le modèle Pub/Sub en [lisant à ce sujet](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Créez une maquette de jeu](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "009bdedee9cc82988264be8cb31f9bf4",
|
||||
"translation_date": "2025-08-23T23:06:27+00:00",
|
||||
"source_file": "6-space-game/1-introduction/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une maquette de jeu
|
||||
|
||||
## Instructions
|
||||
|
||||
En utilisant les exemples de code de la leçon, écrivez une représentation d'un jeu que vous appréciez. Il devra s'agir d'un jeu simple, mais l'objectif est d'utiliser soit le modèle de classe, soit le modèle de composition, ainsi que le modèle pub/sub pour montrer comment un jeu pourrait être lancé. Faites preuve de créativité !
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------- |
|
||||
| | Trois éléments sont placés à l'écran et manipulés | Deux éléments sont placés à l'écran et manipulés | Un élément est placé à l'écran et manipulé |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,228 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
|
||||
"translation_date": "2025-08-23T22:58:47+00:00",
|
||||
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 2 : Dessiner le héros et les monstres sur le canvas
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/31)
|
||||
|
||||
## Le Canvas
|
||||
|
||||
Le canvas est un élément HTML qui, par défaut, n'a aucun contenu ; c'est une toile vierge. Vous devez y ajouter du contenu en dessinant dessus.
|
||||
|
||||
✅ Lisez [plus d'informations sur l'API Canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API) sur MDN.
|
||||
|
||||
Voici comment il est généralement déclaré, en tant que partie du corps de la page :
|
||||
|
||||
```html
|
||||
<canvas id="myCanvas" width="200" height="100"></canvas>
|
||||
```
|
||||
|
||||
Ci-dessus, nous définissons les propriétés `id`, `width` et `height`.
|
||||
|
||||
- `id` : définissez cela pour obtenir une référence lorsque vous devez interagir avec le canvas.
|
||||
- `width` : c'est la largeur de l'élément.
|
||||
- `height` : c'est la hauteur de l'élément.
|
||||
|
||||
## Dessiner des formes simples
|
||||
|
||||
Le canvas utilise un système de coordonnées cartésiennes pour dessiner des éléments. Il utilise donc un axe x et un axe y pour exprimer où quelque chose est situé. La position `0,0` est le coin supérieur gauche, et le coin inférieur droit correspond à la largeur et à la hauteur que vous avez définies pour le canvas.
|
||||
|
||||

|
||||
> Image tirée de [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
|
||||
|
||||
Pour dessiner sur l'élément canvas, vous devez suivre les étapes suivantes :
|
||||
|
||||
1. **Obtenir une référence** à l'élément Canvas.
|
||||
2. **Obtenir une référence** au contexte qui se trouve sur l'élément Canvas.
|
||||
3. **Effectuer une opération de dessin** en utilisant le contexte.
|
||||
|
||||
Le code pour les étapes ci-dessus ressemble généralement à ceci :
|
||||
|
||||
```javascript
|
||||
// draws a red rectangle
|
||||
//1. get the canvas reference
|
||||
canvas = document.getElementById("myCanvas");
|
||||
|
||||
//2. set the context to 2D to draw basic shapes
|
||||
ctx = canvas.getContext("2d");
|
||||
|
||||
//3. fill it with the color red
|
||||
ctx.fillStyle = 'red';
|
||||
|
||||
//4. and draw a rectangle with these parameters, setting location and size
|
||||
ctx.fillRect(0,0, 200, 200) // x,y,width, height
|
||||
```
|
||||
|
||||
✅ L'API Canvas se concentre principalement sur les formes 2D, mais vous pouvez également dessiner des éléments 3D sur un site web ; pour cela, vous pourriez utiliser l'[API WebGL](https://developer.mozilla.org/docs/Web/API/WebGL_API).
|
||||
|
||||
Vous pouvez dessiner toutes sortes de choses avec l'API Canvas, comme :
|
||||
|
||||
- **Formes géométriques** : nous avons déjà montré comment dessiner un rectangle, mais il y a bien plus que vous pouvez dessiner.
|
||||
- **Texte** : vous pouvez dessiner du texte avec n'importe quelle police et couleur.
|
||||
- **Images** : vous pouvez dessiner une image à partir d'une ressource comme un fichier .jpg ou .png, par exemple.
|
||||
|
||||
✅ Essayez-le ! Vous savez comment dessiner un rectangle, pouvez-vous dessiner un cercle sur une page ? Regardez quelques dessins intéressants réalisés avec Canvas sur CodePen. Voici un [exemple particulièrement impressionnant](https://codepen.io/dissimulate/pen/KrAwx).
|
||||
|
||||
## Charger et dessiner une ressource image
|
||||
|
||||
Vous chargez une ressource image en créant un objet `Image` et en définissant sa propriété `src`. Ensuite, vous écoutez l'événement `load` pour savoir quand elle est prête à être utilisée. Le code ressemble à ceci :
|
||||
|
||||
### Charger une ressource
|
||||
|
||||
```javascript
|
||||
const img = new Image();
|
||||
img.src = 'path/to/my/image.png';
|
||||
img.onload = () => {
|
||||
// image loaded and ready to be used
|
||||
}
|
||||
```
|
||||
|
||||
### Modèle de chargement de ressource
|
||||
|
||||
Il est recommandé d'encapsuler le code ci-dessus dans une structure comme celle-ci, afin qu'il soit plus facile à utiliser et que vous ne tentiez de le manipuler que lorsqu'il est complètement chargé :
|
||||
|
||||
```javascript
|
||||
function loadAsset(path) {
|
||||
return new Promise((resolve) => {
|
||||
const img = new Image();
|
||||
img.src = path;
|
||||
img.onload = () => {
|
||||
// image loaded and ready to be used
|
||||
resolve(img);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// use like so
|
||||
|
||||
async function run() {
|
||||
const heroImg = await loadAsset('hero.png')
|
||||
const monsterImg = await loadAsset('monster.png')
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Pour dessiner des ressources de jeu sur un écran, votre code ressemblerait à ceci :
|
||||
|
||||
```javascript
|
||||
async function run() {
|
||||
const heroImg = await loadAsset('hero.png')
|
||||
const monsterImg = await loadAsset('monster.png')
|
||||
|
||||
canvas = document.getElementById("myCanvas");
|
||||
ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(heroImg, canvas.width/2,canvas.height/2);
|
||||
ctx.drawImage(monsterImg, 0,0);
|
||||
}
|
||||
```
|
||||
|
||||
## Il est maintenant temps de commencer à construire votre jeu
|
||||
|
||||
### Ce que vous allez construire
|
||||
|
||||
Vous allez créer une page web avec un élément Canvas. Elle doit afficher un écran noir de `1024*768`. Nous vous avons fourni deux images :
|
||||
|
||||
- Vaisseau du héros
|
||||
|
||||

|
||||
|
||||
- Monstre 5*5
|
||||
|
||||

|
||||
|
||||
### Étapes recommandées pour commencer le développement
|
||||
|
||||
Trouvez les fichiers qui ont été créés pour vous dans le sous-dossier `your-work`. Il devrait contenir les éléments suivants :
|
||||
|
||||
```bash
|
||||
-| assets
|
||||
-| enemyShip.png
|
||||
-| player.png
|
||||
-| index.html
|
||||
-| app.js
|
||||
-| package.json
|
||||
```
|
||||
|
||||
Ouvrez une copie de ce dossier dans Visual Studio Code. Vous devez avoir un environnement de développement local configuré, de préférence avec Visual Studio Code, NPM et Node installés. Si vous n'avez pas configuré `npm` sur votre ordinateur, [voici comment faire](https://www.npmjs.com/get-npm).
|
||||
|
||||
Commencez votre projet en naviguant vers le dossier `your_work` :
|
||||
|
||||
```bash
|
||||
cd your-work
|
||||
npm start
|
||||
```
|
||||
|
||||
Cela démarrera un serveur HTTP à l'adresse `http://localhost:5000`. Ouvrez un navigateur et entrez cette adresse. C'est une page blanche pour l'instant, mais cela va changer.
|
||||
|
||||
> Remarque : pour voir les modifications sur votre écran, actualisez votre navigateur.
|
||||
|
||||
### Ajouter du code
|
||||
|
||||
Ajoutez le code nécessaire dans `your-work/app.js` pour résoudre les points suivants :
|
||||
|
||||
1. **Dessiner** un canvas avec un fond noir
|
||||
> Astuce : ajoutez deux lignes sous le TODO approprié dans `/app.js`, en définissant l'élément `ctx` comme noir et les coordonnées haut/gauche à 0,0, avec la hauteur et la largeur égales à celles du canvas.
|
||||
2. **Charger** les textures
|
||||
> Astuce : ajoutez les images du joueur et des ennemis en utilisant `await loadTexture` et en passant le chemin de l'image. Vous ne les verrez pas encore à l'écran !
|
||||
3. **Dessiner** le héros au centre de l'écran dans la moitié inférieure
|
||||
> Astuce : utilisez l'API `drawImage` pour dessiner `heroImg` sur l'écran, en définissant `canvas.width / 2 - 45` et `canvas.height - canvas.height / 4)`.
|
||||
4. **Dessiner** 5*5 monstres
|
||||
> Astuce : maintenant, vous pouvez décommenter le code pour dessiner les ennemis sur l'écran. Ensuite, allez dans la fonction `createEnemies` et complétez-la.
|
||||
|
||||
Tout d'abord, configurez quelques constantes :
|
||||
|
||||
```javascript
|
||||
const MONSTER_TOTAL = 5;
|
||||
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
|
||||
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
|
||||
const STOP_X = START_X + MONSTER_WIDTH;
|
||||
```
|
||||
|
||||
Ensuite, créez une boucle pour dessiner le tableau de monstres sur l'écran :
|
||||
|
||||
```javascript
|
||||
for (let x = START_X; x < STOP_X; x += 98) {
|
||||
for (let y = 0; y < 50 * 5; y += 50) {
|
||||
ctx.drawImage(enemyImg, x, y);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Résultat
|
||||
|
||||
Le résultat final devrait ressembler à ceci :
|
||||
|
||||

|
||||
|
||||
## Solution
|
||||
|
||||
Essayez de résoudre cela vous-même d'abord, mais si vous êtes bloqué, consultez une [solution](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Vous avez appris à dessiner avec l'API Canvas orientée 2D ; jetez un œil à l'[API WebGL](https://developer.mozilla.org/docs/Web/API/WebGL_API) et essayez de dessiner un objet 3D.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/32)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Apprenez-en davantage sur l'API Canvas en [lisant à ce sujet](https://developer.mozilla.org/docs/Web/API/Canvas_API).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Amusez-vous avec l'API Canvas](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous ne sommes pas responsables des malentendus ou des interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "ca1cf78a4c60df77ab32a154ec024d7f",
|
||||
"translation_date": "2025-08-23T23:00:09+00:00",
|
||||
"source_file": "6-space-game/2-drawing-to-canvas/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Jouez avec l'API Canvas
|
||||
|
||||
## Instructions
|
||||
|
||||
Choisissez un élément de l'API Canvas et créez quelque chose d'intéressant autour de celui-ci. Pouvez-vous créer une petite galaxie d'étoiles répétées ? Pouvez-vous créer une texture intéressante de lignes colorées ? Vous pouvez consulter CodePen pour vous inspirer (mais ne copiez pas).
|
||||
|
||||
## Critères d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | --------------------------------------------------------- | ----------------------------------- | --------------------- |
|
||||
| | Le code soumis montre une texture ou une forme intéressante | Le code est soumis, mais ne fonctionne pas | Aucun code n'est soumis |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,400 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
|
||||
"translation_date": "2025-08-23T22:56:13+00:00",
|
||||
"source_file": "6-space-game/3-moving-elements-around/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 3 : Ajouter du mouvement
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/33)
|
||||
|
||||
Les jeux ne sont pas très amusants tant que vous n'avez pas des aliens qui se déplacent à l'écran ! Dans ce jeu, nous allons utiliser deux types de mouvements :
|
||||
|
||||
- **Mouvement clavier/souris** : lorsque l'utilisateur interagit avec le clavier ou la souris pour déplacer un objet à l'écran.
|
||||
- **Mouvement induit par le jeu** : lorsque le jeu déplace un objet à un certain intervalle de temps.
|
||||
|
||||
Alors, comment déplace-t-on des objets à l'écran ? Tout repose sur les coordonnées cartésiennes : on modifie la position (x, y) de l'objet, puis on redessine l'écran.
|
||||
|
||||
En général, voici les étapes nécessaires pour accomplir un *mouvement* à l'écran :
|
||||
|
||||
1. **Définir une nouvelle position** pour un objet ; cela est nécessaire pour donner l'impression que l'objet s'est déplacé.
|
||||
2. **Effacer l'écran**, l'écran doit être nettoyé entre chaque dessin. On peut le faire en dessinant un rectangle rempli d'une couleur de fond.
|
||||
3. **Redessiner l'objet** à sa nouvelle position. En faisant cela, on parvient finalement à déplacer l'objet d'un endroit à un autre.
|
||||
|
||||
Voici à quoi cela peut ressembler en code :
|
||||
|
||||
```javascript
|
||||
//set the hero's location
|
||||
hero.x += 5;
|
||||
// clear the rectangle that hosts the hero
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// redraw the game background and hero
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.fillStyle = "black";
|
||||
ctx.drawImage(heroImg, hero.x, hero.y);
|
||||
```
|
||||
|
||||
✅ Pouvez-vous penser à une raison pour laquelle redessiner votre héros plusieurs fois par seconde pourrait entraîner des coûts de performance ? Lisez à propos des [alternatives à ce modèle](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
|
||||
|
||||
## Gérer les événements clavier
|
||||
|
||||
Vous gérez les événements en attachant des événements spécifiques à du code. Les événements clavier sont déclenchés sur l'ensemble de la fenêtre, tandis que les événements souris comme un `click` peuvent être liés à un élément spécifique. Nous utiliserons des événements clavier tout au long de ce projet.
|
||||
|
||||
Pour gérer un événement, vous devez utiliser la méthode `addEventListener()` de la fenêtre et lui fournir deux paramètres d'entrée. Le premier paramètre est le nom de l'événement, par exemple `keyup`. Le second paramètre est la fonction qui doit être invoquée lorsque l'événement se produit.
|
||||
|
||||
Voici un exemple :
|
||||
|
||||
```javascript
|
||||
window.addEventListener('keyup', (evt) => {
|
||||
// `evt.key` = string representation of the key
|
||||
if (evt.key === 'ArrowUp') {
|
||||
// do something
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Pour les événements clavier, il existe deux propriétés sur l'événement que vous pouvez utiliser pour voir quelle touche a été pressée :
|
||||
|
||||
- `key`, c'est une représentation sous forme de chaîne de la touche pressée, par exemple `ArrowUp`.
|
||||
- `keyCode`, c'est une représentation sous forme de nombre, par exemple `37`, qui correspond à `ArrowLeft`.
|
||||
|
||||
✅ La manipulation des événements clavier est utile en dehors du développement de jeux. À quels autres usages pouvez-vous penser pour cette technique ?
|
||||
|
||||
### Touches spéciales : une mise en garde
|
||||
|
||||
Il existe certaines touches *spéciales* qui affectent la fenêtre. Cela signifie que si vous écoutez un événement `keyup` et que vous utilisez ces touches spéciales pour déplacer votre héros, cela entraînera également un défilement horizontal. Pour cette raison, vous pourriez vouloir *désactiver* ce comportement intégré du navigateur lorsque vous développez votre jeu. Vous avez besoin de code comme celui-ci :
|
||||
|
||||
```javascript
|
||||
let onKeyDown = function (e) {
|
||||
console.log(e.keyCode);
|
||||
switch (e.keyCode) {
|
||||
case 37:
|
||||
case 39:
|
||||
case 38:
|
||||
case 40: // Arrow keys
|
||||
case 32:
|
||||
e.preventDefault();
|
||||
break; // Space
|
||||
default:
|
||||
break; // do not block other keys
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', onKeyDown);
|
||||
```
|
||||
|
||||
Le code ci-dessus garantira que les touches fléchées et la touche espace ont leur comportement *par défaut* désactivé. Le mécanisme de *désactivation* se produit lorsque nous appelons `e.preventDefault()`.
|
||||
|
||||
## Mouvement induit par le jeu
|
||||
|
||||
Nous pouvons faire bouger des objets par eux-mêmes en utilisant des minuteries comme les fonctions `setTimeout()` ou `setInterval()` qui mettent à jour la position de l'objet à chaque tick ou intervalle de temps. Voici à quoi cela peut ressembler :
|
||||
|
||||
```javascript
|
||||
let id = setInterval(() => {
|
||||
//move the enemy on the y axis
|
||||
enemy.y += 10;
|
||||
})
|
||||
```
|
||||
|
||||
## La boucle de jeu
|
||||
|
||||
La boucle de jeu est un concept qui est essentiellement une fonction invoquée à intervalles réguliers. On l'appelle la boucle de jeu car tout ce qui doit être visible pour l'utilisateur est dessiné dans cette boucle. La boucle de jeu utilise tous les objets du jeu qui en font partie, en les dessinant tous sauf si, pour une raison quelconque, ils ne doivent plus faire partie du jeu. Par exemple, si un objet est un ennemi qui a été touché par un laser et explose, il ne fait plus partie de la boucle de jeu actuelle (vous en apprendrez davantage à ce sujet dans les leçons suivantes).
|
||||
|
||||
Voici à quoi une boucle de jeu peut typiquement ressembler, exprimée en code :
|
||||
|
||||
```javascript
|
||||
let gameLoopId = setInterval(() =>
|
||||
function gameLoop() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
drawHero();
|
||||
drawEnemies();
|
||||
drawStaticObjects();
|
||||
}, 200);
|
||||
```
|
||||
|
||||
La boucle ci-dessus est invoquée toutes les `200` millisecondes pour redessiner le canvas. Vous avez la possibilité de choisir l'intervalle qui convient le mieux à votre jeu.
|
||||
|
||||
## Poursuivre le jeu spatial
|
||||
|
||||
Vous allez prendre le code existant et l'étendre. Soit vous commencez avec le code que vous avez terminé lors de la partie I, soit vous utilisez le code de [Partie II - starter](../../../../6-space-game/3-moving-elements-around/your-work).
|
||||
|
||||
- **Déplacer le héros** : vous ajouterez du code pour permettre de déplacer le héros à l'aide des touches fléchées.
|
||||
- **Déplacer les ennemis** : vous devrez également ajouter du code pour que les ennemis se déplacent de haut en bas à un rythme donné.
|
||||
|
||||
## Étapes recommandées
|
||||
|
||||
Localisez les fichiers qui ont été créés pour vous dans le sous-dossier `your-work`. Il devrait contenir les éléments suivants :
|
||||
|
||||
```bash
|
||||
-| assets
|
||||
-| enemyShip.png
|
||||
-| player.png
|
||||
-| index.html
|
||||
-| app.js
|
||||
-| package.json
|
||||
```
|
||||
|
||||
Vous démarrez votre projet dans le dossier `your_work` en tapant :
|
||||
|
||||
```bash
|
||||
cd your-work
|
||||
npm start
|
||||
```
|
||||
|
||||
Cela démarrera un serveur HTTP à l'adresse `http://localhost:5000`. Ouvrez un navigateur et entrez cette adresse, pour l'instant cela devrait afficher le héros et tous les ennemis ; rien ne bouge - encore !
|
||||
|
||||
### Ajouter du code
|
||||
|
||||
1. **Ajouter des objets dédiés** pour `hero`, `enemy` et `game object`, ils devraient avoir des propriétés `x` et `y`. (Rappelez-vous la partie sur [Héritage ou composition](../README.md)).
|
||||
|
||||
*ASTUCE* `game object` devrait être celui avec `x` et `y` et la capacité de se dessiner sur un canvas.
|
||||
|
||||
>astuce : commencez par ajouter une nouvelle classe GameObject avec son constructeur défini comme ci-dessous, puis dessinez-la sur le canvas :
|
||||
|
||||
```javascript
|
||||
|
||||
class GameObject {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.dead = false;
|
||||
this.type = "";
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.img = undefined;
|
||||
}
|
||||
|
||||
draw(ctx) {
|
||||
ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Maintenant, étendez ce GameObject pour créer le Hero et Enemy.
|
||||
|
||||
```javascript
|
||||
class Hero extends GameObject {
|
||||
constructor(x, y) {
|
||||
...it needs an x, y, type, and speed
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
class Enemy extends GameObject {
|
||||
constructor(x, y) {
|
||||
super(x, y);
|
||||
(this.width = 98), (this.height = 50);
|
||||
this.type = "Enemy";
|
||||
let id = setInterval(() => {
|
||||
if (this.y < canvas.height - this.height) {
|
||||
this.y += 5;
|
||||
} else {
|
||||
console.log('Stopped at', this.y)
|
||||
clearInterval(id);
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Ajouter des gestionnaires d'événements clavier** pour gérer la navigation (déplacer le héros vers le haut/bas gauche/droite).
|
||||
|
||||
*RAPPELEZ-VOUS* c'est un système cartésien, en haut à gauche est `0,0`. Rappelez-vous également d'ajouter du code pour arrêter le *comportement par défaut*.
|
||||
|
||||
>astuce : créez votre fonction onKeyDown et attachez-la à la fenêtre :
|
||||
|
||||
```javascript
|
||||
let onKeyDown = function (e) {
|
||||
console.log(e.keyCode);
|
||||
...add the code from the lesson above to stop default behavior
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", onKeyDown);
|
||||
```
|
||||
|
||||
Vérifiez la console de votre navigateur à ce stade, et observez les frappes de touches qui sont enregistrées.
|
||||
|
||||
3. **Implémenter** le [modèle Pub/Sub](../README.md), cela gardera votre code propre pour les parties restantes.
|
||||
|
||||
Pour réaliser cette dernière partie, vous pouvez :
|
||||
|
||||
1. **Ajouter un écouteur d'événements** sur la fenêtre :
|
||||
|
||||
```javascript
|
||||
window.addEventListener("keyup", (evt) => {
|
||||
if (evt.key === "ArrowUp") {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_UP);
|
||||
} else if (evt.key === "ArrowDown") {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_DOWN);
|
||||
} else if (evt.key === "ArrowLeft") {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_LEFT);
|
||||
} else if (evt.key === "ArrowRight") {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
1. **Créer une classe EventEmitter** pour publier et s'abonner à des messages :
|
||||
|
||||
```javascript
|
||||
class EventEmitter {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
}
|
||||
|
||||
on(message, listener) {
|
||||
if (!this.listeners[message]) {
|
||||
this.listeners[message] = [];
|
||||
}
|
||||
this.listeners[message].push(listener);
|
||||
}
|
||||
|
||||
emit(message, payload = null) {
|
||||
if (this.listeners[message]) {
|
||||
this.listeners[message].forEach((l) => l(message, payload));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. **Ajouter des constantes** et configurer l'EventEmitter :
|
||||
|
||||
```javascript
|
||||
const Messages = {
|
||||
KEY_EVENT_UP: "KEY_EVENT_UP",
|
||||
KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
|
||||
KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
|
||||
KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
|
||||
};
|
||||
|
||||
let heroImg,
|
||||
enemyImg,
|
||||
laserImg,
|
||||
canvas, ctx,
|
||||
gameObjects = [],
|
||||
hero,
|
||||
eventEmitter = new EventEmitter();
|
||||
```
|
||||
|
||||
1. **Initialiser le jeu**
|
||||
|
||||
```javascript
|
||||
function initGame() {
|
||||
gameObjects = [];
|
||||
createEnemies();
|
||||
createHero();
|
||||
|
||||
eventEmitter.on(Messages.KEY_EVENT_UP, () => {
|
||||
hero.y -=5 ;
|
||||
})
|
||||
|
||||
eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
|
||||
hero.y += 5;
|
||||
});
|
||||
|
||||
eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
|
||||
hero.x -= 5;
|
||||
});
|
||||
|
||||
eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => {
|
||||
hero.x += 5;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
1. **Configurer la boucle de jeu**
|
||||
|
||||
Refactorisez la fonction window.onload pour initialiser le jeu et configurer une boucle de jeu à un bon intervalle. Vous ajouterez également un rayon laser :
|
||||
|
||||
```javascript
|
||||
window.onload = async () => {
|
||||
canvas = document.getElementById("canvas");
|
||||
ctx = canvas.getContext("2d");
|
||||
heroImg = await loadTexture("assets/player.png");
|
||||
enemyImg = await loadTexture("assets/enemyShip.png");
|
||||
laserImg = await loadTexture("assets/laserRed.png");
|
||||
|
||||
initGame();
|
||||
let gameLoopId = setInterval(() => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
drawGameObjects(ctx);
|
||||
}, 100)
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
5. **Ajouter du code** pour déplacer les ennemis à un certain intervalle.
|
||||
|
||||
Refactorisez la fonction `createEnemies()` pour créer les ennemis et les ajouter à la nouvelle classe gameObjects :
|
||||
|
||||
```javascript
|
||||
function createEnemies() {
|
||||
const MONSTER_TOTAL = 5;
|
||||
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
|
||||
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
|
||||
const STOP_X = START_X + MONSTER_WIDTH;
|
||||
|
||||
for (let x = START_X; x < STOP_X; x += 98) {
|
||||
for (let y = 0; y < 50 * 5; y += 50) {
|
||||
const enemy = new Enemy(x, y);
|
||||
enemy.img = enemyImg;
|
||||
gameObjects.push(enemy);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
et ajoutez une fonction `createHero()` pour effectuer un processus similaire pour le héros.
|
||||
|
||||
```javascript
|
||||
function createHero() {
|
||||
hero = new Hero(
|
||||
canvas.width / 2 - 45,
|
||||
canvas.height - canvas.height / 4
|
||||
);
|
||||
hero.img = heroImg;
|
||||
gameObjects.push(hero);
|
||||
}
|
||||
```
|
||||
|
||||
et enfin, ajoutez une fonction `drawGameObjects()` pour commencer le dessin :
|
||||
|
||||
```javascript
|
||||
function drawGameObjects(ctx) {
|
||||
gameObjects.forEach(go => go.draw(ctx));
|
||||
}
|
||||
```
|
||||
|
||||
Vos ennemis devraient commencer à avancer vers votre vaisseau spatial héros !
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Comme vous pouvez le constater, votre code peut devenir un "code spaghetti" lorsque vous commencez à ajouter des fonctions, des variables et des classes. Comment pouvez-vous mieux organiser votre code pour qu'il soit plus lisible ? Dessinez un système pour organiser votre code, même s'il reste dans un seul fichier.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/34)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Bien que nous écrivions notre jeu sans utiliser de frameworks, il existe de nombreux frameworks basés sur JavaScript pour le développement de jeux sur canvas. Prenez le temps de faire des [recherches à ce sujet](https://github.com/collections/javascript-game-engines).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Commentez votre code](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "ccfcd8c2932761359fbaff3d6b01ace4",
|
||||
"translation_date": "2025-08-23T22:57:37+00:00",
|
||||
"source_file": "6-space-game/3-moving-elements-around/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Commentez Votre Code
|
||||
|
||||
## Instructions
|
||||
|
||||
Passez en revue votre fichier /app.js actuel dans le dossier de votre jeu, et trouvez des moyens de le commenter et de le structurer. Il est très facile pour le code de devenir chaotique, et c'est maintenant une bonne occasion d'ajouter des commentaires pour garantir que votre code soit lisible et utilisable plus tard.
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------- |
|
||||
| | Le code `app.js` est entièrement commenté et organisé en blocs logiques | Le code `app.js` est suffisamment commenté | Le code `app.js` est quelque peu désorganisé et manque de bons commentaires |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,309 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
|
||||
"translation_date": "2025-08-23T23:01:33+00:00",
|
||||
"source_file": "6-space-game/4-collision-detection/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 4 : Ajouter un laser et détecter les collisions
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/35)
|
||||
|
||||
Dans cette leçon, vous apprendrez à tirer des lasers avec JavaScript ! Nous allons ajouter deux éléments à notre jeu :
|
||||
|
||||
- **Un laser** : ce laser est tiré depuis le vaisseau de votre héros et se déplace verticalement vers le haut.
|
||||
- **Détection de collisions**, dans le cadre de la mise en œuvre de la capacité à *tirer*, nous ajouterons également quelques règles intéressantes au jeu :
|
||||
- **Laser touche un ennemi** : l'ennemi meurt s'il est touché par un laser.
|
||||
- **Laser touche le haut de l'écran** : un laser est détruit s'il atteint la partie supérieure de l'écran.
|
||||
- **Collision entre ennemi et héros** : un ennemi et le héros sont détruits s'ils se percutent.
|
||||
- **Ennemi atteint le bas de l'écran** : un ennemi et un héros sont détruits si l'ennemi atteint le bas de l'écran.
|
||||
|
||||
En résumé, vous -- *le héros* -- devez éliminer tous les ennemis avec un laser avant qu'ils n'atteignent le bas de l'écran.
|
||||
|
||||
✅ Faites quelques recherches sur le tout premier jeu informatique jamais créé. Quelle était sa fonctionnalité ?
|
||||
|
||||
Soyons héroïques ensemble !
|
||||
|
||||
## Détection de collisions
|
||||
|
||||
Comment détecter les collisions ? Nous devons considérer nos objets de jeu comme des rectangles en mouvement. Pourquoi, vous demandez-vous peut-être ? Eh bien, l'image utilisée pour dessiner un objet de jeu est un rectangle : elle possède un `x`, un `y`, une `largeur` et une `hauteur`.
|
||||
|
||||
Si deux rectangles, c'est-à-dire un héros et un ennemi, *se croisent*, il y a une collision. Ce qui doit se produire ensuite dépend des règles du jeu. Pour implémenter la détection de collisions, vous avez donc besoin des éléments suivants :
|
||||
|
||||
1. Un moyen d'obtenir une représentation rectangulaire d'un objet de jeu, comme ceci :
|
||||
|
||||
```javascript
|
||||
rectFromGameObject() {
|
||||
return {
|
||||
top: this.y,
|
||||
left: this.x,
|
||||
bottom: this.y + this.height,
|
||||
right: this.x + this.width
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Une fonction de comparaison, qui peut ressembler à ceci :
|
||||
|
||||
```javascript
|
||||
function intersectRect(r1, r2) {
|
||||
return !(r2.left > r1.right ||
|
||||
r2.right < r1.left ||
|
||||
r2.top > r1.bottom ||
|
||||
r2.bottom < r1.top);
|
||||
}
|
||||
```
|
||||
|
||||
## Comment détruire des objets
|
||||
|
||||
Pour détruire des objets dans un jeu, vous devez informer le jeu qu'il ne doit plus peindre cet élément dans la boucle de jeu qui se déclenche à un certain intervalle. Une façon de le faire est de marquer un objet de jeu comme *mort* lorsqu'un événement se produit, comme ceci :
|
||||
|
||||
```javascript
|
||||
// collision happened
|
||||
enemy.dead = true
|
||||
```
|
||||
|
||||
Ensuite, vous pouvez procéder à l'élimination des objets *morts* avant de repeindre l'écran, comme ceci :
|
||||
|
||||
```javascript
|
||||
gameObjects = gameObject.filter(go => !go.dead);
|
||||
```
|
||||
|
||||
## Comment tirer un laser
|
||||
|
||||
Tirer un laser revient à répondre à un événement de touche et à créer un objet qui se déplace dans une certaine direction. Nous devons donc effectuer les étapes suivantes :
|
||||
|
||||
1. **Créer un objet laser** : à partir du sommet du vaisseau de notre héros, qui commence à se déplacer vers le haut de l'écran dès sa création.
|
||||
2. **Associer du code à un événement de touche** : nous devons choisir une touche du clavier qui représente le joueur tirant le laser.
|
||||
3. **Créer un objet de jeu qui ressemble à un laser** lorsque la touche est pressée.
|
||||
|
||||
## Temps de recharge pour notre laser
|
||||
|
||||
Le laser doit être tiré chaque fois que vous appuyez sur une touche, comme *espace* par exemple. Pour éviter que le jeu ne produise trop de lasers en peu de temps, nous devons corriger cela. La solution consiste à implémenter ce qu'on appelle un *temps de recharge*, un minuteur, qui garantit qu'un laser ne peut être tiré qu'à intervalles réguliers. Vous pouvez l'implémenter de la manière suivante :
|
||||
|
||||
```javascript
|
||||
class Cooldown {
|
||||
constructor(time) {
|
||||
this.cool = false;
|
||||
setTimeout(() => {
|
||||
this.cool = true;
|
||||
}, time)
|
||||
}
|
||||
}
|
||||
|
||||
class Weapon {
|
||||
constructor {
|
||||
}
|
||||
fire() {
|
||||
if (!this.cooldown || this.cooldown.cool) {
|
||||
// produce a laser
|
||||
this.cooldown = new Cooldown(500);
|
||||
} else {
|
||||
// do nothing - it hasn't cooled down yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
✅ Reportez-vous à la leçon 1 de la série sur le jeu spatial pour vous rappeler ce qu'est un *temps de recharge*.
|
||||
|
||||
## Ce que vous allez construire
|
||||
|
||||
Vous allez prendre le code existant (que vous devriez avoir nettoyé et refactorisé) de la leçon précédente et l'étendre. Commencez soit avec le code de la partie II, soit avec le code de [Partie III - starter](../../../../../../../../../your-work).
|
||||
|
||||
> astuce : le laser avec lequel vous allez travailler est déjà dans votre dossier d'actifs et référencé par votre code.
|
||||
|
||||
- **Ajoutez la détection de collisions**, lorsque le laser entre en collision avec quelque chose, les règles suivantes doivent s'appliquer :
|
||||
1. **Laser touche un ennemi** : l'ennemi meurt s'il est touché par un laser.
|
||||
2. **Laser touche le haut de l'écran** : un laser est détruit s'il atteint la partie supérieure de l'écran.
|
||||
3. **Collision entre ennemi et héros** : un ennemi et le héros sont détruits s'ils se percutent.
|
||||
4. **Ennemi atteint le bas de l'écran** : un ennemi et un héros sont détruits si l'ennemi atteint le bas de l'écran.
|
||||
|
||||
## Étapes recommandées
|
||||
|
||||
Localisez les fichiers qui ont été créés pour vous dans le sous-dossier `your-work`. Il devrait contenir les éléments suivants :
|
||||
|
||||
```bash
|
||||
-| assets
|
||||
-| enemyShip.png
|
||||
-| player.png
|
||||
-| laserRed.png
|
||||
-| index.html
|
||||
-| app.js
|
||||
-| package.json
|
||||
```
|
||||
|
||||
Démarrez votre projet dans le dossier `your_work` en tapant :
|
||||
|
||||
```bash
|
||||
cd your-work
|
||||
npm start
|
||||
```
|
||||
|
||||
Cela démarrera un serveur HTTP à l'adresse `http://localhost:5000`. Ouvrez un navigateur et entrez cette adresse, pour l'instant, cela devrait afficher le héros et tous les ennemis, rien ne bouge - encore :).
|
||||
|
||||
### Ajoutez du code
|
||||
|
||||
1. **Configurez une représentation rectangulaire de votre objet de jeu pour gérer les collisions** Le code ci-dessous vous permet d'obtenir une représentation rectangulaire d'un `GameObject`. Modifiez votre classe GameObject pour l'étendre :
|
||||
|
||||
```javascript
|
||||
rectFromGameObject() {
|
||||
return {
|
||||
top: this.y,
|
||||
left: this.x,
|
||||
bottom: this.y + this.height,
|
||||
right: this.x + this.width,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
2. **Ajoutez du code qui vérifie les collisions** Cela sera une nouvelle fonction qui teste si deux rectangles se croisent :
|
||||
|
||||
```javascript
|
||||
function intersectRect(r1, r2) {
|
||||
return !(
|
||||
r2.left > r1.right ||
|
||||
r2.right < r1.left ||
|
||||
r2.top > r1.bottom ||
|
||||
r2.bottom < r1.top
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
3. **Ajoutez la capacité de tirer un laser**
|
||||
1. **Ajoutez un message d'événement de touche**. La touche *espace* doit créer un laser juste au-dessus du vaisseau du héros. Ajoutez trois constantes dans l'objet Messages :
|
||||
|
||||
```javascript
|
||||
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
|
||||
COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
|
||||
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
|
||||
```
|
||||
|
||||
1. **Gérez la touche espace**. Modifiez la fonction `window.addEventListener` keyup pour gérer les espaces :
|
||||
|
||||
```javascript
|
||||
} else if(evt.keyCode === 32) {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_SPACE);
|
||||
}
|
||||
```
|
||||
|
||||
1. **Ajoutez des écouteurs**. Modifiez la fonction `initGame()` pour garantir que le héros peut tirer lorsque la barre d'espace est pressée :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
|
||||
if (hero.canFire()) {
|
||||
hero.fire();
|
||||
}
|
||||
```
|
||||
|
||||
et ajoutez une nouvelle fonction `eventEmitter.on()` pour garantir le comportement lorsqu'un ennemi entre en collision avec un laser :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
|
||||
first.dead = true;
|
||||
second.dead = true;
|
||||
})
|
||||
```
|
||||
|
||||
1. **Déplacez l'objet**, Assurez-vous que le laser se déplace progressivement vers le haut de l'écran. Vous allez créer une nouvelle classe Laser qui étend `GameObject`, comme vous l'avez fait auparavant :
|
||||
|
||||
```javascript
|
||||
class Laser extends GameObject {
|
||||
constructor(x, y) {
|
||||
super(x,y);
|
||||
(this.width = 9), (this.height = 33);
|
||||
this.type = 'Laser';
|
||||
this.img = laserImg;
|
||||
let id = setInterval(() => {
|
||||
if (this.y > 0) {
|
||||
this.y -= 15;
|
||||
} else {
|
||||
this.dead = true;
|
||||
clearInterval(id);
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. **Gérez les collisions**, Implémentez les règles de collision pour le laser. Ajoutez une fonction `updateGameObjects()` qui teste les objets en collision :
|
||||
|
||||
```javascript
|
||||
function updateGameObjects() {
|
||||
const enemies = gameObjects.filter(go => go.type === 'Enemy');
|
||||
const lasers = gameObjects.filter((go) => go.type === "Laser");
|
||||
// laser hit something
|
||||
lasers.forEach((l) => {
|
||||
enemies.forEach((m) => {
|
||||
if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) {
|
||||
eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, {
|
||||
first: l,
|
||||
second: m,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
gameObjects = gameObjects.filter(go => !go.dead);
|
||||
}
|
||||
```
|
||||
|
||||
Assurez-vous d'ajouter `updateGameObjects()` dans votre boucle de jeu dans `window.onload`.
|
||||
|
||||
4. **Implémentez un temps de recharge** pour le laser, afin qu'il ne puisse être tiré qu'à intervalles réguliers.
|
||||
|
||||
Enfin, modifiez la classe Hero pour qu'elle puisse gérer le temps de recharge :
|
||||
|
||||
```javascript
|
||||
class Hero extends GameObject {
|
||||
constructor(x, y) {
|
||||
super(x, y);
|
||||
(this.width = 99), (this.height = 75);
|
||||
this.type = "Hero";
|
||||
this.speed = { x: 0, y: 0 };
|
||||
this.cooldown = 0;
|
||||
}
|
||||
fire() {
|
||||
gameObjects.push(new Laser(this.x + 45, this.y - 10));
|
||||
this.cooldown = 500;
|
||||
|
||||
let id = setInterval(() => {
|
||||
if (this.cooldown > 0) {
|
||||
this.cooldown -= 100;
|
||||
} else {
|
||||
clearInterval(id);
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
canFire() {
|
||||
return this.cooldown === 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
À ce stade, votre jeu a une certaine fonctionnalité ! Vous pouvez naviguer avec vos touches fléchées, tirer un laser avec votre barre d'espace, et les ennemis disparaissent lorsque vous les touchez. Bravo !
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Ajoutez une explosion ! Consultez les ressources du jeu dans [le dépôt Space Art](../../../../6-space-game/solution/spaceArt/readme.txt) et essayez d'ajouter une explosion lorsque le laser touche un alien.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/36)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Expérimentez avec les intervalles dans votre jeu jusqu'à présent. Que se passe-t-il lorsque vous les modifiez ? Lisez-en davantage sur [les événements de timing en JavaScript](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/).
|
||||
|
||||
## Devoir
|
||||
|
||||
[Explorez les collisions](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "8a0a097b45e7c75a611e2795e4013f16",
|
||||
"translation_date": "2025-08-23T23:03:06+00:00",
|
||||
"source_file": "6-space-game/4-collision-detection/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Explorer les collisions
|
||||
|
||||
## Instructions
|
||||
|
||||
Pour mieux comprendre le fonctionnement des collisions, créez un petit jeu avec quelques éléments qui entrent en collision. Faites-les bouger via des pressions de touches ou des clics de souris, et faites en sorte qu'il se passe quelque chose à l'un des éléments lorsqu'il est touché. Cela pourrait être, par exemple, une météorite frappant la Terre ou des autos tamponneuses. Soyez créatif !
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------- |
|
||||
| | Un exemple de code complet et fonctionnel est produit, avec des éléments dessinés sur le canvas, des collisions basiques et des réactions qui se produisent | Le code est incomplet d'une certaine manière | Le code ne fonctionne pas |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T23:04:09+00:00",
|
||||
"source_file": "6-space-game/4-collision-detection/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T23:03:40+00:00",
|
||||
"source_file": "6-space-game/4-collision-detection/your-work/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,201 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
|
||||
"translation_date": "2025-08-23T22:52:42+00:00",
|
||||
"source_file": "6-space-game/5-keeping-score/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 5 : Score et vies
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/37)
|
||||
|
||||
Dans cette leçon, vous apprendrez à ajouter un système de score à un jeu et à calculer les vies.
|
||||
|
||||
## Afficher du texte à l'écran
|
||||
|
||||
Pour afficher un score de jeu à l'écran, vous devez savoir comment placer du texte sur l'écran. La méthode à utiliser est `fillText()` sur l'objet canvas. Vous pouvez également contrôler d'autres aspects comme la police à utiliser, la couleur du texte et même son alignement (gauche, droite, centre). Voici un exemple de code qui affiche du texte à l'écran.
|
||||
|
||||
```javascript
|
||||
ctx.font = "30px Arial";
|
||||
ctx.fillStyle = "red";
|
||||
ctx.textAlign = "right";
|
||||
ctx.fillText("show this on the screen", 0, 0);
|
||||
```
|
||||
|
||||
✅ Lisez-en davantage sur [comment ajouter du texte à un canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), et n'hésitez pas à rendre votre texte plus esthétique !
|
||||
|
||||
## La vie, en tant que concept de jeu
|
||||
|
||||
Le concept de vie dans un jeu n'est qu'un simple nombre. Dans le contexte d'un jeu spatial, il est courant d'attribuer un certain nombre de vies qui sont déduites une par une lorsque votre vaisseau subit des dégâts. Il est agréable de représenter cela graphiquement, par exemple avec des mini-vaisseaux ou des cœurs, au lieu d'un simple nombre.
|
||||
|
||||
## Ce que vous allez construire
|
||||
|
||||
Ajoutons les éléments suivants à votre jeu :
|
||||
|
||||
- **Score du jeu** : Pour chaque vaisseau ennemi détruit, le héros doit recevoir des points, nous suggérons 100 points par vaisseau. Le score du jeu doit être affiché en bas à gauche.
|
||||
- **Vies** : Votre vaisseau dispose de trois vies. Vous perdez une vie chaque fois qu'un vaisseau ennemi entre en collision avec vous. Le nombre de vies doit être affiché en bas à droite sous forme de graphique comme celui-ci : .
|
||||
|
||||
## Étapes recommandées
|
||||
|
||||
Trouvez les fichiers qui ont été créés pour vous dans le sous-dossier `your-work`. Il devrait contenir les éléments suivants :
|
||||
|
||||
```bash
|
||||
-| assets
|
||||
-| enemyShip.png
|
||||
-| player.png
|
||||
-| laserRed.png
|
||||
-| index.html
|
||||
-| app.js
|
||||
-| package.json
|
||||
```
|
||||
|
||||
Démarrez votre projet dans le dossier `your_work` en tapant :
|
||||
|
||||
```bash
|
||||
cd your-work
|
||||
npm start
|
||||
```
|
||||
|
||||
Cela lancera un serveur HTTP à l'adresse `http://localhost:5000`. Ouvrez un navigateur et entrez cette adresse. Actuellement, cela devrait afficher le héros et tous les ennemis, et lorsque vous appuyez sur les flèches gauche et droite, le héros se déplace et peut tirer sur les ennemis.
|
||||
|
||||
### Ajouter du code
|
||||
|
||||
1. **Copiez les ressources nécessaires** du dossier `solution/assets/` dans le dossier `your-work` ; vous ajouterez une ressource `life.png`. Ajoutez `lifeImg` à la fonction `window.onload` :
|
||||
|
||||
```javascript
|
||||
lifeImg = await loadTexture("assets/life.png");
|
||||
```
|
||||
|
||||
1. Ajoutez `lifeImg` à la liste des ressources :
|
||||
|
||||
```javascript
|
||||
let heroImg,
|
||||
...
|
||||
lifeImg,
|
||||
...
|
||||
eventEmitter = new EventEmitter();
|
||||
```
|
||||
|
||||
2. **Ajoutez des variables**. Ajoutez du code pour représenter votre score total (0) et le nombre de vies restantes (3), et affichez ces scores à l'écran.
|
||||
|
||||
3. **Étendez la fonction `updateGameObjects()`**. Modifiez la fonction `updateGameObjects()` pour gérer les collisions avec les ennemis :
|
||||
|
||||
```javascript
|
||||
enemies.forEach(enemy => {
|
||||
const heroRect = hero.rectFromGameObject();
|
||||
if (intersectRect(heroRect, enemy.rectFromGameObject())) {
|
||||
eventEmitter.emit(Messages.COLLISION_ENEMY_HERO, { enemy });
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
4. **Ajoutez les éléments "vie" et "points"**.
|
||||
1. **Initialisez les variables**. Sous `this.cooldown = 0` dans la classe `Hero`, définissez les variables `life` et `points` :
|
||||
|
||||
```javascript
|
||||
this.life = 3;
|
||||
this.points = 0;
|
||||
```
|
||||
|
||||
1. **Affichez les variables à l'écran**. Dessinez ces valeurs à l'écran :
|
||||
|
||||
```javascript
|
||||
function drawLife() {
|
||||
// TODO, 35, 27
|
||||
const START_POS = canvas.width - 180;
|
||||
for(let i=0; i < hero.life; i++ ) {
|
||||
ctx.drawImage(
|
||||
lifeImg,
|
||||
START_POS + (45 * (i+1) ),
|
||||
canvas.height - 37);
|
||||
}
|
||||
}
|
||||
|
||||
function drawPoints() {
|
||||
ctx.font = "30px Arial";
|
||||
ctx.fillStyle = "red";
|
||||
ctx.textAlign = "left";
|
||||
drawText("Points: " + hero.points, 10, canvas.height-20);
|
||||
}
|
||||
|
||||
function drawText(message, x, y) {
|
||||
ctx.fillText(message, x, y);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
1. **Ajoutez des méthodes à la boucle de jeu**. Assurez-vous d'ajouter ces fonctions à votre fonction `window.onload` sous `updateGameObjects()` :
|
||||
|
||||
```javascript
|
||||
drawPoints();
|
||||
drawLife();
|
||||
```
|
||||
|
||||
1. **Implémentez les règles du jeu**. Implémentez les règles suivantes :
|
||||
|
||||
1. **Pour chaque collision entre le héros et un ennemi**, déduisez une vie.
|
||||
|
||||
Étendez la classe `Hero` pour effectuer cette déduction :
|
||||
|
||||
```javascript
|
||||
decrementLife() {
|
||||
this.life--;
|
||||
if (this.life === 0) {
|
||||
this.dead = true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Pour chaque laser qui touche un ennemi**, augmentez le score du jeu de 100 points.
|
||||
|
||||
Étendez la classe `Hero` pour effectuer cet incrément :
|
||||
|
||||
```javascript
|
||||
incrementPoints() {
|
||||
this.points += 100;
|
||||
}
|
||||
```
|
||||
|
||||
Ajoutez ces fonctions à vos émetteurs d'événements de collision :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
|
||||
first.dead = true;
|
||||
second.dead = true;
|
||||
hero.incrementPoints();
|
||||
})
|
||||
|
||||
eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
|
||||
enemy.dead = true;
|
||||
hero.decrementLife();
|
||||
});
|
||||
```
|
||||
|
||||
✅ Faites quelques recherches pour découvrir d'autres jeux créés avec JavaScript/Canvas. Quels sont leurs traits communs ?
|
||||
|
||||
À la fin de ce travail, vous devriez voir les petits vaisseaux "vie" en bas à droite, les points en bas à gauche, et vous devriez voir votre nombre de vies diminuer lorsque vous entrez en collision avec des ennemis et vos points augmenter lorsque vous tirez sur des ennemis. Bien joué ! Votre jeu est presque terminé.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Votre code est presque complet. Pouvez-vous imaginer les prochaines étapes ?
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/38)
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
Faites des recherches sur les différentes façons d'incrémenter et de décrémenter les scores et les vies dans un jeu. Il existe des moteurs de jeu intéressants comme [PlayFab](https://playfab.com). Comment l'utilisation de l'un d'entre eux pourrait-elle améliorer votre jeu ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Construire un jeu avec un système de score](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "81f292dbda01685b91735e0398dc0504",
|
||||
"translation_date": "2025-08-23T22:53:46+00:00",
|
||||
"source_file": "6-space-game/5-keeping-score/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer un Jeu de Score
|
||||
|
||||
## Instructions
|
||||
|
||||
Créez un jeu où vous affichez la vie et les points de manière créative. Une suggestion serait de montrer la vie sous forme de cœurs et les points comme un grand nombre au centre inférieur de l'écran. Consultez cette page pour des [Ressources gratuites pour les jeux](https://www.kenney.nl/)
|
||||
|
||||
# Critères d'Évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À Améliorer |
|
||||
| -------- | ---------------------- | --------------------------- | -------------------------- |
|
||||
| | le jeu complet est présenté | le jeu est partiellement présenté | le jeu partiel contient des bugs |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T22:54:46+00:00",
|
||||
"source_file": "6-space-game/5-keeping-score/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T22:54:18+00:00",
|
||||
"source_file": "6-space-game/5-keeping-score/your-work/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,234 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "01336cddd638242e99b133614111ea40",
|
||||
"translation_date": "2025-08-23T23:07:41+00:00",
|
||||
"source_file": "6-space-game/6-end-condition/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Construire un jeu spatial Partie 6 : Fin et redémarrage
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/39)
|
||||
|
||||
Il existe différentes façons d'exprimer une *condition de fin* dans un jeu. En tant que créateur du jeu, c'est à vous de décider pourquoi le jeu se termine. Voici quelques raisons, en supposant que nous parlons du jeu spatial que vous avez construit jusqu'à présent :
|
||||
|
||||
- **`N` vaisseaux ennemis ont été détruits** : Il est assez courant, si vous divisez un jeu en différents niveaux, de devoir détruire `N` vaisseaux ennemis pour terminer un niveau.
|
||||
- **Votre vaisseau a été détruit** : Il existe des jeux où vous perdez si votre vaisseau est détruit. Une autre approche courante est d'introduire le concept de vies. Chaque fois que votre vaisseau est détruit, une vie est déduite. Une fois toutes les vies perdues, vous perdez le jeu.
|
||||
- **Vous avez collecté `N` points** : Une autre condition de fin courante est de collecter des points. La manière dont vous obtenez des points dépend de vous, mais il est assez courant d'attribuer des points à diverses activités comme détruire un vaisseau ennemi ou collecter des objets que les ennemis *laissent tomber* lorsqu'ils sont détruits.
|
||||
- **Terminer un niveau** : Cela peut impliquer plusieurs conditions, comme détruire `X` vaisseaux ennemis, collecter `Y` points ou peut-être récupérer un objet spécifique.
|
||||
|
||||
## Redémarrage
|
||||
|
||||
Si les gens apprécient votre jeu, ils voudront probablement le rejouer. Une fois le jeu terminé, quelle qu'en soit la raison, vous devriez offrir une option pour recommencer.
|
||||
|
||||
✅ Réfléchissez un peu aux conditions dans lesquelles un jeu se termine, puis à la manière dont vous êtes invité à le redémarrer.
|
||||
|
||||
## Ce que vous allez construire
|
||||
|
||||
Vous allez ajouter ces règles à votre jeu :
|
||||
|
||||
1. **Gagner le jeu**. Une fois que tous les vaisseaux ennemis ont été détruits, vous gagnez le jeu. Affichez également un message de victoire.
|
||||
1. **Redémarrer**. Une fois que toutes vos vies sont perdues ou que le jeu est gagné, vous devez offrir un moyen de redémarrer le jeu. N'oubliez pas ! Vous devrez réinitialiser le jeu et effacer l'état précédent.
|
||||
|
||||
## Étapes recommandées
|
||||
|
||||
Localisez les fichiers qui ont été créés pour vous dans le sous-dossier `your-work`. Il devrait contenir les éléments suivants :
|
||||
|
||||
```bash
|
||||
-| assets
|
||||
-| enemyShip.png
|
||||
-| player.png
|
||||
-| laserRed.png
|
||||
-| life.png
|
||||
-| index.html
|
||||
-| app.js
|
||||
-| package.json
|
||||
```
|
||||
|
||||
Démarrez votre projet dans le dossier `your_work` en tapant :
|
||||
|
||||
```bash
|
||||
cd your-work
|
||||
npm start
|
||||
```
|
||||
|
||||
Cela démarrera un serveur HTTP à l'adresse `http://localhost:5000`. Ouvrez un navigateur et entrez cette adresse. Votre jeu devrait être dans un état jouable.
|
||||
|
||||
> astuce : pour éviter les avertissements dans Visual Studio Code, modifiez la fonction `window.onload` pour appeler `gameLoopId` tel quel (sans `let`), et déclarez `gameLoopId` en haut du fichier, indépendamment : `let gameLoopId;`
|
||||
|
||||
### Ajouter du code
|
||||
|
||||
1. **Suivre la condition de fin**. Ajoutez du code qui suit le nombre d'ennemis ou si le vaisseau héros a été détruit en ajoutant ces deux fonctions :
|
||||
|
||||
```javascript
|
||||
function isHeroDead() {
|
||||
return hero.life <= 0;
|
||||
}
|
||||
|
||||
function isEnemiesDead() {
|
||||
const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead);
|
||||
return enemies.length === 0;
|
||||
}
|
||||
```
|
||||
|
||||
1. **Ajouter une logique aux gestionnaires de messages**. Modifiez le `eventEmitter` pour gérer ces conditions :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
|
||||
first.dead = true;
|
||||
second.dead = true;
|
||||
hero.incrementPoints();
|
||||
|
||||
if (isEnemiesDead()) {
|
||||
eventEmitter.emit(Messages.GAME_END_WIN);
|
||||
}
|
||||
});
|
||||
|
||||
eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
|
||||
enemy.dead = true;
|
||||
hero.decrementLife();
|
||||
if (isHeroDead()) {
|
||||
eventEmitter.emit(Messages.GAME_END_LOSS);
|
||||
return; // loss before victory
|
||||
}
|
||||
if (isEnemiesDead()) {
|
||||
eventEmitter.emit(Messages.GAME_END_WIN);
|
||||
}
|
||||
});
|
||||
|
||||
eventEmitter.on(Messages.GAME_END_WIN, () => {
|
||||
endGame(true);
|
||||
});
|
||||
|
||||
eventEmitter.on(Messages.GAME_END_LOSS, () => {
|
||||
endGame(false);
|
||||
});
|
||||
```
|
||||
|
||||
1. **Ajouter de nouveaux types de messages**. Ajoutez ces Messages à l'objet constants :
|
||||
|
||||
```javascript
|
||||
GAME_END_LOSS: "GAME_END_LOSS",
|
||||
GAME_END_WIN: "GAME_END_WIN",
|
||||
```
|
||||
|
||||
2. **Ajouter du code de redémarrage** qui redémarre le jeu à la pression d'un bouton sélectionné.
|
||||
|
||||
1. **Écouter la touche `Entrée`**. Modifiez l'eventListener de votre fenêtre pour écouter cette touche :
|
||||
|
||||
```javascript
|
||||
else if(evt.key === "Enter") {
|
||||
eventEmitter.emit(Messages.KEY_EVENT_ENTER);
|
||||
}
|
||||
```
|
||||
|
||||
1. **Ajouter un message de redémarrage**. Ajoutez ce Message à votre constante Messages :
|
||||
|
||||
```javascript
|
||||
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
|
||||
```
|
||||
|
||||
1. **Implémenter les règles du jeu**. Implémentez les règles suivantes :
|
||||
|
||||
1. **Condition de victoire du joueur**. Lorsque tous les vaisseaux ennemis sont détruits, affichez un message de victoire.
|
||||
|
||||
1. Tout d'abord, créez une fonction `displayMessage()` :
|
||||
|
||||
```javascript
|
||||
function displayMessage(message, color = "red") {
|
||||
ctx.font = "30px Arial";
|
||||
ctx.fillStyle = color;
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(message, canvas.width / 2, canvas.height / 2);
|
||||
}
|
||||
```
|
||||
|
||||
1. Créez une fonction `endGame()` :
|
||||
|
||||
```javascript
|
||||
function endGame(win) {
|
||||
clearInterval(gameLoopId);
|
||||
|
||||
// set a delay so we are sure any paints have finished
|
||||
setTimeout(() => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
if (win) {
|
||||
displayMessage(
|
||||
"Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew",
|
||||
"green"
|
||||
);
|
||||
} else {
|
||||
displayMessage(
|
||||
"You died !!! Press [Enter] to start a new game Captain Pew Pew"
|
||||
);
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
```
|
||||
|
||||
1. **Logique de redémarrage**. Lorsque toutes les vies sont perdues ou que le joueur a gagné le jeu, affichez que le jeu peut être redémarré. Redémarrez également le jeu lorsque la touche *redémarrer* est pressée (vous pouvez décider quelle touche sera associée au redémarrage).
|
||||
|
||||
1. Créez la fonction `resetGame()` :
|
||||
|
||||
```javascript
|
||||
function resetGame() {
|
||||
if (gameLoopId) {
|
||||
clearInterval(gameLoopId);
|
||||
eventEmitter.clear();
|
||||
initGame();
|
||||
gameLoopId = setInterval(() => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
drawPoints();
|
||||
drawLife();
|
||||
updateGameObjects();
|
||||
drawGameObjects(ctx);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Ajoutez un appel au `eventEmitter` pour réinitialiser le jeu dans `initGame()` :
|
||||
|
||||
```javascript
|
||||
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
|
||||
resetGame();
|
||||
});
|
||||
```
|
||||
|
||||
1. Ajoutez une fonction `clear()` à l'EventEmitter :
|
||||
|
||||
```javascript
|
||||
clear() {
|
||||
this.listeners = {};
|
||||
}
|
||||
```
|
||||
|
||||
👽 💥 🚀 Félicitations, Capitaine ! Votre jeu est terminé ! Bien joué ! 🚀 💥 👽
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Ajoutez un son ! Pouvez-vous ajouter un son pour améliorer l'expérience de jeu, peut-être lorsqu'un laser touche, ou lorsque le héros meurt ou gagne ? Consultez ce [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) pour apprendre à jouer un son avec JavaScript.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/40)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Votre mission est de créer un nouveau jeu d'exemple, alors explorez certains des jeux intéressants disponibles pour voir quel type de jeu vous pourriez construire.
|
||||
|
||||
## Devoir
|
||||
|
||||
[Créer un jeu d'exemple](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,31 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "24201cf428c7edba1ccec2a78a0dd8f8",
|
||||
"translation_date": "2025-08-23T23:09:09+00:00",
|
||||
"source_file": "6-space-game/6-end-condition/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer un jeu d'exemple
|
||||
|
||||
## Instructions
|
||||
|
||||
Essayez de créer un petit jeu où vous explorez différentes conditions de fin. Variez entre atteindre un certain nombre de points, le héros perd toutes ses vies ou tous les monstres sont vaincus. Construisez quelque chose de simple, comme un jeu d'aventure basé sur la console. Utilisez le flux de jeu ci-dessous comme source d'inspiration :
|
||||
|
||||
```
|
||||
Hero> Strikes with broadsword - orc takes 3p damage
|
||||
Orc> Hits with club - hero takes 2p damage
|
||||
Hero> Kicks - orc takes 1p damage
|
||||
Game> Orc is defeated - Hero collects 2 coins
|
||||
Game> ****No more monsters, you have conquered the evil fortress****
|
||||
```
|
||||
|
||||
## Critères d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ---------------------- | --------------------------- | -------------------------- |
|
||||
| | le jeu complet est présenté | le jeu est partiellement présenté | le jeu partiel contient des bugs |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T23:10:12+00:00",
|
||||
"source_file": "6-space-game/6-end-condition/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T23:09:43+00:00",
|
||||
"source_file": "6-space-game/6-end-condition/your-work/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "c40a698395ee5102715f7880bba3f2e7",
|
||||
"translation_date": "2025-08-23T22:51:23+00:00",
|
||||
"source_file": "6-space-game/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer un jeu spatial
|
||||
|
||||
Un jeu spatial pour enseigner des concepts avancés de JavaScript
|
||||
|
||||
Dans cette leçon, vous apprendrez à créer votre propre jeu spatial. Si vous avez déjà joué au jeu "Space Invaders", ce jeu repose sur le même principe : piloter un vaisseau spatial et tirer sur des monstres qui descendent du haut de l'écran. Voici à quoi ressemblera le jeu terminé :
|
||||
|
||||

|
||||
|
||||
Au cours de ces six leçons, vous apprendrez les points suivants :
|
||||
|
||||
- **Interagir** avec l'élément Canvas pour dessiner des éléments à l'écran
|
||||
- **Comprendre** le système de coordonnées cartésiennes
|
||||
- **Apprendre** le modèle Pub-Sub pour créer une architecture de jeu solide, facile à maintenir et à étendre
|
||||
- **Exploiter** Async/Await pour charger les ressources du jeu
|
||||
- **Gérer** les événements clavier
|
||||
|
||||
## Aperçu
|
||||
|
||||
- Théorie
|
||||
- [Introduction à la création de jeux avec JavaScript](1-introduction/README.md)
|
||||
- Pratique
|
||||
- [Dessiner sur le canvas](2-drawing-to-canvas/README.md)
|
||||
- [Déplacer des éléments sur l'écran](3-moving-elements-around/README.md)
|
||||
- [Détection de collisions](4-collision-detection/README.md)
|
||||
- [Compter les points](5-keeping-score/README.md)
|
||||
- [Terminer et redémarrer le jeu](6-end-condition/README.md)
|
||||
|
||||
## Crédits
|
||||
|
||||
Les ressources utilisées pour ce projet proviennent de https://www.kenney.nl/.
|
||||
Si vous aimez créer des jeux, ces ressources sont vraiment excellentes. Beaucoup sont gratuites et certaines sont payantes.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c",
|
||||
"translation_date": "2025-08-23T23:11:00+00:00",
|
||||
"source_file": "6-space-game/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
Ceci est un espace réservé, laissé vide intentionnellement
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,320 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
|
||||
"translation_date": "2025-08-24T00:08:06+00:00",
|
||||
"source_file": "7-bank-project/1-template-route/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une application bancaire Partie 1 : Modèles HTML et routes dans une application web
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/41)
|
||||
|
||||
### Introduction
|
||||
|
||||
Depuis l'apparition de JavaScript dans les navigateurs, les sites web sont devenus plus interactifs et complexes que jamais. Les technologies web sont désormais couramment utilisées pour créer des applications entièrement fonctionnelles qui s'exécutent directement dans un navigateur, que l'on appelle [applications web](https://en.wikipedia.org/wiki/Web_application). Étant donné que les applications web sont très interactives, les utilisateurs ne veulent pas attendre un rechargement complet de la page à chaque action. C'est pourquoi JavaScript est utilisé pour mettre à jour directement le HTML via le DOM, offrant ainsi une expérience utilisateur plus fluide.
|
||||
|
||||
Dans cette leçon, nous allons poser les bases pour créer une application bancaire web, en utilisant des modèles HTML pour créer plusieurs écrans qui peuvent être affichés et mis à jour sans avoir à recharger toute la page HTML.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous avez besoin d'un serveur web local pour tester l'application web que nous allons construire dans cette leçon. Si vous n'en avez pas, vous pouvez installer [Node.js](https://nodejs.org) et utiliser la commande `npx lite-server` depuis votre dossier de projet. Cela créera un serveur web local et ouvrira votre application dans un navigateur.
|
||||
|
||||
### Préparation
|
||||
|
||||
Sur votre ordinateur, créez un dossier nommé `bank` avec un fichier nommé `index.html` à l'intérieur. Nous allons commencer avec ce [code de base HTML](https://en.wikipedia.org/wiki/Boilerplate_code) :
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bank App</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- This is where you'll work -->
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modèles HTML
|
||||
|
||||
Si vous souhaitez créer plusieurs écrans pour une page web, une solution serait de créer un fichier HTML pour chaque écran que vous voulez afficher. Cependant, cette solution présente quelques inconvénients :
|
||||
|
||||
- Vous devez recharger tout le HTML lors du changement d'écran, ce qui peut être lent.
|
||||
- Il est difficile de partager des données entre les différents écrans.
|
||||
|
||||
Une autre approche consiste à n'avoir qu'un seul fichier HTML et à définir plusieurs [modèles HTML](https://developer.mozilla.org/docs/Web/HTML/Element/template) en utilisant l'élément `<template>`. Un modèle est un bloc HTML réutilisable qui n'est pas affiché par le navigateur et qui doit être instancié à l'exécution via JavaScript.
|
||||
|
||||
### Tâche
|
||||
|
||||
Nous allons créer une application bancaire avec deux écrans : la page de connexion et le tableau de bord. Tout d'abord, ajoutons dans le corps HTML un élément de remplacement que nous utiliserons pour instancier les différents écrans de notre application :
|
||||
|
||||
```html
|
||||
<div id="app">Loading...</div>
|
||||
```
|
||||
|
||||
Nous lui donnons un `id` pour le localiser plus facilement avec JavaScript par la suite.
|
||||
|
||||
> Astuce : puisque le contenu de cet élément sera remplacé, nous pouvons y mettre un message ou un indicateur de chargement qui sera affiché pendant le chargement de l'application.
|
||||
|
||||
Ensuite, ajoutons en dessous le modèle HTML pour la page de connexion. Pour l'instant, nous y mettrons uniquement un titre et une section contenant un lien que nous utiliserons pour effectuer la navigation.
|
||||
|
||||
```html
|
||||
<template id="login">
|
||||
<h1>Bank App</h1>
|
||||
<section>
|
||||
<a href="/dashboard">Login</a>
|
||||
</section>
|
||||
</template>
|
||||
```
|
||||
|
||||
Puis, ajoutons un autre modèle HTML pour la page du tableau de bord. Cette page contiendra différentes sections :
|
||||
|
||||
- Un en-tête avec un titre et un lien de déconnexion
|
||||
- Le solde actuel du compte bancaire
|
||||
- Une liste de transactions, affichée dans un tableau
|
||||
|
||||
```html
|
||||
<template id="dashboard">
|
||||
<header>
|
||||
<h1>Bank App</h1>
|
||||
<a href="/login">Logout</a>
|
||||
</header>
|
||||
<section>
|
||||
Balance: 100$
|
||||
</section>
|
||||
<section>
|
||||
<h2>Transactions</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Object</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</section>
|
||||
</template>
|
||||
```
|
||||
|
||||
> Astuce : lorsque vous créez des modèles HTML, si vous voulez voir à quoi ils ressemblent, vous pouvez commenter les lignes `<template>` et `</template>` en les entourant de `<!-- -->`.
|
||||
|
||||
✅ Pourquoi pensez-vous que nous utilisons des attributs `id` sur les modèles ? Pourrait-on utiliser autre chose comme des classes ?
|
||||
|
||||
## Afficher les modèles avec JavaScript
|
||||
|
||||
Si vous essayez votre fichier HTML actuel dans un navigateur, vous verrez qu'il reste bloqué sur `Loading...`. C'est parce que nous devons ajouter du code JavaScript pour instancier et afficher les modèles HTML.
|
||||
|
||||
L'instanciation d'un modèle se fait généralement en 3 étapes :
|
||||
|
||||
1. Récupérer l'élément modèle dans le DOM, par exemple en utilisant [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById).
|
||||
2. Cloner l'élément modèle, en utilisant [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
|
||||
3. L'attacher au DOM sous un élément visible, par exemple en utilisant [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
|
||||
|
||||
✅ Pourquoi devons-nous cloner le modèle avant de l'attacher au DOM ? Que pensez-vous qu'il se passerait si nous sautions cette étape ?
|
||||
|
||||
### Tâche
|
||||
|
||||
Créez un nouveau fichier nommé `app.js` dans votre dossier de projet et importez ce fichier dans la section `<head>` de votre HTML :
|
||||
|
||||
```html
|
||||
<script src="app.js" defer></script>
|
||||
```
|
||||
|
||||
Maintenant, dans `app.js`, nous allons créer une nouvelle fonction `updateRoute` :
|
||||
|
||||
```js
|
||||
function updateRoute(templateId) {
|
||||
const template = document.getElementById(templateId);
|
||||
const view = template.content.cloneNode(true);
|
||||
const app = document.getElementById('app');
|
||||
app.innerHTML = '';
|
||||
app.appendChild(view);
|
||||
}
|
||||
```
|
||||
|
||||
Ce que nous faisons ici correspond exactement aux 3 étapes décrites ci-dessus. Nous instancions le modèle avec l'id `templateId` et mettons son contenu cloné dans notre élément de remplacement de l'application. Notez que nous devons utiliser `cloneNode(true)` pour copier tout l'arbre du modèle.
|
||||
|
||||
Appelez maintenant cette fonction avec l'un des modèles et regardez le résultat.
|
||||
|
||||
```js
|
||||
updateRoute('login');
|
||||
```
|
||||
|
||||
✅ Quel est le but de ce code `app.innerHTML = '';` ? Que se passe-t-il sans lui ?
|
||||
|
||||
## Créer des routes
|
||||
|
||||
Lorsqu'on parle d'une application web, on appelle *Routing* l'intention de mapper des **URLs** à des écrans spécifiques qui doivent être affichés. Sur un site web avec plusieurs fichiers HTML, cela se fait automatiquement car les chemins des fichiers sont reflétés dans l'URL. Par exemple, avec ces fichiers dans votre dossier de projet :
|
||||
|
||||
```
|
||||
mywebsite/index.html
|
||||
mywebsite/login.html
|
||||
mywebsite/admin/index.html
|
||||
```
|
||||
|
||||
Si vous créez un serveur web avec `mywebsite` comme racine, le mapping des URLs sera :
|
||||
|
||||
```
|
||||
https://site.com --> mywebsite/index.html
|
||||
https://site.com/login.html --> mywebsite/login.html
|
||||
https://site.com/admin/ --> mywebsite/admin/index.html
|
||||
```
|
||||
|
||||
Cependant, pour notre application web, nous utilisons un seul fichier HTML contenant tous les écrans, donc ce comportement par défaut ne nous aidera pas. Nous devons créer ce mapping manuellement et mettre à jour l'écran affiché en utilisant JavaScript.
|
||||
|
||||
### Tâche
|
||||
|
||||
Nous allons utiliser un simple objet pour implémenter un [map](https://en.wikipedia.org/wiki/Associative_array) entre les chemins d'URL et nos modèles. Ajoutez cet objet en haut de votre fichier `app.js`.
|
||||
|
||||
```js
|
||||
const routes = {
|
||||
'/login': { templateId: 'login' },
|
||||
'/dashboard': { templateId: 'dashboard' },
|
||||
};
|
||||
```
|
||||
|
||||
Modifions maintenant un peu la fonction `updateRoute`. Au lieu de passer directement l'`templateId` comme argument, nous voulons le récupérer en regardant d'abord l'URL actuelle, puis utiliser notre map pour obtenir la valeur correspondante de l'id du modèle. Nous pouvons utiliser [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) pour obtenir uniquement la section du chemin de l'URL.
|
||||
|
||||
```js
|
||||
function updateRoute() {
|
||||
const path = window.location.pathname;
|
||||
const route = routes[path];
|
||||
|
||||
const template = document.getElementById(route.templateId);
|
||||
const view = template.content.cloneNode(true);
|
||||
const app = document.getElementById('app');
|
||||
app.innerHTML = '';
|
||||
app.appendChild(view);
|
||||
}
|
||||
```
|
||||
|
||||
Ici, nous avons mappé les routes que nous avons déclarées aux modèles correspondants. Vous pouvez essayer de vérifier que cela fonctionne correctement en modifiant l'URL manuellement dans votre navigateur.
|
||||
|
||||
✅ Que se passe-t-il si vous entrez un chemin inconnu dans l'URL ? Comment pourrions-nous résoudre cela ?
|
||||
|
||||
## Ajouter la navigation
|
||||
|
||||
La prochaine étape pour notre application est d'ajouter la possibilité de naviguer entre les pages sans avoir à modifier l'URL manuellement. Cela implique deux choses :
|
||||
|
||||
1. Mettre à jour l'URL actuelle
|
||||
2. Mettre à jour le modèle affiché en fonction de la nouvelle URL
|
||||
|
||||
Nous avons déjà pris en charge la deuxième partie avec la fonction `updateRoute`, donc nous devons trouver comment mettre à jour l'URL actuelle.
|
||||
|
||||
Nous devrons utiliser JavaScript et plus précisément [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), qui permet de mettre à jour l'URL et de créer une nouvelle entrée dans l'historique de navigation, sans recharger le HTML.
|
||||
|
||||
> Note : Bien que l'élément HTML d'ancre [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) puisse être utilisé seul pour créer des hyperliens vers différentes URLs, il fera recharger le HTML par défaut. Il est nécessaire d'empêcher ce comportement lors de la gestion des routes avec un JavaScript personnalisé, en utilisant la fonction `preventDefault()` sur l'événement de clic.
|
||||
|
||||
### Tâche
|
||||
|
||||
Créons une nouvelle fonction que nous pouvons utiliser pour naviguer dans notre application :
|
||||
|
||||
```js
|
||||
function navigate(path) {
|
||||
window.history.pushState({}, path, path);
|
||||
updateRoute();
|
||||
}
|
||||
```
|
||||
|
||||
Cette méthode met d'abord à jour l'URL actuelle en fonction du chemin donné, puis met à jour le modèle. La propriété `window.location.origin` retourne la racine de l'URL, nous permettant de reconstruire une URL complète à partir d'un chemin donné.
|
||||
|
||||
Maintenant que nous avons cette fonction, nous pouvons résoudre le problème que nous avons si un chemin ne correspond à aucune route définie. Nous allons modifier la fonction `updateRoute` en ajoutant une solution de repli vers l'une des routes existantes si nous ne trouvons pas de correspondance.
|
||||
|
||||
```js
|
||||
function updateRoute() {
|
||||
const path = window.location.pathname;
|
||||
const route = routes[path];
|
||||
|
||||
if (!route) {
|
||||
return navigate('/login');
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Si une route ne peut pas être trouvée, nous redirigerons maintenant vers la page de connexion.
|
||||
|
||||
Créons maintenant une fonction pour obtenir l'URL lorsqu'un lien est cliqué et pour empêcher le comportement par défaut du navigateur pour les liens :
|
||||
|
||||
```js
|
||||
function onLinkClick(event) {
|
||||
event.preventDefault();
|
||||
navigate(event.target.href);
|
||||
}
|
||||
```
|
||||
|
||||
Complétons le système de navigation en ajoutant des liaisons à nos liens *Login* et *Logout* dans le HTML.
|
||||
|
||||
```html
|
||||
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
|
||||
...
|
||||
<a href="/login" onclick="onLinkClick(event)">Logout</a>
|
||||
```
|
||||
|
||||
L'objet `event` ci-dessus capture l'événement `click` et le transmet à notre fonction `onLinkClick`.
|
||||
|
||||
En utilisant l'attribut [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick), liez l'événement `click` au code JavaScript, ici l'appel à la fonction `navigate()`.
|
||||
|
||||
Essayez de cliquer sur ces liens, vous devriez maintenant pouvoir naviguer entre les différents écrans de votre application.
|
||||
|
||||
✅ La méthode `history.pushState` fait partie de la norme HTML5 et est implémentée dans [tous les navigateurs modernes](https://caniuse.com/?search=pushState). Si vous construisez une application web pour des navigateurs plus anciens, il existe une astuce que vous pouvez utiliser à la place de cette API : en utilisant un [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) avant le chemin, vous pouvez implémenter un routage qui fonctionne avec la navigation classique des ancres et ne recharge pas la page, car son objectif était de créer des liens internes dans une page.
|
||||
|
||||
## Gérer les boutons de retour et d'avance du navigateur
|
||||
|
||||
L'utilisation de `history.pushState` crée de nouvelles entrées dans l'historique de navigation du navigateur. Vous pouvez vérifier cela en maintenant le *bouton retour* de votre navigateur, il devrait afficher quelque chose comme ceci :
|
||||
|
||||

|
||||
|
||||
Si vous essayez de cliquer plusieurs fois sur le bouton retour, vous verrez que l'URL actuelle change et que l'historique est mis à jour, mais le même modèle continue d'être affiché.
|
||||
|
||||
C'est parce que l'application ne sait pas que nous devons appeler `updateRoute()` chaque fois que l'historique change. Si vous regardez la [documentation de `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), vous verrez que si l'état change - c'est-à-dire que nous avons déplacé vers une URL différente - l'événement [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) est déclenché. Nous allons utiliser cela pour corriger ce problème.
|
||||
|
||||
### Tâche
|
||||
|
||||
Pour nous assurer que le modèle affiché est mis à jour lorsque l'historique du navigateur change, nous allons attacher une nouvelle fonction qui appelle `updateRoute()`. Nous ferons cela en bas de notre fichier `app.js` :
|
||||
|
||||
```js
|
||||
window.onpopstate = () => updateRoute();
|
||||
updateRoute();
|
||||
```
|
||||
|
||||
> Note : nous avons utilisé une [fonction fléchée](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ici pour déclarer notre gestionnaire d'événement `popstate` par souci de concision, mais une fonction classique fonctionnerait de la même manière.
|
||||
|
||||
Voici une vidéo de rappel sur les fonctions fléchées :
|
||||
|
||||
[](https://youtube.com/watch?v=OP6eEbOj2sc "Fonctions fléchées")
|
||||
|
||||
> 🎥 Cliquez sur l'image ci-dessus pour une vidéo sur les fonctions fléchées.
|
||||
|
||||
Essayez maintenant d'utiliser les boutons de retour et d'avance de votre navigateur, et vérifiez que la route affichée est correctement mise à jour cette fois.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Ajoutez un nouveau modèle et une route pour une troisième page qui affiche les crédits de cette application.
|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/42)
|
||||
|
||||
## Révision et étude personnelle
|
||||
|
||||
Le routage est l'une des parties étonnamment complexes du développement web, surtout à mesure que le web passe des comportements de rafraîchissement de page aux rafraîchissements de page des applications monopage. Lisez un peu sur [comment le service Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) gère le routage. Pouvez-vous expliquer pourquoi certaines des décisions décrites dans ce document sont nécessaires ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Améliorez le routage](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,26 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "8223e429218befa731dd5bfd22299520",
|
||||
"translation_date": "2025-08-24T00:10:03+00:00",
|
||||
"source_file": "7-bank-project/1-template-route/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Améliorer le routage
|
||||
|
||||
## Instructions
|
||||
|
||||
La déclaration des routes contient actuellement uniquement l'ID du modèle à utiliser. Mais lorsqu'une nouvelle page est affichée, il faut parfois un peu plus. Améliorons notre implémentation de routage avec deux fonctionnalités supplémentaires :
|
||||
|
||||
- Donner des titres à chaque modèle et mettre à jour le titre de la fenêtre avec ce nouveau titre lorsque le modèle change.
|
||||
- Ajouter une option pour exécuter du code après le changement de modèle. Nous voulons afficher `'Dashboard is shown'` dans la console développeur chaque fois que la page du tableau de bord est affichée.
|
||||
|
||||
## Critères d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| | Les deux fonctionnalités sont implémentées et fonctionnent. L'ajout de titre et de code fonctionne également pour une nouvelle route ajoutée dans la déclaration `routes`. | Les deux fonctionnalités fonctionnent, mais le comportement est codé en dur et non configurable via la déclaration `routes`. Ajouter une troisième route avec titre et code additionnel ne fonctionne pas ou fonctionne partiellement. | Une des fonctionnalités manque ou ne fonctionne pas correctement. |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,311 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
|
||||
"translation_date": "2025-08-23T23:58:30+00:00",
|
||||
"source_file": "7-bank-project/2-forms/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une application bancaire Partie 2 : Construire un formulaire de connexion et d'inscription
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/43)
|
||||
|
||||
### Introduction
|
||||
|
||||
Dans presque toutes les applications web modernes, vous pouvez créer un compte pour avoir votre propre espace privé. Comme plusieurs utilisateurs peuvent accéder à une application web en même temps, il est nécessaire de disposer d'un mécanisme pour stocker les données personnelles de chaque utilisateur séparément et sélectionner les informations à afficher. Nous ne couvrirons pas la gestion [sécurisée de l'identité utilisateur](https://en.wikipedia.org/wiki/Authentication), car c'est un sujet vaste en soi, mais nous nous assurerons que chaque utilisateur puisse créer un (ou plusieurs) compte(s) bancaire(s) sur notre application.
|
||||
|
||||
Dans cette partie, nous utiliserons des formulaires HTML pour ajouter une connexion et une inscription à notre application web. Nous verrons comment envoyer les données à une API serveur de manière programmatique, et finalement comment définir des règles de validation de base pour les entrées utilisateur.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous devez avoir terminé la partie [Modèles HTML et routage](../1-template-route/README.md) de l'application web pour cette leçon. Vous devez également installer [Node.js](https://nodejs.org) et [exécuter l'API serveur](../api/README.md) localement afin de pouvoir envoyer des données pour créer des comptes.
|
||||
|
||||
**À noter**
|
||||
Vous aurez deux terminaux à exécuter en même temps comme indiqué ci-dessous :
|
||||
1. Pour l'application bancaire principale que nous avons construite dans la leçon [Modèles HTML et routage](../1-template-route/README.md)
|
||||
2. Pour l'[API serveur de l'application bancaire](../api/README.md) que nous venons de configurer ci-dessus.
|
||||
|
||||
Vous devez avoir ces deux serveurs en fonctionnement pour suivre le reste de la leçon. Ils écoutent sur des ports différents (port `3000` et port `5000`), donc tout devrait bien fonctionner.
|
||||
|
||||
Vous pouvez tester si le serveur fonctionne correctement en exécutant cette commande dans un terminal :
|
||||
|
||||
```sh
|
||||
curl http://localhost:5000/api
|
||||
# -> should return "Bank API v1.0.0" as a result
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Formulaire et contrôles
|
||||
|
||||
L'élément `<form>` encapsule une section d'un document HTML où l'utilisateur peut saisir et soumettre des données à l'aide de contrôles interactifs. Il existe toutes sortes de contrôles d'interface utilisateur (UI) qui peuvent être utilisés dans un formulaire, les plus courants étant les éléments `<input>` et `<button>`.
|
||||
|
||||
Il existe de nombreux [types](https://developer.mozilla.org/docs/Web/HTML/Element/input) de `<input>`. Par exemple, pour créer un champ où l'utilisateur peut entrer son nom d'utilisateur, vous pouvez utiliser :
|
||||
|
||||
```html
|
||||
<input id="username" name="username" type="text">
|
||||
```
|
||||
|
||||
L'attribut `name` sera utilisé comme nom de propriété lorsque les données du formulaire seront envoyées. L'attribut `id` est utilisé pour associer un `<label>` au contrôle du formulaire.
|
||||
|
||||
> Consultez la liste complète des [types de `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) et [autres contrôles de formulaire](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) pour avoir une idée de tous les éléments d'interface utilisateur natifs que vous pouvez utiliser pour construire votre interface.
|
||||
|
||||
✅ Notez que `<input>` est un [élément vide](https://developer.mozilla.org/docs/Glossary/Empty_element) auquel vous ne devez *pas* ajouter une balise de fermeture correspondante. Vous pouvez cependant utiliser la notation auto-fermante `<input/>`, mais ce n'est pas obligatoire.
|
||||
|
||||
L'élément `<button>` dans un formulaire est un peu spécial. Si vous ne spécifiez pas son attribut `type`, il soumettra automatiquement les données du formulaire au serveur lorsqu'il est pressé. Voici les valeurs possibles pour l'attribut `type` :
|
||||
|
||||
- `submit` : Par défaut dans un `<form>`, le bouton déclenche l'action de soumission du formulaire.
|
||||
- `reset` : Le bouton réinitialise tous les contrôles du formulaire à leurs valeurs initiales.
|
||||
- `button` : N'associe aucun comportement par défaut lorsque le bouton est pressé. Vous pouvez ensuite lui attribuer des actions personnalisées à l'aide de JavaScript.
|
||||
|
||||
### Tâche
|
||||
|
||||
Commençons par ajouter un formulaire au modèle `login`. Nous aurons besoin d'un champ pour le *nom d'utilisateur* et d'un bouton *Connexion*.
|
||||
|
||||
```html
|
||||
<template id="login">
|
||||
<h1>Bank App</h1>
|
||||
<section>
|
||||
<h2>Login</h2>
|
||||
<form id="loginForm">
|
||||
<label for="username">Username</label>
|
||||
<input id="username" name="user" type="text">
|
||||
<button>Login</button>
|
||||
</form>
|
||||
</section>
|
||||
</template>
|
||||
```
|
||||
|
||||
Si vous regardez de plus près, vous pouvez remarquer que nous avons également ajouté un élément `<label>` ici. Les éléments `<label>` sont utilisés pour ajouter un nom aux contrôles de l'interface utilisateur, comme notre champ de nom d'utilisateur. Les étiquettes sont importantes pour la lisibilité de vos formulaires, mais elles offrent également des avantages supplémentaires :
|
||||
|
||||
- En associant une étiquette à un contrôle de formulaire, cela aide les utilisateurs utilisant des technologies d'assistance (comme un lecteur d'écran) à comprendre quelles données ils doivent fournir.
|
||||
- Vous pouvez cliquer sur l'étiquette pour mettre directement le focus sur le champ associé, ce qui le rend plus facile à atteindre sur les appareils à écran tactile.
|
||||
|
||||
> [L'accessibilité](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) sur le web est un sujet très important souvent négligé. Grâce aux [éléments HTML sémantiques](https://developer.mozilla.org/docs/Learn/Accessibility/HTML), il n'est pas difficile de créer du contenu accessible si vous les utilisez correctement. Vous pouvez [en savoir plus sur l'accessibilité](https://developer.mozilla.org/docs/Web/Accessibility) pour éviter les erreurs courantes et devenir un développeur responsable.
|
||||
|
||||
Ajoutons maintenant un deuxième formulaire pour l'inscription, juste en dessous du précédent :
|
||||
|
||||
```html
|
||||
<hr/>
|
||||
<h2>Register</h2>
|
||||
<form id="registerForm">
|
||||
<label for="user">Username</label>
|
||||
<input id="user" name="user" type="text">
|
||||
<label for="currency">Currency</label>
|
||||
<input id="currency" name="currency" type="text" value="$">
|
||||
<label for="description">Description</label>
|
||||
<input id="description" name="description" type="text">
|
||||
<label for="balance">Current balance</label>
|
||||
<input id="balance" name="balance" type="number" value="0">
|
||||
<button>Register</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
En utilisant l'attribut `value`, nous pouvons définir une valeur par défaut pour un champ donné.
|
||||
Remarquez également que le champ pour le `balance` a le type `number`. Cela semble-t-il différent des autres champs ? Essayez d'interagir avec.
|
||||
|
||||
✅ Pouvez-vous naviguer et interagir avec les formulaires uniquement à l'aide d'un clavier ? Comment feriez-vous cela ?
|
||||
|
||||
## Soumettre des données au serveur
|
||||
|
||||
Maintenant que nous avons une interface utilisateur fonctionnelle, l'étape suivante consiste à envoyer les données au serveur. Faisons un test rapide avec notre code actuel : que se passe-t-il si vous cliquez sur le bouton *Connexion* ou *Inscription* ?
|
||||
|
||||
Avez-vous remarqué le changement dans la section URL de votre navigateur ?
|
||||
|
||||

|
||||
|
||||
L'action par défaut d'un `<form>` est de soumettre le formulaire à l'URL actuelle du serveur en utilisant la [méthode GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), en ajoutant directement les données du formulaire à l'URL. Cependant, cette méthode présente quelques inconvénients :
|
||||
|
||||
- Les données envoyées sont très limitées en taille (environ 2000 caractères).
|
||||
- Les données sont directement visibles dans l'URL (pas idéal pour les mots de passe).
|
||||
- Cela ne fonctionne pas avec les téléchargements de fichiers.
|
||||
|
||||
C'est pourquoi vous pouvez changer cela pour utiliser la [méthode POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), qui envoie les données du formulaire au serveur dans le corps de la requête HTTP, sans les limitations précédentes.
|
||||
|
||||
> Bien que POST soit la méthode la plus couramment utilisée pour envoyer des données, [dans certains scénarios spécifiques](https://www.w3.org/2001/tag/doc/whenToUseGet.html), il est préférable d'utiliser la méthode GET, par exemple lors de l'implémentation d'un champ de recherche.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez les propriétés `action` et `method` au formulaire d'inscription :
|
||||
|
||||
```html
|
||||
<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">
|
||||
```
|
||||
|
||||
Essayez maintenant de créer un nouveau compte avec votre nom. Après avoir cliqué sur le bouton *Inscription*, vous devriez voir quelque chose comme ceci :
|
||||
|
||||

|
||||
|
||||
Si tout se passe bien, le serveur devrait répondre à votre requête avec une réponse [JSON](https://www.json.org/json-en.html) contenant les données du compte qui a été créé.
|
||||
|
||||
✅ Essayez de vous inscrire à nouveau avec le même nom. Que se passe-t-il ?
|
||||
|
||||
## Soumettre des données sans recharger la page
|
||||
|
||||
Comme vous l'avez probablement remarqué, il y a un léger problème avec l'approche que nous venons d'utiliser : en soumettant le formulaire, nous quittons notre application et le navigateur redirige vers l'URL du serveur. Nous essayons d'éviter tous les rechargements de page avec notre application web, car nous créons une [application monopage (SPA)](https://en.wikipedia.org/wiki/Single-page_application).
|
||||
|
||||
Pour envoyer les données du formulaire au serveur sans forcer un rechargement de la page, nous devons utiliser du code JavaScript. Au lieu de mettre une URL dans la propriété `action` d'un élément `<form>`, vous pouvez utiliser n'importe quel code JavaScript précédé de la chaîne `javascript:` pour effectuer une action personnalisée. Cela signifie également que vous devrez implémenter certaines tâches qui étaient auparavant effectuées automatiquement par le navigateur :
|
||||
|
||||
- Récupérer les données du formulaire.
|
||||
- Convertir et encoder les données du formulaire dans un format approprié.
|
||||
- Créer la requête HTTP et l'envoyer au serveur.
|
||||
|
||||
### Tâche
|
||||
|
||||
Remplacez l'attribut `action` du formulaire d'inscription par :
|
||||
|
||||
```html
|
||||
<form id="registerForm" action="javascript:register()">
|
||||
```
|
||||
|
||||
Ouvrez `app.js` et ajoutez une nouvelle fonction nommée `register` :
|
||||
|
||||
```js
|
||||
function register() {
|
||||
const registerForm = document.getElementById('registerForm');
|
||||
const formData = new FormData(registerForm);
|
||||
const data = Object.fromEntries(formData);
|
||||
const jsonData = JSON.stringify(data);
|
||||
}
|
||||
```
|
||||
|
||||
Ici, nous récupérons l'élément du formulaire à l'aide de `getElementById()` et utilisons l'assistant [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) pour extraire les valeurs des contrôles du formulaire sous forme de paires clé/valeur. Ensuite, nous convertissons les données en un objet régulier à l'aide de [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) et enfin, nous sérialisons les données en [JSON](https://www.json.org/json-en.html), un format couramment utilisé pour échanger des données sur le web.
|
||||
|
||||
Les données sont maintenant prêtes à être envoyées au serveur. Créez une nouvelle fonction nommée `createAccount` :
|
||||
|
||||
```js
|
||||
async function createAccount(account) {
|
||||
try {
|
||||
const response = await fetch('//localhost:5000/api/accounts', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: account
|
||||
});
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
return { error: error.message || 'Unknown error' };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Que fait cette fonction ? Tout d'abord, remarquez le mot-clé `async` ici. Cela signifie que la fonction contient du code qui s'exécutera de manière [**asynchrone**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Lorsqu'il est utilisé avec le mot-clé `await`, il permet d'attendre l'exécution du code asynchrone - comme attendre la réponse du serveur ici - avant de continuer.
|
||||
|
||||
Voici une courte vidéo sur l'utilisation de `async/await` :
|
||||
|
||||
[](https://youtube.com/watch?v=YwmlRkrxvkk "Async et Await pour gérer les promesses")
|
||||
|
||||
> 🎥 Cliquez sur l'image ci-dessus pour une vidéo sur async/await.
|
||||
|
||||
Nous utilisons l'API `fetch()` pour envoyer des données JSON au serveur. Cette méthode prend 2 paramètres :
|
||||
|
||||
- L'URL du serveur, donc nous remettons `//localhost:5000/api/accounts` ici.
|
||||
- Les paramètres de la requête. C'est là que nous définissons la méthode sur `POST` et fournissons le `body` de la requête. Comme nous envoyons des données JSON au serveur, nous devons également définir l'en-tête `Content-Type` sur `application/json` pour que le serveur sache comment interpréter le contenu.
|
||||
|
||||
Comme le serveur répondra à la requête avec du JSON, nous pouvons utiliser `await response.json()` pour analyser le contenu JSON et retourner l'objet résultant. Notez que cette méthode est asynchrone, donc nous utilisons le mot-clé `await` ici avant de retourner pour nous assurer que toutes les erreurs lors de l'analyse sont également capturées.
|
||||
|
||||
Ajoutez maintenant du code à la fonction `register` pour appeler `createAccount()` :
|
||||
|
||||
```js
|
||||
const result = await createAccount(jsonData);
|
||||
```
|
||||
|
||||
Comme nous utilisons le mot-clé `await` ici, nous devons ajouter le mot-clé `async` avant la fonction register :
|
||||
|
||||
```js
|
||||
async function register() {
|
||||
```
|
||||
|
||||
Enfin, ajoutons quelques journaux pour vérifier le résultat. La fonction finale devrait ressembler à ceci :
|
||||
|
||||
```js
|
||||
async function register() {
|
||||
const registerForm = document.getElementById('registerForm');
|
||||
const formData = new FormData(registerForm);
|
||||
const jsonData = JSON.stringify(Object.fromEntries(formData));
|
||||
const result = await createAccount(jsonData);
|
||||
|
||||
if (result.error) {
|
||||
return console.log('An error occurred:', result.error);
|
||||
}
|
||||
|
||||
console.log('Account created!', result);
|
||||
}
|
||||
```
|
||||
|
||||
C'était un peu long, mais nous y sommes arrivés ! Si vous ouvrez les [outils de développement de votre navigateur](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) et essayez de créer un nouveau compte, vous ne devriez voir aucun changement sur la page web, mais un message apparaîtra dans la console confirmant que tout fonctionne.
|
||||
|
||||

|
||||
|
||||
✅ Pensez-vous que les données sont envoyées au serveur de manière sécurisée ? Que se passerait-il si quelqu'un interceptait la requête ? Vous pouvez lire sur [HTTPS](https://en.wikipedia.org/wiki/HTTPS) pour en savoir plus sur la communication sécurisée des données.
|
||||
|
||||
## Validation des données
|
||||
|
||||
Si vous essayez de créer un nouveau compte sans définir un nom d'utilisateur au préalable, vous pouvez voir que le serveur retourne une erreur avec le code de statut [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
|
||||
|
||||
Avant d'envoyer des données à un serveur, il est bon de [valider les données du formulaire](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) au préalable lorsque cela est possible, pour s'assurer que vous envoyez une requête valide. Les contrôles de formulaire HTML5 offrent une validation intégrée à l'aide de divers attributs :
|
||||
|
||||
- `required` : le champ doit être rempli, sinon le formulaire ne peut pas être soumis.
|
||||
- `minlength` et `maxlength` : définissent le nombre minimum et maximum de caractères dans les champs texte.
|
||||
- `min` et `max` : définissent la valeur minimale et maximale d'un champ numérique.
|
||||
- `type` : définit le type de données attendu, comme `number`, `email`, `file` ou [d'autres types intégrés](https://developer.mozilla.org/docs/Web/HTML/Element/input). Cet attribut peut également modifier le rendu visuel du contrôle de formulaire.
|
||||
- `pattern` : permet de définir un modèle [d'expression régulière](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) pour tester si les données saisies sont valides ou non.
|
||||
> Astuce : vous pouvez personnaliser l'apparence de vos contrôles de formulaire en fonction de leur validité ou non en utilisant les pseudo-classes CSS `:valid` et `:invalid`.
|
||||
### Tâche
|
||||
|
||||
Il y a 2 champs obligatoires pour créer un nouveau compte valide : le nom d'utilisateur et la devise, les autres champs étant facultatifs. Mettez à jour le HTML du formulaire en utilisant à la fois l'attribut `required` et du texte dans l'étiquette du champ pour cela :
|
||||
|
||||
```html
|
||||
<label for="user">Username (required)</label>
|
||||
<input id="user" name="user" type="text" required>
|
||||
...
|
||||
<label for="currency">Currency (required)</label>
|
||||
<input id="currency" name="currency" type="text" value="$" required>
|
||||
```
|
||||
|
||||
Bien que cette implémentation particulière du serveur n'impose pas de limites spécifiques sur la longueur maximale des champs, il est toujours recommandé de définir des limites raisonnables pour toute saisie de texte par l'utilisateur.
|
||||
|
||||
Ajoutez un attribut `maxlength` aux champs de texte :
|
||||
|
||||
```html
|
||||
<input id="user" name="user" type="text" maxlength="20" required>
|
||||
...
|
||||
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
|
||||
...
|
||||
<input id="description" name="description" type="text" maxlength="100">
|
||||
```
|
||||
|
||||
Maintenant, si vous appuyez sur le bouton *S'inscrire* et qu'un champ ne respecte pas une règle de validation que nous avons définie, vous devriez voir quelque chose comme ceci :
|
||||
|
||||

|
||||
|
||||
Une validation comme celle-ci, effectuée *avant* d'envoyer des données au serveur, est appelée validation **côté client**. Mais notez qu'il n'est pas toujours possible d'effectuer toutes les vérifications sans envoyer les données. Par exemple, nous ne pouvons pas vérifier ici si un compte existe déjà avec le même nom d'utilisateur sans envoyer une requête au serveur. Une validation supplémentaire effectuée sur le serveur est appelée validation **côté serveur**.
|
||||
|
||||
En général, les deux doivent être mises en œuvre, et bien que l'utilisation de la validation côté client améliore l'expérience utilisateur en fournissant un retour instantané, la validation côté serveur est essentielle pour garantir que les données utilisateur que vous manipulez sont fiables et sécurisées.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Affichez un message d'erreur dans le HTML si l'utilisateur existe déjà.
|
||||
|
||||
Voici un exemple de ce à quoi la page de connexion finale peut ressembler après un peu de stylisation :
|
||||
|
||||

|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/44)
|
||||
|
||||
## Révision & Auto-apprentissage
|
||||
|
||||
Les développeurs ont fait preuve de beaucoup de créativité dans leurs efforts de création de formulaires, notamment en ce qui concerne les stratégies de validation. Découvrez différents flux de formulaires en parcourant [CodePen](https://codepen.com) ; pouvez-vous trouver des formulaires intéressants et inspirants ?
|
||||
|
||||
## Devoir
|
||||
|
||||
[Stylisez votre application bancaire](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "474f3ab1ee755ca980fc9104a0316e17",
|
||||
"translation_date": "2025-08-24T00:01:16+00:00",
|
||||
"source_file": "7-bank-project/2-forms/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Stylisez votre application bancaire
|
||||
|
||||
## Instructions
|
||||
|
||||
Créez un nouveau fichier `styles.css` et ajoutez un lien vers celui-ci dans votre fichier `index.html` actuel. Dans le fichier CSS que vous venez de créer, ajoutez des styles pour rendre les pages *Connexion* et *Tableau de bord* agréables et bien organisées. Essayez de créer un thème de couleurs pour donner à votre application une identité visuelle propre.
|
||||
|
||||
> Conseil : vous pouvez modifier le HTML et ajouter de nouveaux éléments et classes si nécessaire.
|
||||
|
||||
## Critères
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| | Toutes les pages sont propres et lisibles, avec un thème de couleurs cohérent et des sections bien mises en valeur. | Les pages sont stylisées mais sans thème ou avec des sections mal délimitées. | Les pages manquent de style, les sections sont désorganisées et les informations difficiles à lire. |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,345 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
|
||||
"translation_date": "2025-08-24T00:03:32+00:00",
|
||||
"source_file": "7-bank-project/3-data/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une application bancaire Partie 3 : Méthodes pour récupérer et utiliser des données
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/45)
|
||||
|
||||
### Introduction
|
||||
|
||||
Au cœur de chaque application web se trouvent les *données*. Les données peuvent prendre de nombreuses formes, mais leur objectif principal est toujours d'afficher des informations à l'utilisateur. Avec des applications web devenant de plus en plus interactives et complexes, la manière dont l'utilisateur accède et interagit avec les informations est désormais un aspect clé du développement web.
|
||||
|
||||
Dans cette leçon, nous verrons comment récupérer des données d'un serveur de manière asynchrone et utiliser ces données pour afficher des informations sur une page web sans recharger le HTML.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous devez avoir construit la partie [Formulaire de connexion et d'inscription](../2-forms/README.md) de l'application web pour cette leçon. Vous devez également installer [Node.js](https://nodejs.org) et [exécuter l'API du serveur](../api/README.md) localement pour obtenir les données de compte.
|
||||
|
||||
Vous pouvez tester que le serveur fonctionne correctement en exécutant cette commande dans un terminal :
|
||||
|
||||
```sh
|
||||
curl http://localhost:5000/api
|
||||
# -> should return "Bank API v1.0.0" as a result
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## AJAX et récupération de données
|
||||
|
||||
Les sites web traditionnels mettent à jour le contenu affiché lorsque l'utilisateur sélectionne un lien ou soumet des données via un formulaire, en rechargeant la page HTML complète. Chaque fois que de nouvelles données doivent être chargées, le serveur web renvoie une toute nouvelle page HTML qui doit être traitée par le navigateur, interrompant l'action en cours de l'utilisateur et limitant les interactions pendant le rechargement. Ce flux de travail est également appelé *Application Multi-Page* ou *MPA*.
|
||||
|
||||

|
||||
|
||||
Lorsque les applications web ont commencé à devenir plus complexes et interactives, une nouvelle technique appelée [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) a émergé. Cette technique permet aux applications web d'envoyer et de récupérer des données d'un serveur de manière asynchrone en utilisant JavaScript, sans avoir à recharger la page HTML, ce qui entraîne des mises à jour plus rapides et des interactions utilisateur plus fluides. Lorsque de nouvelles données sont reçues du serveur, la page HTML actuelle peut également être mise à jour avec JavaScript en utilisant l'API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Avec le temps, cette approche a évolué pour devenir ce que l'on appelle aujourd'hui une [*Application Mono-Page* ou *SPA*](https://en.wikipedia.org/wiki/Single-page_application).
|
||||
|
||||

|
||||
|
||||
Lorsque AJAX a été introduit pour la première fois, la seule API disponible pour récupérer des données de manière asynchrone était [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Mais les navigateurs modernes implémentent désormais l'API [`Fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API), plus pratique et puissante, qui utilise des promesses et est mieux adaptée pour manipuler des données JSON.
|
||||
|
||||
> Bien que tous les navigateurs modernes prennent en charge l'API `Fetch`, si vous souhaitez que votre application web fonctionne sur des navigateurs anciens ou obsolètes, il est toujours judicieux de vérifier d'abord le [tableau de compatibilité sur caniuse.com](https://caniuse.com/fetch).
|
||||
|
||||
### Tâche
|
||||
|
||||
Dans [la leçon précédente](../2-forms/README.md), nous avons implémenté le formulaire d'inscription pour créer un compte. Nous allons maintenant ajouter du code pour se connecter avec un compte existant et récupérer ses données. Ouvrez le fichier `app.js` et ajoutez une nouvelle fonction `login` :
|
||||
|
||||
```js
|
||||
async function login() {
|
||||
const loginForm = document.getElementById('loginForm')
|
||||
const user = loginForm.user.value;
|
||||
}
|
||||
```
|
||||
|
||||
Ici, nous commençons par récupérer l'élément du formulaire avec `getElementById()`, puis nous obtenons le nom d'utilisateur à partir de l'entrée avec `loginForm.user.value`. Chaque contrôle de formulaire peut être accédé par son nom (défini dans le HTML à l'aide de l'attribut `name`) en tant que propriété du formulaire.
|
||||
|
||||
De manière similaire à ce que nous avons fait pour l'inscription, nous allons créer une autre fonction pour effectuer une requête au serveur, mais cette fois pour récupérer les données du compte :
|
||||
|
||||
```js
|
||||
async function getAccount(user) {
|
||||
try {
|
||||
const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user));
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
return { error: error.message || 'Unknown error' };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Nous utilisons l'API `fetch` pour demander les données de manière asynchrone au serveur, mais cette fois, nous n'avons pas besoin de paramètres supplémentaires autres que l'URL à appeler, car nous ne faisons que demander des données. Par défaut, `fetch` crée une requête HTTP [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), ce qui est exactement ce que nous recherchons ici.
|
||||
|
||||
✅ `encodeURIComponent()` est une fonction qui échappe les caractères spéciaux pour les URL. Quels problèmes pourrions-nous rencontrer si nous ne faisons pas appel à cette fonction et utilisons directement la valeur `user` dans l'URL ?
|
||||
|
||||
Mettons maintenant à jour notre fonction `login` pour utiliser `getAccount` :
|
||||
|
||||
```js
|
||||
async function login() {
|
||||
const loginForm = document.getElementById('loginForm')
|
||||
const user = loginForm.user.value;
|
||||
const data = await getAccount(user);
|
||||
|
||||
if (data.error) {
|
||||
return console.log('loginError', data.error);
|
||||
}
|
||||
|
||||
account = data;
|
||||
navigate('/dashboard');
|
||||
}
|
||||
```
|
||||
|
||||
Tout d'abord, comme `getAccount` est une fonction asynchrone, nous devons l'associer au mot-clé `await` pour attendre le résultat du serveur. Comme pour toute requête serveur, nous devons également gérer les cas d'erreur. Pour l'instant, nous ajouterons simplement un message de journal pour afficher l'erreur et y reviendrons plus tard.
|
||||
|
||||
Ensuite, nous devons stocker les données quelque part pour pouvoir les utiliser plus tard pour afficher les informations du tableau de bord. Comme la variable `account` n'existe pas encore, nous allons créer une variable globale pour cela en haut de notre fichier :
|
||||
|
||||
```js
|
||||
let account = null;
|
||||
```
|
||||
|
||||
Une fois que les données utilisateur sont enregistrées dans une variable, nous pouvons naviguer de la page *login* à la page *dashboard* en utilisant la fonction `navigate()` que nous avons déjà.
|
||||
|
||||
Enfin, nous devons appeler notre fonction `login` lorsque le formulaire de connexion est soumis, en modifiant le HTML :
|
||||
|
||||
```html
|
||||
<form id="loginForm" action="javascript:login()">
|
||||
```
|
||||
|
||||
Testez que tout fonctionne correctement en enregistrant un nouveau compte et en essayant de vous connecter avec ce même compte.
|
||||
|
||||
Avant de passer à la partie suivante, nous pouvons également compléter la fonction `register` en ajoutant ceci à la fin de la fonction :
|
||||
|
||||
```js
|
||||
account = result;
|
||||
navigate('/dashboard');
|
||||
```
|
||||
|
||||
✅ Saviez-vous que par défaut, vous ne pouvez appeler les API serveur que depuis le *même domaine et port* que la page web que vous consultez ? C'est un mécanisme de sécurité appliqué par les navigateurs. Mais attendez, notre application web fonctionne sur `localhost:3000` alors que l'API du serveur fonctionne sur `localhost:5000`, pourquoi cela fonctionne-t-il ? En utilisant une technique appelée [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS), il est possible d'effectuer des requêtes HTTP inter-origines si le serveur ajoute des en-têtes spéciaux à la réponse, permettant des exceptions pour des domaines spécifiques.
|
||||
|
||||
> Apprenez-en davantage sur les API en suivant cette [leçon](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon)
|
||||
|
||||
## Mettre à jour le HTML pour afficher les données
|
||||
|
||||
Maintenant que nous avons les données utilisateur, nous devons mettre à jour le HTML existant pour les afficher. Nous savons déjà comment récupérer un élément du DOM en utilisant par exemple `document.getElementById()`. Une fois que vous avez un élément de base, voici quelques API que vous pouvez utiliser pour le modifier ou ajouter des éléments enfants :
|
||||
|
||||
- En utilisant la propriété [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent), vous pouvez changer le texte d'un élément. Notez que changer cette valeur supprime tous les enfants de l'élément (s'il y en a) et les remplace par le texte fourni. Ainsi, c'est également une méthode efficace pour supprimer tous les enfants d'un élément donné en lui assignant une chaîne vide `''`.
|
||||
|
||||
- En utilisant [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) avec la méthode [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append), vous pouvez créer et attacher un ou plusieurs nouveaux éléments enfants.
|
||||
|
||||
✅ En utilisant la propriété [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) d'un élément, il est également possible de changer son contenu HTML, mais cela doit être évité car c'est vulnérable aux attaques de [cross-site scripting (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting).
|
||||
|
||||
### Tâche
|
||||
|
||||
Avant de passer à l'écran du tableau de bord, il y a une chose de plus que nous devrions faire sur la page *login*. Actuellement, si vous essayez de vous connecter avec un nom d'utilisateur qui n'existe pas, un message est affiché dans la console, mais pour un utilisateur normal, rien ne change et vous ne savez pas ce qui se passe.
|
||||
|
||||
Ajoutons un élément de remplacement dans le formulaire de connexion où nous pourrons afficher un message d'erreur si nécessaire. Un bon endroit serait juste avant le bouton de connexion `<button>` :
|
||||
|
||||
```html
|
||||
...
|
||||
<div id="loginError"></div>
|
||||
<button>Login</button>
|
||||
...
|
||||
```
|
||||
|
||||
Cet élément `<div>` est vide, ce qui signifie que rien ne sera affiché à l'écran tant que nous n'y ajouterons pas du contenu. Nous lui donnons également un `id` pour pouvoir le récupérer facilement avec JavaScript.
|
||||
|
||||
Revenez au fichier `app.js` et créez une nouvelle fonction utilitaire `updateElement` :
|
||||
|
||||
```js
|
||||
function updateElement(id, text) {
|
||||
const element = document.getElementById(id);
|
||||
element.textContent = text;
|
||||
}
|
||||
```
|
||||
|
||||
Celle-ci est assez simple : étant donné un *id* d'élément et un *texte*, elle mettra à jour le contenu texte de l'élément DOM correspondant à l'`id`. Utilisons cette méthode à la place du précédent message d'erreur dans la fonction `login` :
|
||||
|
||||
```js
|
||||
if (data.error) {
|
||||
return updateElement('loginError', data.error);
|
||||
}
|
||||
```
|
||||
|
||||
Maintenant, si vous essayez de vous connecter avec un compte invalide, vous devriez voir quelque chose comme ceci :
|
||||
|
||||

|
||||
|
||||
Nous avons maintenant un texte d'erreur qui s'affiche visuellement, mais si vous essayez avec un lecteur d'écran, vous remarquerez que rien n'est annoncé. Pour que le texte ajouté dynamiquement à une page soit annoncé par les lecteurs d'écran, il devra utiliser quelque chose appelé une [Région Active](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions). Ici, nous allons utiliser un type spécifique de région active appelé une alerte :
|
||||
|
||||
```html
|
||||
<div id="loginError" role="alert"></div>
|
||||
```
|
||||
|
||||
Implémentez le même comportement pour les erreurs de la fonction `register` (n'oubliez pas de mettre à jour le HTML).
|
||||
|
||||
## Afficher les informations sur le tableau de bord
|
||||
|
||||
En utilisant les mêmes techniques que nous venons de voir, nous allons également nous occuper d'afficher les informations du compte sur la page du tableau de bord.
|
||||
|
||||
Voici à quoi ressemble un objet compte reçu du serveur :
|
||||
|
||||
```json
|
||||
{
|
||||
"user": "test",
|
||||
"currency": "$",
|
||||
"description": "Test account",
|
||||
"balance": 75,
|
||||
"transactions": [
|
||||
{ "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
|
||||
{ "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
|
||||
{ "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
> Remarque : pour vous faciliter la tâche, vous pouvez utiliser le compte `test` préexistant qui est déjà rempli avec des données.
|
||||
|
||||
### Tâche
|
||||
|
||||
Commençons par remplacer la section "Balance" dans le HTML pour ajouter des éléments de remplacement :
|
||||
|
||||
```html
|
||||
<section>
|
||||
Balance: <span id="balance"></span><span id="currency"></span>
|
||||
</section>
|
||||
```
|
||||
|
||||
Nous ajouterons également une nouvelle section juste en dessous pour afficher la description du compte :
|
||||
|
||||
```html
|
||||
<h2 id="description"></h2>
|
||||
```
|
||||
|
||||
✅ Comme la description du compte fonctionne comme un titre pour le contenu en dessous, elle est balisée de manière sémantique comme un titre. Apprenez-en davantage sur l'importance de la [structure des titres](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) pour l'accessibilité et examinez de manière critique la page pour déterminer ce qui pourrait également être un titre.
|
||||
|
||||
Ensuite, nous allons créer une nouvelle fonction dans `app.js` pour remplir les éléments de remplacement :
|
||||
|
||||
```js
|
||||
function updateDashboard() {
|
||||
if (!account) {
|
||||
return navigate('/login');
|
||||
}
|
||||
|
||||
updateElement('description', account.description);
|
||||
updateElement('balance', account.balance.toFixed(2));
|
||||
updateElement('currency', account.currency);
|
||||
}
|
||||
```
|
||||
|
||||
Tout d'abord, nous vérifions que nous avons les données du compte nécessaires avant d'aller plus loin. Ensuite, nous utilisons la fonction `updateElement()` que nous avons créée plus tôt pour mettre à jour le HTML.
|
||||
|
||||
> Pour rendre l'affichage du solde plus joli, nous utilisons la méthode [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) pour forcer l'affichage de la valeur avec 2 chiffres après la virgule.
|
||||
|
||||
Nous devons maintenant appeler notre fonction `updateDashboard()` chaque fois que le tableau de bord est chargé. Si vous avez déjà terminé l'[exercice de la leçon 1](../1-template-route/assignment.md), cela devrait être simple, sinon vous pouvez utiliser l'implémentation suivante.
|
||||
|
||||
Ajoutez ce code à la fin de la fonction `updateRoute()` :
|
||||
|
||||
```js
|
||||
if (typeof route.init === 'function') {
|
||||
route.init();
|
||||
}
|
||||
```
|
||||
|
||||
Et mettez à jour la définition des routes avec :
|
||||
|
||||
```js
|
||||
const routes = {
|
||||
'/login': { templateId: 'login' },
|
||||
'/dashboard': { templateId: 'dashboard', init: updateDashboard }
|
||||
};
|
||||
```
|
||||
|
||||
Avec ce changement, chaque fois que la page du tableau de bord est affichée, la fonction `updateDashboard()` est appelée. Après une connexion, vous devriez alors pouvoir voir le solde du compte, la devise et la description.
|
||||
|
||||
## Créer dynamiquement des lignes de tableau avec des modèles HTML
|
||||
|
||||
Dans la [première leçon](../1-template-route/README.md), nous avons utilisé des modèles HTML avec la méthode [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) pour implémenter la navigation dans notre application. Les modèles peuvent également être plus petits et utilisés pour remplir dynamiquement des parties répétitives d'une page.
|
||||
|
||||
Nous allons utiliser une approche similaire pour afficher la liste des transactions dans le tableau HTML.
|
||||
|
||||
### Tâche
|
||||
|
||||
Ajoutez un nouveau modèle dans le `<body>` du HTML :
|
||||
|
||||
```html
|
||||
<template id="transaction">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</template>
|
||||
```
|
||||
|
||||
Ce modèle représente une seule ligne de tableau, avec les 3 colonnes que nous voulons remplir : *date*, *objet* et *montant* d'une transaction.
|
||||
|
||||
Ensuite, ajoutez cette propriété `id` à l'élément `<tbody>` du tableau dans le modèle du tableau de bord pour le rendre plus facile à trouver avec JavaScript :
|
||||
|
||||
```html
|
||||
<tbody id="transactions"></tbody>
|
||||
```
|
||||
|
||||
Notre HTML est prêt, passons au code JavaScript et créons une nouvelle fonction `createTransactionRow` :
|
||||
|
||||
```js
|
||||
function createTransactionRow(transaction) {
|
||||
const template = document.getElementById('transaction');
|
||||
const transactionRow = template.content.cloneNode(true);
|
||||
const tr = transactionRow.querySelector('tr');
|
||||
tr.children[0].textContent = transaction.date;
|
||||
tr.children[1].textContent = transaction.object;
|
||||
tr.children[2].textContent = transaction.amount.toFixed(2);
|
||||
return transactionRow;
|
||||
}
|
||||
```
|
||||
|
||||
Cette fonction fait exactement ce que son nom implique : en utilisant le modèle que nous avons créé plus tôt, elle crée une nouvelle ligne de tableau et remplit son contenu avec les données de la transaction. Nous utiliserons cela dans notre fonction `updateDashboard()` pour remplir le tableau :
|
||||
|
||||
```js
|
||||
const transactionsRows = document.createDocumentFragment();
|
||||
for (const transaction of account.transactions) {
|
||||
const transactionRow = createTransactionRow(transaction);
|
||||
transactionsRows.appendChild(transactionRow);
|
||||
}
|
||||
updateElement('transactions', transactionsRows);
|
||||
```
|
||||
|
||||
Ici, nous utilisons la méthode [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) qui crée un nouveau fragment DOM sur lequel nous pouvons travailler, avant de l'attacher finalement à notre tableau HTML.
|
||||
|
||||
Il reste encore une chose à faire avant que ce code puisse fonctionner, car notre fonction `updateElement()` prend actuellement en charge uniquement le contenu texte. Modifions un peu son code :
|
||||
|
||||
```js
|
||||
function updateElement(id, textOrNode) {
|
||||
const element = document.getElementById(id);
|
||||
element.textContent = ''; // Removes all children
|
||||
element.append(textOrNode);
|
||||
}
|
||||
```
|
||||
|
||||
Nous utilisons la méthode [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) car elle permet d'attacher soit du texte, soit des [nœuds DOM](https://developer.mozilla.org/docs/Web/API/Node) à un élément parent, ce qui est parfait pour tous nos cas d'utilisation.
|
||||
Si vous essayez d'utiliser le compte `test` pour vous connecter, vous devriez maintenant voir une liste de transactions sur le tableau de bord 🎉.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Travaillez ensemble pour rendre la page du tableau de bord semblable à une véritable application bancaire. Si vous avez déjà stylisé votre application, essayez d'utiliser [les media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) pour créer un [design responsive](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) qui fonctionne bien à la fois sur les appareils de bureau et mobiles.
|
||||
|
||||
Voici un exemple de page de tableau de bord stylisée :
|
||||
|
||||

|
||||
|
||||
## Quiz après le cours
|
||||
|
||||
[Quiz après le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/46)
|
||||
|
||||
## Devoir
|
||||
|
||||
[Refactorisez et commentez votre code](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,27 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "a4abf305ede1cfaadd56a8fab4b4c288",
|
||||
"translation_date": "2025-08-24T00:06:14+00:00",
|
||||
"source_file": "7-bank-project/3-data/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Refactorisez et commentez votre code
|
||||
|
||||
## Instructions
|
||||
|
||||
À mesure que votre base de code grandit, il est important de refactoriser fréquemment votre code pour le rendre lisible et facile à maintenir sur le long terme. Ajoutez des commentaires et refactorisez votre `app.js` afin d'améliorer la qualité du code :
|
||||
|
||||
- Extrayez les constantes, comme l'URL de base de l'API du serveur
|
||||
- Factorisez le code similaire : par exemple, vous pouvez créer une fonction `sendRequest()` pour regrouper le code utilisé dans `createAccount()` et `getAccount()`
|
||||
- Réorganisez le code pour le rendre plus facile à lire, et ajoutez des commentaires
|
||||
|
||||
## Barème
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| | Le code est commenté, bien organisé en différentes sections et facile à lire. Les constantes sont extraites et une fonction factorisée `sendRequest()` a été créée. | Le code est propre mais pourrait être amélioré avec plus de commentaires, l'extraction de constantes ou la factorisation. | Le code est désordonné, non commenté, les constantes ne sont pas extraites et le code n'est pas factorisé. |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,292 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
|
||||
"translation_date": "2025-08-24T00:12:54+00:00",
|
||||
"source_file": "7-bank-project/4-state-management/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Créer une application bancaire Partie 4 : Concepts de gestion d'état
|
||||
|
||||
## Quiz avant le cours
|
||||
|
||||
[Quiz avant le cours](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/47)
|
||||
|
||||
### Introduction
|
||||
|
||||
À mesure qu'une application web grandit, il devient difficile de suivre tous les flux de données. Quel code obtient les données, quelle page les consomme, où et quand elles doivent être mises à jour... il est facile de se retrouver avec un code désordonné et difficile à maintenir. Cela est particulièrement vrai lorsque vous devez partager des données entre différentes pages de votre application, comme les données utilisateur. Le concept de *gestion d'état* a toujours existé dans tous les types de programmes, mais à mesure que les applications web deviennent de plus en plus complexes, il est désormais essentiel d'y réfléchir pendant le développement.
|
||||
|
||||
Dans cette dernière partie, nous allons examiner l'application que nous avons construite pour repenser la gestion de l'état, permettant de prendre en charge le rafraîchissement du navigateur à tout moment et de conserver les données entre les sessions utilisateur.
|
||||
|
||||
### Prérequis
|
||||
|
||||
Vous devez avoir terminé la partie [récupération de données](../3-data/README.md) de l'application web pour cette leçon. Vous devez également installer [Node.js](https://nodejs.org) et [exécuter l'API serveur](../api/README.md) localement afin de pouvoir gérer les données de compte.
|
||||
|
||||
Vous pouvez tester que le serveur fonctionne correctement en exécutant cette commande dans un terminal :
|
||||
|
||||
```sh
|
||||
curl http://localhost:5000/api
|
||||
# -> should return "Bank API v1.0.0" as a result
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repenser la gestion d'état
|
||||
|
||||
Dans la [leçon précédente](../3-data/README.md), nous avons introduit un concept de base de l'état dans notre application avec la variable globale `account` qui contient les données bancaires de l'utilisateur actuellement connecté. Cependant, notre implémentation actuelle présente quelques défauts. Essayez de rafraîchir la page lorsque vous êtes sur le tableau de bord. Que se passe-t-il ?
|
||||
|
||||
Il y a trois problèmes avec le code actuel :
|
||||
|
||||
- L'état n'est pas conservé, car un rafraîchissement du navigateur vous ramène à la page de connexion.
|
||||
- Plusieurs fonctions modifient l'état. À mesure que l'application grandit, cela peut rendre difficile le suivi des changements et il est facile d'oublier d'en mettre un à jour.
|
||||
- L'état n'est pas nettoyé, donc lorsque vous cliquez sur *Déconnexion*, les données du compte sont toujours présentes même si vous êtes sur la page de connexion.
|
||||
|
||||
Nous pourrions mettre à jour notre code pour résoudre ces problèmes un par un, mais cela créerait plus de duplication de code et rendrait l'application plus complexe et difficile à maintenir. Ou nous pourrions prendre quelques minutes pour repenser notre stratégie.
|
||||
|
||||
> Quels problèmes essayons-nous vraiment de résoudre ici ?
|
||||
|
||||
La [gestion d'état](https://en.wikipedia.org/wiki/State_management) consiste à trouver une bonne approche pour résoudre ces deux problèmes particuliers :
|
||||
|
||||
- Comment garder les flux de données dans une application compréhensibles ?
|
||||
- Comment maintenir les données d'état toujours synchronisées avec l'interface utilisateur (et vice versa) ?
|
||||
|
||||
Une fois que vous avez pris soin de ces points, tout autre problème que vous pourriez avoir pourrait déjà être résolu ou devenir plus facile à résoudre. Il existe de nombreuses approches possibles pour résoudre ces problèmes, mais nous opterons pour une solution courante qui consiste à **centraliser les données et les moyens de les modifier**. Les flux de données fonctionneraient comme suit :
|
||||
|
||||

|
||||
|
||||
> Nous ne couvrirons pas ici la partie où les données déclenchent automatiquement la mise à jour de la vue, car elle est liée à des concepts plus avancés de [programmation réactive](https://en.wikipedia.org/wiki/Reactive_programming). C'est un bon sujet de suivi si vous êtes prêt pour une plongée approfondie.
|
||||
|
||||
✅ Il existe de nombreuses bibliothèques avec différentes approches de gestion d'état, [Redux](https://redux.js.org) étant une option populaire. Jetez un œil aux concepts et aux modèles utilisés, car c'est souvent une bonne façon d'apprendre quels problèmes potentiels vous pourriez rencontrer dans les grandes applications web et comment ils peuvent être résolus.
|
||||
|
||||
### Tâche
|
||||
|
||||
Nous allons commencer par un peu de refactoring. Remplacez la déclaration `account` :
|
||||
|
||||
```js
|
||||
let account = null;
|
||||
```
|
||||
|
||||
Par :
|
||||
|
||||
```js
|
||||
let state = {
|
||||
account: null
|
||||
};
|
||||
```
|
||||
|
||||
L'idée est de *centraliser* toutes les données de notre application dans un seul objet d'état. Nous n'avons pour l'instant que `account` dans l'état, donc cela ne change pas grand-chose, mais cela ouvre la voie à des évolutions.
|
||||
|
||||
Nous devons également mettre à jour les fonctions qui l'utilisent. Dans les fonctions `register()` et `login()`, remplacez `account = ...` par `state.account = ...`;
|
||||
|
||||
Au début de la fonction `updateDashboard()`, ajoutez cette ligne :
|
||||
|
||||
```js
|
||||
const account = state.account;
|
||||
```
|
||||
|
||||
Ce refactoring en soi n'a pas apporté beaucoup d'améliorations, mais l'idée était de poser les bases des prochains changements.
|
||||
|
||||
## Suivre les changements de données
|
||||
|
||||
Maintenant que nous avons mis en place l'objet `state` pour stocker nos données, l'étape suivante consiste à centraliser les mises à jour. L'objectif est de faciliter le suivi de tout changement et de savoir quand ils se produisent.
|
||||
|
||||
Pour éviter que des modifications soient apportées à l'objet `state`, il est également judicieux de le considérer comme [*immuable*](https://en.wikipedia.org/wiki/Immutable_object), ce qui signifie qu'il ne peut pas être modifié du tout. Cela signifie également que vous devez créer un nouvel objet d'état si vous souhaitez modifier quoi que ce soit. En faisant cela, vous construisez une protection contre des [effets secondaires](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) potentiellement indésirables et ouvrez des possibilités pour de nouvelles fonctionnalités dans votre application, comme la mise en œuvre d'annulation/rétablissement, tout en facilitant le débogage. Par exemple, vous pourriez enregistrer chaque changement apporté à l'état et conserver un historique des modifications pour comprendre la source d'un bug.
|
||||
|
||||
En JavaScript, vous pouvez utiliser [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) pour créer une version immuable d'un objet. Si vous essayez de modifier un objet immuable, une exception sera levée.
|
||||
|
||||
✅ Connaissez-vous la différence entre un objet immuable *superficiel* et *profond* ? Vous pouvez en lire davantage [ici](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze).
|
||||
|
||||
### Tâche
|
||||
|
||||
Créons une nouvelle fonction `updateState()` :
|
||||
|
||||
```js
|
||||
function updateState(property, newData) {
|
||||
state = Object.freeze({
|
||||
...state,
|
||||
[property]: newData
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Dans cette fonction, nous créons un nouvel objet d'état et copions les données de l'état précédent en utilisant l'[*opérateur de propagation (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Ensuite, nous remplaçons une propriété particulière de l'objet d'état avec les nouvelles données en utilisant la [notation entre crochets](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` pour l'affectation. Enfin, nous verrouillons l'objet pour empêcher les modifications en utilisant `Object.freeze()`. Nous n'avons pour l'instant que la propriété `account` stockée dans l'état, mais avec cette approche, vous pouvez ajouter autant de propriétés que nécessaire dans l'état.
|
||||
|
||||
Nous mettrons également à jour l'initialisation de `state` pour nous assurer que l'état initial est également figé :
|
||||
|
||||
```js
|
||||
let state = Object.freeze({
|
||||
account: null
|
||||
});
|
||||
```
|
||||
|
||||
Après cela, mettez à jour la fonction `register` en remplaçant l'affectation `state.account = result;` par :
|
||||
|
||||
```js
|
||||
updateState('account', result);
|
||||
```
|
||||
|
||||
Faites de même avec la fonction `login`, en remplaçant `state.account = data;` par :
|
||||
|
||||
```js
|
||||
updateState('account', data);
|
||||
```
|
||||
|
||||
Nous allons maintenant profiter de l'occasion pour résoudre le problème des données de compte qui ne sont pas effacées lorsque l'utilisateur clique sur *Déconnexion*.
|
||||
|
||||
Créez une nouvelle fonction `logout()` :
|
||||
|
||||
```js
|
||||
function logout() {
|
||||
updateState('account', null);
|
||||
navigate('/login');
|
||||
}
|
||||
```
|
||||
|
||||
Dans `updateDashboard()`, remplacez la redirection `return navigate('/login');` par `return logout()`;
|
||||
|
||||
Essayez de créer un nouveau compte, de vous déconnecter et de vous reconnecter pour vérifier que tout fonctionne toujours correctement.
|
||||
|
||||
> Astuce : vous pouvez consulter tous les changements d'état en ajoutant `console.log(state)` en bas de `updateState()` et en ouvrant la console dans les outils de développement de votre navigateur.
|
||||
|
||||
## Conserver l'état
|
||||
|
||||
La plupart des applications web doivent conserver des données pour fonctionner correctement. Toutes les données critiques sont généralement stockées dans une base de données et accessibles via une API serveur, comme les données de compte utilisateur dans notre cas. Mais parfois, il est également intéressant de conserver certaines données dans l'application cliente qui s'exécute dans votre navigateur, pour une meilleure expérience utilisateur ou pour améliorer les performances de chargement.
|
||||
|
||||
Lorsque vous souhaitez conserver des données dans votre navigateur, il y a quelques questions importantes à vous poser :
|
||||
|
||||
- *Les données sont-elles sensibles ?* Vous devriez éviter de stocker des données sensibles côté client, comme les mots de passe utilisateur.
|
||||
- *Pendant combien de temps avez-vous besoin de conserver ces données ?* Prévoyez-vous d'accéder à ces données uniquement pour la session en cours ou souhaitez-vous qu'elles soient stockées indéfiniment ?
|
||||
|
||||
Il existe plusieurs façons de stocker des informations dans une application web, en fonction de ce que vous souhaitez accomplir. Par exemple, vous pouvez utiliser les URLs pour stocker une requête de recherche et la rendre partageable entre utilisateurs. Vous pouvez également utiliser les [cookies HTTP](https://developer.mozilla.org/docs/Web/HTTP/Cookies) si les données doivent être partagées avec le serveur, comme les informations d'[authentification](https://en.wikipedia.org/wiki/Authentication).
|
||||
|
||||
Une autre option consiste à utiliser l'une des nombreuses API de navigateur pour stocker des données. Deux d'entre elles sont particulièrement intéressantes :
|
||||
|
||||
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage) : un [stockage clé/valeur](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) permettant de conserver des données spécifiques au site web actuel entre différentes sessions. Les données enregistrées dans celui-ci n'expirent jamais.
|
||||
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) : celui-ci fonctionne de la même manière que `localStorage`, sauf que les données stockées sont effacées lorsque la session se termine (lorsque le navigateur est fermé).
|
||||
|
||||
Notez que ces deux API permettent uniquement de stocker des [chaînes de caractères](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Si vous souhaitez stocker des objets complexes, vous devrez les sérialiser au format [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) en utilisant [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
|
||||
|
||||
✅ Si vous souhaitez créer une application web qui ne fonctionne pas avec un serveur, il est également possible de créer une base de données côté client en utilisant l'API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Celle-ci est réservée à des cas d'utilisation avancés ou si vous devez stocker une quantité importante de données, car elle est plus complexe à utiliser.
|
||||
|
||||
### Tâche
|
||||
|
||||
Nous voulons que nos utilisateurs restent connectés jusqu'à ce qu'ils cliquent explicitement sur le bouton *Déconnexion*, donc nous utiliserons `localStorage` pour stocker les données du compte. Tout d'abord, définissons une clé que nous utiliserons pour stocker nos données.
|
||||
|
||||
```js
|
||||
const storageKey = 'savedAccount';
|
||||
```
|
||||
|
||||
Ajoutez ensuite cette ligne à la fin de la fonction `updateState()` :
|
||||
|
||||
```js
|
||||
localStorage.setItem(storageKey, JSON.stringify(state.account));
|
||||
```
|
||||
|
||||
Avec cela, les données du compte utilisateur seront conservées et toujours à jour, car nous avons centralisé précédemment toutes nos mises à jour d'état. C'est ici que nous commençons à bénéficier de tous nos refactorings précédents 🙂.
|
||||
|
||||
Comme les données sont enregistrées, nous devons également nous occuper de leur restauration lorsque l'application est chargée. Étant donné que nous commencerons à avoir plus de code d'initialisation, il peut être judicieux de créer une nouvelle fonction `init`, qui inclut également notre code précédent en bas de `app.js` :
|
||||
|
||||
```js
|
||||
function init() {
|
||||
const savedAccount = localStorage.getItem(storageKey);
|
||||
if (savedAccount) {
|
||||
updateState('account', JSON.parse(savedAccount));
|
||||
}
|
||||
|
||||
// Our previous initialization code
|
||||
window.onpopstate = () => updateRoute();
|
||||
updateRoute();
|
||||
}
|
||||
|
||||
init();
|
||||
```
|
||||
|
||||
Ici, nous récupérons les données enregistrées, et si elles existent, nous mettons à jour l'état en conséquence. Il est important de faire cela *avant* de mettre à jour la route, car il pourrait y avoir du code qui dépend de l'état pendant la mise à jour de la page.
|
||||
|
||||
Nous pouvons également faire de la page *Tableau de bord* la page par défaut de notre application, car nous conservons maintenant les données du compte. Si aucune donnée n'est trouvée, le tableau de bord s'occupe de rediriger vers la page *Connexion* de toute façon. Dans `updateRoute()`, remplacez le fallback `return navigate('/login');` par `return navigate('/dashboard');`.
|
||||
|
||||
Connectez-vous maintenant à l'application et essayez de rafraîchir la page. Vous devriez rester sur le tableau de bord. Avec cette mise à jour, nous avons pris soin de tous nos problèmes initiaux...
|
||||
|
||||
## Rafraîchir les données
|
||||
|
||||
...Mais nous pourrions également en avoir créé un nouveau. Oups !
|
||||
|
||||
Accédez au tableau de bord en utilisant le compte `test`, puis exécutez cette commande dans un terminal pour créer une nouvelle transaction :
|
||||
|
||||
```sh
|
||||
curl --request POST \
|
||||
--header "Content-Type: application/json" \
|
||||
--data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \
|
||||
http://localhost:5000/api/accounts/test/transactions
|
||||
```
|
||||
|
||||
Essayez de rafraîchir la page du tableau de bord dans le navigateur maintenant. Que se passe-t-il ? Voyez-vous la nouvelle transaction ?
|
||||
|
||||
L'état est conservé indéfiniment grâce à `localStorage`, mais cela signifie également qu'il n'est jamais mis à jour jusqu'à ce que vous vous déconnectiez de l'application et vous reconnectiez !
|
||||
|
||||
Une stratégie possible pour résoudre cela est de recharger les données du compte chaque fois que le tableau de bord est chargé, afin d'éviter des données obsolètes.
|
||||
|
||||
### Tâche
|
||||
|
||||
Créez une nouvelle fonction `updateAccountData` :
|
||||
|
||||
```js
|
||||
async function updateAccountData() {
|
||||
const account = state.account;
|
||||
if (!account) {
|
||||
return logout();
|
||||
}
|
||||
|
||||
const data = await getAccount(account.user);
|
||||
if (data.error) {
|
||||
return logout();
|
||||
}
|
||||
|
||||
updateState('account', data);
|
||||
}
|
||||
```
|
||||
|
||||
Cette méthode vérifie que nous sommes actuellement connectés, puis recharge les données du compte depuis le serveur.
|
||||
|
||||
Créez une autre fonction nommée `refresh` :
|
||||
|
||||
```js
|
||||
async function refresh() {
|
||||
await updateAccountData();
|
||||
updateDashboard();
|
||||
}
|
||||
```
|
||||
|
||||
Celle-ci met à jour les données du compte, puis s'occupe de mettre à jour le HTML de la page du tableau de bord. C'est ce que nous devons appeler lorsque la route du tableau de bord est chargée. Mettez à jour la définition de la route avec :
|
||||
|
||||
```js
|
||||
const routes = {
|
||||
'/login': { templateId: 'login' },
|
||||
'/dashboard': { templateId: 'dashboard', init: refresh }
|
||||
};
|
||||
```
|
||||
|
||||
Essayez de recharger le tableau de bord maintenant, il devrait afficher les données du compte mises à jour.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Défi
|
||||
|
||||
Maintenant que nous rechargeons les données du compte chaque fois que le tableau de bord est chargé, pensez-vous que nous avons encore besoin de conserver *toutes les données du compte* ?
|
||||
|
||||
Essayez de travailler ensemble pour modifier ce qui est enregistré et chargé depuis `localStorage` afin d'inclure uniquement ce qui est absolument nécessaire au fonctionnement de l'application.
|
||||
|
||||
## Quiz après le cours
|
||||
[Quiz après la conférence](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/48)
|
||||
|
||||
## Devoir
|
||||
|
||||
[Implémenter la boîte de dialogue "Ajouter une transaction"](assignment.md)
|
||||
|
||||
Voici un exemple de résultat après avoir terminé le devoir :
|
||||
|
||||

|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "f23a868536c07da991b1d4e773161e25",
|
||||
"translation_date": "2025-08-24T00:15:20+00:00",
|
||||
"source_file": "7-bank-project/4-state-management/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Implémenter la boîte de dialogue "Ajouter une transaction"
|
||||
|
||||
## Instructions
|
||||
|
||||
Notre application bancaire manque encore d'une fonctionnalité essentielle : la possibilité d'ajouter de nouvelles transactions.
|
||||
En utilisant tout ce que vous avez appris dans les quatre leçons précédentes, implémentez une boîte de dialogue "Ajouter une transaction" :
|
||||
|
||||
- Ajoutez un bouton "Ajouter une transaction" sur la page du tableau de bord
|
||||
- Créez soit une nouvelle page avec un modèle HTML, soit utilisez JavaScript pour afficher/masquer le HTML de la boîte de dialogue sans quitter la page du tableau de bord (vous pouvez utiliser la propriété [`hidden`](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/hidden) pour cela, ou des classes CSS)
|
||||
- Assurez-vous de gérer [l'accessibilité au clavier et aux lecteurs d'écran](https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) pour la boîte de dialogue
|
||||
- Implémentez un formulaire HTML pour recevoir les données d'entrée
|
||||
- Créez des données JSON à partir des données du formulaire et envoyez-les à l'API
|
||||
- Mettez à jour la page du tableau de bord avec les nouvelles données
|
||||
|
||||
Consultez les [spécifications de l'API serveur](../api/README.md) pour voir quelle API vous devez appeler et quel format JSON est attendu.
|
||||
|
||||
Voici un exemple de résultat après avoir terminé l'exercice :
|
||||
|
||||

|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------|
|
||||
| | L'ajout d'une transaction est entièrement implémenté en suivant toutes les bonnes pratiques vues dans les leçons. | L'ajout d'une transaction est implémenté, mais ne suit pas les bonnes pratiques vues dans les leçons, ou fonctionne seulement partiellement. | L'ajout d'une transaction ne fonctionne pas du tout. |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,33 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "830359535306594b448db6575ce5cdee",
|
||||
"translation_date": "2025-08-23T23:54:46+00:00",
|
||||
"source_file": "7-bank-project/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# :dollar: Construire une Banque
|
||||
|
||||
Dans ce projet, vous apprendrez à créer une banque fictive. Ces leçons incluent des instructions sur la mise en page d'une application web, la création de routes, la construction de formulaires, la gestion de l'état, et la récupération de données depuis une API pour accéder aux données de la banque.
|
||||
|
||||
|  |  |
|
||||
|--------------------------------|--------------------------------|
|
||||
|
||||
## Leçons
|
||||
|
||||
1. [Modèles HTML et Routes dans une Application Web](1-template-route/README.md)
|
||||
2. [Créer un Formulaire de Connexion et d'Inscription](2-forms/README.md)
|
||||
3. [Méthodes pour Récupérer et Utiliser des Données](3-data/README.md)
|
||||
4. [Concepts de Gestion d'État](4-state-management/README.md)
|
||||
|
||||
### Crédits
|
||||
|
||||
Ces leçons ont été écrites avec :hearts: par [Yohan Lasorsa](https://twitter.com/sinedied).
|
||||
|
||||
Si vous souhaitez apprendre à construire l'[API serveur](/7-bank-project/api/README.md) utilisée dans ces leçons, vous pouvez suivre [cette série de vidéos](https://aka.ms/NodeBeginner) (en particulier les vidéos 17 à 21).
|
||||
|
||||
Vous pouvez également consulter [ce tutoriel interactif sur Learn](https://aka.ms/learn/express-api).
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "461aa4fc74c6b1789c3a13b5d82c0cd9",
|
||||
"translation_date": "2025-08-24T00:10:41+00:00",
|
||||
"source_file": "7-bank-project/solution/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Application bancaire
|
||||
|
||||
> Exemple de solution pour le projet d'application bancaire, construit avec HTML5, CSS et JavaScript pur (aucun framework ou bibliothèque utilisé).
|
||||
|
||||
## Exécution de l'application
|
||||
|
||||
Assurez-vous d'abord que le [serveur API](../api/README.md) est en cours d'exécution.
|
||||
|
||||
Tout serveur web peut être utilisé pour exécuter l'application, mais puisque vous devriez déjà avoir [Node.js](https://nodejs.org) installé pour exécuter l'API, vous pouvez :
|
||||
|
||||
1. Cloner ce dépôt avec Git.
|
||||
2. Ouvrir un terminal, naviguer vers ce répertoire, puis exécuter `npx lite-server .`. Cela démarrera un serveur web de développement sur le port `3000`.
|
||||
3. Ouvrir `http://localhost:3000` dans un navigateur pour exécuter l'application.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,172 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
|
||||
"translation_date": "2025-08-23T23:33:00+00:00",
|
||||
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Utiliser un éditeur de code
|
||||
|
||||
Cette leçon couvre les bases de l'utilisation de [VSCode.dev](https://vscode.dev), un éditeur de code basé sur le web, afin que vous puissiez modifier votre code et contribuer à un projet sans rien installer sur votre ordinateur.
|
||||
|
||||
<!----
|
||||
TODO : ajouter une image optionnelle
|
||||

|
||||
> Sketchnote par [Nom de l'auteur](https://example.com)
|
||||
---->
|
||||
|
||||
<!---
|
||||
## Quiz avant la leçon
|
||||
[Quiz avant la leçon](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/3)
|
||||
---->
|
||||
|
||||
## Objectifs d'apprentissage
|
||||
|
||||
Dans cette leçon, vous apprendrez à :
|
||||
|
||||
- Utiliser un éditeur de code dans un projet de code
|
||||
- Suivre les modifications avec le contrôle de version
|
||||
- Personnaliser l'éditeur pour le développement
|
||||
|
||||
### Prérequis
|
||||
|
||||
Avant de commencer, vous devrez créer un compte sur [GitHub](https://github.com). Rendez-vous sur [GitHub](https://github.com/) et créez un compte si ce n'est pas déjà fait.
|
||||
|
||||
### Introduction
|
||||
|
||||
Un éditeur de code est un outil essentiel pour écrire des programmes et collaborer sur des projets de codage existants. Une fois que vous comprenez les bases d'un éditeur et comment utiliser ses fonctionnalités, vous pourrez les appliquer lors de l'écriture de code.
|
||||
|
||||
## Prise en main avec VSCode.dev
|
||||
|
||||
[VSCode.dev](https://vscode.dev) est un éditeur de code sur le web. Vous n'avez rien à installer pour l'utiliser, comme si vous ouvriez n'importe quel autre site web. Pour commencer avec l'éditeur, ouvrez le lien suivant : [https://vscode.dev](https://vscode.dev). Si vous n'êtes pas connecté à [GitHub](https://github.com/), suivez les instructions pour vous connecter ou créer un nouveau compte, puis connectez-vous.
|
||||
|
||||
Une fois chargé, il devrait ressembler à cette image :
|
||||
|
||||

|
||||
|
||||
Il y a trois sections principales, de la gauche vers la droite :
|
||||
|
||||
1. La _barre d'activité_ qui inclut quelques icônes, comme la loupe 🔎, l'engrenage ⚙️, et quelques autres.
|
||||
2. La barre d'activité étendue qui par défaut affiche l'_Explorateur_, appelée la _barre latérale_.
|
||||
3. Enfin, la zone de code à droite.
|
||||
|
||||
Cliquez sur chacune des icônes pour afficher un menu différent. Une fois terminé, cliquez sur l'_Explorateur_ pour revenir à l'état initial.
|
||||
|
||||
Lorsque vous commencez à créer ou modifier du code, cela se fera dans la plus grande zone à droite. Vous utiliserez également cette zone pour visualiser le code existant, ce que vous ferez ensuite.
|
||||
|
||||
## Ouvrir un dépôt GitHub
|
||||
|
||||
La première chose à faire est d'ouvrir un dépôt GitHub. Il existe plusieurs façons d'ouvrir un dépôt. Dans cette section, vous verrez deux méthodes différentes pour ouvrir un dépôt et commencer à travailler sur des modifications.
|
||||
|
||||
### 1. Avec l'éditeur
|
||||
|
||||
Utilisez l'éditeur lui-même pour ouvrir un dépôt distant. Si vous allez sur [VSCode.dev](https://vscode.dev), vous verrez un bouton _"Open Remote Repository"_ :
|
||||
|
||||

|
||||
|
||||
Vous pouvez également utiliser la palette de commandes. La palette de commandes est une boîte de saisie où vous pouvez taper un mot faisant partie d'une commande ou d'une action pour trouver la commande à exécuter. Utilisez le menu en haut à gauche, sélectionnez _View_, puis choisissez _Command Palette_, ou utilisez le raccourci clavier suivant : Ctrl-Shift-P (sur MacOS, ce serait Command-Shift-P).
|
||||
|
||||

|
||||
|
||||
Une fois le menu ouvert, tapez _open remote repository_, puis sélectionnez la première option. Plusieurs dépôts auxquels vous appartenez ou que vous avez ouverts récemment apparaîtront. Vous pouvez également utiliser une URL GitHub complète pour en sélectionner un. Utilisez l'URL suivante et collez-la dans la boîte :
|
||||
|
||||
```
|
||||
https://github.com/microsoft/Web-Dev-For-Beginners
|
||||
```
|
||||
|
||||
✅ Si tout se passe bien, vous verrez tous les fichiers de ce dépôt chargés dans l'éditeur de texte.
|
||||
|
||||
### 2. En utilisant l'URL
|
||||
|
||||
Vous pouvez également utiliser une URL directement pour charger un dépôt. Par exemple, l'URL complète pour le dépôt actuel est [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), mais vous pouvez remplacer le domaine GitHub par `VSCode.dev/github` et charger directement le dépôt. L'URL résultante serait [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners).
|
||||
|
||||
## Modifier des fichiers
|
||||
|
||||
Une fois que vous avez ouvert le dépôt dans le navigateur/vscode.dev, l'étape suivante consiste à effectuer des mises à jour ou des modifications sur le projet.
|
||||
|
||||
### 1. Créer un nouveau fichier
|
||||
|
||||
Vous pouvez soit créer un fichier dans un dossier existant, soit le créer dans le répertoire/dossier racine. Pour créer un nouveau fichier, ouvrez un emplacement/dossier où vous souhaitez enregistrer le fichier, sélectionnez l'icône _'New file ...'_ sur la barre d'activité _(à gauche)_, donnez-lui un nom et appuyez sur Entrée.
|
||||
|
||||

|
||||
|
||||
### 2. Modifier et enregistrer un fichier dans le dépôt
|
||||
|
||||
Utiliser vscode.dev est utile lorsque vous souhaitez effectuer rapidement des mises à jour sur votre projet sans avoir à charger de logiciel localement.
|
||||
Pour mettre à jour votre code, cliquez sur l'icône 'Explorer', également située sur la barre d'activité, pour afficher les fichiers et dossiers du dépôt.
|
||||
Sélectionnez un fichier pour l'ouvrir dans la zone de code, apportez vos modifications et enregistrez.
|
||||
|
||||

|
||||
|
||||
Une fois que vous avez terminé de mettre à jour votre projet, sélectionnez l'icône _`source control`_ qui contient toutes les nouvelles modifications que vous avez apportées à votre dépôt.
|
||||
|
||||
Pour voir les modifications que vous avez apportées à votre projet, sélectionnez le(s) fichier(s) dans le dossier `Changes` de la barre d'activité étendue. Cela ouvrira un 'Working Tree' pour que vous puissiez visualiser les modifications apportées au fichier. Le rouge indique une suppression dans le projet, tandis que le vert signifie une addition.
|
||||
|
||||

|
||||
|
||||
Si vous êtes satisfait des modifications apportées, survolez le dossier `Changes` et cliquez sur le bouton `+` pour mettre en scène les modifications. Mettre en scène signifie simplement préparer vos modifications pour les valider sur GitHub.
|
||||
|
||||
Si toutefois vous n'êtes pas à l'aise avec certaines modifications et que vous souhaitez les annuler, survolez le dossier `Changes` et sélectionnez l'icône `undo`.
|
||||
|
||||
Ensuite, saisissez un `message de commit` _(Une description des modifications apportées au projet)_, cliquez sur l'icône `check` pour valider et pousser vos modifications.
|
||||
|
||||
Une fois que vous avez terminé de travailler sur votre projet, sélectionnez l'icône `menu hamburger` en haut à gauche pour revenir au dépôt sur github.com.
|
||||
|
||||

|
||||
|
||||
## Utiliser des extensions
|
||||
|
||||
Installer des extensions sur VSCode vous permet d'ajouter de nouvelles fonctionnalités et des options de personnalisation à votre environnement de développement dans l'éditeur, afin d'améliorer votre flux de travail. Ces extensions vous aident également à ajouter la prise en charge de plusieurs langages de programmation et sont souvent soit des extensions génériques, soit des extensions spécifiques à un langage.
|
||||
|
||||
Pour parcourir la liste de toutes les extensions disponibles, cliquez sur l'icône _`Extensions`_ sur la barre d'activité et commencez à taper le nom de l'extension dans le champ de texte intitulé _'Search Extensions in Marketplace'_.
|
||||
Vous verrez une liste d'extensions, chacune contenant **le nom de l'extension, le nom de l'éditeur, une description en une phrase, le nombre de téléchargements** et **une note en étoiles**.
|
||||
|
||||

|
||||
|
||||
Vous pouvez également voir toutes les extensions précédemment installées en développant le dossier _`Installed`_, les extensions populaires utilisées par la plupart des développeurs dans le dossier _`Popular`_ et les extensions recommandées pour vous, soit par des utilisateurs dans le même espace de travail, soit en fonction de vos fichiers récemment ouverts, dans le dossier _`Recommended`_.
|
||||
|
||||

|
||||
|
||||
### 1. Installer des extensions
|
||||
|
||||
Pour installer une extension, tapez son nom dans le champ de recherche et cliquez dessus pour afficher des informations supplémentaires sur l'extension dans la zone de code une fois qu'elle apparaît dans la barre d'activité étendue.
|
||||
|
||||
Vous pouvez soit cliquer sur le _bouton bleu Installer_ dans la barre d'activité étendue pour l'installer, soit utiliser le bouton d'installation qui apparaît dans la zone de code une fois que vous sélectionnez l'extension pour charger des informations supplémentaires.
|
||||
|
||||

|
||||
|
||||
### 2. Personnaliser les extensions
|
||||
|
||||
Après avoir installé l'extension, vous devrez peut-être modifier son comportement et la personnaliser en fonction de vos préférences. Pour ce faire, sélectionnez l'icône Extensions, et cette fois, votre extension apparaîtra dans le dossier _Installed_, cliquez sur l'_**icône d'engrenage**_ et naviguez vers _Extensions Setting_.
|
||||
|
||||

|
||||
|
||||
### 3. Gérer les extensions
|
||||
|
||||
Après avoir installé et utilisé votre extension, vscode.dev offre des options pour gérer votre extension en fonction de différents besoins. Par exemple, vous pouvez choisir de :
|
||||
|
||||
- **Désactiver :** _(Vous désactivez temporairement une extension lorsque vous n'en avez plus besoin mais que vous ne voulez pas la désinstaller complètement)_
|
||||
|
||||
Sélectionnez l'extension installée dans la barre d'activité étendue > cliquez sur l'icône d'engrenage > sélectionnez 'Disable' ou 'Disable (Workspace)' **OU** ouvrez l'extension dans la zone de code et cliquez sur le bouton bleu Disable.
|
||||
|
||||
- **Désinstaller :** Sélectionnez l'extension installée dans la barre d'activité étendue > cliquez sur l'icône d'engrenage > sélectionnez 'Uninstall' **OU** ouvrez l'extension dans la zone de code et cliquez sur le bouton bleu Uninstall.
|
||||
|
||||
---
|
||||
|
||||
## Devoir
|
||||
|
||||
[Créer un site web CV en utilisant vscode.dev](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
|
||||
|
||||
<!----
|
||||
## Quiz après la leçon
|
||||
[Quiz après la leçon](https://ashy-river-0debb7803.1.azurestaticapps.net/quiz/4)
|
||||
---->
|
||||
|
||||
## Révision et auto-apprentissage
|
||||
|
||||
Lisez-en davantage sur [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) et certaines de ses autres fonctionnalités.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,21 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "b0a9b4cccd918195f58224d5793da1a6",
|
||||
"translation_date": "2025-08-23T22:20:24+00:00",
|
||||
"source_file": "CODE_OF_CONDUCT.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Code de conduite Open Source de Microsoft
|
||||
|
||||
Ce projet a adopté le [Code de conduite Open Source de Microsoft](https://opensource.microsoft.com/codeofconduct/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Ressources :
|
||||
|
||||
- [Code de conduite Open Source de Microsoft](https://opensource.microsoft.com/codeofconduct/?WT.mc_id=academic-77807-sagibbon)
|
||||
- [FAQ sur le Code de conduite de Microsoft](https://opensource.microsoft.com/codeofconduct/faq/?WT.mc_id=academic-77807-sagibbon)
|
||||
- Contactez [opencode@microsoft.com](mailto:opencode@microsoft.com) pour toute question ou préoccupation
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "777400e9f0336c7ee2f9a1200a88478f",
|
||||
"translation_date": "2025-08-23T22:22:42+00:00",
|
||||
"source_file": "CONTRIBUTING.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Contribution
|
||||
|
||||
Ce projet accueille avec plaisir les contributions et suggestions. La plupart des contributions nécessitent que vous acceptiez un Contrat de Licence de Contributeur (CLA) déclarant que vous avez le droit de, et que vous accordez effectivement, les droits nécessaires pour que nous puissions utiliser votre contribution. Pour plus de détails, visitez [https://cla.microsoft.com](https://cla.microsoft.com/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Lorsque vous soumettez une pull request, un CLA-bot déterminera automatiquement si vous devez fournir un CLA et annotera la PR en conséquence (par exemple, étiquette, commentaire). Suivez simplement les instructions fournies par le bot. Vous n'aurez à faire cela qu'une seule fois pour tous les dépôts utilisant notre CLA. Essayez également de nous expliquer pourquoi vous avez effectué ce changement afin que nous puissions mieux comprendre votre demande.
|
||||
|
||||
Ce projet a adopté le [Code de Conduite Open Source de Microsoft](https://opensource.microsoft.com/codeofconduct/?WT.mc_id=academic-77807-sagibbon).
|
||||
Pour plus d'informations, consultez la [FAQ sur le Code de Conduite](https://opensource.microsoft.com/codeofconduct/faq/?WT.mc_id=academic-77807-sagibbon) ou contactez [opencode@microsoft.com](mailto:opencode@microsoft.com) pour toute question ou commentaire supplémentaire.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,203 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "b672130244189715ac084c3259f6ab58",
|
||||
"translation_date": "2025-08-23T22:15:25+00:00",
|
||||
"source_file": "README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
[](https://github.com/microsoft/Web-Dev-For-Beginners/blob/master/LICENSE)
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/graphs/contributors/)
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/issues/)
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/pulls/)
|
||||
[](http://makeapullrequest.com)
|
||||
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/watchers/)
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/network/)
|
||||
[](https://GitHub.com/microsoft/Web-Dev-For-Beginners/stargazers/)
|
||||
|
||||
[](https://discord.gg/zxKYvhSnVp?WT.mc_id=academic-000002-leestott)
|
||||
|
||||
[](https://open.vscode.dev/microsoft/Web-Dev-For-Beginners)
|
||||
|
||||
# Développement Web pour Débutants - Un Programme
|
||||
|
||||
Apprenez les bases du développement web avec notre cours complet de 12 semaines proposé par les Microsoft Cloud Advocates. Chacune des 24 leçons explore JavaScript, CSS et HTML à travers des projets pratiques comme des terrariums, des extensions de navigateur et des jeux spatiaux. Participez à des quiz, des discussions et des exercices pratiques. Améliorez vos compétences et optimisez votre apprentissage grâce à notre pédagogie basée sur les projets. Commencez votre aventure de codage dès aujourd'hui !
|
||||
|
||||
#### 🧑🎓 _Vous êtes étudiant ?_
|
||||
|
||||
Visitez la [**page Student Hub**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) où vous trouverez des ressources pour débutants, des packs étudiants et même des moyens d'obtenir un bon de certification gratuit. C'est une page à mettre en favori et à consulter régulièrement, car nous changeons le contenu chaque mois.
|
||||
|
||||
### 📣 Annonce - _Nouveau programme_ sur l'IA générative pour JavaScript vient d'être publié
|
||||
|
||||
Ne manquez pas notre nouveau programme sur l'IA générative !
|
||||
|
||||
Visitez [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) pour commencer !
|
||||
|
||||
<div>
|
||||
<img src="./images/background.png" width="600px" />
|
||||
</div>
|
||||
|
||||
- Leçons couvrant tout, des bases à RAG.
|
||||
- Interagissez avec des personnages historiques grâce à GenAI et notre application compagnon.
|
||||
- Une narration amusante et engageante, vous voyagerez dans le temps !
|
||||
|
||||
<div>
|
||||
<img src="./images/character.png" width="600px" />
|
||||
</div>
|
||||
|
||||
Chaque leçon inclut un exercice à réaliser, une vérification des connaissances et un défi pour vous guider dans l'apprentissage de sujets tels que :
|
||||
- Les prompts et l'ingénierie des prompts
|
||||
- La génération d'applications texte et image
|
||||
- Les applications de recherche
|
||||
|
||||
Visitez [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) pour commencer !
|
||||
|
||||
## 🌱 Premiers pas
|
||||
|
||||
> **Enseignants**, nous avons [inclus quelques suggestions](for-teachers.md) sur la façon d'utiliser ce programme. Nous aimerions avoir vos retours [dans notre forum de discussion](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) !
|
||||
|
||||
**[Apprenants](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, pour chaque leçon, commencez par un quiz pré-lecture, puis lisez le contenu de la leçon, réalisez les différentes activités et vérifiez votre compréhension avec le quiz post-lecture.
|
||||
|
||||
Pour enrichir votre expérience d'apprentissage, connectez-vous avec vos pairs pour travailler ensemble sur les projets ! Les discussions sont encouragées dans notre [forum de discussion](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) où notre équipe de modérateurs sera disponible pour répondre à vos questions.
|
||||
|
||||
Pour approfondir votre éducation, nous vous recommandons vivement d'explorer [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) pour des ressources d'étude supplémentaires.
|
||||
|
||||
### 📋 Configuration de votre environnement
|
||||
|
||||
Ce programme dispose d'un environnement de développement prêt à l'emploi ! Lorsque vous commencez, vous pouvez choisir de suivre le programme dans un [Codespace](https://github.com/features/codespaces/) (_un environnement basé sur le navigateur, sans installation nécessaire_), ou localement sur votre ordinateur en utilisant un éditeur de texte tel que [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
#### Créez votre dépôt
|
||||
Pour sauvegarder facilement votre travail, il est recommandé de créer votre propre copie de ce dépôt. Vous pouvez le faire en cliquant sur le bouton **Use this template** en haut de la page. Cela créera un nouveau dépôt dans votre compte GitHub avec une copie du programme.
|
||||
|
||||
Suivez ces étapes :
|
||||
1. **Forkez le dépôt** : Cliquez sur le bouton "Fork" en haut à droite de cette page.
|
||||
2. **Clonez le dépôt** : `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
|
||||
|
||||
#### Exécuter le programme dans un Codespace
|
||||
|
||||
Dans votre copie de ce dépôt que vous avez créée, cliquez sur le bouton **Code** et sélectionnez **Open with Codespaces**. Cela créera un nouveau Codespace pour travailler.
|
||||
|
||||
<img src="./images/createcodespace.png" alt="Créer un Codespace" style="width:270px;"/>
|
||||
|
||||
#### Exécuter le programme localement sur votre ordinateur
|
||||
|
||||
Pour exécuter ce programme localement sur votre ordinateur, vous aurez besoin d'un éditeur de texte, d'un navigateur et d'un outil en ligne de commande. Notre première leçon, [Introduction aux langages de programmation et outils de travail](https://github.com/microsoft/Web-Dev-For-Beginners/tree/main/1-getting-started-lessons/1-intro-to-programming-languages), vous guidera à travers les différentes options pour chacun de ces outils afin que vous puissiez choisir ce qui vous convient le mieux.
|
||||
|
||||
Nous recommandons d'utiliser [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) comme éditeur, qui dispose également d'un [Terminal intégré](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon). Vous pouvez télécharger Visual Studio Code [ici](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
1. Clonez votre dépôt sur votre ordinateur. Vous pouvez le faire en cliquant sur le bouton **Code** et en copiant l'URL :
|
||||
|
||||
<img src="./images/createcodespace.png" alt="Copier l'URL de votre dépôt" style="width:270px;"/>
|
||||
|
||||
Ensuite, ouvrez [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) dans [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) et exécutez la commande suivante, en remplaçant `<your-repository-url>` par l'URL que vous venez de copier :
|
||||
|
||||
```bash
|
||||
git clone <your-repository-url>
|
||||
```
|
||||
|
||||
2. Ouvrez le dossier dans Visual Studio Code. Vous pouvez le faire en cliquant sur **File** > **Open Folder** et en sélectionnant le dossier que vous venez de cloner.
|
||||
|
||||
> Extensions recommandées pour Visual Studio Code :
|
||||
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - pour prévisualiser les pages HTML directement dans Visual Studio Code
|
||||
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - pour vous aider à écrire du code plus rapidement
|
||||
|
||||
## 📂 Chaque leçon inclut :
|
||||
|
||||
- un sketchnote optionnel
|
||||
- une vidéo complémentaire optionnelle
|
||||
- un quiz d'échauffement avant la leçon
|
||||
- une leçon écrite
|
||||
- pour les leçons basées sur des projets, des guides étape par étape pour construire le projet
|
||||
- des vérifications des connaissances
|
||||
- un défi
|
||||
- des lectures complémentaires
|
||||
- un exercice
|
||||
- un quiz après la leçon
|
||||
|
||||
> **À propos des quiz** : Tous les quiz sont contenus dans le dossier Quiz-app, 48 quiz au total avec trois questions chacun. Ils sont liés dans les leçons et l'application de quiz peut être exécutée localement ou déployée sur Azure ; suivez les instructions dans le dossier `quiz-app`. Ils sont progressivement traduits.
|
||||
|
||||
## 🗃️ Leçons
|
||||
|
||||
| | Nom du projet | Concepts enseignés | Objectifs d'apprentissage | Leçon liée | Auteur |
|
||||
| :-: | :-------------------------------------------------------: | :---------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
|
||||
| 01 | Premiers pas | Introduction à la programmation et outils de travail | Apprenez les bases communes à la plupart des langages de programmation et les outils utilisés par les développeurs professionnels | [Introduction aux langages de programmation et outils de travail](/1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
|
||||
| 02 | Premiers pas | Bases de GitHub, y compris le travail en équipe | Comment utiliser GitHub dans votre projet et collaborer avec d'autres sur une base de code | [Introduction à GitHub](/1-getting-started-lessons/2-github-basics/README.md) | Floor |
|
||||
| 03 | Premiers pas | Accessibilité | Apprenez les bases de l'accessibilité web | [Fondamentaux de l'accessibilité](/1-getting-started-lessons/3-accessibility/README.md) | Christopher |
|
||||
| 04 | Bases JS | Types de données en JavaScript | Les bases des types de données en JavaScript | [Types de données](/2-js-basics/1-data-types/README.md) | Jasmine |
|
||||
| 05 | Bases JS | Fonctions et méthodes | Apprenez à utiliser les fonctions et méthodes pour gérer le flux logique d'une application | [Fonctions et méthodes](/2-js-basics/2-functions-methods/README.md) | Jasmine et Christopher |
|
||||
| 06 | Bases JS | Prendre des décisions avec JS | Apprenez à créer des conditions dans votre code en utilisant des méthodes de prise de décision | [Prendre des décisions](/2-js-basics/3-making-decisions/README.md) | Jasmine |
|
||||
| 07 | Bases JS | Tableaux et boucles | Travaillez avec des données en utilisant des tableaux et des boucles en JavaScript | [Tableaux et boucles](/2-js-basics/4-arrays-loops/README.md) | Jasmine |
|
||||
| 08 | [Terrarium](/3-terrarium/solution/README.md) | HTML en pratique | Construisez le HTML pour créer un terrarium en ligne, en vous concentrant sur la création d'une mise en page | [Introduction au HTML](/3-terrarium/1-intro-to-html/README.md) | Jen |
|
||||
| 09 | [Terrarium](/3-terrarium/solution/README.md) | CSS en pratique | Construisez le CSS pour styliser le terrarium en ligne, en vous concentrant sur les bases du CSS, y compris rendre la page responsive | [Introduction au CSS](/3-terrarium/2-intro-to-css/README.md) | Jen |
|
||||
| 10 | [Terrarium](/3-terrarium/solution/README.md) | Fermetures JavaScript, manipulation du DOM | Construisez le JavaScript pour faire fonctionner le terrarium comme une interface glisser-déposer, en vous concentrant sur les fermetures et la manipulation du DOM | [Fermetures JavaScript, manipulation du DOM](/3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
|
||||
| 11 | [Jeu de frappe](/4-typing-game/solution/README.md) | Construire un jeu de frappe | Apprenez à utiliser les événements clavier pour piloter la logique de votre application JavaScript | [Programmation pilotée par événements](/4-typing-game/typing-game/README.md) | Christopher |
|
||||
| 12 | [Green Browser Extension](/5-browser-extension/solution/README.md) | Travailler avec les navigateurs | Apprenez comment fonctionnent les navigateurs, leur histoire, et comment structurer les premiers éléments d'une extension de navigateur | [À propos des navigateurs](/5-browser-extension/1-about-browsers/README.md) | Jen |
|
||||
| 13 | [Green Browser Extension](/5-browser-extension/solution/README.md) | Construire un formulaire, appeler une API et stocker des variables en local storage | Créez les éléments JavaScript de votre extension de navigateur pour appeler une API en utilisant des variables stockées en local storage | [APIs, Formulaires et Local Storage](/5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
|
||||
| 14 | [Green Browser Extension](/5-browser-extension/solution/README.md) | Processus en arrière-plan dans le navigateur, performance web | Utilisez les processus en arrière-plan du navigateur pour gérer l'icône de l'extension ; découvrez la performance web et quelques optimisations à apporter | [Tâches en arrière-plan et performance](/5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
|
||||
| 15 | [Space Game](/6-space-game/solution/README.md) | Développement de jeu plus avancé avec JavaScript | Découvrez l'héritage en utilisant à la fois les classes et la composition, ainsi que le modèle Pub/Sub, en préparation à la création d'un jeu | [Introduction au développement de jeu avancé](/6-space-game/1-introduction/README.md) | Chris |
|
||||
| 16 | [Space Game](/6-space-game/solution/README.md) | Dessiner sur canvas | Découvrez l'API Canvas, utilisée pour dessiner des éléments à l'écran | [Dessiner sur Canvas](/6-space-game/2-drawing-to-canvas/README.md) | Chris |
|
||||
| 17 | [Space Game](/6-space-game/solution/README.md) | Déplacer des éléments sur l'écran | Découvrez comment les éléments peuvent se déplacer en utilisant les coordonnées cartésiennes et l'API Canvas | [Déplacer des éléments](/6-space-game/3-moving-elements-around/README.md) | Chris |
|
||||
| 18 | [Space Game](/6-space-game/solution/README.md) | Détection de collision | Faites en sorte que les éléments entrent en collision et réagissent entre eux en utilisant les touches du clavier, et ajoutez une fonction de cooldown pour garantir la performance du jeu | [Détection de collision](/6-space-game/4-collision-detection/README.md) | Chris |
|
||||
| 19 | [Space Game](/6-space-game/solution/README.md) | Comptabiliser les points | Effectuez des calculs mathématiques basés sur l'état et la performance du jeu | [Comptabiliser les points](/6-space-game/5-keeping-score/README.md) | Chris |
|
||||
| 20 | [Space Game](/6-space-game/solution/README.md) | Terminer et redémarrer le jeu | Apprenez à terminer et redémarrer le jeu, y compris nettoyer les ressources et réinitialiser les valeurs des variables | [Condition de fin](/6-space-game/6-end-condition/README.md) | Chris |
|
||||
| 21 | [Banking App](/7-bank-project/solution/README.md) | Modèles HTML et routes dans une application web | Apprenez à créer la structure d'architecture d'un site web multipage en utilisant le routage et les modèles HTML | [Modèles HTML et routes](/7-bank-project/1-template-route/README.md) | Yohan |
|
||||
| 22 | [Banking App](/7-bank-project/solution/README.md) | Construire un formulaire de connexion et d'inscription | Découvrez comment créer des formulaires et gérer les routines de validation | [Formulaires](/7-bank-project/2-forms/README.md) | Yohan |
|
||||
| 23 | [Banking App](/7-bank-project/solution/README.md) | Méthodes pour récupérer et utiliser des données | Découvrez comment les données circulent dans et hors de votre application, comment les récupérer, les stocker et les supprimer | [Données](/7-bank-project/3-data/README.md) | Yohan |
|
||||
| 24 | [Banking App](/7-bank-project/solution/README.md) | Concepts de gestion d'état | Apprenez comment votre application conserve son état et comment le gérer de manière programmatique | [Gestion d'état](/7-bank-project/4-state-management/README.md) | Yohan |
|
||||
|
||||
|
||||
## 🏫 Pédagogie
|
||||
|
||||
Notre programme est conçu autour de deux principes pédagogiques clés :
|
||||
* apprentissage basé sur les projets
|
||||
* quiz fréquents
|
||||
|
||||
Le programme enseigne les bases de JavaScript, HTML et CSS, ainsi que les outils et techniques les plus récents utilisés par les développeurs web d'aujourd'hui. Les étudiants auront l'opportunité d'acquérir une expérience pratique en créant un jeu de dactylographie, un terrarium virtuel, une extension de navigateur écologique, un jeu de type Space Invader et une application bancaire pour entreprises. À la fin de la série, les étudiants auront acquis une solide compréhension du développement web.
|
||||
|
||||
> 🎓 Vous pouvez suivre les premières leçons de ce programme sous forme de [parcours d'apprentissage](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) sur Microsoft Learn !
|
||||
|
||||
En veillant à ce que le contenu soit aligné avec les projets, le processus devient plus engageant pour les étudiants et la rétention des concepts est augmentée. Nous avons également écrit plusieurs leçons d'introduction aux bases de JavaScript, accompagnées d'une vidéo de la collection "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)", dont certains auteurs ont contribué à ce programme.
|
||||
|
||||
De plus, un quiz à faible enjeu avant un cours oriente l'intention de l'étudiant vers l'apprentissage d'un sujet, tandis qu'un second quiz après le cours assure une meilleure rétention. Ce programme a été conçu pour être flexible et amusant, et peut être suivi en totalité ou en partie. Les projets commencent petits et deviennent de plus en plus complexes à la fin du cycle de 12 semaines.
|
||||
|
||||
Bien que nous ayons délibérément évité d'introduire des frameworks JavaScript pour nous concentrer sur les compétences de base nécessaires en tant que développeur web avant d'adopter un framework, une bonne étape suivante après avoir terminé ce programme serait d'apprendre Node.js via une autre collection de vidéos : "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
|
||||
|
||||
> Consultez notre [Code de conduite](CODE_OF_CONDUCT.md) et nos directives de [Contributions](CONTRIBUTING.md). Nous accueillons vos retours constructifs !
|
||||
|
||||
|
||||
## 🧭 Accès hors ligne
|
||||
|
||||
Vous pouvez exécuter cette documentation hors ligne en utilisant [Docsify](https://docsify.js.org/#/). Forkez ce dépôt, [installez Docsify](https://docsify.js.org/#/quickstart) sur votre machine locale, puis dans le dossier racine de ce dépôt, tapez `docsify serve`. Le site web sera servi sur le port 3000 de votre localhost : `localhost:3000`.
|
||||
|
||||
## 📘 PDF
|
||||
|
||||
Un PDF de toutes les leçons est disponible [ici](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf).
|
||||
|
||||
|
||||
## 🎒 Autres cours
|
||||
|
||||
Notre équipe produit d'autres cours ! Découvrez :
|
||||
|
||||
- [Generative AI for Beginners](https://aka.ms/genai-beginners)
|
||||
- [Generative AI for Beginners .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
|
||||
- [Generative AI with JavaScript](https://github.com/microsoft/generative-ai-with-javascript)
|
||||
- [Generative AI with Java](https://github.com/microsoft/Generative-AI-for-beginners-java)
|
||||
- [AI for Beginners](https://aka.ms/ai-beginners)
|
||||
- [Data Science for Beginners](https://aka.ms/datascience-beginners)
|
||||
- [ML for Beginners](https://aka.ms/ml-beginners)
|
||||
- [Cybersécurité pour débutants](https://github.com/microsoft/Security-101)
|
||||
- [Développement Web pour Débutants](https://aka.ms/webdev-beginners)
|
||||
- [IoT pour Débutants](https://aka.ms/iot-beginners)
|
||||
- [Développement XR pour Débutants](https://github.com/microsoft/xr-development-for-beginners)
|
||||
- [Maîtriser GitHub Copilot pour une utilisation agentique](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
|
||||
- [Maîtriser GitHub Copilot pour les développeurs C#/.NET](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
|
||||
- [Choisissez votre propre aventure Copilot](https://github.com/microsoft/CopilotAdventures)
|
||||
|
||||
## Licence
|
||||
|
||||
Ce dépôt est sous licence MIT. Consultez le fichier [LICENSE](../../LICENSE) pour plus d'informations.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,49 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "4ecc3bf2e27983d4c780be6f26ee6228",
|
||||
"translation_date": "2025-08-23T22:21:47+00:00",
|
||||
"source_file": "SECURITY.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
## Sécurité
|
||||
|
||||
Microsoft prend très au sérieux la sécurité de ses produits logiciels et services, y compris tous les dépôts de code source gérés via nos organisations GitHub, qui incluent [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin) et [nos organisations GitHub](https://opensource.microsoft.com/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Si vous pensez avoir découvert une vulnérabilité de sécurité dans un dépôt appartenant à Microsoft qui correspond à [la définition d'une vulnérabilité de sécurité de Microsoft](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)/?WT.mc_id=academic-77807-sagibbon), veuillez nous en informer comme décrit ci-dessous.
|
||||
|
||||
## Signaler des problèmes de sécurité
|
||||
|
||||
**Veuillez ne pas signaler de vulnérabilités de sécurité via les issues publiques de GitHub.**
|
||||
|
||||
Au lieu de cela, veuillez les signaler au Microsoft Security Response Center (MSRC) à l'adresse [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Si vous préférez soumettre sans vous connecter, envoyez un email à [secure@microsoft.com](mailto:secure@microsoft.com). Si possible, chiffrez votre message avec notre clé PGP ; vous pouvez la télécharger depuis la [page de la clé PGP du Microsoft Security Response Center](https://www.microsoft.com/msrc/pgp-key-msrc/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Vous devriez recevoir une réponse sous 24 heures. Si, pour une raison quelconque, vous ne recevez pas de réponse, veuillez faire un suivi par email pour vous assurer que nous avons bien reçu votre message initial. Des informations supplémentaires sont disponibles sur [microsoft.com/msrc](https://www.microsoft.com/msrc/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
Veuillez inclure les informations demandées ci-dessous (dans la mesure du possible) pour nous aider à mieux comprendre la nature et l'étendue du problème potentiel :
|
||||
|
||||
* Type de problème (par exemple, dépassement de tampon, injection SQL, script intersite, etc.)
|
||||
* Chemins complets des fichiers source liés à la manifestation du problème
|
||||
* Emplacement du code source affecté (tag/branche/commit ou URL directe)
|
||||
* Toute configuration spéciale requise pour reproduire le problème
|
||||
* Instructions détaillées pour reproduire le problème
|
||||
* Code de preuve de concept ou d'exploitation (si possible)
|
||||
* Impact du problème, y compris comment un attaquant pourrait exploiter le problème
|
||||
|
||||
Ces informations nous aideront à prioriser votre rapport plus rapidement.
|
||||
|
||||
Si vous signalez dans le cadre d'un programme de récompense pour bugs, des rapports plus complets peuvent contribuer à une récompense plus élevée. Veuillez consulter notre page [Programme de récompense pour bugs Microsoft](https://microsoft.com/msrc/bounty/?WT.mc_id=academic-77807-sagibbon) pour plus de détails sur nos programmes actifs.
|
||||
|
||||
## Langues préférées
|
||||
|
||||
Nous préférons que toutes les communications soient en anglais.
|
||||
|
||||
## Politique
|
||||
|
||||
Microsoft suit le principe de la [Divulgation coordonnée des vulnérabilités](https://www.microsoft.com/msrc/cvd/?WT.mc_id=academic-77807-sagibbon).
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,23 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "c9d207ff77b4bb46e46dc2b607a8ec1a",
|
||||
"translation_date": "2025-08-23T22:18:42+00:00",
|
||||
"source_file": "SUPPORT.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Support
|
||||
|
||||
## Comment signaler des problèmes et obtenir de l'aide
|
||||
|
||||
Ce projet utilise GitHub Issues pour suivre les bugs et les demandes de fonctionnalités. Veuillez rechercher les problèmes existants avant d'en créer de nouveaux afin d'éviter les doublons. Pour les nouveaux problèmes, signalez votre bug ou demande de fonctionnalité en tant que nouvel Issue.
|
||||
|
||||
Pour obtenir de l'aide et poser des questions sur l'utilisation de ce projet, veuillez consulter [nos directives de contribution](CONTRIBUTING.md).
|
||||
|
||||
## Politique de support de Microsoft
|
||||
|
||||
Le support pour ce projet se limite aux ressources mentionnées ci-dessus.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,19 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "ea9f0804bd62f46d9808e953ec7fc459",
|
||||
"translation_date": "2025-08-23T22:20:57+00:00",
|
||||
"source_file": "_404.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# Travail en cours
|
||||
|
||||
Nous travaillons sur cette page. Veuillez revenir plus tard.
|
||||
|
||||
Ouvrez une [issue](https://github.com/microsoft/Web-Dev-For-Beginners/issues/new/choose) si vous avez des questions.
|
||||
|
||||
**[Retour à l'accueil](../../../../../../..)**
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous ne sommes pas responsables des malentendus ou des interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,32 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "3bd2f51ecf4ac9b39277cba748943793",
|
||||
"translation_date": "2025-08-23T22:50:41+00:00",
|
||||
"source_file": "docs/_navbar.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
- Traductions
|
||||
- [English (United States)](../../../docs/README)
|
||||
- [বাংলা](../../../docs/README.bn)
|
||||
- [中文(中国)](../../../docs/README.zh-cn)
|
||||
- [中文(台湾)](../../../docs/README.zh-tw)
|
||||
- [Español](../../../docs/README.es)
|
||||
- [Français](../../../docs/README.fr)
|
||||
- [Ελληνικά](../../../docs/README.el)
|
||||
- [हिन्दी](../../../docs/README.hi)
|
||||
- [Bahasa Melayu](../../../docs/README.ms)
|
||||
- [മലയാളം](../../../docs/README.ml)
|
||||
- [தமிழ்](../../../docs/README.ta)
|
||||
- [తెలుగు](../../../docs/README.te)
|
||||
- [Bahasa Indonesia](../../../docs/README.id)
|
||||
- [Italiano](../../../docs/README.it)
|
||||
- [日本語](../../../docs/README.ja)
|
||||
- [Nederlands](../../../docs/README.nl)
|
||||
- [नेपाली](../../../docs/README.np)
|
||||
- [Português](../../../docs/README.pt)
|
||||
- [Русский](../../../docs/README.ru)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,49 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "655c91b5979de46f1d70d97f0c5f1d14",
|
||||
"translation_date": "2025-08-23T22:49:52+00:00",
|
||||
"source_file": "docs/_sidebar.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
- Introduction
|
||||
- [1](../1-getting-started-lessons/1-intro-to-programming-languages/README.md)
|
||||
- [2](../1-getting-started-lessons/2-github-basics/README.md)
|
||||
- [3](../1-getting-started-lessons/3-accessibility/README.md)
|
||||
|
||||
- Bases de JS
|
||||
- [4](../2-js-basics/1-data-types/README.md)
|
||||
- [5](../2-js-basics/2-functions-methods/README.md)
|
||||
- [6](../2-js-basics/3-making-decisions/README.md)
|
||||
- [7](../2-js-basics/4-arrays-loops/README.md)
|
||||
|
||||
- HTML, CSS, JS
|
||||
- [8](../3-terrarium/1-intro-to-html/README.md)
|
||||
- [9](../3-terrarium/2-intro-to-css/README.md)
|
||||
- [10](../3-terrarium/3-intro-to-DOM-and-closures/README.md)
|
||||
|
||||
- Jeu de dactylographie
|
||||
- [11](../4-typing-game/typing-game/README.md)
|
||||
|
||||
- Extension de navigateur
|
||||
- [12](../5-browser-extension/1-about-browsers/README.md)
|
||||
- [13](../5-browser-extension/2-forms-browsers-local-storage/README.md)
|
||||
- [14](../5-browser-extension/3-background-tasks-and-performance/README.md)
|
||||
|
||||
- Jeu spatial
|
||||
- [15](../6-space-game/1-introduction/README.md)
|
||||
- [16](../6-space-game/2-drawing-to-canvas/README.md)
|
||||
- [17](../6-space-game/3-moving-elements-around/README.md)
|
||||
- [18](../6-space-game/4-collision-detection/README.md)
|
||||
- [19](../6-space-game/5-keeping-score/README.md)
|
||||
- [20](../6-space-game/6-end-condition/README.md)
|
||||
|
||||
- Projet bancaire
|
||||
- [21](../7-bank-project/1-template-route/README.md)
|
||||
- [22](../7-bank-project/2-forms/README.md)
|
||||
- [23](../7-bank-project/3-data/README.md)
|
||||
- [24](../7-bank-project/4-state-management/README.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,45 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "75cb51f7ca9ea0b097ef4a1287e9290c",
|
||||
"translation_date": "2025-08-23T22:19:30+00:00",
|
||||
"source_file": "for-teachers.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
## Pour les enseignants
|
||||
|
||||
Souhaitez-vous utiliser ce programme dans votre classe ? N'hésitez pas !
|
||||
|
||||
En fait, vous pouvez l'utiliser directement sur GitHub en utilisant GitHub Classroom.
|
||||
|
||||
Pour ce faire, clonez ce dépôt. Vous devrez créer un dépôt pour chaque leçon, donc il faudra extraire chaque dossier dans un dépôt séparé. Ainsi, [GitHub Classroom](https://classroom.github.com/classrooms) pourra gérer chaque leçon individuellement.
|
||||
|
||||
Ces [instructions complètes](https://github.blog/2020-03-18-set-up-your-digital-classroom-with-github-classroom/) vous donneront une idée de la manière de configurer votre classe.
|
||||
|
||||
## Utilisation dans Moodle, Canvas ou Blackboard
|
||||
|
||||
Ce programme fonctionne très bien dans ces systèmes de gestion de l'apprentissage ! Utilisez le [fichier d'importation Moodle](../../../../../../../teaching-files/webdev-moodle.mbz) pour accéder à tout le contenu, ou essayez le [fichier Common Cartridge](../../../../../../../teaching-files/webdev-common-cartridge.imscc) qui contient une partie du contenu. Moodle Cloud ne prend pas en charge les exports complets de Common Cartridge, il est donc préférable d'utiliser le fichier Moodle qui peut être importé dans Canvas. Faites-nous savoir comment nous pouvons améliorer cette expérience.
|
||||
|
||||

|
||||
> Le programme dans une classe Moodle
|
||||
|
||||

|
||||
> Le programme dans Canvas
|
||||
|
||||
## Utilisation du dépôt tel quel
|
||||
|
||||
Si vous souhaitez utiliser ce dépôt tel qu'il est, sans passer par GitHub Classroom, cela est également possible. Vous devrez communiquer avec vos étudiants pour leur indiquer quelle leçon suivre ensemble.
|
||||
|
||||
Dans un format en ligne (Zoom, Teams ou autre), vous pourriez créer des salles de discussion pour les quiz et encadrer les étudiants afin de les préparer à apprendre. Ensuite, invitez les étudiants à participer aux quiz et à soumettre leurs réponses sous forme de 'issues' à un moment donné. Vous pourriez faire de même avec les devoirs si vous souhaitez que les étudiants travaillent de manière collaborative et ouverte.
|
||||
|
||||
Si vous préférez un format plus privé, demandez à vos étudiants de cloner le programme, leçon par leçon, dans leurs propres dépôts GitHub privés, et donnez-vous accès. Ils pourront alors compléter les quiz et les devoirs de manière privée et vous les soumettre via des issues sur votre dépôt de classe.
|
||||
|
||||
Il existe de nombreuses façons de faire fonctionner ce programme dans un format de classe en ligne. Faites-nous savoir ce qui fonctionne le mieux pour vous !
|
||||
|
||||
## Donnez-nous votre avis !
|
||||
|
||||
Nous souhaitons que ce programme soit adapté à vous et à vos étudiants. Connectez-vous avec nous dans le [coin des enseignants](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) et ouvrez une [**nouvelle issue**](https://github.com/microsoft/Web-Dev-For-Beginners/issues/new/choose) pour toute demande, problème ou retour.
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de faire appel à une traduction professionnelle humaine. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,63 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "0494be70ad7fadd13a8c3d549c23e355",
|
||||
"translation_date": "2025-08-24T00:16:04+00:00",
|
||||
"source_file": "lesson-template/README.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# [Sujet de la leçon]
|
||||
|
||||

|
||||
|
||||
## [Quiz avant le cours](../../../lesson-template/quiz-url)
|
||||
|
||||
[Décrire ce que nous allons apprendre]
|
||||
|
||||
### Introduction
|
||||
|
||||
Décrire ce qui sera abordé
|
||||
|
||||
> Notes
|
||||
|
||||
### Prérequis
|
||||
|
||||
Quelles étapes devraient avoir été couvertes avant cette leçon ?
|
||||
|
||||
### Préparation
|
||||
|
||||
Étapes préparatoires pour commencer cette leçon
|
||||
|
||||
---
|
||||
|
||||
[Parcourir le contenu par blocs]
|
||||
|
||||
## [Sujet 1]
|
||||
|
||||
### Tâche :
|
||||
|
||||
Travaillez ensemble pour améliorer progressivement votre base de code afin de construire le projet avec du code partagé :
|
||||
|
||||
```html
|
||||
code blocks
|
||||
```
|
||||
|
||||
✅ Vérification des connaissances - utilisez ce moment pour élargir les connaissances des étudiants avec des questions ouvertes
|
||||
|
||||
## [Sujet 2]
|
||||
|
||||
## [Sujet 3]
|
||||
|
||||
🚀 Défi : Ajoutez un défi pour que les étudiants travaillent ensemble en classe afin d'améliorer le projet
|
||||
|
||||
Optionnel : ajoutez une capture d'écran de l'interface utilisateur de la leçon terminée si cela est pertinent
|
||||
|
||||
## [Quiz après le cours](../../../lesson-template/quiz-url)
|
||||
|
||||
## Révision & Étude personnelle
|
||||
|
||||
**Devoir à rendre [MM/AA]** : [Nom du devoir](assignment.md)
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
@ -0,0 +1,21 @@
|
||||
<!--
|
||||
CO_OP_TRANSLATOR_METADATA:
|
||||
{
|
||||
"original_hash": "b5f62ec256c7e43e771f0d3b4e1a9130",
|
||||
"translation_date": "2025-08-24T00:16:39+00:00",
|
||||
"source_file": "lesson-template/assignment.md",
|
||||
"language_code": "fr"
|
||||
}
|
||||
-->
|
||||
# [Nom de l'assignation]
|
||||
|
||||
## Instructions
|
||||
|
||||
## Grille d'évaluation
|
||||
|
||||
| Critères | Exemplaire | Adéquat | À améliorer |
|
||||
| -------- | ---------- | ------- | ----------- |
|
||||
| | | | |
|
||||
|
||||
**Avertissement** :
|
||||
Ce document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de recourir à une traduction professionnelle réalisée par un humain. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue