JavaScript — rendre une page vivante

Le troisième langage du web : celui qui réagit. Le HTML structure, le CSS habille, JavaScript fait bouger.

📌

Résumé flash

JavaScript est le langage de programmation du navigateur. Il stocke des données (let, const), les teste (if, switch), les répète (for, while) et les organise en fonctions. Sa vraie puissance : le DOM — la page vue comme un arbre d'objets qu'il peut lire et modifier — et les événements, qui déclenchent du code quand l'utilisateur agit.

🔑 #let-const #typeof #=== #template-literal #if-else #switch #for #while #function #arrow #scope #DOM #querySelector #addEventListener #preventDefault #regex

01Le rôle de JavaScript

JavaScript est le langage de programmation du navigateur. Contrairement au HTML (structure) et au CSS (mise en forme), c'est un vrai langage : il calcule, décide, répète. Il permet :

  • d'ajouter de l'interactivité — réponses aux clics, menus, formulaires dynamiques ;
  • de modifier l'apparence en temps réel — changer un texte, cacher un élément, basculer une classe CSS ;
  • de communiquer avec un serveur sans recharger la page (AJAX, fetch) ;
  • de créer des animations ;
  • de contrôler le navigateur — redirections, alertes, stockage local.
💡 Le retour du corps humain

On avait posé l'image au chapitre HTML : le HTML est le squelette, le CSS la peau et les vêtements. JavaScript, ce sont les muscles et les nerfs — ce qui permet de réagir à ce qui arrive de l'extérieur. Sans lui, la page est une photo ; avec lui, elle devient une application.

02Intégrer et tester

Deux façons d'ajouter du JavaScript

html — script interne
<script>
    console.log("Script interne exécuté !");
</script>

Pratique pour tester vite, déconseillé sur un vrai projet.

html — fichier externe (recommandé)
<script src="script.js"></script>

Plus organisé, réutilisable, maintenable. C'est la même logique qu'un style.css séparé.

Où placer la balise <script> ?

L'emplacement décide du moment où le code s'exécute — et c'est capital, car un script ne peut pas manipuler des éléments qui n'existent pas encore.

EmplacementComportement
À la fin du <body> le HTML est déjà lu quand le script démarre — la méthode la plus courante
Dans le <head> avec defer chargé en arrière-plan pendant la lecture du HTML, exécuté une fois le DOM complet — la méthode moderne recommandée
Dans le <head> sans defer bloque l'affichage, et le DOM n'existe pas encore
html
<head>
    <script src="script.js" defer></script>
</head>

La console : votre meilleur outil

Ouvrir avec F12 → onglet Console, ou clic droit → Inspecter.

javascript
console.log("message");                        // message normal
console.error("erreur");                       // en rouge
console.table(["HTML", "CSS", "JavaScript"]);  // tableau lisible

Commentaires et points-virgules

javascript
// commentaire sur une seule ligne

/* commentaire
   sur plusieurs lignes */

Les points-virgules ne sont pas toujours obligatoires : si chaque instruction est sur sa propre ligne, JavaScript les devine. Mais si plusieurs instructions partagent une ligne, ils sont indispensables :

javascript
x += 1; y -= 1; z = 0;
⚠️ Mettez toujours les points-virgules

Le mécanisme qui les devine (l'insertion automatique) se trompe dans certains cas — notamment quand une ligne commence par ( ou [. Le bug qui en résulte est inintelligible pour un débutant. Prenez l'habitude de les écrire : zéro inconvénient, un piège en moins.

03Variables et types

Une variable est un espace mémoire qui contient une valeur. En JavaScript, son nom n'a pas de symbole particulier.

Règles de nommage

  • lettres, chiffres, $ ou _ uniquement ;
  • ni espace, ni caractère spécial ;
  • ne commence jamais par un chiffre ;
  • JavaScript est sensible à la casse : y ≠ Y ;
  • pas de mot réservé du langage.

Trois mots pour déclarer

Mot-cléUsageVerdict
letvariable modifiable, portée de bloc à utiliser
constconstante : ne peut plus être réaffectée à privilégier
varl'ancienne façon, portée de fonction à éviter
javascript
let age = 20;          // déclaration
age = 21;              // modification : autorisée
console.log(age);      // 21

const pi = 3.14;
pi = 3.1415;           // ✘ Erreur : impossible de réaffecter une constante

Les chaînes de caractères

javascript
let texte1 = "Bonjour";          // guillemets doubles
let texte2 = 'Bienvenue !';      // guillemets simples
let texte3 = `Ceci est une chaîne.`;   // backticks : template literal

Les types de données

TypeExempleDescription
number42, 3.14valeurs numériques
string"Alice"chaînes de caractères
booleantrue / falsevrai ou faux
undefinedlet x;déclarée sans valeur
nullnullvaleur vide volontaire
array[1, 2, 3]liste ordonnée
object{nom: "Bob"}regroupement clé/valeur
🧰 Le template literal, bien plus lisible

Les backticks permettent d'insérer des variables directement avec ${…}, au lieu d'empiler les + :

javascript
let nom = "Alice", age = 25;

console.log("Je m'appelle " + nom + " et j'ai " + age + " ans.");   // à l'ancienne
console.log(`Je m'appelle ${nom} et j'ai ${age} ans.`);             // template literal

Moins de guillemets à fermer, donc moins d'erreurs. C'est aussi la seule façon simple d'écrire une chaîne sur plusieurs lignes.

⚠️ undefined n'est pas null

undefined : la variable existe mais personne ne lui a donné de valeur. null : quelqu'un a volontairement décidé qu'elle était vide. Le premier signale souvent un oubli, le second une intention. Les confondre, c'est se priver d'un indice de débogage.

04Opérateurs et conversions

Arithmétiques

+ - * / % (reste) et ** (puissance).

Comparaison

Ils retournent toujours un booléen.

OpérateurSignificationExemple
==égal — valeur seulement 5 == "5" → true
===strictement égal — valeur + type 5 === "5" → false
!=différent5 != 3 → true
!==strictement différent 5 !== "5" → true
> < >= <= comparaisons numériques7 > 3 → true
⚠️ Utilisez toujours ===

== convertit avant de comparer : il juge que la chaîne "5" et le nombre 5 sont égaux. Cela produit des résultats déroutants :

javascript
5 == "5"        // true   ← la chaîne est convertie en nombre
0 == ""         // true
0 == false      // true

5 === "5"       // false  ← types différents : la réponse honnête
0 === false     // false

C'est un piège majeur quand on lit un formulaire : input.value renvoie toujours une chaîne. Comparez avec === après conversion explicite, et vous supprimez toute une famille de bugs.

Logiques

OpérateurVrai quand…Exemple
&&toutes les conditions sont vraies (ET) age >= 18 && mdp === "1234"
||au moins une est vraie (OU) role === "admin" || role === "prof"
!inverse la valeur (NON) !(age >= 18)
🔧 Corrigé — le OU logique manque dans le polycopié

Le tableau des opérateurs logiques du cours ne présente que && et !. L'opérateur || (OU logique), tout aussi fondamental, en est absent. Il est vrai dès qu'au moins une des conditions l'est :

javascript
if (nom === "" || email === "") {
    alert("Merci de remplir tous les champs");
}

Sans lui, impossible d'écrire proprement « si l'un OU l'autre pose problème » — ce qui est exactement le cas dans une validation de formulaire.

Concaténation et conversions

javascript
let texte1 = "Bonjour ", texte2 = "le monde";
console.log(texte1 + texte2);        // "Bonjour le monde"

let age = 20;
console.log("J'ai " + age + " ans.");  // "J'ai 20 ans."

Number("42")     // 42        → transforme en nombre
String(100)      // "100"     → transforme en texte
typeof "Alice"   // "string"  → donne le type
⚠️ Le + a deux métiers

Avec deux nombres il additionne ; dès qu'une chaîne apparaît, il concatène :

javascript
2 + 3          // 5      ← addition
"2" + 3        // "23"   ← concaténation !
Number("2") + 3  // 5    ← conversion explicite : correct

C'est le bug du calculateur de TP : on lit deux champs, on les additionne, et « 2 + 3 » affiche « 23 ». La cause est toujours la même — .value renvoie du texte. Convertissez avant de calculer.

05Les conditions

javascript — if / else if / else
let age = 18;

if (age < 18) {
    console.log("Vous êtes mineur");
} else if (age === 18) {
    console.log("Vous venez d'atteindre la majorité");
} else {
    console.log("Vous êtes majeur");
}

switch : tester une variable contre plusieurs valeurs

javascript
let jour = "lundi";

switch (jour) {
    case "lundi":
        console.log("C'est le début de la semaine");
        break;
    case "vendredi":
        console.log("Dernier jour avant le weekend");
        break;
    case "dimanche":
        console.log("C'est le weekend !");
        break;
    default:
        console.log("Jour quelconque");
}
⚠️ Le break n'est pas décoratif

Sans break, l'exécution continue dans les cas suivants — c'est la « chute » (fall-through). Avec jour = "lundi" et un break oublié, les trois messages s'afficheraient.

Ce comportement est parfois voulu (regrouper plusieurs cas), mais il est presque toujours accidentel. default joue le rôle du else final.

06Les boucles

Même logique qu'en algorithmique, avec la syntaxe du langage.

for — quand on connaît le nombre de tours

javascript
for (initialisation; condition; incrémentation) {
    // instructions à répéter
}

for (let i = 1; i <= 5; i++) {
    console.log("Tour numéro :", i);
}

Les trois parties, séparées par des points-virgules : on part de i = 1, on continue tant que i <= 5, et on ajoute 1 à chaque tour.

while — quand on ne sait pas combien de fois

javascript
let compteur = 1;

while (compteur <= 5) {
    console.log("Compteur :", compteur);
    compteur++;          // ← sans cette ligne : boucle infinie
}

do…while — au moins un tour, toujours

javascript
let nombre = 10;

do {
    console.log("Le nombre est :", nombre);
} while (nombre < 5);

// Affiche une fois « Le nombre est : 10 »,
// alors même que 10 < 5 est faux : le test vient APRÈS.
⚠️ La boucle infinie

Toute boucle while doit contenir une instruction qui fait évoluer sa condition. Oubliez le compteur++ et l'onglet se fige — le navigateur ne rend plus la main.

Le réflexe : après avoir écrit un while, cherchez des yeux la ligne qui permettra d'en sortir. Si vous ne la trouvez pas, elle manque.

07Les fonctions

Une fonction est un bloc de code autonome, réutilisable : elle reçoit des paramètres, effectue un traitement, et peut retourner une valeur.

Trois écritures

javascript — déclarée
function addition(a, b) {
    return a + b;
}
console.log(addition(5, 3));      // 8

// Particularité : elle est « hoistée », donc appelable AVANT sa déclaration
console.log(addition(3, 4));      // fonctionne
javascript — expression
const multiplication = function (a, b) {
    return a * b;
};
console.log(multiplication(4, 6));    // 24
// Utilisable seulement APRÈS sa déclaration.
javascript — fléchée
const soustraction = (a, b) => a - b;          // une seule expression : return implicite
console.log(soustraction(10, 7));   // 3

const calcul = (x, y) => {                     // plusieurs instructions : accolades + return
    let resultat = x * y + 10;
    return resultat;
};
console.log(calcul(2, 5));          // 20
🔧 Corrigé — une fonction anonyme ne s'écrit pas toute seule

Le polycopié présente la « fonction anonyme » ainsi :

erreur de syntaxe
function() {
    // instructions
}

Écrit seul sur une ligne, ce code ne se contente pas d'être inutilisable : il ne compile pas. Le navigateur répond « Function statements require a function name ». Une fonction anonyme n'existe que comme expression — assignée à une variable, ou passée en argument :

javascript — correct
const f = function () { /* … */ };        // assignée

setTimeout(function () {                   // passée en argument (callback)
    console.log("Bonjour après 2 secondes !");
}, 2000);

setTimeout(() => console.log("idem, en fléchée"), 2000);

Paramètres, retour et valeurs par défaut

javascript
function carre(nombre) {
    return nombre * nombre;
}
let resultat = carre(5);          // 25

function afficherMessage() {
    console.log("Bonjour !");
}
let valeur = afficherMessage();   // undefined : pas de return

function saluer(nom = "Invité") { // valeur par défaut
    console.log("Bonjour " + nom + " !");
}
saluer();          // Bonjour Invité !
saluer("Alice");   // Bonjour Alice !

Les paramètres sont les noms déclarés ; les arguments sont les valeurs réellement passées à l'appel. Après return, la fonction s'arrête.

La portée (scope)

javascript
let global = "Je suis global";

function testScope() {
    let local = "Je suis local";
    console.log(global);   // ✔ accessible
    console.log(local);    // ✔ accessible
}

testScope();
console.log(global);       // ✔
console.log(local);        // ✘ Erreur : local n'existe pas ici

Une variable déclarée dans une fonction n'existe que là. C'est une protection : deux fonctions peuvent utiliser un i sans se gêner.

08Le DOM

Le DOM (Document Object Model) est la représentation en arbre de la page. Quand le navigateur charge le HTML, il le transforme en objets JavaScript : chaque balise devient un nœud, que le code peut lire et modifier.

document html head body h1 button chaque balise = un nœud
Le DOM n'est pas le fichier HTML : c'est ce que le navigateur en a fait, en mémoire. Le modifier change la page immédiatement.

Sélectionner un élément

MéthodeCe qu'elle prendCe qu'elle rend
getElementById("id")un identifiantl'élément
querySelector("…")un sélecteur CSS le premier qui correspond
querySelectorAll("…")un sélecteur CSS tous ceux qui correspondent
javascript
let titre       = document.getElementById("titre");
let paragraphe  = document.querySelector("p");          // le premier <p>
let important   = document.querySelector(".important");  // la 1re classe "important"
let conteneur   = document.querySelector("#conteneur");  // par id, façon CSS
let paragraphes = document.querySelectorAll("p");        // tous les <p>

Modifier un élément

javascript
titre.textContent = "Nouveau titre";                    // texte brut
titre.innerHTML   = "<span style='color:red'>Rouge</span>";  // interprète le HTML

titre.style.color           = "blue";                   // style en ligne
titre.style.backgroundColor = "yellow";                 // camelCase !

texte.classList.add("rouge");        // ajouter une classe
texte.classList.remove("rouge");     // l'enlever
texte.classList.toggle("rouge");     // l'un ou l'autre selon l'état

Créer et ajouter

javascript
let p = document.createElement("p");
p.textContent = "Paragraphe ajouté par JavaScript";
document.body.appendChild(p);
⚠️ textContent ou innerHTML ?

textContent insère du texte brut ; innerHTML interprète le HTML. La règle :

Par défaut textContent. innerHTML seulement si l'on veut vraiment des balises.

Pourquoi ? Parce qu'injecter dans innerHTML du texte venant de l'utilisateur laisse exécuter du code étranger dans votre page — c'est la faille XSS, vue au chapitre cybersécurité. textContent affiche les balises telles quelles, donc sans danger.

⚠️ Les propriétés CSS passent en camelCase

En CSS on écrit background-color ; en JavaScript, le tiret est interdit dans un nom de propriété. On écrit donc style.backgroundColor, style.fontSize, style.marginTop.

Cela dit, modifier classList est presque toujours préférable à style : le design reste dans le CSS, et JavaScript se contente de basculer une classe.

09Les événements

Un événement est une action détectée par le navigateur : un clic, une touche du clavier, l'envoi d'un formulaire, le chargement de la page. JavaScript peut les écouter et exécuter du code en réponse.

javascript
element.addEventListener("typeEvenement", fonctionCallback);
  • "typeEvenement" — click, submit, keydown…
  • fonctionCallback — la fonction exécutée quand l'événement se produit.
javascript
const bouton = document.getElementById("btn");
const zone   = document.getElementById("zone");
let compteur = 0;

bouton.addEventListener("click", function () {
    compteur++;
    zone.textContent = "Clics : " + compteur;
    zone.style.color = compteur >= 5 ? "crimson" : "#2D5A27";
});

↑ Cliquez réellement sur le bouton : le code de gauche s'exécute dans le cadre de droite.

Les principaux événements

CatégorieÉvénementDéclenché quand…
Sourisclickclic simple
dblclickdouble clic
mouseover / mouseoutla souris entre / quitte
contextmenuclic droit
Clavierkeydowntouche enfoncée
keyuptouche relâchée
Formulairesubmitenvoi du formulaire
change / inputune valeur change
⚠️ addEventListener("click", maFonction) — sans parenthèses
javascript
bouton.addEventListener("click", direBonjour);      // ✔ on PASSE la fonction
bouton.addEventListener("click", direBonjour());    // ✘ on l'APPELLE tout de suite

Avec les parenthèses, la fonction s'exécute immédiatement, au chargement, et c'est son résultat (souvent undefined) qui est enregistré comme écouteur. Résultat : l'action se produit une fois toute seule, puis le bouton reste inerte.

10Valider un formulaire

Objectifs : empêcher l'envoi de données incorrectes, améliorer l'expérience utilisateur, réduire les erreurs côté serveur et sécuriser les données. Avec JavaScript on peut intercepter l'envoi, vérifier, et bloquer si nécessaire.

Récupérer les valeurs

PropriétéRôleSur quoi
.valuele texte saisi input, textarea, select
.checkedcoché ou non checkbox, radio
.selectedIndexl'index choisi (à partir de 0) select
javascript
let nom   = document.getElementById("nom").value;
let email = document.getElementById("email").value;

Les vérifications de base

javascript
if (nom === "") {
    alert("Le nom est obligatoire");
}

if (password.length < 8) {
    alert("Mot de passe trop court");
}

if (!email.includes("@")) {
    alert("Email invalide");
}

Les expressions régulières

Une regex vérifie un format précis.

javascript
let regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!regex.test(email)) {
    alert("Email invalide");
}

