Skip to content

Module 9 : JavaScript - Structures de données, fonctions et DOM

Introduction

Maintenant que les bases du langage JavaScript sont maîtrisées (variables, types, structures de contrôle), il est temps d'aller plus loin. Dans ce module, nous allons apprendre à organiser nos données avec les tableaux et les objets, à structurer notre code avec les fonctions, et à interagir avec la page web en manipulant le DOM et en répondant aux événements de l'utilisateur.

Avant d'aller plus loin : Installer ESLint pour JavaScript

ESLint est un outil d'analyse statique pour JavaScript qui aide à identifier et corriger les problèmes de syntaxe, de style et de bonnes pratiques dans votre code. Dans le cadre de ce cours, nous utiliserons ESLint pouvoir se vérifier dans Vs Code

Installer ESLint pour JavaScript

Objectifs du cours

  • Maîtriser les tableaux linéaires et associatifs
  • Créer des objets avec la syntaxe littérale
  • Comprendre et utiliser les fonctions nommées
  • Appliquer les normes de documentation JavaScript
  • Comprendre ce qu'est le DOM (Document Object Model)
  • Modifier le contenu d'un élément HTML avec textContent
  • Réagir à un événement « click » avec addEventListener

Théorie

1 : Tableaux linéaires et associatifs

Définition

En JavaScript, il existe deux types de tableaux : les tableaux linéaires (indexés numériquement) et les tableaux associatifs (indexés par des clés). Ils permettent de stocker des collections de données de manière organisée.

Tableaux linéaires (Array)

Les tableaux linéaires sont des collections ordonnées d'éléments indexés numériquement, commençant par 0. Les éléments peuvent être de n'importe quel type de données.

javascript
let fruits = ["pomme", "banane", "orange"];

console.log(fruits[0]); // Affiche "pomme"
console.log(fruits[1]); // Affiche "banane"
console.log(fruits[2]); // Affiche "orange"
console.log(fruits.length); // Affiche 3

Parcourir un tableau linéaire

javascript
let fruits = ["pomme", "banane", "orange"];

// Avec for classique
for (let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
}

// Avec for...of (recommandé pour les tableaux)
for (let fruit of fruits) {
    console.log(fruit);
}

2 : Fonctions utiles pour les tableaux linéaires

push()

La méthode push() ajoute un ou plusieurs éléments à la fin d'un tableau et retourne la nouvelle longueur du tableau.

javascript
let fruits = ["pomme", "banane"];
let nouvelleLongueur = fruits.push("orange"); // Ajoute "orange" à la fin
console.log(fruits); // Affiche ["pomme", "banane", "orange"]
console.log(nouvelleLongueur); // Affiche 3

pop()

La méthode pop() retire le dernier élément d'un tableau et le retourne.

javascript
let fruits = ["pomme", "banane", "orange"];
let dernierFruit = fruits.pop(); // Retire "orange"
console.log(fruits); // Affiche ["pomme", "banane"]
console.log(dernierFruit); // Affiche "orange"

shift()

La méthode shift() retire le premier élément d'un tableau et le retourne.

javascript
let fruits = ["pomme", "banane", "orange"];
let premierFruit = fruits.shift(); // Retire "pomme"
console.log(fruits); // Affiche ["banane", "orange"]
console.log(premierFruit); // Affiche "pomme"

indexOf()

La fonction indexOf() recherche un élément dans un tableau et retourne son index (position) s'il est trouvé, sinon -1.

javascript
let fruits = ["pomme", "banane", "orange"];
console.log(fruits.indexOf("banane")); // Affiche 1
console.log(fruits.indexOf("poire"));  // Affiche -1

splice()

La fonction splice() permet de modifier le contenu d'un tableau en retirant des éléments à partir d'un index donné.

javascript
let fruits = ["pomme", "banane", "orange"];
fruits.splice(1, 1); // Retire 1 élément à partir de l'index 1
console.log(fruits); // Affiche ["pomme", "orange"]

La fonction splice() permet également d'insérer des éléments dans un tableau. Par exemple, pour insérer "kiwi" à l'index 1 sans retirer d'éléments :

javascript
let fruits = ["pomme", "banane", "orange"];

// Paramètre 1 : index de départ
// Paramètre 2 : nombre d'éléments à retirer, 0 dans ce cas-ci
// Paramètre 3 : élément(s) à insérer, "kiwi" dans ce cas-ci
fruits.splice(1, 0, "kiwi"); 
console.log(fruits); // Affiche ["pomme", "kiwi", "banane", "orange"]

Autre exemple : insérer 2 éléments à l'index 2 et retirer 1 élément à partir de cet index :

javascript
let fruits = ["pomme", "kiwi", "banane", "orange"];
// Paramètre 1 : index de départ
// Paramètre 2 : nombre d'éléments à retirer, 1 dans ce cas-ci
// Paramètre 3 et 4 : éléments à insérer, "fraise" et "melon" dans ce cas-ci
fruits.splice(2, 1, "fraise", "melon");
console.log(fruits); // Affiche ["pomme", "kiwi", "fraise", "melon", "orange"]

includes()

La fonction includes() vérifie si un tableau contient un élément spécifique et retourne true s'il est présent, sinon false.

