Accueil

Traduction

Tutoriel sur Javascript

Recherche dans ce tuto

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

JavaScript : les évènements

Notion de programmation évènementielle

JavaScript est un langage évènementiel : il détecte un évènement qui survient et lance un traitement.
Un évènement est quelque chose qui se produit dans le navigateur mais ce peut être aussi une action du visiteur.
Le clic ("click" en anglais) est l'évènement le plus courant mais il y en a bien d'autres ...

Digression orthographique : on peut écrire le mot évènement de deux façons : le deuxième e accentué peut être "é" (orthographe ancienne) ou "è" (orthographe nouvelle qui fait coïncider la graphie avec la prononciation). Il en est de même pour le terme "évènementiel".

Les principaux événements en JS

Cette liste n'est pas exhaustive.

Les événements liés à la souris

Événements liés au clavier

Événements liés à la fenêtre

Événements liés au formulaire

Remarque

Il existe d'autres événements mais qui sont très rarement utilisés car peu connus.

Détection des évènements par HTML

À l'origine les événements étaient détectés par le HTML (mais traités via JS).
On utilisait en effet les attributs évènementiels du HTML. On parle aussi de "gestion évènementielle en ligne".
Pour créer un attribut évènementiel il suffit de préfixer par "on" l'évènement. On obtient ainsi les attributs : onclick, onfocus, onchange, oninput, onchange, etc.
La notation "camelCase" des attributs évènementiels n'est pas obligatoire ni souhaitable ; en clair écrivez toutes les lettres en minuscule.

Exemple

Rendu d'un document HTML :

Le code de ce document HTML

De la partie BODY

Notez les attributs évènementiels pour l'élément IMG : onmouseover, onclick, ondblclick, onmouseout.
Cette technique de détection des événements est obsolète mais toujours comprise par les navigateurs.
Ne confondez pas l'évènement ("click", par exemple) avec l'attribut qui détecte ledit évènement ("onclick" dans ce cas).

Le script

	function f1() {image.src ='../images/femme_normale.jpg' ; }
	function f2() {image.src ='../images/femme_maigre.jpg' ; }
	function f3() {image.src ='../images/squelette.jpg' ; }
	function f4() {image.src ='../images/femme_grosse.jpg' ; }

La gestion des évènements en ligne présente un gros inconvénient : mélange de HTML & JS dans la partie BODY ce qui rend le code difficile à lire et donc à maintenir.

Détection des évèments via le JavaScript

À la place de la gestion des événéments de HTML on peut utiliser le gestionnaire d'évènements de JavaScript ;
Cette solution offre un gros avantage : plus de "scories" JS dans la partie BODY de la page ; la totalité du code JavaScript peut être centralisée dans le script.

Exemple

Rendu d'un document HTML dans un Iframe :

Le code de ce document HTML

De la partie BODY

Plus aucune "scorie" JS dans la code de la partie BODY ; uniquement du HTML !
L'élément BODY identifié "page" et l'élément DIV est identifié "boite".

Le script

La détection des évènements et les traitements qui en découlent sont dans le script.
Le code de ce script :

Rappel : le script est délimité par le conteneur SCRIPT qui se situe après la balise </body>

// référencer dans le script des éléments de la page :
var page = document.querySelector('body') ;
var boite = document.getElementById('boite') ; 

// systématiquement des fonctions anonymes : 
page.onload = function() 
	{boite.style.backgroundImage ='url(../images/burkini.jpg )' ; }

boite.onmouseover = function() 
	{boite.style.backgroundImage ='url(../images/bikini2.jpg )' ; }

boite.onclick = function() 
	{boite.style.backgroundImage = 'url(../images/seins_nus.jpg )' ; }

boite.ondblclick = function() 
	{boite.style.backgroundImage = 'url(../images/jolie_fille.jpg )' ; }

boite.onmouseout = function() 
	{boite.style.backgroundImage ='url(../images/squelette.jpg )' ; }

page.onkeydown = function() 
	{boite.style.backgroundImage ='url(../images/brune_nue.jpg )' ; }

page.onkeyup = function() 
	{boite.style.backgroundImage  = 'url(../images/black_nue.jpg )' ; }

Les évènements sont détectés par JS selon la méthode dite "onEvent" ; méthode intitulée ainsi car toutes les propriétés sont construites selon la syntaxe "on" + évènement.

Actualiser la page consiste à la recharger donc l'évènement load se produit.

Détection des évènements : solution moderne

