commit
9c1814a9f7
@ -0,0 +1,196 @@
|
|||||||
|
# Les bases du JavaScript : Méthodes et fonctions
|
||||||
|
|
||||||
|

|
||||||
|
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||||
|
|
||||||
|
## Quiz préalable
|
||||||
|
[Quizz préalable](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/9?loc=fr)
|
||||||
|
|
||||||
|
Lorsque nous pensons à écrire du code, nous voulons toujours nous assurer que notre code est lisible. Bien que cela puisse paraître contre-intuitif, le code est lu bien plus souvent qu'il n'est écrit. Un outil essentiel dans la boîte à outils d'un développeur pour garantir un code maintenable est la **fonction**.
|
||||||
|
|
||||||
|
[](https://youtube.com/watch?v=XgKsD6Zwvlc "Methods and Functions")
|
||||||
|
|
||||||
|
> 🎥 Cliquez sur l'image ci-dessus pour voir une vidéo sur les méthodes et les fonctions.
|
||||||
|
|
||||||
|
> Vous pouvez suivre cette leçon sur [Microsoft Learn](https://docs.microsoft.com/fr-fr/learn/modules/web-development-101-functions/?WT.mc_id=academic-13441-cxa)!
|
||||||
|
|
||||||
|
## Fonctions
|
||||||
|
|
||||||
|
À la base, une fonction est un bloc de code que nous pouvons exécuter à la demande. C'est parfait pour les scénarios où nous devons effectuer la même tâche plusieurs fois; plutôt que de dupliquer la logique à plusieurs endroits (ce qui rendrait difficile la mise à jour le moment venu), nous pouvons la centraliser à un seul endroit et l'appeler chaque fois que nous avons besoin d'effectuer l'opération - vous pouvez même appeler des fonctions à partir d'autres fonctions !
|
||||||
|
|
||||||
|
La possibilité de nommer une fonction est tout aussi importante. Bien que cela puisse sembler trivial, le nom fournit un moyen rapide de documenter une section de code. On pourrait penser à l'étiquette d'un bouton. Si je clique sur un bouton qui indique "Annuler le chronomètre", je sais qu'il va arrêter le chronomètre.
|
||||||
|
|
||||||
|
## Créer et appeler une fonction
|
||||||
|
|
||||||
|
La syntaxe d'une fonction ressemble à ce qui suit :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function nameOfFunction() { // Définition de la fonction
|
||||||
|
// Code de la fonction
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Si je voulais créer une fonction pour afficher une salutation, elle pourrait ressembler à ceci :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function displayGreeting() {
|
||||||
|
console.log('Hello, world!');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque fois que nous voulons appeler (ou invoquer) notre fonction, nous utilisons le nom de la fonction suivi de `()`. Il est important de noter que notre fonction peut être définie avant ou après que nous ayons décidé de l'appeler; le compilateur JavaScript la trouvera pour vous.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Appel de notre fonction
|
||||||
|
displayGreeting();
|
||||||
|
```
|
||||||
|
|
||||||
|
> **NOTE:** Il existe un type spécial de fonction appelé **méthode**, que vous avez déjà utilisé ! En fait, nous l'avons vu dans notre démonstration ci-dessus lorsque nous avons utilisé `console.log`. Ce qui différencie une méthode d'une fonction, c'est qu'une méthode est attachée à un objet (`console` dans notre exemple), alors qu'une fonction est flottante. Vous entendrez de nombreux développeurs utiliser ces termes de manière interchangeable.
|
||||||
|
|
||||||
|
### Bonnes pratiques des fonctions
|
||||||
|
|
||||||
|
Il existe une poignée de bonnes pratiques à garder à l'esprit lors de la création de fonctions
|
||||||
|
|
||||||
|
- Comme toujours, utilisez des noms descriptifs afin de savoir ce que fera la fonction.
|
||||||
|
- Utilisez le **camelCase** pour combiner les mots.
|
||||||
|
- Faites en sorte que vos fonctions se concentrent sur une tâche spécifique
|
||||||
|
|
||||||
|
## Transmettre des informations à une fonction
|
||||||
|
|
||||||
|
Pour rendre une fonction plus réutilisable, vous voudrez souvent lui passer des informations. Si nous considérons notre exemple `displayGreeting` ci-dessus, il affichera seulement **Hello, world!**. Ce n'est pas la fonction la plus utile que l'on puisse créer. Si on veut la rendre un peu plus flexible, comme permettre à quelqu'un de spécifier le nom de la personne à saluer, on peut ajouter un **paramètre**. Un paramètre (aussi parfois appelé **argument**), est une information supplémentaire envoyée à une fonction.
|
||||||
|
|
||||||
|
Les paramètres sont énumérés dans la partie définition entre parenthèses et sont séparés par des virgules comme suit :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function name(param, param2, param3) {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nous pouvons mettre à jour notre `displayGreeting` pour accepter un nom et l'afficher.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function displayGreeting(name) {
|
||||||
|
const message = `Hello, ${name}!`;
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Lorsque nous voulons appeler notre fonction et passer le paramètre, nous le spécifions dans la parenthèse.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
displayGreeting('Christopher');
|
||||||
|
// Affiche "Hello, Christopher!"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Valeurs par défaut
|
||||||
|
|
||||||
|
Nous pouvons rendre notre fonction encore plus flexible en ajoutant d'autres paramètres. Mais que faire si nous ne voulons pas exiger que chaque valeur soit spécifiée ? Pour reprendre l'exemple de notre message d'accueil, nous pourrions laisser le nom comme paramètre obligatoire (nous devons savoir qui nous accueillons), mais nous voulons permettre à l'accueil lui-même d'être personnalisé à volonté. Si quelqu'un ne veut pas le personnaliser, nous fournissons une valeur par défaut à la place. Pour fournir une valeur par défaut à un paramètre, nous le définissons de la même manière que nous définissons une valeur pour une variable - `parameterName = 'defaultValue'`. Pour voir un exemple complet :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function displayGreeting(name, salutation='Hello') {
|
||||||
|
console.log(`${salutation}, ${name}`);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Lorsque nous appelons la fonction, nous pouvons alors décider si nous voulons définir une valeur pour `salutation`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
displayGreeting('Christopher');
|
||||||
|
// Affiche "Hello, Christopher"
|
||||||
|
|
||||||
|
displayGreeting('Christopher', 'Hi');
|
||||||
|
// Affiche "Hi, Christopher"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Valeurs de retour
|
||||||
|
|
||||||
|
Jusqu'à présent, la fonction que nous avons créée s'affiche toujours dans la [console] (https://developer.mozilla.org/docs/Web/API/console). Parfois, c'est exactement ce que nous recherchons, notamment lorsque nous créons des fonctions qui appelleront d'autres services. Mais que faire si je veux créer une fonction d'aide pour effectuer un calcul et renvoyer la valeur afin de pouvoir l'utiliser ailleurs ?
|
||||||
|
|
||||||
|
Nous pouvons le faire en utilisant une **valeur de retour**. Une valeur de retour est renvoyée par la fonction et peut être stockée dans une variable de la même manière qu'une valeur littérale telle qu'une chaîne ou un nombre.
|
||||||
|
|
||||||
|
Si une fonction renvoie quelque chose, le mot-clé `return` est utilisé. Le mot-clé `return` attend une valeur ou une référence de ce qui est retourné comme ceci :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return myVariable;
|
||||||
|
```
|
||||||
|
|
||||||
|
Nous pouvons créer une fonction pour créer un message d'accueil et renvoyer la valeur à l'appelant.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function createGreetingMessage(name) {
|
||||||
|
const message = `Hello, ${name}`;
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Lorsque nous appelons cette fonction, nous stockons la valeur dans une variable. C'est à peu près la même chose que de définir une variable à une valeur statique (comme `const name = 'Christopher'`).
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const greetingMessage = createGreetingMessage('Christopher');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fonctions comme paramètres de fonctions
|
||||||
|
|
||||||
|
Au fur et à mesure que vous progressez dans votre carrière de programmeur, vous rencontrerez des fonctions qui acceptent des fonctions comme paramètres. Cette astuce est couramment utilisée lorsque nous ne savons pas quand quelque chose va se produire ou se terminer, mais que nous savons que nous devons effectuer une opération en réponse.
|
||||||
|
|
||||||
|
Prenons l'exemple de [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), qui lance une minuterie et exécute un code lorsqu'elle est terminée. Nous devons lui indiquer quel code nous voulons exécuter. C'est le travail idéal pour une fonction !
|
||||||
|
|
||||||
|
Si vous exécutez le code ci-dessous, après 3 secondes, vous verrez le message **3 secondes se sont écoulées**.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function displayDone() {
|
||||||
|
console.log('3 secondes se sont écoulées');
|
||||||
|
}
|
||||||
|
// Valeur du délai en millisecondes
|
||||||
|
setTimeout(displayDone, 3000);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fonctions anonymes
|
||||||
|
|
||||||
|
Regardons à nouveau ce que nous avons construit. Nous créons une fonction avec un nom qui ne sera utilisé qu'une seule fois. Au fur et à mesure que notre application devient plus complexe, nous pouvons nous voir créer un grand nombre de fonctions qui ne seront appelées qu'une seule fois. Ce n'est pas l'idéal. Il s'avère que nous n'avons pas toujours besoin de fournir un nom !
|
||||||
|
|
||||||
|
Lorsque nous passons une fonction en paramètre, nous pouvons éviter d'en créer une à l'avance et en construire une en tant que partie du paramètre. Nous utilisons le même mot-clé `function`, mais nous le construisons comme un paramètre.
|
||||||
|
|
||||||
|
Réécrivons le code ci-dessus pour utiliser une fonction anonyme :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log('3 secondes se sont écoulées');
|
||||||
|
}, 3000);
|
||||||
|
```
|
||||||
|
|
||||||
|
Si vous exécutez notre nouveau code, vous remarquerez que nous obtenons les mêmes résultats. Nous avons créé une fonction, mais nous n'avons pas eu besoin de lui donner un nom !
|
||||||
|
|
||||||
|
### Fonctions fléchées
|
||||||
|
|
||||||
|
Un raccourci commun à de nombreux langages de programmation (y compris JavaScript) est la possibilité d'utiliser ce que l'on appelle une fonction **fléchée**. Elle utilise un indicateur spécial, `=>`, qui ressemble à une flèche - d'où son nom ! En utilisant `=>`, nous sommes en mesure de sauter le mot-clé `function`.
|
||||||
|
|
||||||
|
Réécrivons notre code une fois de plus pour utiliser une fonction fléchée :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('3 secondes se sont écoulées');
|
||||||
|
}, 3000);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quand utiliser chaque stratégie
|
||||||
|
|
||||||
|
Vous avez maintenant vu que nous avons trois façons de passer une fonction en paramètre et vous vous demandez peut-être quand utiliser chacune d'entre elles. Si vous savez que vous utiliserez la fonction plus d'une fois, créez-la normalement. Si vous ne l'utilisez qu'à un seul endroit, il est généralement préférable d'utiliser une fonction anonyme. C'est à vous de décider si vous utilisez une fonction fléchée ou la syntaxe plus traditionnelle `function`, mais vous remarquerez que la plupart des développeurs modernes préfèrent `=>`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Défi
|
||||||
|
|
||||||
|
Pouvez-vous expliquer en une phrase la différence entre les fonctions et les méthodes ? Essayez de le faire !
|
||||||
|
|
||||||
|
## Quiz de validation des connaissances
|
||||||
|
[Quiz de validation des connaissances](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/10?loc=fr)
|
||||||
|
|
||||||
|
## Révision et étude personnelle
|
||||||
|
|
||||||
|
Cela vaut la peine de [lire un peu plus sur les fonctions fléchées] (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), car elles sont de plus en plus utilisées dans les bases de code. Entraînez-vous à écrire une fonction, puis à la réécrire avec cette syntaxe.
|
||||||
|
|
||||||
|
## Affectation
|
||||||
|
|
||||||
|
[S'amuser avec les fonctions](assignment.md)
|
@ -0,0 +1,233 @@
|
|||||||
|
# Projet Terrarium Partie 1 : Introduction au HTML
|
||||||
|
|
||||||
|

|
||||||
|
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||||
|
|
||||||
|
## Quiz préalable
|
||||||
|
|
||||||
|
[Quiz préalable](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/15?loc=fr)
|
||||||
|
|
||||||
|
### Introduction
|
||||||
|
|
||||||
|
Le langage HTML (HyperText Markup Language) est le "squelette" du Web. Si le CSS "habille" votre HTML et JavaScript lui donne vie, HTML est le corps de votre application Web. La syntaxe du HTML reflète même cette idée, puisqu'elle comprend des balises "head", "body" et "footer".
|
||||||
|
|
||||||
|
Dans cette leçon, nous allons utiliser le HTML pour mettre en page le "squelette" de l'interface de notre terrarium virtuel. Elle comportera un titre et trois colonnes : une colonne de droite et une colonne de gauche où se trouvent les plantes que l'on peut faire glisser, et une zone centrale qui sera le véritable terrarium en verre. À la fin de cette leçon, vous serez en mesure de 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 à l'interface pour l'améliorer.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Sur votre ordinateur, créez un dossier appelé "terrarium" et, à l'intérieur, un fichier appelé "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 le dossier" et en naviguant vers votre nouveau dossier. Cliquez sur le petit bouton "file" dans le panneau de l'explorateur et créez le nouveau fichier :
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Ou alors :
|
||||||
|
|
||||||
|
Utilisez ces commandes sur votre terminal git :
|
||||||
|
* `mkdir terrarium`
|
||||||
|
* `cd terrarium`
|
||||||
|
* `touch index.html`
|
||||||
|
* `code index.html` ou `nano index.html`
|
||||||
|
|
||||||
|
> Les fichiers index.html indiquent au navigateur qu'il s'agit du fichier par défaut d'un dossier ; des URL telles que `https://anysite.com/test` peuvent être construites à l'aide d'une structure de dossiers comprenant un dossier appelé `test` avec `index.html` à l'intérieur ; `index.html` ne doit pas nécessairement apparaître dans une URL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Les balises DocType et html
|
||||||
|
|
||||||
|
La première ligne d'un fichier HTML est son doctype. Il est un peu surprenant que cette ligne doive figurer tout en haut du fichier, mais elle indique aux navigateurs plus anciens que le navigateur doit rendre la page en mode standard, conformément à la spécification html actuelle.
|
||||||
|
|
||||||
|
> Conseil : dans VS Code, vous pouvez passer la souris sur une balise et obtenir des informations sur son utilisation dans les guides de référence MDN.
|
||||||
|
|
||||||
|
La deuxième ligne doit être la balise d'ouverture de la balise `<html>`, suivie tout de suite par sa balise de fermeture `</html>`. Ces balises sont les éléments racine de votre interface.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Ajoutez ces lignes en haut de votre fichier `index.html` :
|
||||||
|
|
||||||
|
```HTML
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html></html>
|
||||||
|
```
|
||||||
|
|
||||||
|
✅ Il existe quelques modes différents qui peuvent être déterminés en définissant le DocType avec une chaîne d'interrogation: [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Ces modes permettaient de prendre en charge des navigateurs très anciens qui ne sont plus utilisés de nos jours (Netscape Navigator 4 et Internet Explorer 5). Vous pouvez vous en tenir à la déclaration doctype standard.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## La "tête" du document
|
||||||
|
|
||||||
|
La zone "head" du document HTML contient des informations essentielles 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 choses :
|
||||||
|
|
||||||
|
- le titre de la page
|
||||||
|
- les métadonnées de la page dont :
|
||||||
|
- le "jeu de caractères", qui indique le codage des caractères utilisé dans la page.
|
||||||
|
- des informations sur le navigateur, notamment `x-ua-compatible` qui indique que le navigateur IE=edge est pris en charge
|
||||||
|
- des informations sur la façon dont la fenêtre d'affichage doit se comporter lorsqu'elle est chargée. Le fait de donner à la fenêtre d'affichage une échelle initiale de 1 permet de contrôler le niveau de zoom lors du premier chargement de la page.
|
||||||
|
|
||||||
|
### 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 métabalise viewport comme ceci : `<meta name="viewport" content="width=600">`? En savoir plus sur le [viewport](https://developer.mozilla.org/docs/Mozilla/Mobile/Viewport_meta_tag).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Le "corps" du document
|
||||||
|
|
||||||
|
### Balises HTML
|
||||||
|
|
||||||
|
En HTML, vous ajoutez des balises à votre fichier .html pour créer les éléments d'une page Web. Chaque balise a généralement une balise d'ouverture et de fermeture, comme ceci : `<p>hello</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 les 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 dont la page a besoin pour rendre l'élément.
|
||||||
|
|
||||||
|
Créez un dossier dans votre application appelé `images` et ajoutez-y toutes les images du [dossier de code source](../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 et Divs. Les divs sont considérés comme des éléments de type "bloc", tandis que les spans sont "en ligne". Que se passerait-il si vous transformiez ces divs en spans ?
|
||||||
|
|
||||||
|
Avec ce balisage, les plantes apparaissent maintenant à l'écran. L'apparence est assez mauvaise, car elles n'ont pas encore été stylisées à l'aide de CSS, ce que nous ferons dans la prochaine leçon.
|
||||||
|
|
||||||
|
Chaque image possède un texte alternatif qui s'affiche même si vous ne pouvez pas voir ou rendre l'image. Il s'agit d'un attribut important à inclure pour l'accessibilité. Vous en saurez plus sur l'accessibilité dans les prochaines leçons ; pour l'instant, souvenez-vous que l'attribut alt fournit des informations alternatives pour une image si, pour une raison ou une autre, 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 la même balise alt ? Est-ce une bonne pratique ? Pourquoi ou pourquoi pas ? Pouvez-vous améliorer ce code ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Le balisage sémantique
|
||||||
|
|
||||||
|
En général, il est préférable d'utiliser une "sémantique" significative lors de l'écriture du HTML. Qu'est-ce que cela signifie ? Cela signifie que vous utilisez les balises HTML pour représenter le type de données ou d'interaction pour lequel elles ont été conçues. Par exemple, le texte du titre principal d'une page doit utiliser une balise `<h1>`.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Ajoutez la ligne suivante juste en dessous de votre balise d'ouverture `<body>` :
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h1>My Terrarium</h1>
|
||||||
|
```
|
||||||
|
|
||||||
|
L'utilisation de balises sémantiques, telles que des en-têtes `<h1>` et des listes non ordonnées rendues sous la forme de `<ul>`, aide les lecteurs d'écran à naviguer dans une page. En général, les boutons doivent être écrits sous la forme `<button>` et les listes sous la forme `<li>`. S'il est _possible_ d'utiliser des éléments `<span>` spécialement stylisés avec des gestionnaires de clics pour simuler des boutons, il est préférable pour les utilisateurs handicapés d'utiliser des technologies permettant de déterminer où se trouve un bouton sur une page et d'interagir avec lui, si l'élément apparaît comme un bouton. Pour cette raison, essayez d'utiliser le balisage sémantique autant que possible.
|
||||||
|
|
||||||
|
✅ 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 peut frustrer l'utilisateur ?
|
||||||
|
|
||||||
|
## Le terrarium
|
||||||
|
|
||||||
|
La dernière partie de cette interface consiste à créer des balises qui seront stylisées pour créer un terrarium.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Ajoutez cette balise 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>
|
||||||
|
```
|
||||||
|
|
||||||
|
✅ Bien que vous ayez ajouté cette balise à l'écran, vous ne voyez absolument rien rendre. Pourquoi ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀Défi
|
||||||
|
|
||||||
|
Il existe quelques "vieilles" balises sauvages en HTML avec lesquelles il est encore amusant de jouer, même si vous ne devriez pas utiliser des balises obsolètes telles que [ces balises](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) dans votre balisage. 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 de validation des connaissances
|
||||||
|
|
||||||
|
[Quiz de validation des connaissances](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/16?loc=fr)
|
||||||
|
|
||||||
|
## Révision et autoformation
|
||||||
|
|
||||||
|
Le HTML est le système de blocs de construction qui a contribué à faire du Web ce qu'il est aujourd'hui. Apprenez-en un peu plus sur son histoire en étudiant certaines balises anciennes et nouvelles. Pouvez-vous comprendre pourquoi certaines balises ont été supprimées et d'autres ajoutées ? Quelles balises pourraient être introduites à l'avenir ?
|
||||||
|
|
||||||
|
Pour en savoir plus sur la création de sites pour le web et les appareils mobiles, consultez le site [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-13441-cxa).
|
||||||
|
|
||||||
|
|
||||||
|
## Exercice
|
||||||
|
|
||||||
|
[Pratiquez votre HTML : Construisez une maquette de blog](assignment.md)
|
@ -0,0 +1,265 @@
|
|||||||
|
# Projet Terrarium Partie 2 : Introduction à CSS
|
||||||
|
|
||||||
|

|
||||||
|
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||||
|
|
||||||
|
## Quiz préalable
|
||||||
|
|
||||||
|
[Quiz préalable](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/17?loc=fr)
|
||||||
|
|
||||||
|
### Introduction
|
||||||
|
|
||||||
|
Les CSS, ou feuilles de style en cascade, résolvent un problème important du développement web : comment rendre votre site web agréable à regarder. Le style de vos applications les rend plus faciles à utiliser et plus belles. Vous pouvez également utiliser les feuilles de style CSS pour créer un design Web réactif (Responsive Web Design, RWD), ce qui permet à vos applications d'être belles quelle que soit la taille de l'écran sur lequel elles sont affichées. CSS n'a pas pour seul but d'améliorer l'apparence de votre application ; ses spécifications incluent des animations et des transformations qui permettent des interactions sophistiquées pour vos applications. Le groupe de travail CSS contribue à la mise à jour des spécifications CSS ; vous pouvez suivre leurs travaux sur le [site du World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
|
||||||
|
|
||||||
|
> Remarque : CSS est un langage qui évolue, comme tout ce qui existe sur le Web, et tous les navigateurs ne prennent pas en charge les parties les plus récentes de la spécification. 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 et l'utilisation de sélecteurs, le positionnement et l'utilisation de CSS pour créer des mises en page. Au cours de ce processus, nous allons mettre en page le terrarium et créer le terrarium lui-même.
|
||||||
|
|
||||||
|
### Pré-requis
|
||||||
|
|
||||||
|
Vous devriez avoir construit le HTML de votre terrarium et être prêt à le styliser.
|
||||||
|
|
||||||
|
### Tâches
|
||||||
|
|
||||||
|
Dans le dossier de votre 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 intègrent l'idée que les styles sont "en cascade", de sorte que l'application d'un style est guidée par sa priorité. Les styles définis par l'auteur du site Web sont prioritaires sur ceux définis par le navigateur. Les styles définis "en ligne" sont prioritaires par rapport à ceux définis dans une feuille de style externe.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Ajoutez le style en ligne "color : red" à votre balise `<h1>` :
|
||||||
|
|
||||||
|
```HTML
|
||||||
|
<h1 style="color: red">Mon 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 le faire, ou pourquoi pas ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Héritage
|
||||||
|
|
||||||
|
Les styles sont hérités d'un style ancestral à un style descendant, de sorte que les éléments imbriqués héritent des styles de leurs parents.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Définir la police du corps à une police donnée, et vérifier 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 de caractères de la page H1. Elle hérite de la police du corps, comme indiqué dans le navigateur :
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
✅ Peut-on 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` n'a que quelques balises stylisées, et l'application a un aspect assez étrange :
|
||||||
|
|
||||||
|
```CSS
|
||||||
|
body {
|
||||||
|
font-family: helvetica, arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #3a241d;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette façon de styliser une balise vous permet de contrôler des éléments uniques, mais vous devez contrôler les styles de plusieurs plantes de votre terrarium. Pour ce faire, vous devez utiliser les sélecteurs CSS.
|
||||||
|
|
||||||
|
### Identifiants
|
||||||
|
|
||||||
|
Ajoutez du style pour mettre en page les conteneurs gauche et droit. Comme il n'y a qu'un seul conteneur gauche et qu'un seul conteneur droit, on leur donne des identifiants dans le balisage. Pour leur donner un style, 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 placé ces conteneurs avec un positionnement absolu à l'extrême gauche et droite de l'écran, et vous avez utilisé des pourcentages pour leur largeur afin qu'ils puissent s'adapter aux petits écrans mobiles.
|
||||||
|
|
||||||
|
✅ Ce code est assez répété, 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 ? Il faudrait modifier le balisage et remanier le CSS :
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div id="left-container" class="container"></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Classes
|
||||||
|
|
||||||
|
Dans l'exemple ci-dessus, vous avez donné un style à deux éléments uniques de l'écran. Si vous souhaitez que les styles s'appliquent à de nombreux éléments à l'écran, vous pouvez utiliser des classes CSS. Faites-le pour disposer les plantes dans les conteneurs de gauche et de droite.
|
||||||
|
|
||||||
|
Remarquez que chaque plante dans le balisage HTML a une combinaison d'identifiants et de classes. Les identifiants sont utilisés par le JavaScript que vous ajouterez plus tard pour manipuler le placement des plantes du terrarium. Les classes, quant à elles, 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 ce qui suit à 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 remarquable dans cet extrait, c'est le mélange de positionnement relatif et absolu, que nous aborderons dans la section suivante. Jetez un coup d'œil à la façon dont les hauteurs sont traitées par les pourcentages :
|
||||||
|
|
||||||
|
Vous définissez la hauteur du porte-plante à 13%, un bon chiffre pour garantir que toutes les plantes sont affichées dans chaque conteneur vertical sans qu'il soit nécessaire de les faire défiler.
|
||||||
|
|
||||||
|
Vous réglez le porte-plante pour qu'il se déplace vers la gauche afin de permettre aux plantes d'être plus centrées dans leur conteneur. Les images ont une grande quantité d'arrière-plan transparent afin de les rendre plus glissantes, et doivent donc être déplacées vers la gauche pour mieux s'adapter à l'écran.
|
||||||
|
|
||||||
|
Ensuite, la plante elle-même se voit attribuer une largeur maximale de 150 %. Cela lui permet de s'adapter à la taille du navigateur. Essayez de redimensionner votre navigateur ; les plantes restent dans leurs conteneurs, mais leur taille est réduite pour s'adapter.
|
||||||
|
|
||||||
|
On notera également l'utilisation du z-index, qui permet de contrôler l'altitude relative d'un élément (de sorte que les plantes se trouvent sur le dessus du récipient et semblent se trouver à l'intérieur du terrarium).
|
||||||
|
|
||||||
|
✅ Pourquoi faut-il à la fois un support de plantes et un sélecteur CSS de plantes ?
|
||||||
|
|
||||||
|
## Positionnement CSS
|
||||||
|
|
||||||
|
Le mélange des propriétés de position (il existe des positions statiques, relatives, fixes, absolues et collantes) peut être un peu délicat, mais lorsqu'il est fait correctement, il vous donne un bon contrôle sur les éléments de vos pages.
|
||||||
|
|
||||||
|
Les éléments à positionnement 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 en fonction du corps du document.
|
||||||
|
|
||||||
|
Les éléments positionnés de manière relative sont positionnés en fonction des indications du CSS pour ajuster leur placement par rapport à leur position initiale.
|
||||||
|
|
||||||
|
Dans notre exemple, le `plant-holder` est un élément à positionnement relatif qui est positionné dans un conteneur à positionnement absolu. Le comportement qui en résulte est que les conteneurs de la barre latérale sont épinglés à gauche et à droite, et que le porte-plante est imbriqué, s'ajustant lui-même dans les barres latérales, ce qui donne de l'espace pour que les plantes soient placées dans une rangée verticale.
|
||||||
|
|
||||||
|
> La "plante" elle-même a également un positionnement absolu, nécessaire pour la rendre glissante, comme vous le découvrirez dans la prochaine leçon.
|
||||||
|
|
||||||
|
✅ Expérimentez en changeant les types de positionnement des récipients latéraux et du porte-plante. Que se passe-t-il ?
|
||||||
|
|
||||||
|
## Dispositions CSS
|
||||||
|
|
||||||
|
Vous allez maintenant utiliser ce que vous avez appris pour construire le terrarium lui-même, tout en utilisant le CSS !
|
||||||
|
|
||||||
|
Tout d'abord, donnez aux enfants de la div `.terrarium` le style d'un rectangle arrondi à l'aide de 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 la taille de votre navigateur, vous pouvez voir comment le bocal est également mis à l'échelle. Remarquez également les pourcentages de largeur et de hauteur des éléments du pot et la manière dont chaque élément est positionné de manière absolue au centre, épinglé au bas de la fenêtre.
|
||||||
|
|
||||||
|
Nous utilisons également `rem` pour le border-radius, une longueur relative à la police. Pour en savoir plus sur ce type de mesure relative, consultez la [spécification CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
|
||||||
|
|
||||||
|
✅ Essayez de modifier les couleurs et l'opacité du bocal par rapport à celles de la saleté. Que se passe-t-il ? Pourquoi ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Défi
|
||||||
|
|
||||||
|
Ajoutez un éclat "bulle" à la partie inférieure gauche du pot pour qu'il ressemble davantage à du verre. Vous allez styliser les fichiers `.jar-glossy-long` et `.jar-glossy-short` pour qu'ils ressemblent à une brillance réfléchie. Voici à quoi cela ressemblerait :
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Pour répondre au Quiz de validation des connaissances, suivez ce module d'apprentissage : [Donnez du style à votre application HTML avec CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics?WT.mc_id=academic-13441-cxa)
|
||||||
|
|
||||||
|
## Quiz de validation des connaissances
|
||||||
|
|
||||||
|
[Quiz de validation des connaissances](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/18?loc=fr)
|
||||||
|
|
||||||
|
## Révision et étude personnelle
|
||||||
|
|
||||||
|
Les feuilles de style en cascade (CSS) sont apparemment très simples, mais les difficultés sont nombreuses lorsqu'il s'agit d'adapter parfaitement une application à tous les navigateurs et à toutes les tailles d'écran. CSS-Grid et Flexbox sont des outils qui ont été développés pour rendre le travail un peu plus structuré et plus fiable. Découvrez ces outils en jouant à [Flexbox Froggy](https://flexboxfroggy.com/) et [Grid Garden](https://codepip.com/games/grid-garden/).
|
||||||
|
|
||||||
|
## Affectation
|
||||||
|
|
||||||
|
[Refactoring CSS](assignment.md)
|
@ -0,0 +1,217 @@
|
|||||||
|
# Projet Terrarium Partie 3 : Manipulation DOM et une fermeture
|
||||||
|
|
||||||
|

|
||||||
|
> Sketchnote par [Tomomi Imura](https://twitter.com/girlie_mac)
|
||||||
|
|
||||||
|
## Quiz préalable
|
||||||
|
|
||||||
|
[Quiz préalable](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/19?loc=fr)
|
||||||
|
|
||||||
|
### Introduction
|
||||||
|
|
||||||
|
La manipulation du DOM, ou "Document Object Model", est un aspect essentiel 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 comprennent la structure et le contenu d'un document sur le Web". Les défis autour de la manipulation du DOM sur le web ont souvent été à l'origine de l'utilisation de frameworks JavaScript au lieu de vanilla JavaScript pour gérer le DOM, mais nous nous débrouillerons seuls !
|
||||||
|
|
||||||
|
En outre, cette leçon présente l'idée d'une [fermeture JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), que vous pouvez considérer comme une fonction entourée d'une autre fonction, de sorte que la fonction interne ait accès à la portée de la fonction externe.
|
||||||
|
|
||||||
|
> Les fermetures JavaScript sont un sujet vaste et complexe. Cette leçon aborde l'idée la plus élémentaire : dans le code de ce terrarium, vous trouverez une fermeture : une fonction interne et une fonction externe construites de manière à permettre à la fonction interne d'accéder à la portée de la fonction externe. Pour de plus amples informations sur la façon dont cela fonctionne, veuillez consulter la [documentation approfondie](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
|
||||||
|
|
||||||
|
Nous allons utiliser une fermeture pour manipuler le DOM.
|
||||||
|
|
||||||
|
Imaginez le DOM comme un arbre, représentant toutes les façons dont un document de page Web peut être manipulé. Diverses API (interfaces de programme d'application) ont été écrites pour que les programmeurs, en utilisant le langage de programmation de leur choix, puissent accéder au DOM et l'éditer, le modifier, le réorganiser et le gérer.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 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 allons compléter 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 en mesure de faire entrer et sortir les plantes du terrarium en les faisant glisser.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Dans le dossier de votre terrarium, créez un nouveau fichier appelé `script.js`. Importez ce fichier dans la section `<head>` :
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="./script.js" defer></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
> Remarque : utilisez l'attribut `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 le chargement complet du fichier HTML. Vous pourriez également utiliser l'attribut `async`, qui permet au script de s'exécuter pendant l'analyse du fichier HTML, mais dans notre cas, il est important que les éléments HTML soient entièrement disponibles pour le glisser avant de permettre l'exécution du script de glisser.
|
||||||
|
---
|
||||||
|
|
||||||
|
## Les éléments du DOM
|
||||||
|
|
||||||
|
La première chose à faire est de créer des références aux éléments que vous voulez manipuler dans le DOM. Dans notre cas, il s'agit des 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 cherchez dans son DOM un élément avec un Id particulier. Vous vous souvenez que dans la première leçon sur le HTML, vous avez donné des Ids individuels à chaque image de plante (`id="plant1"`) ? Vous allez maintenant mettre à profit cet effort. Après avoir identifié chaque élément, vous passez cet élément à une fonction appelée `dragElement` que vous allez construire dans une minute. Ainsi, l'élément dans le HTML est maintenant capable de glisser, ou le sera bientôt.
|
||||||
|
|
||||||
|
✅ Pourquoi référençons-nous les éléments par leur Id ? Pourquoi pas par leur classe CSS ? Vous pouvez vous référer à la leçon précédente sur les CSS pour répondre à cette question.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## La fermeture
|
||||||
|
|
||||||
|
Vous êtes maintenant prêt à créer la fermeture dragElement, qui est une fonction externe entourant une ou plusieurs fonctions internes (dans notre cas, nous en aurons trois).
|
||||||
|
|
||||||
|
Les fermetures sont utiles lorsqu'une ou plusieurs fonctions doivent accéder à la portée d'une 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 pousse un nouveau type de bonbon dans un tableau qui existe déjà dans la fonction. Si vous deviez exécuter ce code, le tableau `candy` serait indéfini, car il s'agit d'une variable locale (locale à la fermeture).
|
||||||
|
|
||||||
|
✅ Comment pouvez-vous rendre le tableau `candy` accessible ? Essayez de le déplacer à l'extérieur de la fermeture. De cette façon, le tableau devient global, plutôt que de rester uniquement disponible à la portée locale de la fermeture.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Sous les déclarations d'éléments dans `script.js`, créez une fonction :
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function dragElement(terrariumElement) {
|
||||||
|
// Définir 4 positions pour le positionnement sur l'écran
|
||||||
|
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 quelques positions locales à `0` pour l'objet passé dans la fonction. Ce sont les variables locales qui seront manipulées pour chaque élément au fur et à mesure que vous ajouterez la fonctionnalité de glisser-déposer dans la fermeture à chaque élément. Le terrarium sera peuplé par ces éléments glissés, l'application doit donc garder la trace de l'endroit où ils sont placés.
|
||||||
|
|
||||||
|
En outre, l'élément terrariumElement qui est passé à cette fonction se voit attribuer un événement `pointerdown`, qui fait partie des [web APIs](https://developer.mozilla.org/docs/Web/API) conçus pour aider à la gestion du DOM. L'événement `onpointerdown` se déclenche lorsqu'on appuie sur un bouton ou, dans notre cas, lorsqu'on touche un élément glissant. Ce gestionnaire d'événements fonctionne à la fois sur les [navigateurs Web et mobiles](https://caniuse.com/?search=onpointerdown), à quelques exceptions près.
|
||||||
|
|
||||||
|
✅ Le [gestionnaire d'événement `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) est bien mieux supporté par les différents navigateurs ; pourquoi ne l'utiliseriez-vous pas ici ? Pensez au type exact d'interaction à l'écran que vous essayez de créer ici.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## La fonction Pointerdrag
|
||||||
|
|
||||||
|
Le 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. Premièrement, vous empêchez les événements par défaut qui se produisent normalement lors d'un pointeur vers le bas de se produire 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 avez construit le fichier de script complètement et essayez-le sans `e.preventDefault()` - que se passe-t-il ?
|
||||||
|
|
||||||
|
Ensuite, ouvrez `index.html` dans une fenêtre du navigateur, et inspectez l'interface. Lorsque vous cliquez sur une plante, vous pouvez voir comment l'événement 'e' est capturé. Creusez dans l'événement pour voir combien d'informations sont recueillies par un événement de type "pointeur vers le bas" !
|
||||||
|
|
||||||
|
Ensuite, notez comment les variables locales `pos3` et `pos4` sont définies sur e.clientX. Vous pouvez trouver les valeurs `e` dans le volet 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 cliquerez dessus et les ferez glisser, afin de garder une trace de leurs coordonnées.
|
||||||
|
|
||||||
|
✅ On comprend mieux pourquoi toute cette application est construite avec une seule grosse fermeture ? Si ce n'était pas le cas, comment maintiendriez-vous la portée de chacune des 14 plantes glissantes ?
|
||||||
|
|
||||||
|
Complétez la fonction initiale en ajoutant deux autres manipulations d'événements de pointeurs sous `pos4 = e.clientY` :
|
||||||
|
|
||||||
|
```html
|
||||||
|
document.onpointermove = elementDrag;
|
||||||
|
document.onpointerup = stopElementDrag;
|
||||||
|
```
|
||||||
|
Vous indiquez maintenant que vous voulez que la plante soit déplacée avec le pointeur lorsque vous la déplacez, et que le geste de déplacement s'arrête lorsque vous désélectionnez la plante. `onpointertermove` et `onpointerup` font partie de la même API que `onpointerdown`. L'interface lancera des erreurs maintenant car vous n'avez pas encore défini les fonctions `elementDrag` et `stopElementDrag`, donc construisez-les ensuite.
|
||||||
|
|
||||||
|
## Les fonctions elementDrag et stopElementDrag
|
||||||
|
|
||||||
|
Vous compléterez votre fermeture en ajoutant deux autres fonctions internes qui géreront ce qui se passe lorsque vous faites glisser une plante et que vous arrêtez de la faire glisser. Le comportement que vous souhaitez est que vous puissiez glisser n'importe quelle plante à tout moment et la placer n'importe où sur l'écran. Cette interface est assez libre (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, en retirant et en repositionnant les plantes.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
Ajoutez la fonction `elementDrag` juste après le crochet fermant 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 effectuez de nombreuses modifications des positions initiales 1-4 que vous avez définies comme variables locales dans la fonction externe. Que se passe-t-il ici ?
|
||||||
|
|
||||||
|
En glissant, vous réassignez `pos1` en le rendant égal à `pos3` (que vous avez défini précédemment comme `e.clientX`) moins la valeur actuelle de `e.clientX`. Vous effectuez une opération similaire pour `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 l'élément. Ensuite, vous manipulez 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 du haut et de la gauche de la plante 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 permettent d'affiner le comportement du terrarium et de ses plantes.
|
||||||
|
|
||||||
|
### Tâche
|
||||||
|
|
||||||
|
La dernière tâche pour compléter l'interface est d'ajouter la fonction `stopElementDrag` après l'accolade de fermeture 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 relancer la progression de votre plante en recommençant à la faire glisser, soit commencer à faire glisser une nouvelle plante.
|
||||||
|
|
||||||
|
✅ Que se passe-t-il si vous ne mettez pas ces événements à zéro ?
|
||||||
|
|
||||||
|
Vous avez maintenant terminé votre projet !
|
||||||
|
|
||||||
|
🥇Congratulations ! Tu as terminé ton magnifique terrarium. !terrarium fini](./images/terrarium-final.png)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Défi
|
||||||
|
|
||||||
|
Ajoutez un nouveau gestionnaire d'événements à votre fermeture pour faire quelque chose de plus aux plantes ; par exemple, double-cliquez sur une plante pour la mettre en avant. Soyez créatif !
|
||||||
|
|
||||||
|
## Quiz de validation des connaissances
|
||||||
|
|
||||||
|
[Quiz de validation des connaissances](https://happy-mud-02d95f10f.azurestaticapps.net/quiz/20?loc=fr)
|
||||||
|
|
||||||
|
## Examen et étude personnelle
|
||||||
|
|
||||||
|
Si faire glisser des éléments à l'écran semble trivial, il existe de nombreuses façons de le faire et de nombreux pièges, en fonction de l'effet recherché. En fait, il existe toute une [API de glisser-déposer](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) que vous pouvez essayer. Nous ne l'avons pas utilisée dans ce module car l'effet recherché était quelque peu différent, mais essayez cette API sur votre propre projet et voyez ce que vous pouvez réaliser.
|
||||||
|
|
||||||
|
Vous trouverez plus d'informations sur les événements liés aux pointeurs sur le site [W3C docs](https://www.w3.org/TR/pointerevents1/) et sur le site [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events).
|
||||||
|
|
||||||
|
Vérifiez toujours les capacités du navigateur en utilisant [CanIUse.com](https://caniuse.com/).
|
||||||
|
|
||||||
|
## Affectation
|
||||||
|
|
||||||
|
[Travailler un peu plus avec le DOM](assignment.md)
|
||||||
|
|
Binary file not shown.
@ -0,0 +1,15 @@
|
|||||||
|
# Améliorer le routage
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
|
||||||
|
La déclaration de routes ne contient actuellement que l'ID de modèle à utiliser. Mais lors de l'affichage d'une nouvelle page, un peu plus que celà est parfois nécessaire. Améliorons notre implémentation de routage avec deux fonctionnalités supplémentaires :
|
||||||
|
|
||||||
|
- Donnez des titres à chaque modèle et mettez à 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 les modifications du modèle. Nous voulons afficher « Le tableau de bord est affiché » dans la console du développeur à chaque fois que la page du tableau de bord est affichée.
|
||||||
|
|
||||||
|
## Rubrique
|
||||||
|
|
||||||
|
| Critères | Exemplaire | Adéquat | Besoin d'amélioration |
|
||||||
|
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
|
||||||
|
| | 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`. L'ajout d'une troisième route avec une addition de titre et de code ne fonctionne pas ou fonctionne partiellement. | L'une des fonctionnalités est manquante ou ne fonctionne pas correctement. |
|
Loading…
Reference in new issue