javascript
let fruits = ["pomme", "banane", "orange"];
console.log(fruits.includes("banane")); // Affiche true
console.log(fruits.includes("poire"));  // Affiche false

Math.max() et Math.min() avec spread operator

Pour trouver la valeur maximale ou minimale dans un tableau numérique, on peut utiliser Math.max() et Math.min() en combinaison avec l'opérateur de spread (...) pour "déplier" le tableau en arguments individuels.

javascript
const arr = [5, 12, 8, 130, 44];

const max = Math.max(...arr);
console.log(max); // 130

const min = Math.min(...arr);
console.log(min); // 5

Exercices

Exercice #1 en lien avec cette matière.

3 : Tableaux associatifs (Objet)

Les tableaux associatifs sont des collections d'éléments indexés par des clés (chaînes de caractères). En JavaScript, les tableaux associatifs sont en fait des objets.

javascript
let personne = {
    nom: "Dupont",
    prenom: "Jean",
    age: 30
};

// Accès avec la notation par crochets (comme un tableau associatif)
console.log(personne["nom"]);    // Affiche "Dupont"
console.log(personne["prenom"]); // Affiche "Jean"
console.log(personne["age"]);    // Affiche 30

// Accès avec la notation par point (recommandé)
console.log(personne.nom);    // Affiche "Dupont"
console.log(personne.prenom); // Affiche "Jean"

Parcourir un tableau associatif (objet)

On utilise la boucle for...in pour parcourir les propriétés (clés) d'un objet :

javascript
let personne = {
    nom: "Dupont",
    prenom: "Jean",
    age: 30
};

for (let propriete in personne) {
    console.log(propriete + " : " + personne[propriete]);
}
// Affiche :
// nom : Dupont
// prenom : Jean
// age : 30

Quand utiliser quel type ?

TypeUtilisationAccèsBoucle recommandée
Tableau linéaire ([])Collection ordonnée d'élémentstableau[0], tableau[1]for, for...of
Tableau associatif ({})Collection indexée par des clésobjet["clé"], objet.cléfor...in

Points importants

  • Les tableaux linéaires sont créés avec des crochets [ ]
  • Les tableaux associatifs sont en réalité des objets créés avec des accolades { }
  • Utilisez for...of pour les tableaux linéaires et for...in pour les objets
  • L'index d'un tableau linéaire commence toujours à 0

Stocker plusieurs objets dans un tableau

Pour stocker plusieurs objets, on peut utiliser un tableau linéaire d'objets :

Linéaire veut dire : indexé numériquement, avec des crochets [] et un indice numérique (0, 1, 2, etc.)

javascript
let personnes = [
    {
        nom: "Dupont",
        prenom: "Jean",
        age: 30
    },
    {
        nom: "Durand",
        prenom: "Marie",
        age: 25
    },
    {
        nom: "Martin",
        prenom: "Pierre",
        age: 35
    }
];

// Accéder au nom de la deuxième personne
console.log(personnes[1].nom); // Affiche "Durand"

// Parcourir toutes les personnes
for (let personne of personnes) {
    console.log(personne.prenom + " " + personne.nom + " - " + personne.age + " ans");
}

// Ou encore avec une boucle For classique
for (let i = 0; i < personnes.length; i++) {
    console.log(personnes[i].prenom + " " + personnes[i].nom + " - " + personnes[i].age + " ans");
}

Exercices

Exercice #2 en lien avec cette matière.

4 : Fonctions nommées

Définition

Une fonction est un bloc de code réutilisable qui effectue une tâche spécifique. Une fonction nommée est une fonction déclarée avec le mot-clé function suivi d'un nom. Elle peut recevoir des paramètres et retourner une valeur.

Syntaxe d'une fonction nommée

javascript
function nomDeLaFonction(parametre1, parametre2) {
    // Code de la fonction
    return resultat; // optionnel
}

Exemple simple : fonction sans paramètre ni retour

javascript
function direBonjour() {
    console.log("Bonjour tout le monde !");
}

// Appel de la fonction
direBonjour(); // Affiche "Bonjour tout le monde !"

Exemple avec paramètres

javascript
function saluer(prenom, nom) {
    console.log("Bonjour " + prenom + " " + nom + " !");
}

saluer("Jean", "Dupont");  // Affiche "Bonjour Jean Dupont !"
saluer("Marie", "Durand"); // Affiche "Bonjour Marie Durand !"

Exemple avec valeur de retour

javascript
function additionner(a, b) {
    return a + b;
}

let resultat = additionner(5, 3);
console.log("Résultat :", resultat); // Affiche "Résultat : 8"

// On peut aussi utiliser le retour directement
console.log("10 + 20 =", additionner(10, 20)); // Affiche "10 + 20 = 30"

Exemple complet : calculer la moyenne

javascript
function calculerMoyenne(notes) {
    let somme = 0;
    for (let note of notes) {
        somme = somme + note;
    }
    return somme / notes.length;
}

let mesNotes = [85, 72, 91, 60, 78];
let moyenne = calculerMoyenne(mesNotes);
console.log("La moyenne est :", moyenne);

Note importante