Il existe désormais une solution JavaScript plus récente et qui est à priviligier : la méthode addEventListener() (écoute d'évènement).
Les deux méthodes décrites précédemment (gestion via le HTML et gestion JS dite "onevent") sont considérées comme obsolètes mais sont toujours (heureusement) comprises par les navigateurs.

Thématique

Suite à un clic sur un bouton de commande le visiteur peut saisir son nom et en retour il y a affichage d'un message de bienvenue.
Nous allons traiter ce thème avec deux méthodes JS : onEvent puis addEventListener.

Le code de la partie BODY dans les deux cas

Le script

Avec la méthode "onevent"

document.querySelector('button').onclick = function()
{ 
	var nom = prompt('tapez votre nom') ; 
	document.write("bonjour " + nom );
}

Le script avec la méthode "addEventListener"

var bouton = document.querySelector('button');  
bouton.addEventListener('click', bonjour);
		
function bonjour(event)
{
	var nom = prompt('tapez votre nom') ; 
	document.write("bonjour " + nom ); 
	document.write('
' + event.type); document.write('
' + event.currentTarget); }

Le script est plus long mais retourne beaucoup plus d'informations grâce au passage en argument d'un objet de type "event".
Attention à la syntaxe : notez que le premier argument de la méthode addEvenListener() est "click" (et non "onclick") et que le deuxième argument est le nom de la fonction sans parenthèses

Le rendu de la solution "addEventListener"

Affichage du type d'évènement et l'élément concerné par l'évènement.

Méthode addEventListener : autre exemple

L'emploi de la méthode addEventListener donne la possibilité d'associer pour un même élément et pour le même évènement plusieurs fonctions. C'est ce que je montre dans l'exemple ci-dessous : trois fonctions associées à un clic sur le bouton de commande.
Cette gestion multiple d'évènements est impossible avec les méthodes anciennes de détection.

Le code d'un document HTML

Notez l'élément H4 qui est vide de tout contenu.

Deux fonctions anonymes étaient initialement associées au bouton de commande sur l'évènement clic.
J'ai pu rajouter une troisième fonction (toujours avec les mêmes cible et évènement) sans avoir besoin de corriger le code des deux anciennes fonctions. Donc la méthode addEvenListener() offre une très grande souplesse.

Le rendu

L'élément H4 a désormais un contenu.

Les événements liés aux formulaires

Dans le cadre d'un formulaire il faut détecter de nombreux événements.

Les évènements focus & blur

Le code du document HTML

Deux fonction anonymes liées au premier INPUT sur les évènements focus & blur.

Le rendu

Événements change & input

Dans l'exemple qui suit le bouton de commande (pour appeler un traitement) a disparu du formulaire !

Le code du formulaire

Le code est identique dans les deux versions.

Notez l'emploi de l'élément output et d'éléments "input type range" pour la saisie.
Notez l'absence de bouton de commande.
Chaque champ du formulaire a un ID ; ID qui est utilisé par chacun des scripts.

Script basé sur évènement change
	var form = document.querySelector('form'); 
	var premier = document.getElementById('premier');
	var deuxieme = document.getElementById('deuxieme');
	var resultat = document.getElementById('resultat');
	
	premier.onchange = function() {resultat.value = parseInt(premier.value) + parseInt(deuxieme.value);} ; 
	deuxieme.onchange = function() {resultat.value = parseInt(premier.value) + parseInt(deuxieme.value);} ;

change : évènement lié à un champ.

Le rendu

Actualisation de la somme lorsque le champ perd le focus.

Script basé sur évènement input

L'évènement de formulaire input se déclenche lors de la mise à jour d'un contrôle du formulaire (zone de texte, zone de liste, bouton radio, etc. ).
Exemple de script :

var form = document.querySelector('form'); 
var premier = document.getElementById('premier');
var deuxieme = document.getElementById('deuxieme');
var resultat = document.getElementById('resultat');
	
form.oninput = function() 
	{resultat.value = parseInt(premier.value) + parseInt(deuxieme.value);} ; 
Le rendu

Actualisation de la somme est instantanée.

Les évènements submit, reset

Deux événements de formulaire qui supposent que le formulaire comprenne un bouton de type 'submit' et un autre de type 'reset'.

Le code d'un document HTML

Ce document comprend un formulaire et un script.

Le code du formulaire

Notez que le formulaire et les champs sont nommés ; les attributs ID sont alors inutiles.
Notez l'élément H3 qui est vide de tout contenu.

Le script
var message = document.querySelector('h3');
f.oninput = function() 
	{f.resultat.value = parseInt(f.poids.value) - parseInt(f.volume.value);} ; 
f.onreset = function() 
	{message.innerHTML ="Formulaire vidé";  };
f.onsubmit = function(e) 
{
	if (f.poids.value == 0  || f.volume.value == 0)                     
		{e.preventDefault(); message.innerHTML = "Soumission avortée"; }
}; 

Notez comment les champs sont identifiées dans le script : nomFormulaire.nomChamp.
Les événements submit & reset sont liés au formulaire.

La soumission n'est effective que si les champs sont remplis.
Rappel : la méthode preventDefault() est appliquée à l'objet de type "event" et annule le comportement par défaut du navigateur ; ici la soumission.

Le rendu dans un Iframe

En cas de soumission réusssie : accès au document "submit_reset.php" qui exécute alors un script PHP indiquant si l'objet coule ou flotte selon la loi d'Archimède.

L'objet de type "Event"

J'ai déjà évoqué l'objet de type "event". Dans ce paragraphe je vous montre tout le parti que l'on peut en tirer.

On peut aussi récupérer la position du curseur avec les propriété clientX & clientY.
On peut associer à "target" les propriétés id, name, src, alt, style, etc.

Exemple

Le code HTML d'une page web

Le script

Déroulez !

Le script comprend six fonctions anonymes.
Pour chaque fonction j'obtiens de précieuses informations sauf la dernière où là je modifie l'aspect de l'image.
Le nom de l'objet de type "event" est libre. Ici et pour chaque fonction j'ai utilisé un terme différent : event, e, evt, evenement.

Le rendu dans un Iframe de ce document HTML

J'espère que grâce à cet exemple assez complet, vous voyez tout l'intérêt de manipuler un objet de type "event" dans le cadre d'une gestion évènementielle.

Empécher le plagiat de votre site

Vous avez sans doute remarqué en surfant sur Internet que de plus en plus de sites Web bloquent le clic droit, interdisent la sélection du texte par la souris ou le clavier.
Pourquoi ?
Pour éviter le plagiat !

La solution JS

Il existe aussi une solution CSS mais moins complète.

Le clic droit sur l'image n'a aucun impact ; le menu contextuel n'apparait pas !
L'appui avec le bouton gauche de la souris n'a aucun effet ; le texte n'est pas sélectionné.
Heureusement le clic gauche est toujours possible ; donc le visiteur peut toujours naviguer dans votre site en cliquant sur les liens hypertextes.

Le code de la partie BODY

Le script

	var contenu = document.querySelector('body'); 
	contenu.oncontextmenu = function(e) {e.preventDefault();}
	contenu.onkeydown = function(event) {event.preventDefault();}
	contenu.onmousedown =function(evenement) {evenement.preventDefault();}

Chaque fonction anonyme se résume à l'appel de la méthode preventDefault().
Rappel : cette méthode annule le comportement par défaut du navigateur suite à un évènement ; par exemple annule l'affichage d'un menu contextuel en cas de clic droit.

Programmation du clavier

À l'occasion de l'exemple précédent, vous avez pu noté que le code ASCII des touches directionnelles est compris entre 37 et 40.

Thématique : grâce aux touches directionnelles, vous devez déplacer la boule du billard.

Exemple

La feuille de style

Notez que l'élément HTML identifié boule est positionné en absolu à l'intérieur du conteneur billard.
Pour dessiner un rond il faut appliquer la propriété de style border-radius à un élément de type block.

Le code HTML

Il est d'une simplificité déroutante ...

Le script (extraits)

var billard = document.querySelector('#billard'); 	// variables objet 
var boule = document.querySelector('#boule'); 
var x; var y ; 
	
// programmation des touches de direction
document.onkeydown = function(event)
{	
	if (event.keyCode == 37)  gauche(); 
	if (event.keyCode == 39) droite() ; 
	if (event.keyCode == 38) haut();  
	if (event.keyCode == 40) bas() ; 
} // fin fonction 
	
// quatre fonctions de déplacement
function gauche() 
{
	x = getComputedStyle(boule).left; 
	console.log(x);
	x = parseInt(x); 
	x= x-20;  
	x = x + "px";
	boule.style.left = x ; 
} 
function droite()
...
function haut()
{
	y = getComputedStyle(boule).top; 
	console.log(x)
	y = parseInt(y); 
	y= y-20;  
	y = y+"px"; 
	boule.style.top = y ; 
}
function bas()
...

Les quatre touches du pavé directionnel sont programmées : si appui sur l'une de ces touches appel d'une des quatre fonctions.
Deux fonctions pour changer la valeur de la propriété left de l'objet boule et deux fonctions pour augmenter ou diminuer la valeur de la propriété top.

La méthode getComputedStyle retourne une chaîne telle "90px".
Il faut donc convertir en entier puis incrémenter (ou décrémenter) puis rajouter "px". Bref le traitement est un peu lourd.
Nous n'aurions pas eu ce problème en utilisant un véritable repère cartésien : une zone de dessin Canvas ou SVG.

Le rendu

Rendu dans un nouvel onglet !

La boule peut sortir du billard mais ça ne serait pas très compliqué d'éviter cela ; il suffirait de rajouter un test dans chacune des quatre fonctions :
Exemple : if (x <= 0) x = 0 ;

Solution avec une zone de dessin SVG

Un script peut animer non seulement des éléments HTML mais aussi des objets SVG.
Animer des objets SVG via JavaScript