Cours JavaScript et TypeScript · Module 8: Événements et DOM
Les événements et les interactions en JavaScript
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 clicmouseenter/mouseleave- entrée/sortie de la sourismousemove- 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éekeyup- touche relâchéekeypress- obsolète, ne l'utilise pas (à la place :keydownouinput)
Événements de formulaire :
submit- envoi du formulairechange- valeur d'un champ modifiéeinput- saisie de textefocus/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éesscroll- défilement de la pageresize- 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 :
- L'interactivité - réagir aux actions de l'utilisateur
- La performance - le code ne s'exécute que lorsque c'est nécessaire
- L'asynchronisme - différentes parties de l'application peuvent fonctionner indépendamment
- 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. Quelle méthode est la méthode principale pour gérer les événements en JavaScript ?