Dans ce cours, nous allons utiliser exclusivement les fonctions nommées et non les fonctions fléchées (arrow functions). Les fonctions fléchées sont une syntaxe plus moderne introduite dans ES6, mais nous nous concentrons sur les bases avec les fonctions nommées pour une meilleure compréhension.

Par exemple :

Fonction nommée (bonne façon) :

javascript
function direBonjour() {
    console.log("Bonjour !");
}

Fonction fléchée (NE PAS UTILISER) :

javascript
const direBonjour = () => {
    console.log("Bonjour !");
};

Points importants

  • Une fonction se déclare avec function, un nom, des parenthèses () et des accolades { }
  • Les paramètres sont des variables locales à la fonction
  • return permet de renvoyer une valeur (et arrête l'exécution de la fonction)
  • Nommez vos fonctions de manière descriptive : verbe + complément (ex. : calculerMoyenne, afficherMessage)
  • Une fonction devrait faire une seule chose
  • Utiliser des fonctions nommées et ne pas utiliser les fonctions fléchées pour ce cours

5 : Normes de documentation (JSDoc)

Définition

La documentation du code est essentielle pour rendre votre code compréhensible par d'autres développeurs (et par vous-même dans le futur). En JavaScript, la norme de documentation standard est JSDoc, qui utilise des commentaires spéciaux pour décrire les fonctions, leurs paramètres et leur valeur de retour.

Syntaxe JSDoc

Un commentaire JSDoc commence par /** et se termine par */. Chaque ligne de description commence par *.

javascript
/**
 * Calcule la somme de deux nombres.
 * @param {number} a - Le premier nombre.
 * @param {number} b - Le deuxième nombre.
 * @returns {number} La somme des deux nombres.
 */
function additionner(a, b) {
    return a + b;
}

Tags JSDoc courants

TagDescriptionExemple
@param {type} nomDécrit un paramètre de la fonction@param {string} nom - Le nom de l'utilisateur.
@returns {type}Décrit la valeur de retour@returns {number} Le total calculé.
@descriptionDescription détaillée (optionnel, la première ligne suffit)@description Cette fonction fait...

Exemple complet

javascript
/**
 * Calcule la moyenne d'un tableau de notes.
 * @param {number[]} notes - Le tableau contenant les notes.
 * @returns {number} La moyenne des notes.
 */
function calculerMoyenne(notes) {
    let somme = 0;
    for (let note of notes) {
        somme = somme + note;
    }
    return somme / notes.length;
}

/**
 * Affiche un message de bienvenue personnalisé dans la console.
 * @param {string} prenom - Le prénom de l'utilisateur.
 * @param {string} nom - Le nom de l'utilisateur.
 */
function afficherBienvenue(prenom, nom) {
    console.log("Bienvenue " + prenom + " " + nom + " !");
}

Note : Dans VS Code, lorsque vous tapez /** au-dessus d'une fonction et appuyez sur Entrée, l'éditeur génère automatiquement un squelette de commentaire JSDoc avec les @param correspondants.

Points importants

  • Documentez toutes vos fonctions avec JSDoc
  • Décrivez ce que fait la fonction, chaque paramètre et la valeur de retour
  • La documentation rend votre code plus professionnel et maintenable
  • VS Code utilise les commentaires JSDoc pour l'autocomplétion et les infobulles

Exercices

Exercice #3 en lien avec cette matière.

6 : Le DOM (Document Object Model)

Définition

Le DOM (Document Object Model) est une interface de programmation qui permet d'interagir avec les éléments d'un document HTML via JavaScript. Le DOM représente la structure de la page sous forme d'arborescence d'objets, que l'on peut lire et modifier avec du code.

Structure du DOM

Le DOM est organisé sous forme d'arborescence, où chaque élément HTML est un nœud dans l'arbre :

html
├── head
│   └── title
└── body
    └── div
        ├── h1
        ├── p
        └── img

Chaque nœud peut être un élément HTML (balise), un attribut, un commentaire ou du texte.

document.getElementById()

La méthode document.getElementById() permet de récupérer un élément HTML par son attribut id. C'est la méthode la plus utilisée pour cibler un élément spécifique.

javascript
// Récupérer l'élément HTML qui a l'id "titre"
let titre = document.getElementById("titre");
console.log(titre); // Affiche l'élément HTML complet

Modifier le texte d'un élément avec textContent

La propriété textContent permet de lire ou modifier le contenu texte d'un élément HTML.

javascript
// Récupérer l'élément h1
let titre = document.getElementById("titre");

// Lire le texte actuel
console.log(titre.textContent); // Affiche le texte du h1

// Modifier le texte
titre.textContent = "Nouveau titre";

Exemple complet

html
<!-- index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemple DOM</title>
</head>
<body>
    <h1 id="titre">Titre original</h1>
    <p id="paragraphe">Ceci est un paragraphe.</p>

    <script src="js/script.js"></script>
</body>
</html>
javascript
// script.js
"use strict";

// Récupérer les éléments du DOM
let titre = document.getElementById("titre");
let paragraphe = document.getElementById("paragraphe");

// Modifier leur contenu
titre.textContent = "Titre modifié par JavaScript";
paragraphe.textContent = "Ce texte a été changé dynamiquement !";

Points importants

  • Le DOM est la représentation en arbre de la page HTML, accessible via JavaScript
  • document.getElementById("id") retourne l'élément HTML correspondant à l'id donné
  • textContent permet de lire et modifier le texte d'un élément
  • L'élément doit exister dans le HTML avant que le script tente d'y accéder (d'où l'importance de placer <script> avant </body>)

7 : Méthode de travail avec un fichier JavaScript

Avant de commencer à programmer, il est conseillé d'organiser votre fichier JavaScript en plusieurs sections bien distinctes. Voici un exemple de script.js

javascript
// =============================
// Variables globales : c'est ici que l'on déclarerait les variables globales de notre script

// =============================
// Fonctions et événements : c'est ici que l'on déclarerait les fonctions et les événements de notre script

// =============================
// Initialisation
// =============================
function initialisation() {
    /* Une fois la page chargée, c'est ici que le code va débuter */
}

