Skip to content
Snippets Groups Projects
Commit 012d630f authored by Thomas Fritsch's avatar Thomas Fritsch
Browse files

maj readme

parent 0e90f6c6
No related branches found
No related tags found
No related merge requests found
Showing
with 43 additions and 44 deletions
......@@ -2,7 +2,7 @@
# A. Les bases de l'API DOM <!-- omit in toc -->
## Sommaire <!-- omit in toc -->
- [A.1. Installation](#a1-installation)
- [A.1. Configuration du projet](#a1-configuration-du-projet)
- [A.2. Sélectionner des éléments](#a2-sélectionner-des-éléments)
- [A.2.1. querySelector()](#a21-queryselector)
- [A.2.2. querySelectorAll()](#a22-queryselectorall)
......@@ -13,26 +13,24 @@
***Ce TP va permettre de mettre en oeuvre les principales méthodes de sélection et de modification d'éléments de l'arbre DOM.***
## A.1. Installation
1. **Récupérez le contenu du dossier `demarrage`, il contient une solution du TP sur la POO, les modules et le typage qui servira de base pour ce TP sur l'API DOM.** Comme lors du TP précédent n'oubliez pas de lancer un serveur web dans ce dossier
## A.1. Configuration du projet
**Ce repo contient une solution commentée du précédent TP. Il servira de base au T3 :**
1. Clonez le projet
```bash
cd /chemin/vers/votre/dossier/demarrage
python3 -m http.server 8000
mkdir -p ~/ws-js/tp3
git clone https://gitlab.univ-lille.fr/js/tp3.git ~/ws-js/tp3
```
*Si vous avez des questions sur le lancement de ce serveur, ou sur la procédure à suivre dans le cas où vous n'utiliseriez pas les postes des salles de TP mais votre propre machine, relisez attentivement le [README du premier TP](../01-premiers-pas-en-js/README.md#Préparatifs) !*
2. **Ouvrez le fichier `package.json` et constatez que Babel, webpack et Flow sont listés dans les dépendances du projet.** Le dossier `demarrage` est en effet **déjà configuré pour l'utilisation de tous les outils nécessaires au dev JS moderne**. On va donc pouvoir tout installer facilement grâce à la commande :
2. Lancez VSCodium :
```bash
codium ~/ws-js/tp2
```
3. Ouvrez un terminal intégré dans VSCodium à l'aide du raccourci <kbd>CTRL</kbd>+<kbd>SHIFT</kbd>+<kbd>²</kbd> et tapez :
```bash
npm install
```
(à lancer à la racine du dossier de votre projet, cad là où se trouve le fichier `package.json`)
*Si vous voulez en savoir plus sur le détail de l'installation et de la configuration des différents outils, vous pouvez consulter les TPs précédents : [modules](../02-poo-modules-typage/C-modules.md#c2-rendre-les-modules-compatibles-avec-les-vieux-navigateurs) et [typage](../02-poo-modules-typage/D-typage.md#d1-installation-et-configuration).*
3. **Une fois tout installé, vous pouvez relancer la compilation à l'aide de la commande `npm run watch`**. Vérifiez ensuite que la page s'affiche correctement dans le navigateur :<br><a href="images/pizzaland-05-modules-webpack.jpg"><img src="images/pizzaland-05.jpg" width="80%"></a>
Tout au long du TP pensez à vérifier régulièrement que les types que vous utilisez pour les variables, paramètres et valeurs de retour des fonctions/méthodes, sont corrects à l'aide de la commande `./node_modules/.bin/flow`
4. **Une fois tout installé, vous pouvez relancer la compilation à l'aide de la commande `npm run watch`**. Vérifiez ensuite que la page s'affiche correctement dans le navigateur :<br><a href="images/readme/pizzaland-05-modules-webpack.jpg"><img src="images/readme/pizzaland-05.jpg" width="80%"></a>
## A.2. Sélectionner des éléments
......@@ -41,26 +39,25 @@ Comme vu en cours, la principale méthode pour sélectionner un élément de la
querySelector() est une méthode de la classe Element qui permet de retourner une référence vers un élément de la page (une balise) à partir d'un sélecteur CSS. Par exemple :
```js
const appContainerElement:?HTMLElement = document.querySelector('#appContainer');
document.querySelector('#appContainer');
```
assigne dans la constante `appContainerElement` la balise d'id html 'appContainer' :
retourne la balise d'id html 'appContainer' :
```html
<main id="appContainer">
```
Dans le fichier `main.js`, sélectionnez les éléments suivants et affichez les dans la console à l'aide de l'instruction `console.log()`. Par exemple si l'on demande d'afficher la balise d'id *"appContainer"* il faudra taper le code suivant :
Dans le fichier `main.js`, utilisez la fonction `console.log()` et la méthode `querySelector` pour afficher la balise qui a comme classe `"pageTitle"` comme ceci :
```js
console.log( document.querySelector('#appContainer') );
console.log( document.querySelector('.pageTitle') );
```
En inspectant le code html de la page (à l'aide de l'onglet Elements/Inspecteur des devtools) trouvez les sélecteurs qui permettront d'afficher dans la console :
Sur le même modèle, affichez dans la console :
1. La balise `<img>` qui contient le logo de la page (les 2 parts de pizza)
2. Le lien du menu "Ajouter une pizza"
3. Le lien vers le site [Unsplash](https://unsplash.com/) dans les crédits
4. le titre de la première pizza (*`<h4>Regina</h4>`*)
<a href="images/queryselector-console.jpg"><img src="images/queryselector-console.jpg" width="80%"></a>
<a href="images/readme/queryselector-console.jpg"><img src="images/readme/queryselector-console.jpg" width="80%"></a>
### A.2.2. querySelectorAll()
La méthode `querySelectorAll()` permet de récupérer non pas un, mais tous les éléments qui correspondent au sélecteur CSS passé en paramètre.
......@@ -69,7 +66,7 @@ Affichez dans la console :
1. la liste des liens du menu de navigation ("La carte" et "Ajouter une pizza")
2. la liste des prix de toutes les pizzas de la page
<a href="images/queryselectorall-console.jpg"><img src="images/queryselectorall-console.jpg" width="80%"></a>
<a href="images/readme/queryselectorall-console.jpg"><img src="images/readme/queryselectorall-console.jpg" width="80%"></a>
## A.3. Modifier des éléments
### A.3.1. innerHTML
......@@ -82,7 +79,7 @@ La propriété `innerHTML` permet à la fois de lire et de modifier le contenu d
<small class="label label-success">les pizzas c'est la vie</small>
```
<a href="images/pizzaland-innerhtml.jpg"><img src="images/pizzaland-innerhtml.jpg" width="80%"></a>
<a href="images/readme/pizzaland-innerhtml.jpg"><img src="images/readme/pizzaland-innerhtml.jpg" width="80%"></a>
### A.3.2. getAttribute/setAttribute
Les méthodes `getAttribute()` et `setAttribute()` de la classe Element permettent de lire, d'ajouter ou de modifier des attributs HTML.
......@@ -90,7 +87,7 @@ Les méthodes `getAttribute()` et `setAttribute()` de la classe Element permette
1. Affichez dans la console l'url du 2e lien contenu dans le footer (`"https://www.freepik.com/"`)
2. Ajoutez la classe CSS "active" au `<li>` qui contient le lien "La carte" dans le menu
<a href="images/pizzaland-setatttribute.jpg"><img src="images/pizzaland-setatttribute.jpg" width="80%"></a>
<a href="images/readme/pizzaland-setatttribute.jpg"><img src="images/readme/pizzaland-setatttribute.jpg" width="80%"></a>
## Étape suivante
Maintenant que l'on est capable de sélectionner / modifier des éléments HTML, nous allons voir dans le prochain exercice comment détecter les événements : [B. Les événements](./B-evenements.md).
\ No newline at end of file
......@@ -14,14 +14,12 @@ Comme vu en cours (cf. pdf du cours sur moodle) on peut associer une fonction à
Par exemple, pour déclencher la fonction `handleClick` lors du clic sur le premier lien de la page, on peut écrire :
```JavaScript
const link:?HTMLElement = document.querySelector('a');
function handleClick( event:Event ) {
function handleClick( event ) {
event.preventDefault();
console.log(event);
}
if ( link ){
link.addEventListener('click', handleClick);
}
const link = document.querySelector('a');
link.addEventListener('click', handleClick);
```
Notez que comme vu en cours :
......@@ -30,7 +28,7 @@ Notez que comme vu en cours :
3. Il faut presque systématiquement (sauf cas particuliers) appeler en premier lieu la méthode `event.preventDefault()` qui permet d'éviter que le navigateur n'exécute le traitement par défaut de l'événement : par exemple rediriger l'utilisateur vers une nouvelle page lorsqu'il clique sur un lien, recharger la page lorsqu'il soumet un formulaire, etc.
## B.2. La gestion du menu
Dans le fichier `main.js`
Dans le fichier `main.js` :
1. **Commencez par commenter le code de l'exercice [A. Les bases de l'API DOM](./A-les-bases.md)** (certains sélecteurs pourront vous être utiles par la suite)
2. A l'aide de `querySelector()` et `addEventListener()`, **affichez un message dans la console à chaque fois que l'utilisateur clique sur le lien du menu de navigation "Ajouter une pizza"**
3. **Effacez le code précédent et remplacez le par un code qui permette d'écouter le clic sur *tous* les liens du menu de navigation** :
......@@ -41,5 +39,10 @@ Dans le fichier `main.js`
4. **Ajoutez la classe CSS "active" sur la balise `<li>` qui contient le lien qui a été cliqué** (utilisez pour cela la propriété [element.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement))
5. **Juste avant d'ajouter la classe "active" sur le lien cliqué, effacez les classes CSS du `<li>` du menu qui était précédemment actif** de manière à n'avoir qu'un seul lien actif à la fois<br><img src="./images/pizzaland-nav.gif">
<!--## B.3. Navigation en JS
Il existe plusieurs façons de gérer la navigation en JS.
On peut afficher/masquer des parties de code HTML déjà
-->
## Étape suivante
Maintenant que l'on est capable de détecter les actions de l'utilisateur nous allons travailler sur la gestion des formulaires dans le prochain exercice : [C. Les formulaires](./C-formulaires.md).
\ No newline at end of file
......@@ -9,36 +9,35 @@
- [C.5. Le formulaire complet :](#c5-le-formulaire-complet-)
## C.1. Rappels
Comme vu en cours (cf. pdf sur moodle), on peut utiliser l'API DOM avec les formulaires principalement pour 3 utilisations :
- vérifier la saisie de l'utilisateur et afficher des messages d'erreur si besoin
- modifier éventuellement les valeurs des champs (corriger une valeur, ou vider un formulaire)
- Soumettre les données en AJAX (ce qui sera abordé dans le prochain cours et TP)
Comme vu en cours (cf. pdf sur moodle), on peut utiliser l'API DOM avec les formulaires principalement pour 2 utilisations :
- détecter les changements de valeurs dans les champs de saisie et afficher des messages d'erreur si besoin
- détecter la soumission du formulaire (pour envoyer des données en AJAX par exemple)
## C.2. Préparatifs
Avant d'aller plus loin dans le TP faisons un point sur le code qui est fourni dans le dossier `demarrage` : il contient en effet des classes `Page` et `PageRenderer` qui correspondent à la solution de l'exercice [E. pour aller plus loin](../02-poo-modules-typage/E-pour-aller-plus-loin.md) :
Avant d'aller plus loin dans le TP faisons un point sur le code qui est fourni dans ce repo : il contient en effet des classes `Page` et `PageRenderer` qui correspondent à la solution de l'exercice [D. POO avancée](https://gitlab.univ-lille.fr/js/tp2/blob/master/D-poo-avancee.md) du précédent TP :
- La classe `Page` est une classe de base dont hérite la classe `HomePage` et qui implémente une méthode `renderTitle()`.
- La classe `PageRenderer` est une classe qui dispose d'une méthode statique `PageRenderer.renderPage( page )` qui permet d'afficher une page (méthode `render()`) et son titre (méthode `renderTitle()` ci-dessus).
- La classe `PageRenderer` est une classe qui dispose d'une méthode statique `PageRenderer.renderPage( page )`. Cette méthode permet d'afficher une page (méthode `page.render()`) et son titre (méthode `page.renderTitle()`).
Pour permettre à chaque page de réagir aux événements de l'utilisateur, on va ajouter une méthode `mount()` dans la classe `Page` et qui sera appelée par la classe `PageRenderer` à chaque fois qu'on affiche une page via `renderPage()` :
1. **Ajouter la méthode `mount()` à la classe `Page`** :
```js
mount():void {
mount(contentElement) {
// par défaut, cette méthode ne fait rien
// ce sont les classes filles qui devront surcharger cette méthode
}
```
2. **Appeler la méthode `mount()` à la fin de la méthode statique `PageRenderer.renderPage()`** :
```js
static renderPage( page:Page ):void {
static renderPage(page) {
// ...
page.mount();
page.mount(this.contentElement);
}
```
## C.3. Le formulaire d'ajout de pizza
1. **Créez la classe `AddPizzaPage`** (dans un module `js/AddPizzaPage.js`) dont le titre est "Ajouter une pizza" et dont la méthode `render()` est surchargée comme suit :
1. **Créez la classe `AddPizzaPage`** (dans un module `js/pages/AddPizzaPage.js`). Le titre de la page devra être "Ajouter une pizza" et la méthode `render()` sera surchargée comme suit :
```js
render():string {
return `<form class="addPizzaPage">
......@@ -58,14 +57,14 @@ Pour permettre à chaque page de réagir aux événements de l'utilisateur, on v
```
3. **Ajoutez une méthode `submit()` dans la classe `AddPizzaPage`.** Cette méthode sera appelée lorsque l'utilisateur soumettra le formulaire :
```js
submit(event:Event):void {
submit(event) {
// ici le code de votre méthode
}
```
Cette méthode va pour le moment juste afficher un message dans la console.
***NB:** Souvenez vous de la méthode `event.preventDefault()`...*
3. **Overridez la méthode `mount()` dans la classe `AddPizzaPage`** en y ajoutant un écouteur d'événement 'submit' sur la balise `<form class="addPizzaPage">` qui va déclencer la méthode `submit()` de l'instance.
4. **Overridez la méthode `mount()` dans la classe `AddPizzaPage`** en y ajoutant un écouteur d'événement 'submit' sur la balise `<form class="addPizzaPage">` qui va déclencher la méthode `submit()` de l'instance.
***NB :** Pour rappel, la valeur du `this` à l'intérieur d'un écouteur d'événement (fonction appelée par addEventListener) est toujours l'élément HTML qui a déclenché l'événement (ici le formulaire). Pour pouvoir appeler une méthode de l'instance, il faut forcer la valeur du `this` pour qu'elle corresponde toujours à l'instance dans laquelle le code s'exécute. Comme expliqué dans le pdf du cours, il existe plusieurs manières de le faire, mais celle que je vous recommande est l'emploi de la méthode [`bind()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) dans le constructeur de la classe :*
```js
......
images/readme/flow-error.jpg

61.5 KiB

images/readme/npm-run-test.gif

80.7 KiB

images/readme/pizzaland-00.jpg

255 KiB

images/readme/pizzaland-01.jpg

32.2 KiB

images/readme/pizzaland-02.jpg

35.9 KiB

images/readme/pizzaland-03.jpg

194 KiB

images/readme/pizzaland-04.jpg

61.7 KiB

images/readme/pizzaland-05.jpg

122 KiB

images/readme/pizzaland-06-modules.jpg

314 KiB

images/readme/pizzaland-07-modules-webpack.jpg

285 KiB

images/readme/pizzaland-innerhtml.jpg

136 KiB

images/readme/pizzaland-nav.gif

52.9 KiB

images/readme/pizzaland-setatttribute.jpg

137 KiB

images/readme/queryselector-console.jpg

81.7 KiB

images/readme/queryselectorall-console.jpg

55.4 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment