Cours JavaScript et TypeScript · Module 8: Événements et DOM

Les événements et les interactions en JavaScript

7 min de lecture
Dans cette leçon3

« Bon retour à Jurassic Park », te salue Ray Arnold, l'ingénieur système en chef. « Aujourd'hui, je vais te montrer comment fonctionne l'aspect le plus critique de nos systèmes : l'interactivité. Chaque système du parc, des portails de sécurité à la surveillance des dinosaures, doit réagir en temps réel à différents signaux. »

Ray te conduit jusqu'au panneau de contrôle central, où des centaines d'indicateurs clignotent et pulsent. « Regarde », pointe-t-il l'écran, « tous ces systèmes écoutent des événements : l'ouverture d'un portail, un mouvement dans un enclos, un changement de température. En JavaScript, on travaille exactement de la même manière. »

Qu'est-ce qu'un événement en JavaScript ?

Les événements sont un mécanisme de communication fondamental dans le navigateur. Chaque interaction de l'utilisateur - un clic, un mouvement de souris, l'appui sur une touche - génère un événement auquel on peut réagir.

1// Comme un capteur de mouvement dans un enclos de dinosaures
2const motionSensor = document.getElementById('dino-enclosure');
3
4motionSensor.addEventListener('click', function() {
5  console.log('Activité détectée dans l\'enclos !');
6  checkDinosaurStatus();
7});

« À Jurassic Park », poursuit Ray, « on a des milliers de capteurs. Chacun envoie des signaux au centre de contrôle. Si on devait vérifier en permanence chaque capteur, le système s'effondrerait. À la place, les capteurs n'envoient des événements que lorsqu'il se passe quelque chose. »

Le modèle d'événements du navigateur

Le navigateur met en œuvre ce qu'on appelle une Event-Driven Architecture - une architecture pilotée par les événements. Cela signifie que le code ne s'exécute pas séquentiellement de haut en bas, mais réagit aux événements qui surviennent dans le système.

1// Le code enregistre des écouteurs et attend les événements
2console.log('Système actif - en écoute...');
3
4document.addEventListener('click', () => {
5  console.log('Clic enregistré !');
6});
7
8document.addEventListener('keydown', () => {
9  console.log('Touche pressée !');
10});
11
12// Le programme ne se termine pas - il attend les événements
13console.log('Tous les systèmes sont prêts');

Les types d'événements

Ray te montre une liste à l'écran. « On a des dizaines de types de capteurs dans le parc. De la même façon, JavaScript possède des dizaines de types d'événements : »