/* Écouteur d'événement pour déclencher la fonction d'initialisation une fois la page web chargée */
addEventListener("load", initialisation, false);

Principe :

  • Toutes les variables globales sont déclarées en haut du fichier.
  • Les fonctions et événements sont regroupés dans une section dédiée.
  • La fonction initialisation sert de point d'entrée : elle est appelée automatiquement lorsque la page est chargée.
  • Cela permet de contrôler précisément quand et comment le code s'exécute, et d'avoir un script bien organisé et lisible.

Exemple d'utilisation :

javascript
"use strict";
// =============================
// Variables globales
let compteur = 0;

// =============================
// Fonctions et événements
function incrementerCompteur() {
    compteur++;
    console.log("Compteur :", compteur);
}
// =============================
// Initialisation
function initialisation() {
    let bouton = document.getElementById("monBouton");
    bouton.addEventListener("click", incrementerCompteur);
}
addEventListener("load", initialisation, false);

Explication :

  • Dès que la page web aura terminée de charger, la fonction initialisation sera appelée car l'événement "load" sera déclenché, et elle attachera un événement "click" au bouton avec l'id "monBouton". Chaque fois que ce bouton sera cliqué, la fonction incrementerCompteur sera exécutée, ce qui incrémentera la variable compteur et affichera sa valeur dans la console.

Portée de vie de la variable compteur :

  • La variable compteur est déclarée en haut du fichier, ce qui en fait une variable globale. Elle est accessible et modifiable par toutes les fonctions du script.

8 : Introduction à l'événement « click »

Définition

Un événement en JavaScript est une action effectuée par l'utilisateur (clic, saisie, déplacement de la souris, etc.) qui peut déclencher l'exécution d'une fonction. Le principe d'événement est la base de l'interactivité dans une page web.

Fonctionnement du système d'événements

Le principe repose sur trois éléments :

  1. Une fonction de rappel (callback) : la fonction qui sera exécutée lorsque l'événement se produit
  2. Un élément HTML cible : l'élément sur lequel on écoute l'événement
  3. Un gestionnaire d'événements : addEventListener() qui lie la fonction à l'événement sur l'élément

Étape 1 : Définir la fonction de rappel (callback)

javascript
function gererClick() {
    alert("Le bouton a été cliqué !");
}

Étape 2 : Attacher l'événement avec addEventListener

javascript
let bouton = document.getElementById("monBouton");
bouton.addEventListener("click", gererClick);

Important : On passe le nom de la fonction sans les parenthèses (). Si on écrivait gererClick(), la fonction serait exécutée immédiatement au lieu d'attendre le clic.

Exemple complet : changer le titre au clic

html
<!-- index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Événement click</title>
</head>
<body>
    <h1 id="titre">Titre original</h1>
    <button id="monBouton">Changer le titre</button>

    <script src="js/script.js"></script>
</body>
</html>
javascript
// script.js
"use strict";

/**
 * Change le texte du titre h1.
 */
function changerTitre() {
    let titre = document.getElementById("titre");
    titre.textContent = "Nouveau titre";
}

// Attacher l'événement "click" au bouton
let bouton = document.getElementById("monBouton");
bouton.addEventListener("click", changerTitre);

Lorsque l'utilisateur clique sur le bouton, la fonction changerTitre() est exécutée et le texte du <h1> est modifié.

Autre exemple avec un formulaire

html
<form>
    <input id="btnSayHello" type="button" value="Say Hello" />
</form>
javascript
"use strict";

function direBonjour() {
    console.log("Bonjour !");
}

let bouton = document.getElementById("btnSayHello");
bouton.addEventListener("click", direBonjour);

Points importants

  • addEventListener("click", maFonction) permet de réagir au clic de l'utilisateur
  • La fonction de rappel est passée sans parenthèses : maFonction et non maFonction()
  • Un seul élément peut avoir plusieurs événements attachés
  • Toujours récupérer l'élément avec getElementById() avant d'y attacher un événement
  • Le script doit être chargé après les éléments HTML (balise <script> avant </body>)

Exercices

Exercice #4 en lien avec cette matière.

Exercice #5 : synthèse de tous les concepts vus dans ce module.

Exercices pratiques