let telRegex = /^[0-9]{10}$/;
if (!telRegex.test(telephone)) {
    alert("Numéro invalide");
}
PartieSignification
^début de la chaîne
[^\s@]+un ou plusieurs caractères qui ne sont ni un espace ni @
@l'arobase, obligatoire
\.un point (le \ l'échappe)
[0-9]{10}un chiffre, exactement 10 fois
$fin de la chaîne

Messages d'erreur dans la page

Plutôt qu'un alert() qui bloque tout, on affiche l'erreur à côté du champ.

javascript
const form  = document.getElementById("formulaire");
const champ = document.getElementById("email");
const err   = document.getElementById("erreurEmail");
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

form.addEventListener("submit", function (e) {
    e.preventDefault();              // ← bloque l'envoi
    const email = champ.value.trim();

    if (email === "") {
        err.textContent = "L'email est obligatoire";
    } else if (!regex.test(email)) {
        err.textContent = "Format d'email invalide";
    } else {
        err.textContent = "";
        champ.style.borderColor = "green";
    }
});

↑ Essayez d'envoyer le formulaire vide, puis avec « abc », puis avec une vraie adresse.

🧰 preventDefault() : la clé de toute validation

Par défaut, un submit envoie le formulaire et recharge la page — votre code de vérification n'a même pas le temps d'agir. e.preventDefault() annule ce comportement par défaut et vous laisse la main.

javascript
form.addEventListener("submit", function (e) {
    e.preventDefault();     // sans cette ligne, rien de ce qui suit ne sert
    // … vérifications …
});

Notez aussi .trim(), qui retire les espaces avant et après : sans lui, un champ ne contenant qu'une espace passerait le test === "".

⚠️ La validation côté client ne sécurise rien

Tout ce JavaScript s'exécute dans le navigateur de l'utilisateur : il peut le désactiver, le modifier, ou envoyer la requête sans passer par votre page. La validation côté client sert le confort — un retour immédiat, une faute signalée avant l'envoi.

La sécurité, elle, se joue côté serveur, où l'utilisateur n'a pas la main. Toute donnée reçue doit y être revérifiée. C'est le sujet du chapitre PHP.

🧠 Auto-évaluation

Ce code additionne deux champs et affiche « 23 » au lieu de « 5 ». Pourquoi, et comment le corriger ?

javascript
let a = document.getElementById("a").value;   // l'utilisateur a saisi 2
let b = document.getElementById("b").value;   // l'utilisateur a saisi 3
console.log(a + b);

.value renvoie toujours une chaîne de caractères, même quand le champ est un type="number". On a donc "2" + "3", et le + concatène au lieu d'additionner.

javascript — corrigé
let a = Number(document.getElementById("a").value);
let b = Number(document.getElementById("b").value);
console.log(a + b);      // 5

La règle : tout ce qui sort d'un formulaire est du texte. Convertissez avec Number() avant tout calcul, et comparez avec === après conversion.

⚡ Récap 2 minutes

  • Intégration : fichier externe, dans le <head> avec defer (ou en fin de <body>).
  • Variables : const par défaut, let si ça change, var jamais.
  • Comparaison : toujours ===. == convertit et ment.
  • Logiques : && (et), || (ou), ! (non).
  • Le + additionne les nombres, concatène dès qu'il y a du texte → Number().
  • Boucles : for (nombre connu), while, do…while (1 tour minimum). Faire évoluer la condition.
  • Fonctions : déclarée (hoistée), expression, fléchée (=>). Anonyme = seulement en expression.
  • DOM : querySelector / querySelectorAll, textContent (sûr) vs innerHTML, classList.
  • Événements : addEventListener("click", fn) — sans parenthèses.
  • Validation : e.preventDefault(), .trim(), regex — et tout revérifier côté serveur.

Sources exploitées

  • Cours « Développement web — JavaScript » (le professeur, BTS CIEL 2025-2026)
  • Cours « JavaScript et le DOM » · « Formulaires et validation »
  • TP 1 à 4 — opérateurs et conditions, fonctions, DOM, validation de formulaire
  • comptes rendus d'élève (TP3 DOM, TP4 validation)