• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 05/07/2019

Réagissez à des événements

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Rendre une page web interactive nécessite de répondre aux actions effectuées par son visiteur : nous allons découvrir comment faire dans ce chapitre.

Introduction aux événements

Les programmes JavaScript que nous avons écrits jusqu'ici s'exécutaient automatiquement dès leur chargement par la page web. L'ordre d'exécution des instructions était déterminé à l'avance et les interactions avec l'utilisateur se limitaient à la saisie de valeurs au moyen de l'instructionprompt.

Pour augmenter le niveau d'interactivité, il faut que la page puisse réagir au comportement de l'utilisateur : clic sur un bouton ou un lien, remplissage d'un formulaire, etc. Dans ce cas, l'ordre d'exécution des instructions n'est pas prévisible à l'avance : il dépend des actions de l'utilisateur. Ces actions déclenchent des événements auxquels la page va pouvoir réagir via du code JavaScript.

Ce mode de fonctionnement est appelé programmation événementielle. Il est utilisé par les interfaces graphiques et toutes les applications en interaction avec un utilisateur.

Un premier exemple

La page web initiale

Créez le fichiercours.html dans le répertoirechapitre_5/html, puis donnez-lui le contenu ci-dessous. 

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Gestion des événements</title>
</head>

<body>
    <button id="bouton">Cliquez-moi !</button>

    <script src="../js/cours.js"></script>
</body>

</html>

Créez ensuite le fichiercours.js dans le répertoirechapitre_5/js avec le contenu suivant.

function clic() {
    console.log("Clic !");
}

var boutonElt = document.getElementById("bouton");
// Ajout d'un gestionnaire pour l'événement click
boutonElt.addEventListener("click", clic);

Ouvrez la page webcours.html dans votre navigateur. Vous obtenez le résultat suivant.

Après vous être assuré(e) que la console du navigateur était affichée, cliquez sur le bouton "Cliquez-moi !" de la page web. Une nouvelle ligne apparaît dans la console : la page a réagi à l'action de l'utilisateur.

Ajout d'un gestionnaire d'événement

Étudions le code source du fichiercours.js. On commence par définir une fonction nomméeclicqui ajoute une ligne dans la console. Ensuite, on récupère l'élément bouton du DOM puis on lui ajoute un gestionnaire d'événement

Appelée sur un élément du DOM, la méthodeaddEventListenerlui ajoute un gestionnaire pour un événement particulier. Cette méthode prend deux paramètres : le type de l'événement et la fonction qui gère l'événement. Cette fonction sera appelée à chaque fois que l'événement se déclenchera sur l'élément.

Dans notre exemple, le clic sur le bouton (événementclick) déclenchera l'appel de la fonctionclic.

 

Il est possible d'utiliser une syntaxe un peu plus concise en définissant la fonction appelée au moment de l'appel àaddEventListener. Le code ci-dessous est fonctionnellement identique au précédent.

var boutonElt = document.getElementById("bouton");
// Ajout d'un gestionnaire pour l'événement click
boutonElt.addEventListener("click", function () {
    console.log("clic");
});

Dans ce cas, la fonction n'est plus identifiée par un nom et ne peut plus être utilisée ailleurs dans le programme. Il s'agit d'une fonction anonyme. Les fonctions anonymes sont fréquemment utilisées en JavaScript.

Suppression d'un gestionnaire d'événement

Il peut arriver que vous ne souhaitiez plus gérer un type d'événement sur un élément du DOM. Dans ce cas, appelez la méthoderemoveEventListenersur cet élément, en lui passant en paramètre la fonction qui gérait l'événement.

Ajoutez la ligne suivante à la fin du fichiercours.js pour que le clic sur le bouton ne soit plus géré par la fonction clic.

// Suppression du gestionnaire pour l'événement click
boutonElt.removeEventListener("click", clic);

La grande famille des événements

Les événements que les éléments du DOM peuvent déclencher sont très nombreux. Le tableau ci-dessus présente les principales catégories d'événements.

Catégorie

Exemples

Événements clavier

Appui ou relâchement d'une touche du clavier