Exercice 1 : Gestion d'un tableau de personnes et salaires

Énoncé

Créer un script JavaScript qui permet de saisir 5 personnes avec leur salaire, les stocker dans un tableau linéaire alterné (nom, salaire, nom, salaire...), puis effectuer diverses opérations sur ce tableau en utilisant les fonctions utiles des tableaux linéaires.

Consignes

  1. Activer le mode strict
  2. Créer un tableau vide personnesSalaires pour stocker les données de façon linéaire
  3. Utiliser des boucles et prompt() pour saisir 5 noms et 5 salaires, en les ajoutant alternativement au tableau (nom, salaire, nom, salaire...)
  4. Détecter et afficher les noms en double dans le tableau en utilisant des boucles et les méthodes des tableaux
  5. Rechercher le salaire d'un nom spécifique (par exemple "Dupont") et l'afficher dans la console
  6. Retirer un nom et son salaire du tableau (par exemple "Dupont") en se servant des méthodes utiles des tableaux
    1. Affiche ensuite le tableau : il devrait ne plus contenir le nom et le salaire retirés et d'une taille réduite de 2 éléments

Exercice 2 : Gestion d'un inventaire de voitures

Énoncé

Créer un script JavaScript qui permet à l'utilisateur de saisir les informations de 3 voitures (marque, prix, année) via des prompts, de les stocker dans un tableau d'objets, d'afficher le contenu du tableau à la console en décrivant chaque voiture, et enfin d'alerter l'utilisateur sur la voiture dont le prix dépasse 50000$.

Consignes

  1. Activer le mode strict
  2. Créer un tableau vide voitures pour stocker les objets voiture. Ne pas lui donner de taille ou structure à l'avance : let voitures = []
  3. Utiliser une boucle pour saisir 3 voitures, via des prompts. Les propriétés de chaque voiture sont : marque, prix et annee
  4. Après la saisie, parcourir le tableau avec une boucle for...of et afficher à la console une description de chaque voiture, par exemple : "Voiture 1 : Marque Toyota, Prix 25000$, Année 2020"
  5. Parcourir le tableau une deuxième fois pour trouver la (ou les) voiture(s) dont le prix est supérieur à 50000$ et afficher un message d'alerte pour cette voiture qui dépasse ce prix. Par exemple : "La voiture 2 a un prix supérieur à 50000$"

Exercice 3 : Manipulation de fonctions et tableaux

Énoncé

Créer un script JavaScript utilisant des fonctions nommées pour manipuler des tableaux. Les fonctions doivent être définies puis appelées immédiatement après leur définition.

Consignes

  1. Activer le mode strict
  2. Créer une fonction trierCouleurs qui prend 5 noms de couleurs en paramètres, les insère dans un tableau, trie ce tableau en ordre croissant (alphabétique) avec array.sort(), et retourne le tableau trié. Appeler cette fonction avec 5 couleurs différentes et afficher le résultat à la console.
    1. Note importante : la fonction array.sort() ne fonctionnera pas correctement si les éléments du tableau sont des nombres.
  3. Créer une fonction afficherTypes qui prend un tableau en paramètre et affiche le type (typeof) de chaque élément à la console. Appeler cette fonction avec le tableau retourné par la fonction précédente.
  4. Créer une fonction insererElement qui prend un tableau, une position (index), et un élément en paramètres, insère l'élément à la position donnée ce tableau et le retourne. Appeler cette fonction avec un tableau existant, une position, et un élément à insérer. Afficher le contenu du nouveau tableau à la console. Utiliser le fonction intégré d'un tableau .splice() pour insérer l'élément à la position souhaitée.

Important : Chaque fonction doit être documentée avec JSDoc, en décrivant les paramètres et la valeur de retour.

Exercice 4 : Manipulation du DOM avec événements

Énoncé

Créer une page HTML avec 3 paragraphes et 2 boutons, puis un script JavaScript structuré avec une fonction initialisation() qui attache des événements aux boutons pour modifier le contenu des paragraphes via le DOM.

Voici le code HTML à utiliser :

html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Exercice 4 - DOM et événements</title>
</head>
<body>
    <h1>Exercice 4 : Manipulation du DOM</h1>
    
    <p id="para1">Paragraphe 1</p>
    <p id="para2">Paragraphe 2</p>
    <p id="para3">Paragraphe 3</p>
    
    <button id="bouton1">Modifier Para 1</button>
    <button id="bouton2">Modifier Para 2</button>
    <button id="bouton3">Modifier Para 3</button>
    
    <script src="js/script.js"></script>
</body>
</html>

Consignes

  1. Activer le mode strict dans script.js
  2. Structurer le script avec les sections : Variables globales, Fonctions et événements, Initialisation
  3. Créer une fonction modifierParagraphe1() qui modifie le paragraphe 1 avec un texte hard codé (par exemple : "Texte modifié par le programme")
  4. Créer une fonction modifierParagraphe2() qui modifie le paragraphe 2 avec un texte saisi par l'utilisateur via prompt()
  5. Créer une fonction modifierUnParagraphe() qui demande à l'utilisateur l'ID du paragraphe à modifier, ainsi que son contenu à remplacer. À partir de cet ID et de ce contenu, Cette fonction récupère le paragraphe correspondant et modifie son texte avec textContent
  6. Dans la fonction initialisation(), attacher l'événement "click" au bouton 1 pour appeler modifierParagraphe1, au bouton 2 pour appeler modifierParagraphe2, et au bouton 3 pour appeler modifierUnParagraphe. Utiliser addEventListener("load", initialisation, false) (placé à la fin du script) pour déclencher l'initialisation une fois la page chargée.