Événements souris :

  • click - clic (comme un bouton d'urgence)
  • dblclick - double clic
  • mouseenter / mouseleave - entrée/sortie de la souris
  • mousemove - mouvement de la souris (comme un capteur de mouvement)
  • mousedown / mouseup - pression/relâchement d'un bouton de la souris

Événements clavier :

  • keydown - touche pressée
  • keyup - touche relâchée
  • keypress - obsolète, ne l'utilise pas (à la place : keydown ou input)

Événements de formulaire :

  • submit - envoi du formulaire
  • change - valeur d'un champ modifiée
  • input - saisie de texte
  • focus / blur - activation/désactivation d'un champ

Événements du document :

  • DOMContentLoaded - DOM prêt (comme un système qui se met en ligne)
  • load - toutes les ressources chargées
  • scroll - défilement de la page
  • resize - redimensionnement de la fenêtre

L'anatomie d'un événement

« Chaque événement transporte des informations avec lui », explique Ray en montrant un rapport de capteur détaillé. « De la même façon, chaque objet Event en JavaScript contient des données sur ce qui s'est passé. »

1const enclosureMap = document.getElementById('park-map');
2
3enclosureMap.addEventListener('click', function(event) {
4  // L'objet event contient des informations détaillées
5
6  console.log('Type d\'événement :', event.type); // 'click'
7  console.log('Élément cible :', event.target); // l'élément cliqué
8  console.log('Position X :', event.clientX); // coordonnée X
9  console.log('Position Y :', event.clientY); // coordonnée Y
10  console.log('Bouton de la souris :', event.button); // 0=gauche, 1=milieu, 2=droit
11  console.log('Ctrl enfoncé ?', event.ctrlKey); // true/false
12  console.log('Shift enfoncé ?', event.shiftKey); // true/false
13
14  // On peut utiliser ces informations pour des réactions précises
15  if (event.ctrlKey) {
16    selectMultipleDinosaurs(event.target);
17  } else {
18    selectSingleDinosaur(event.target);
19  }
20});

Pourquoi les événements sont-ils importants ?

Ray pointe le grand écran qui affiche les cartes de tous les enclos. « Sans le système d'événements, on devrait vérifier chaque capteur chaque seconde. Ce serait inefficace et très gourmand en ressources. Les événements permettent aux systèmes de réagir instantanément et uniquement quand c'est nécessaire. »

Dans les applications web, les événements permettent :

  1. L'interactivité - réagir aux actions de l'utilisateur
  2. La performance - le code ne s'exécute que lorsque c'est nécessaire
  3. L'asynchronisme - différentes parties de l'application peuvent fonctionner indépendamment
  4. La modularité - différents composants peuvent communiquer via les événements

Premier exemple pratique

« Voyons cela en action », dit Ray en ouvrant un panneau de code. « Créons un système simple de surveillance d'enclos. »

1// Système de surveillance de l'enclos du T-Rex
2const trexEnclosure = {
3  temperature: 28,
4  humidity: 65,
5  feedingSchedule: '14:00',
6  lastActivity: null,
7
8  initialize() {
9    // Enregistrement des écouteurs pour différents systèmes
10    const tempSensor = document.getElementById('temp-sensor');
11    const feedButton = document.getElementById('feed-button');
12    const activityMonitor = document.getElementById('activity-monitor');
13
14    // Surveillance de la température
15    tempSensor.addEventListener('change', (e) => {
16      this.temperature = parseFloat(e.target.value);
17      this.checkConditions();
18    });
19
20    // Système de nourrissage
21    feedButton.addEventListener('click', () => {
22      this.feedDinosaur();
23    });
24
25    // Détection d'activité
26    activityMonitor.addEventListener('motion', (e) => {
27      this.lastActivity = new Date();
28      this.logActivity(e.detail);
29    });
30
31    console.log('Système de surveillance du T-Rex actif');
32  },
33
34  checkConditions() {
35    if (this.temperature > 35) {
36      this.triggerAlert('Température trop élevée !', 'warning');
37    } else if (this.temperature < 20) {
38      this.triggerAlert('Température trop basse !', 'warning');
39    } else {
40      console.log('Conditions optimales');
41    }
42  },
43
44  feedDinosaur() {
45    console.log('Démarrage de la procédure de nourrissage du T-Rex...');
46    this.triggerAlert('Nourrissage en cours', 'info');
47
48    setTimeout(() => {
49      console.log('Nourrissage terminé avec succès');
50      this.triggerAlert('Nourrissage terminé', 'success');
51    }, 3000);
52  },
53
54  logActivity(details) {
55    console.log(`Activité enregistrée : ${details.type} à ${this.lastActivity.toLocaleTimeString()}`);
56  },
57
58  triggerAlert(message, level) {
59    const alertEvent = new CustomEvent('parkAlert', {
60      detail: { message, level, timestamp: new Date() }
61    });
62    document.dispatchEvent(alertEvent);
63  }
64};
65
66// Initialisation du système
67document.addEventListener('DOMContentLoaded', () => {
68  trexEnclosure.initialize();
69});
70
71// Système d'alerte central
72document.addEventListener('parkAlert', (e) => {
73  const { message, level, timestamp } = e.detail;
74  console.log(`[${timestamp.toLocaleTimeString()}] ${level.toUpperCase()} : ${message}`);
75});

Bonnes pratiques - les règles de Ray Arnold

« Après des années passées à travailler sur les systèmes de Jurassic Park », dit Ray, « j'ai appris quelques règles essentielles : »

1. Vérifie toujours que l'élément existe

1const emergencyButton = document.getElementById('emergency');
2
3if (emergencyButton) {
4  emergencyButton.addEventListener('click', evacuatePark);
5} else {
6  console.error('ERREUR CRITIQUE : bouton d\'urgence introuvable !');
7}

2. Supprime les écouteurs lorsqu'ils ne sont plus nécessaires

1function setupTemporaryMonitoring() {
2  const sensor = document.getElementById('temp-sensor');
3
4  function handleReading(e) {
5    console.log('Relevé :', e.target.value);
6  }
7
8  sensor.addEventListener('change', handleReading);
9
10  // Au bout d'1 heure, on désactive la surveillance
11  setTimeout(() => {
12    sensor.removeEventListener('change', handleReading);
13    console.log('Surveillance terminée');
14  }, 3600000);
15}

3. Utilise des fonctions nommées pour la lisibilité

Le nom de la fonction indique tout de suite ce que fait l'écouteur, et si quelque chose se passe mal, tu le verras dans la pile d'appels des outils de développement.

1// Mieux
2function handleEmergencyClick(event) {
3  console.log('Activation du protocole d\'urgence');
4  evacuatePark();
5}
6
7emergencyButton.addEventListener('click', handleEmergencyClick);
8
9// Plutôt que
10emergencyButton.addEventListener('click', function(e) {
11  console.log('Activation du protocole d\'urgence');
12  evacuatePark();
13});

4. Regroupe les événements similaires

1class EnclosureMonitor {
2  constructor(enclosureId) {
3    this.enclosure = document.getElementById(enclosureId);
4    this.initializeEvents();
5  }
6
7  initializeEvents() {
8    // Tous les écouteurs d'événements au même endroit
9    this.enclosure.addEventListener('click', (e) => this.handleClick(e));
10    this.enclosure.addEventListener('mouseenter', (e) => this.handleMouseEnter(e));
11    this.enclosure.addEventListener('mouseleave', (e) => this.handleMouseLeave(e));
12  }
13
14  handleClick(event) {
15    console.log('Enclos cliqué');
16  }
17
18  handleMouseEnter(event) {
19    this.enclosure.classList.add('highlighted');
20  }
21
22  handleMouseLeave(event) {
23    this.enclosure.classList.remove('highlighted');
24  }
25}

Récapitulatif

« Les événements sont le cœur de tout système interactif », résume Ray. « Sans eux, nos applications seraient statiques et inutiles - comme un parc sans systèmes de sécurité. »

Concepts clés :

  • Les événements sont générés par le navigateur en réponse aux actions de l'utilisateur
  • addEventListener() permet d'écouter les événements
  • L'objet event contient des informations détaillées sur l'événement
  • Une bonne gestion des écouteurs est cruciale pour la performance

Dans les leçons suivantes, nous approfondirons les techniques avancées de gestion des événements, en découvrant la propagation, la délégation et les événements personnalisés.

Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Parc Jurassique - Panneau d'alarme</title>
7    <style>
8        body {
9            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10            background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
11            margin: 0;
12            padding: 20px;
13            color: white;
14        }
15
16        .emergency-panel {
17            max-width: 400px;
18            margin: 50px auto;
19            background: rgba(0, 0, 0, 0.8);
20            border-radius: 15px;
21            padding: 30px;
22            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
23            border: 2px solid #e74c3c;
24        }
25
26        .emergency-button {
27            width: 100%;
28            height: 100px;
29            background: linear-gradient(45deg, #e74c3c, #c0392b);
30            border: none;
31            border-radius: 10px;
32            color: white;
33            font-size: 24px;
34            font-weight: bold;
35            cursor: pointer;
36            transition: all 0.3s ease;
37            margin-bottom: 20px;
38            box-shadow: 0 5px 15px rgba(231, 76, 60, 0.4);
39        }
40
41        .emergency-button:hover {
42            transform: translateY(-2px);
43            box-shadow: 0 10px 25px rgba(231, 76, 60, 0.6);
44            background: linear-gradient(45deg, #c0392b, #a93226);
45        }
46
47        .emergency-button:active {
48            transform: translateY(0);
49            box-shadow: 0 5px 15px rgba(231, 76, 60, 0.4);
50        }
51
52        .status-display {
53            background: rgba(255, 255, 255, 0.1);
54            border-radius: 8px;
55            padding: 15px;
56            margin-top: 20px;
57            border: 1px solid rgba(255, 255, 255, 0.2);
58        }
59
60        .alert-message {
61            display: none;
62            background: #e74c3c;
63            color: white;
64            padding: 15px;
65            border-radius: 8px;
66            margin-top: 15px;
67            text-align: center;
68            font-weight: bold;
69            animation: pulse 1s infinite;
70        }
71
72        @keyframes pulse {
73            0% { opacity: 1; }
74            50% { opacity: 0.7; }
75            100% { opacity: 1; }
76        }
77
78        h1 {
79            text-align: center;
80            margin-bottom: 30px;
81            color: #ecf0f1;
82        }
83
84        .last-activation {
85            color: #bdc3c7;
86            font-size: 14px;
87        }
88    </style>
89</head>
90<body>
91    <div class="emergency-panel">
92        <h1>PANNEAU D'ALARME T-REX</h1>
93        <button id="emergency-button" class="emergency-button">
94            ACTIVER L'ALARME D'URGENCE
95        </button>
96
97        <div class="status-display">
98            <div>Status du système: <span id="system-status">PRÊT</span></div>
99            <div class="last-activation">Dernière activation: <span id="last-activation">JAMAIS</span></div>
100        </div>
101
102        <div id="alert-message" class="alert-message">
103            ALARM! T-REX ESCAPED FROM THE PADDOCK!
104        </div>
105    </div>
106
107    <script>
108        // Getting references to DOM elements
109        const emergencyButton = document.getElementById('emergency-button');
110        const systemStatus = document.getElementById('system-status');
111        const lastActivation = document.getElementById('last-activation');
112        const alertMessage = document.getElementById('alert-message');
113
114        // Ajout de l'event listener sur le bouton
115        emergencyButton.addEventListener('click', function() {
116            // Displaying alert
117            alert('EMERGENCY ALARM ACTIVATED!\n\nT-Rex escaped from the paddock!\nÉvacuation in progress...');
118
119            // Mise à jour du status du système
120            systemStatus.textContent = 'ALARME ACTIVE';
121            systemStatus.style.color = '#e74c3c';
122
123            // Enregistrement de l'heure de la dernière activation
124            const now = new Date();
125            lastActivation.textContent = now.toLocaleTimeString('fr-FR');
126
127            // Affichage du message d'alarme
128            alertMessage.style.display = 'block';
129
130            // Changement du texte du bouton
131            emergencyButton.textContent = 'ALARME ACTIVE';
132            emergencyButton.style.background = 'linear-gradient(45deg, #27ae60, #2ecc71)';
133
134            // Après 5 secondes, réinitialisation du système
135            setTimeout(function() {
136                systemStatus.textContent = 'PRÊT';
137                systemStatus.style.color = '#2ecc71';
138                alertMessage.style.display = 'none';
139                emergencyButton.textContent = "ACTIVER L'ALARME D'URGENCE";
140                emergencyButton.style.background = 'linear-gradient(45deg, #e74c3c, #c0392b)';
141            }, 5000);
142        });
143
144        // Adding mouse hover handling
145        emergencyButton.addEventListener('mouseenter', function() {
146            console.log("Curseur sur le bouton d'urgence - ATTENTION !");
147        });
148
149        emergencyButton.addEventListener('mouseleave', function() {
150            console.log('Cursor left the emergency button');
151        });
152    </script>
153</body>
154</html>

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelle méthode est la méthode principale pour gérer les événements en JavaScript ?

Articles utiles