Événements souris

Clic avec les différents boutons, appui ou relâchement d'un bouton de la souris, survol d'une zone avec la souris

Événements fenêtre

Chargement ou fermeture de la page, redimensionnement, défilement (scrolling)

Événements formulaire

Changement de cible de saisie (focus), envoi d'un formulaire

Quel que soit le type d'événement, son déclenchement s'accompagne de la création d'un objetEvent qui peut être utilisé par la fonction qui gère l'événement. Cet objet dispose de propriétés qui fournissent des informations sur l'événement, et de méthodes qui permettent d'agir sur celui-ci. 

La plupart des propriétés de l'objetEvent dépendent du type d'événement déclenché. Parmi les propriétés présentes dansEvent, quel que soit le type d'événement,typerenvoie le type ettarget renvoie la cible de l'événement, c'est-à-dire l'élément du DOM auquel l'événement est destiné.

Le code ci-dessous utilise l'objetEventpour afficher le type de l'événement déclenché ainsi que le texte de l'élément cible lors d'un clic sur le bouton de notre page web. Cet objet est fourni à la fonction qui gère l'événement sous la forme d'un paramètre nommé e. Le choix du nom du paramètre est libre, et vous pourrez rencontrer également le nomevent.

// Ajout d'un gestionnaire qui affiche le type et la cible de l'événement
document.getElementById("bouton").addEventListener("click", function (e) {
    console.log("Evènement : " + e.type + 
        ", texte de la cible : " + e.target.textContent);
});

Gestion des événements les plus courants

Appui sur une touche du clavier

La solution la plus courante pour réagir à l'appui sur une touche du clavier consiste à gérer les événements de type keypressdéclenchés sur le corps de la page web (élémentbodydu DOM, correspondant en JavaScript à la variable globaledocument).

L'exemple suivant permet d'afficher dans la console le caractère associé à la touche frappée. Ici, l'information sur ce caractère est fournie sous la forme de la propriétécharCodede l'objetEvent(le paramètree). Il s'agit de la valeur numérique (appelée valeur Unicode) associée au caractère. La méthodeString.fromCharCode permet de traduire cette valeur en une chaîne représentant le caractère.

// Gestion de l'appui sur une touche du clavier produisant un caractère
document.addEventListener("keypress", function (e) {
    console.log("Vous avez appuyé sur la touche " + String.fromCharCode(e.charCode));
});

Pour gérer l'appui et le relâchement sur n'importe quelle touche du clavier (pas seulement celles qui produisent des caractères), on utilise les événementskeydownetkeyup.

L'exemple suivant utilise la même fonction pour gérer ces deux événements. Cette fois-ci, le code de la touche est accessible dans la propriétékeyCodede l'objetEvent.

// Affiche des informations sur un événement clavier
function infosClavier(e) {
    console.log("Evènement clavier : " + e.type + ", touche : " + e.keyCode);
}

// Gestion de l'appui et du relâchement d'une touche du clavier
document.addEventListener("keydown", infosClavier);
document.addEventListener("keyup", infosClavier);

On constate que l'ordre de déclenchement des événements clavier est le suivant :keydown->keypress->keyup.

Clic sur un bouton de la souris

Le clic souris sur n'importe quel élément du DOM déclenche l'apparition d'un événement de typeclick.

L'objetEventassocié à un événement de typeclickcontient (entre autres) une propriétébuttonqui permet de connaître le bouton de la souris utilisé, ainsi que des propriétésclientXetclientYqui renvoient les coordonnées horizontales et verticales de l'endroit où le clic s'est produit. Ces coordonnées sont définies par rapport à la zone de la page actuellement affichée par le navigateur. Le schéma suivant illustre la différence entre les propriétésclientX/Y etpageX/Y, également présentes dans l'objetEventassocié à un clic souris.

Différence entre clientX/Y et pageX/Y

L'exemple de code ci-dessous affiche des informations sur tous les événementsclickdéclenchés sur la page web. Ces événements sont gérés par une fonction nomméeinfosSouris. Elle-même utilise une fonctiongetBoutonSourispour déduire le nom du bouton de la souris cliqué, à partir de son code fourni par la propriétébuttonde l'objetEvent.