Structure du script.js :

javascript
"use strict";
// =============================
// Fonctions et événements
// Fonction 1
// Fonction 2
// [...]

// =============================
// Fonction d'initialisation (initialisation)
// =============================
// addEventListener("load", initialisation, false);

Exercice 5 : Gestion d'une newsletter (synthèse)

Énoncé

Créer une page HTML avec un formulaire pour ajouter des abonnés à une newsletter. Le formulaire contient 3 champs (prénom, nom, courriel) et un bouton "Ajouter". Un deuxième bouton permet d'afficher le contenu du tableau des abonnés à la console. Les données sont stockées dans un tableau d'objets. Dans cet exercice, l'interface est donc 100% HTML, et le script JavaScript gère la logique de stockage et d'affichage des abonnés.

Voici le code HTML à utiliser :

html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title>Exercice 5 - Gestion d'une newsletter</title>
</head>
<body>
    <h1>Exercice 5 : Gestion d'une newsletter</h1>
    
    <form id="formAbonne">
        <label for="prenom">Prénom :</label>
        <input type="text" id="prenom" required><br><br>
        
        <label for="nom">Nom :</label>
        <input type="text" id="nom" required><br><br>
        
        <label for="courriel">Courriel :</label>
        <input type="email" id="courriel" required><br><br>
        
        <button type="button" id="btnAjouter">Ajouter</button>
        <button type="button" id="btnAfficher">Afficher abonnés</button>
    </form>
    
    <script src="js/script.js"></script>
</body>
</html>

Consignes

  1. Activer le mode strict dans script.js
  2. Créer un tableau global newsletter vide au début du script pour stocker les objets abonnés.
  3. Structurer le script avec les sections : Variables globales, Fonctions et événements, Initialisation
  4. Créer une fonction ajouterAbonne() qui :
    • Récupère les valeurs des champs avec document.getElementById("id").value
    • Crée un objet abonné avec les propriétés prenom, nom et courriel
    • Ajoute l'objet au tableau newsletter (qui existe déjà en tant que variable globale)
    • Vide les champs du formulaire après ajout. Pour cette opération, créer une fonction viderFormulaire(), qui récupère les champs et les remet à une chaîne vide .value = "". Il faudra appeler cette fonction à la fin de ajouterAbonne().
  5. Créer une fonction afficherAbonnes() qui parcourt le tableau newsletter et affiche chaque abonné à la console (par exemple : "Prénom Nom - courriel@email.com")
  6. Dans la fonction initialisation(), attacher l'événement "click" au bouton "Ajouter" pour appeler ajouterAbonne, et l'événement "click" au bouton "Afficher abonnés" pour appeler afficherAbonnes.
  7. Utiliser addEventListener("load", initialisation, false) pour déclencher l'initialisation une fois la page chargée.

Résumé

Tableaux linéaires

  • Les tableaux linéaires ([]) stockent des éléments indexés par des numéros (0, 1, 2...) — on les parcourt avec for ou for...of
  • Méthodes utiles :
    • push() : ajoute un élément à la fin
    • pop() : retire le dernier élément
    • shift() : retire le premier élément
    • indexOf() : trouve l'index d'un élément
    • splice() : modifie le tableau en retirant/ajoutant des éléments
    • includes() : vérifie si un élément est présent
  • Math.max() et Math.min() avec l'opérateur spread (...) pour trouver les valeurs extrêmes

Tableaux associatifs (Objets)

  • Les tableaux associatifs sont des objets créés avec {} et indexés par des clés (chaînes de caractères)
  • Accès : notation par point (objet.cle) ou par crochets (objet["cle"])
  • Parcours : boucle for...in pour les propriétés

Fonctions nommées

  • Syntaxe : function nomFonction(parametres) { ... }
  • Peuvent recevoir des paramètres et retourner une valeur avec return
  • Nommez-les avec un verbe descriptif (ex. : calculerMoyenne, afficherMessage)
  • Ne pas utiliser les fonctions fléchées (=>) dans notre cours