// Renvoie le nom du bouton souris à partir de son code
function getBoutonSouris(code) {
    var bouton = "inconnu";
    switch (code) {
    case 0: // 0 est le code du bouton gauche
        bouton = "gauche";
        break;
    case 1: // 1 est le code du bouton du milieu
        bouton = "milieu";
        break;
    case 2: // 2 est le code du bouton droit
        bouton = "droit";
        break;
    }
    return bouton;
}

// Affiche des informations sur un événement souris
function infosSouris(e) {
    console.log("Evènement souris : " + e.type + ", bouton " +
        getBoutonSouris(e.button) + ", X : " + e.clientX + ", Y : " + e.clientY);
}

// Gestion du clic souris
document.addEventListener("click", infosSouris);

De manière similaire aux événements clavier, on peut utiliser les événementsmousedownetmouseup pour détecter l'appui et le relâchement d'un bouton de la souris.

Ajoutez le code ci-dessous pour associer le même gestionnaire à ces deux événements.

// Gestion de l'appui et du relâchement d'un bouton de la souris
document.addEventListener("mousedown", infosSouris);
document.addEventListener("mouseup", infosSouris);

On constate que l'ordre de déclenchement des événements souris est le suivant :mousedown->mouseup->click.

Fin du chargement de la page web

En fonction de sa complexité, une page web peut mettre un certain temps à être entièrement chargée par un navigateur. Il est possible de détecter la fin du chargement de la page en ajoutant un gestionnaire pour l'événementloadsur l'objetwindow, qui représente la fenêtre du navigateur. Cela permet d'éviter d'interagir via JavaScript avec des parties de la page non encore chargées.

L'exemple de code suivant affiche un message dans la console lorsque la page web est entièrement chargée.

// Gestion de la fin du chargement de la page web
window.addEventListener("load", function () {
    console.log("Page entièrement chargée");
});

Fermeture de la page web

On peut parfois vouloir détecter la fermeture d'une page web, qui se produit lorsque l'utilisateur ferme l'onglet qui l'affiche ou navigue vers une autre page dans cet onglet. Un cas d'utilisation fréquent consiste à afficher une demande de confirmation. Pour cela, il faut ajouter un gestionnaire pour l'événementbeforeunloadsur l'objetwindow, comme dans l'exemple suivant.

// Gestion de la fermeture de la page web
window.addEventListener("beforeunload", function (e) {
    var message = "On est bien ici !";
    e.returnValue = message; // Provoque une demande de confirmation (standard)
    return message; // Provoque une demande de confirmation (certains navigateurs)
});

En théorie, c'est la modification de la propriétéreturnValuede l'objetEventqui suspend la fermeture de la page et provoque l'apparition d'une boîte de dialogue de confirmation affichant la valeur de cette propriété. Cependant, certains navigateurs se basent sur la valeur de retour de la fonction qui gère l'événement plutôt que sur la propriétéreturnValue. Le code ci-dessus associe les deux techniques et fonctionne quel que soit le navigateur utilisé.

Aller plus loin avec les événements

Comprendre la propagation des événements

Le DOM représente une page web sous la forme d'une hiérarchie de noeuds. Les événements déclenchés sur un noeud enfant vont se déclencher ensuite sur son noeud parent, puis sur le parent de celui-ci, et ce jusqu'à la racine du DOM (la variabledocument). C'est ce qu'on appelle la propagation des événements.

Pour observer la dynamique de la propagation, ajoutez le code HTML suivant dans la balise<body> du fichiercours.html.

<p id="para">Un paragraphe avec un
    <button id="propa">bouton</button> à l'intérieur
</p>

Ajoutez ensuite le code JavaScript ci-dessous au fichiercours.js. Il ajoute des gestionnaires pour les événements de typeclicksur le bouton, son parent (le paragraphe) et le parent de celui-ci (la racine du DOM).

// Gestion du clic sur le document
document.addEventListener("click", function () {
    console.log("Gestionnaire document");
});
// Gestion du clic sur le paragraphe
document.getElementById("para").addEventListener("click", function () {
    console.log("Gestionnaire paragraphe");
});
// Gestion du clic sur le bouton
document.getElementById("propa").addEventListener("click", function (e) {
    console.log("Gestionnaire bouton");
});

Le résultat obtenu dans le navigateur illustre la propagation de l'événementclickdepuis le bouton jusqu'au document.

La propagation des événements peut être interrompue à tout moment en appelant la méthodestopPropagationsur l'objetEvent depuis une fonction qui gère un événement. C'est utile pour éviter qu'un même événement soit géré plusieurs fois.

L'ajout d'une ligne dans le gestionnaire d'événement du bouton empêche l'événementclickde se propager dans l'arborescence du DOM.

// Gestion du clic sur le bouton
document.getElementById("propa").addEventListener("click", function (e) {
    console.log("Gestionnaire bouton");
    e.stopPropagation(); // Arrêt de la propagation de l'événement
});

Modifier le comportement par défaut en cas d'événement

La plupart des événements sont associés à une action par défaut. Le clic sur un lien déclenche la navigation vers la cible de ce lien, le clic avec le bouton droit de la souris affiche un menu contextuel, etc. Il est possible d'annuler ce comportement par défaut en appelant la méthodepreventDefaultsur l'objetEvent.

Pour observer l'effet de cette méthode, ajoutez le code HTML suivant dans la balise<body> du fichiercours.html.

<p>Du temps à perdre ? <a id="interdit" href="https://9gag.com/">Cliquez ici</a></p>

Ajoutez ensuite le code JavaScript suivant dans le fichiercours.js.

// Gestion du clic sur le lien interdit
document.getElementById("interdit").addEventListener("click", function (e) {
    console.log("Continuez plutôt à lire le cours ;)");
    e.preventDefault(); // Annulation de la navigation vers la cible du lien
});

À présent, essayez de cliquer sur le lien affiché par la page web : le navigateur affiche un message dans sa console au lieu de naviguer vers la cible du lien.

Nous verrons une application pratique de cette technique dans le prochain chapitre, consacré aux formulaires.

En résumé

Voici les principales informations à retenir de ce chapitre.

  • On peut rendre une page web interactive en écrivant du code JavaScript qui réagit aux événements déclenchés sur la page.

  • De nombreux types d'événements peuvent être gérés. Chaque type d'événement est associé à un objetEvent spécifique qui apporte des informations sur l'événement via ses propriétés.

  • Les événementskeypresskeydownetkeyuppermettent de réagir à l'utilisation du clavier.

  • Les événementsclickmousedownetmouseuppermettent de gérer les interactions avec la souris.

  • Le chargement et la fermeture de la page web sont associés aux événementsloadetbeforeunload.

  • Un événement se propage dans l'arborescence du DOM depuis son noeud d'origine jusqu'à la racine du document. Cette propagation peut être interrompue à l'aide de la méthodestopPropagation.

  • Il est possible d'annuler le comportement par défaut lié à un événement en appelant la méthodepreventDefault

À vous de jouer !

À présent, voici quelques exercices pour mettre en pratique vos nouvelles connaissances. Écrivez-les dans le répertoirechapitre_5.

Compteur de clics (résultat à obtenir)

Créez le fichierhtml/compteurClics.html avec le contenu suivant.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Compteur de clics</title>
</head>

<body>
    <button id="clic">Cliquez-moi !</button>
    <p>Vous avez cliqué <span id="compteurClics">0</span> fois</p>
    <button id="desactiver">Désactiver le comptage</button>

    <script src="../js/compteurClics.js"></script>
</body>

</html>

Créez ensuite le fichierjs/compteurClics.js qui compte et affiche sur la page le nombre de clics sur le bouton nommé "clic". Le bouton nommé "desactiver" permet d'arrêter le comptage.

Changement de couleur (résultat à obtenir)

Créez le fichierhtml/couleurs.html et donnez-lui le contenu suivant.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Changement de couleur</title>
</head>