Documentation JSDoc

  • Utilisez des commentaires /** ... */ pour documenter les fonctions
  • Tags principaux : @param {type} nom - description pour les paramètres, @returns {type} description pour la valeur de retour
  • VS Code génère automatiquement le squelette avec /** + Entrée

Le DOM (Document Object Model)

  • Représentation en arbre de la page HTML, manipulable via JavaScript
  • document.getElementById("id") : récupère un élément par son ID
  • element.textContent : lit ou modifie le contenu texte d'un élément
    • Lorsque l'élément est un input d'un formulaire, utilisez element.value pour accéder à sa valeur

Méthode de travail avec JavaScript

  • Structurez votre script en sections :
    • // Variables globales : déclarez les variables globales en haut
    • // Fonctions et événements : regroupez les fonctions et gestionnaires d'événements
    • // Initialisation : fonction initialisation() appelée au chargement de la page
  • Utilisez addEventListener("load", initialisation, false) à la fin du script pour déclencher l'initialisation

Événements

  • Un événement est une action utilisateur (clic, saisie...) qui déclenche une fonction
  • element.addEventListener("click", maFonction) : attache un gestionnaire au clic — passez le nom de la fonction sans parenthèses

Corrigés

Corrigé Ex1

javascript
// Créer un tableau vide pour stocker les personnes et leurs salaires
let personnesSalaires = [];

// Utiliser des boucles et prompt() pour saisir 5 noms et 5 salaires, en les ajoutant alternativement au tableau (nom, salaire, nom, salaire...)
for (let i = 0; i < 5; i++) {
    let nom = prompt(`Entrez le nom de la personne ${i + 1}:`);
    let salaire = parseFloat(prompt(`Entrez le salaire de ${nom}:`));
    personnesSalaires.push(nom, salaire);
}

// Rechercher le salaire d'un nom spécifique (par exemple "Dupont") et l'afficher dans la console
let nomRecherche = "Dupont";
let index = personnesSalaires.indexOf(nomRecherche);
if (index !== -1) {
    console.log(`Le salaire de ${nomRecherche} est: ${personnesSalaires[index + 1]}`);
} else {
    console.log(`${nomRecherche} n'a pas été trouvé dans le tableau.`);
}

// Retirer un nom et son salaire du tableau (par exemple "Dupont") en se servant des méthodes utiles des tableaux
if (index !== -1) {
    personnesSalaires.splice(index, 2); // Retire le nom et le salaire (2 éléments)
}

//Affiche ensuite le tableau : il devrait ne plus contenir le nom et le salaire retirés et d'une taille réduite de 2 éléments
// La console support l'affichage direct d'un tableau ! :
console.log("Tableau après suppression :", personnesSalaires);

// On peut aussi l'afficher en parcourant le tableau avec une boucle for :
console.log("Affichage du tableau avec une boucle for :");
for (let i = 0; i < personnesSalaires.length; i += 2) 
{
    console.log(`Nom : ${personnesSalaires[i]}, Salaire : ${personnesSalaires[i + 1]}`);
}

Corrigé Ex2

javascript
// 1. Créer un tableau vide pour stocker les voitures
let voitures = [];

// 2. Utiliser des boucles et prompt() pour saisir les informations de 3 voitures, en les stockant dans un tableau d'objets
for (let i = 0; i < 3; i++) {
    let marque = prompt(`Entrez la marque de la voiture ${i + 1}:`);
    let prix = parseFloat(prompt(`Entrez le prix de la voiture ${marque}:`));
    let annee = parseInt(prompt(`Entrez l'année de la voiture ${marque}:`));

    let voiture = {
        marque: marque,
        prix: prix,
        annee: annee
    };
    voitures.push(voiture);
}

// 3. Afficher le contenu du tableau à la console en décrivant chaque voiture
// Boucle for...of pour parcourir le tableau de voitures et afficher les détails de chaque voiture
for (let voiture of voitures) {
    console.log(`Marque: ${voiture.marque}, Prix: ${voiture.prix}$, Année: ${voiture.annee}`);
}

// 4. Alerter l'utilisateur sur la voiture dont le prix dépasse 50000$
for (let voiture of voitures) {
    if (voiture.prix > 50000) {
        alert(`La voiture ${voiture.marque} dépasse le prix de 50000$ avec un prix de ${voiture.prix}$!`);
    }
}

Corrigé Ex3

javascript
/* 2 :
Créer une fonction trierCouleurs qui prend 5 noms de couleurs en paramètres, les insère dans un tableau,
 trie ce tableau en ordre croissant (alphabétique) avec array.sort(), et retourne le tableau trié.
  Appeler cette fonction avec 5 couleurs différentes et afficher le résultat à la console.
*/

function trierCouleurs(couleur1, couleur2, couleur3, couleur4, couleur5) 
{

    let couleurs = [couleur1, couleur2, couleur3, couleur4, couleur5];
    couleurs.sort();

    console.log("Couleurs triées :", couleurs);
    return couleurs;
}

let tableau = trierCouleurs("rouge", "bleu", "vert", "jaune", "noir");



/*
Créer une fonction afficherTypes qui prend un tableau en paramètre et affiche le type (typeof) de chaque élément à la console.
 Appeler cette fonction avec le tableau retourné par la fonction précédente.
*/
function afficherTypes(tableau)
{
    console.log("Types des éléments du tableau :"); 
    for (let i = 0; i < tableau.length; i++)
    {
        console.log(`Type de ${tableau[i]} : ${typeof tableau[i]}`);
    }   
}
afficherTypes(tableau);

/*
Créer une fonction insererElement qui prend un tableau, une position (index), et un élément en paramètres, insère l'élément à la position donnée dans le tableau (en créant un nouveau tableau), et retourne ce nouveau tableau. Afficher le contenu du nouveau tableau à la console. 
Appeler cette fonction avec un tableau existant, une position, et un élément à insérer.
*/

function insererElement(tableau, index, element)
{
    let nouveauTableau = tableau; 

    nouveauTableau.splice(index, 0, element); // Insère l'élément à la position donnée
    console.log("Nouveau tableau après insertion :", nouveauTableau);
    return nouveauTableau;
}

// Portée de vie différente, alors on pourrait réutiliser le même nom de variable sans problèmes.
let nouveauTableau = insererElement(tableau, 2, "ORANGE");
console.log("Tableau après insertion :", nouveauTableau);

Explications

  • La fonction trierCouleurs prend 5 couleurs en paramètres, les stocke dans un tableau, trie ce tableau avec sort(), affiche le résultat et le retourne.
  • La fonction afficherTypes prend un tableau en paramètre et affiche le type de chaque élément à la console.
  • La fonction insererElement prend un tableau, une position et un élément, insère l'élément à la position donnée dans le tableau avec splice(), affiche le nouveau tableau et le retourne.

Corrigé Ex4

javascript
// =============================
// Variables globales : c'est ici que l'on déclarerait les variables globales de notre script

// =============================
// Fonctions et événements : c'est ici que l'on déclarerait les fonctions et les événements de notre script

/**
 * Fonction qui modifie le contenu du paragraphe 1 avec un texte hard codé
 */
function modifierParagraphe1() {
    document.getElementById("para1").textContent = "Texte modifié par le programme";
}

/**
 * Fonction qui modifie le contenu du paragraphe 2 avec un texte saisi par l'utilisateur
 */
function modifierParagraphe2() {
    let texteUtilisateur = prompt("Veuillez saisir le texte pour le paragraphe 2 :");
    document.getElementById("para2").textContent = texteUtilisateur;
}

/**
 * Fonction qui modifie le contenu d'un paragraphe spécifié par l'utilisateur
 */
function modifierUnParagraphe() {
    let idParagraphe = prompt("Veuillez saisir l'ID du paragraphe à modifier (para1, para2 ou para3) :");
    let nouveauTexte = prompt("Veuillez saisir le nouveau texte pour le paragraphe :");
    document.getElementById(idParagraphe).textContent = nouveauTexte;
}


// =============================
// Initialisation
// =============================
function initialisation() {
    document.getElementById("bouton1").addEventListener("click", modifierParagraphe1, false);
    document.getElementById("bouton2").addEventListener("click", modifierParagraphe2, false);
    document.getElementById("bouton3").addEventListener("click", modifierUnParagraphe, false);
}

/* Écouteur d'événement pour déclencher la fonction d'initialisation une fois la page web chargée */
addEventListener("load", initialisation, false);

Explications :

  • La fonction modifierParagraphe1 modifie le texte du paragraphe 1 avec un texte prédéfini.
  • La fonction modifierParagraphe2 demande à l'utilisateur de saisir un texte via prompt() et modifie le paragraphe 2 avec ce texte.
  • La fonction modifierUnParagraphe demande à l'utilisateur de saisir l'ID du paragraphe à modifier et le nouveau texte, puis modifie le paragraphe correspondant avec le nouveau texte.
  • Dans la fonction initialisation, les événements "click" sont attachés aux boutons pour appeler les fonctions correspondantes lorsque les boutons sont cliqués.

Corrigé Ex5

javascript
// =============================
// Variables globales : c'est ici que l'on déclarerait les variables globales de notre script
// Créer un tableau global newsletter vide au début du script pour stocker les objets abonnés.
let newsletter = [];

// =============================
// Fonctions et événements : c'est ici que l'on déclarerait les fonctions et les événements de notre script

/**
 * Fonction pour ajouter un abonné à la newsletter
 * Récupère les valeurs des champs du formulaire, crée un objet abonné, l'ajoute au tableau newsletter, et vide le formulaire.
 */
function ajouterAbonne() {
    let prenom = document.getElementById("prenom").value;
    let nom = document.getElementById("nom").value;
    let courriel = document.getElementById("courriel").value;
    let abonne = {
        prenom: prenom,
        nom: nom,
        courriel: courriel
    };
    newsletter.push(abonne);
    viderFormulaire();
}

/**
 * Fonction pour vider les champs du formulaire
 * Récupère les champs du formulaire et les remet à une chaîne vide pour les réinitialiser.
 */
function viderFormulaire() {
    document.getElementById("prenom").value = "";
    document.getElementById("nom").value = "";
    document.getElementById("courriel").value = "";
}

/**
 * Fonction qui parcourt le tableau newsletter et affiche les informations de chaque abonné à la console.
 */
function afficherAbonnes() {
    for (let i = 0; i < newsletter.length; i++) {
        let abonne = newsletter[i];
        console.log(`${abonne.prenom} ${abonne.nom} - ${abonne.courriel}`);
    }
}   

// =============================
// Initialisation
// =============================
function initialisation() {
    document.getElementById("btnAjouter").addEventListener("click", ajouterAbonne, false);
    document.getElementById("btnAfficher").addEventListener("click", afficherAbonnes, false);
}

/* Écouteur d'événement pour déclencher la fonction d'initialisation une fois la page web chargée */
addEventListener("load", initialisation, false);