<body>
    <p>Appuyez sur les touches R, J, V et B pour changer la couleur des paragraphes</p>

    <h1>Paragraphe 1</h1>
    <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dignissim fringilla dapibus. Curabitur placerat efficitur molestie. Quisque quis consequat nibh. Aenean feugiat, eros eget aliquam vulputate, leo augue luctus lectus, non lobortis libero quam non sem. Aliquam sit amet tincidunt ex, mollis interdum massa. Sed vulputate mi id accumsan scelerisque. Nam interdum iaculis ipsum, non convallis mauris faucibus et. Pellentesque in imperdiet lorem, in condimentum neque. Nullam auctor sem eu sapien pulvinar, non ultricies ipsum hendrerit. Aliquam at magna convallis, ultrices enim vitae, mollis lacus.</div>

    <h1>Paragraphe 2</h1>
    <div>Vivamus at justo blandit, ornare leo id, vehicula urna. Fusce sed felis eget magna viverra feugiat eget nec orci. Duis non massa nibh. Aenean vehicula velit a magna lobortis tempor ut quis felis. Proin vitae dui a eros facilisis fringilla ut ut ante. Curabitur eu magna dui. Ut hendrerit suscipit metus, id vehicula velit. Pellentesque ac nisl rutrum, efficitur velit dictum, cursus odio.</div>

    <h1>Paragraphe 3</h1>
    <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sit amet pharetra massa. Nulla blandit erat nulla, et scelerisque libero varius ut. Praesent bibendum eu magna ullamcorper venenatis. Sed ut pellentesque leo. Sed ultrices sapien consequat odio posuere gravida. Nunc lorem tortor, volutpat nec maximus in, suscipit a ex. Praesent efficitur ex ut viverra placerat. Vivamus eu sapien sed enim vehicula sodales.</div>

    <script src="../js/couleurs.js"></script>
</body>

</html>

Créez ensuite le fichierjs/couleurs.js qui permet de modifier la couleur de fond des trois éléments div lorsque l'utilisateur appuie sur la touche R (rouge), J (jaune), V (vert) ou B (blanc). On ne fera pas de distinction entre minuscules et majuscules.

Liste de desserts (résultat à obtenir)

Créez le fichierhtml/desserts.html avec le contenu suivant.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Mes desserts préférés</title>
</head>

<body>
    <h1>Mes desserts préférés</h1>

    <ul id="desserts">
    </ul>

    <button>Ajouter un dessert</button>

    <script src="../js/desserts.js"></script>
</body>

</html>

Ensuite, écrivez le fichierjs/desserts.js qui permet d'ajouter un nouveau dessert à la liste "desserts" lors d'un clic sur le bouton "Ajouter un dessert".

 

En bonus, ajoutez la possibilité de modifier un dessert présent dans la liste en cliquant dessus.

Quiz interactif (résultat à obtenir)

Créez le fichierhtml/quiz.html et donnez-lui le contenu suivant.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Quiz interactif</title>
</head>

<body>
    <div id="contenu"></div>

    <script src="../js/quiz.js"></script>
</body>

</html>

Créez ensuite le fichierjs/quiz.js avec le contenu initial suivant.

// Liste des questions à afficher. Une question est définie par son énoncé et sa réponse
var questions = [
    {
        enonce: "Combien font 2+2 ?",
        reponse: "2+2 = 4"
    },
    {
        enonce: "En quelle année Christophe Colomb a-t-il découvert l'Amérique ?",
        reponse: "1492"
    },
    {
        enonce: "On me trouve 2 fois dans l'année, 1 fois dans la semaine, mais pas du tout dans le jour... Qui suis-je ?",
        reponse: "La lettre N"
    }
];

Éditez ce fichier pour afficher la liste des questions ainsi qu'un bouton "Afficher la réponse" sous chaque question.

Enfin, faites apparaître la réponse associée à chaque question lors d'un clic sur le bouton "Afficher la réponse".

Solutions des exercices

Le code source des solutions est consultable en ligne.

Exemple de certificat de réussite
Exemple de certificat de réussite