Leçon 07 : JavaScript et HTML
Contenu :
Cette leçon montre comment on utilise JavaScript dans un document HTML. Elle montre comment associer des actions JavaScript à des évènements. Elle constitue une introduction au DOM (Document Object Model) qui sera étudié plus en détail dans les leçons suivantes
Objectifs :
Etre capable de lier un fichier JavaScript à un document HTML. Connaitre les manipulations de base (accès, modification) des éléments HTML depuis JavaScript
Exemples et motivation
Le code JavaScript s'exécute dans le contexte d'une page HTML donnée. Ce code est destiné à ajouter du dynamisme à la page HTML en
associant à des évènements des actions (des fonctions) JavaScript. Par exemple, on peut appeler une fonction JavaScript lors
du survol par le curseur d'un élément particulier :
<p>
Attention, ne passez pas le curseur au dessus de
<strong>
<span onmouseover="alert('Qu\'est-ce que je viens de dire ?!');">cet élément</span> !
</strong>
</p>
Dans la portion de code HTML précédent, on associe une action JavaScript à l'évènement "passer la souris au-dessus de" pour
l'élément span. Un autre évènement très commun est "cliquer sur" qui peut être défini (on dirait plutôt
associé) pour la plupart des éléments HTML, comme par exemple :
<p>
Et voici un panda :<br />
<img onclick="alert('Le panda est un ursidé');" src="panda.jpg" alt="Panda" />
</p>
Les évènements peuvent être très variés et ne pas correspondre à une action de l'utilisateur, comme par exemple :
<body onload="alert('La page est chargée');">
...
</body>
Dans l'exemple précédent, l'alerte JavaScript sera exécutée immédiatement après le chargement de la page HTML correspondante.
Les actions JavaScript associées à des évènements sont pour la plupart plus compliquées qu'une unique instruction (du type
alert des exemples précédents) et l'usage est d'utiliser des fonctions JavaScript pour
définir ces actions et les associer aux évènements. Par exemple, si colorier est la fonction suivante :
function colorier( couleur ) {
var tac = document.querySelector( "#texte" );
tac.style.color = couleur;
}
on peut l'utiliser dans le code HTLM suivant
<p>
<div id="texte">
<strong>
Le texte à colorier !
</strong>
</div>
Cliquez sur la couleur pour colorier le texte en
<span style="color: red" onclick="colorier('red');">rouge</span>,
<span style="color: blue" onclick="colorier('blue');">bleu</span> ou
<span style="color: green" onclick="colorier('green');">vert</span>
</p>
pour colorier le texte apparaissant dans l'élément d'identifiant texte (un div) en cliquant sur la
couleur désirée. Nous détaillerons un peu plus loin le rôle des variables globales, méthodes et attributs présentés dans cet exemple, mais
nous pouvons déjà expliquer sommairement le code précédent :
-
l'élément
div dans lequel se trouve le texte à colorier est repéré par l'attribut id
(dont la valeur est nécessairement unique au sein d'une même page) et accessible depuis JavaScript via la fonction
querySelector appliquée à l'objet prédéfini document avec le
paramètre #texte
-
à la ligne 2 de la fonction
colorier, on récupère l'objet JavaScript lié à l'élément HTML
d'identifiant texte, qui est l'élément div dans lequel se trouve le texte à colorier. Cet
objet est une valeur complexe constituée de plusieurs valeurs regroupées ensemble, un peu comme une boite contenant plusieurs
cases contenant chacune une valeur. Cet objet est stocké dans la variable tac (comme texte
à colorier), dont le nom est bien sûr quelconque
-
à la ligne 3, on modifie le style de l'élément d'identifiant
texte (l'élément div
stocké dans la variable tac) avec la valeur du paramètre de la fonction
La fonction colorier est donc utilisée potentiellement trois fois ; elle est appelée lors des trois évènements
onclick associés aux trois éléments span, avec chaque fois un paramètre différent afin de définir la
couleur désirée.
Les exemples précédents sont disponibles dans les fichiers
exemple-1.html et
exemple-1.js
Liaison JavaScript-HTML
Il a deux façons de lier le code JavaScript au code HTML :
-
en plaçant le code JavaScript dans un fichier séparé et en incluant ce fichier dans le code HTML à l'aide
de l'élément
script
-
en insérant directement du code JavaScript à l'intérieur du code HTML (encore à l'aide de l'élément
script)
Sauf situation particulière, on préfère la première méthode qui présente l'avantage majeur de précisément
séparer le code JavaScript du code HTML. Cette séparation facilite le développement mais aussi la génération du code
HTML et du code JavaScript par le PHP côté serveur.
Pour inclure un fichier JavaScript séparé dans un fichier HTML, on utilise la balise script avec l'attribut src
de la façon suivante :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Exemple 1</title>
<script src="scripts.js"></script>
</head>
<body>
...
</body>
</html>
Dans la portion de code HTML précédente, on inclut le fichier scripts.js en tête du fichier. Le code JavaScript va être
lu et évalué au tout début du chargement de la page HTML et avant que le document HTML soit
effectivement lu et construit par le navigateur. Le chemin du fichier JavaScript inclu est relatif à celui de la page HTML
qui le référence : dans l'exemple précédent, le fichier scripts.js doit être dans le même dossier que le fichier HTML.
Remarquez que la balise script n'est pas auto-fermante et qu'il faut donc adopter la syntaxe
<script ...></script> (élément sans contenu).
Pour insérer du code JavaScript directement dans du code HTML, on utilise encore l'élément script mais cette fois sans
l'attribut src (destiné à inclure un fichier JavaScript). On peut insérer cet élément partout dans la page HTML, comme
par exemple dans la page HTML suivante :
<html>
<head>
<meta charset="utf-8">
<title>Exemple 2</title>
<script>
function normaliser( nom ) {
nom = nom.trim().toLowerCase();
return nom.substring(0,1).toUpperCase() + nom.substring(1);
}
</script>
</head>
<body id="leBody">
<header>
<h1>Exemple 2</h1>
</header>
<p>
Bonjour ! Donnez vos nom et prénom :
<script>
var nom = normaliser( prompt( "Votre nom :" ) );
var prenom = normaliser( prompt( "Votre prénom :" ) );
</script>
</p>
<p>
Maintenant, nous allons vous souhaiter la bienvenue :
<script>
alert( "Bonjour " + prenom + " " + nom );
</script>
Voilà qui est fait !
</p>
<p>
Nous vous souhaitons une bonne journée !!
<script>
confirm( "Vous allez quitter cette page !" );
document.querySelector( "body" ).innerHTML = "Au revoir, à bientôt !";
</script>
</p>
</body>
</html>
Dans l'exemple précédent, le code JavaScript se mélange au code HTML via la balise script. De cette façon, lors du chargement
de la page, le nagivateur alterne entre la lecture et l'affichage du code HTML, et la lecture et l'évaluation du code JavaScript. Ce style
de programmation est à proscrire car il rend beaucoup plus complexe la conception et, pire, la génération du code HTML côté serveur. Nous ne
l'utiliserons pas dans ce cours et nous associerons le JavaScript au code HTML uniquement via un fichier séparé.
Remarquez que dans l'exemple précédent, on appelle la fonction querySelector sur l'objet prédéfini
document avec le paramètre body : cet appel va retourner le premier (et
unique, dans ce cas) élément body du document HTML. La fonction querySelector prend
en paramètre un sélecteur CSS et retourne la première occurence parmi les éléments sélectionnés. Il est possibe de récupérer
toutes les occurences sélectionnées en utilisant la fonction querySelectorAll qui retourne la liste
de ces occurences (donc, un tableau).
L'exemple précédent est disponible dans le fichier exemple-2.html
Un exemple détaillé
Pour résumer, nous allons étudier un petit exemple complet. Le but est de concevoir une page HTML qui, étant donné un montant en euros,
permet d'afficher le montant équivalent en francs. La première version de notre page HTML peut ressembler à ça :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Exemple 3</title>
<script src="exemple-3.js"></script>
</head>
<body>
<header>
<h1>Exemple 3</h1>
</header>
<p>
Entrez la valeur en euros :
<input id="euros" type="text" value="0" /><br />
<input type="button" value="Convertir" onclick="calculer();" /><br />
La valeur correspondante en francs est <span id="francs">0</span> francs.
</p>
</body>
</html>
Cette page doit permettre de :
-
lire une valeur fournie par l'utilisateur dans un champ de saisie (l'élément
input d'identifiant euros)
-
vérifier que cette valeur est bien un nombre, et si ce n'est pas le cas, afficher une alerte le signalant
-
convertir cette valeur qui représente une somme en euros, en la valeur correspondante en francs, et l'afficher
dans un élément prévu à cet effet (l'élément
span d'identifant francs)
L'élément input dans lequel l'utilisateur saisit le montant en euros et l'élément span dans lequel
on doit écrire le résultat de la conversion en francs sont repérés par l'attribut id (dont les valeurs sont nécessairement
uniques au sein d'une même page) et accessibles depuis JavaScript via la fonction querySelector
appliquée à l'objet prédéfini document. Ces différentes actions sont réalisées par la fonction
calculer qui est appelée lors de l'évènement cliquer sur sur l'élément input de type button.
La fonction calculer peut être définie de la façon suivante :
function calculer() {
var euros = document.querySelector( "#euros" );
var valeur = euros.value;
if ( isNaN( valeur ) ) {
alert( "Le montant en euros n'est pas un nombre !" );
euros.focus();
}
else {
var francs = document.querySelector( "#francs" );
francs.innerHTML = ( valeur * 6.55957 ).toFixed( 2 );
}
}
Analysons le code précédent en détail :
-
à la ligne 2, on récupère l'objet JavaScript lié à l'élément HTML
d'identifiant
euros, qui est l'élément input dans lequel l'utilisateur saisi la valeur en euros. Cet
objet est une valeur complexe constituée de plusieurs valeurs regroupées ensemble, un peu comme une boite contenant plusieurs
cases contenant chacune une valeur
-
à la ligne 3, on récupère la chaîne de caractères saisie par l'utilisateur via l'attribut (ou la case)
de l'objet (ou la boite) qui s'appelle
value. Cet attribut est prédéfini et n'existe que pour
certains éléments HTML
-
aux lignes 4 et 5, on teste si cette chaîne n'est pas un nombre, et dans l'affirmative, on affiche une alerte
-
à la ligne 6, donne le focus à l'élément HTML d'identifiant
euros, autrement dit place le curseur à l'intérieur de
la zone de saisie de l'élément input correspondant
-
à la ligne 9, on récupère l'objet JavaScript lié à l'élément HTML d'identifiant
francs,
qui est l'élément span dans lequel on va écrire le résultat de la conversion euros-francs
-
à la ligne 10, on modifie le contenu de l'élément d'identifiant
francs (l'élément span) avec le
résultat de la conversion euros-francs
On désire maintenant produire une deuxième version de l'exemple précédent dans laquelle on affiche le résultat de la conversion
uniquement quand on clique sur le bouton. On veut également faire disparaître ce résultat dès
qu'on modifie le montant en euros dans la zone de saisie. Un moyen de contrôler la visibilité d'un élément HTML est d'utiliser la
propriété visibility de son style. On va donc modifier le code HTML afin de pouvoir contrôler la visibilité du
résultat :
<p>
Entrez la valeur en euros :
<input id="euros" type="text" oninput="cacher();" /><br />
<input type="button" value="Convertir" onclick="calculer();" /><br />
<div style="visibility: hidden" id="resultat">
La valeur correspondante en francs est <span id="francs">0</span> francs.
</div>
</p>
Le résultat est maintenant le contenu d'un élément (un div) repéré par l'identifiant resultat. Au
chargement de la page HYTML, cet élément n'est pas visible et il sera rendu visible par un clic sur le bouton (donc, par la fonction
calculer). Pour pouvoir faire disparaitre cet élément lors d'une mise à jour du montant en euros, on utilise l'évènement
oninput sur l'élément input de type texte, évènement qui correspond à un changement du contenu de la
zone de saisie et auquel on associe la fonction cacher :
function cacher() {
document.querySelector("#resultat").style.visibility = "hidden";
}
function calculer() {
var euros = document.querySelector("#euros");
if ( isNaN( euros.value ) ) {
alert("Le montant en euros n'est pas un nombre !");
euros.focus();
} else {
var francs = document.querySelector("#francs");
francs.innerHTML = ( euros.value * 6.55957 ).toFixed(2);
document.querySelector("#resultat").style.visibility = "visible";
}
}
Remarquez que dans les fonctions cacher et calculer, l'élément d'identifiant resultat
(l'élément div) a son style modifié par une instruction qui combine l'accès à l'élément et sa modification :
contrairement aux éléments d'identifiant euros et francs, on ne passe pas par une variable intermédiaire et on
travaille directement sur le résultat produit par la fonction querySelector.
Les exemples précédents sont disponibles dans les fichiers
exemple-3.html et
exemple-3.js
Exercice 1
En vous inspirant fortement de l'exemple précédent, écrivez le code JavaScript nécessaire au document HTML exo1.html pour
permettre à l'utilisateur de saisir un montant hors taxe et, après avoir cliqué sur le bouton, d'afficher ce montant augmenté de la TVA
(qu'on fixera à 10%). Comme dans l'exemple précédent, l'affichage du résultat est réalisé en modifiant le contenu d'un élément
HTML particulier et en le faisant apparaitre alors qu'il était initialement invisible. Si la chaîne de caractères saisies
par l'utilisateur n'est pas un nombre, une erreur est signalée dans une alerte.
Fichier(s)
exo1.html
Exercice 2
Reprenez l'exercice précédent, mais cette fois l'utilisateur doit saisir également la TVA dans le champ adéquat. Comme précédemment, si le
montant ou la TVA saisi n'est pas un nombre, l'erreur est signalée par une alerte.
Fichier(s)
exo2.html
Exercice 3
Ecrivez le code JavaScript nécessaire au document HTML exo3.html pour permettre à l'utilisateur de saisir trois notes et,
après avoir cliqué sur le bouton, d'afficher la moyenne de ces notes. Comme dans les exercices précédents, le résultat apparait dans un
élément HTML prévu à cet effet. Si l'une des chaînes de caractères saisies par l'utilisateur n'est pas un nombre, une erreur est signalée
dans une alerte.
Fichier(s)
exo3.html
Exercice 4
Reprenez l'exercice précédent, en affichant maintenant à la suite de la moyenne, l'appréciation correspondante. Pour calculer l'appréciation
à partir de la moyenne, vous pouvez réutiliser la fonction appreciation de l'exercice 5 de la leçon 6.
Fichier(s)
exo4.html
Exercice 5
Cet exercice est une nouvelle version de l'exercice 5 de la leçon 3. On veut réaliser une page HTML qui serve de répétiteur de
multiplications. Dans cette nouvelle version, les multiplications successives sont proposées sur la même page HTML. Lors du chargement de
la page, une multiplication est proposée en tirant deux nombres au hasard compris entre 1 et 10. L'utilisateur doit alors proposer un
résultat en saisissant un nombre dans le champ adéquat. Lorsqu'il clique sur le bouton, le programme vérifie sa proposition et affiche le
message adéquat dans l'élément prévu à cet effet. Le bouton change également de label et passe de verifier à
continuer. Lors d'un nouveau clic sur ce bouton, le message disparait et une nouvelle multiplication est proposée. Dans le
même temps, le label du bouton change à nouveau, et passe de continuer à verifier.
Remarquez que pour réaliser ce programme, il est nécessaire que la fonction valider (appelée lors du clic sur le
bouton) fasse alternativement deux choses différentes. Cette alternance peut être implémenter à l'aide d'une variable
globale qui prend successivement et alternativement deux valeurs distinctes, permettant à chaque appel de la fonction de savoir qu'elle
est la partie à exécuter.
Fichier(s)
exo5.html
Exercice 6
Cet exercice est une nouvelle version de l'exercice 10 de la leçon 6. On veut réaliser une page HTML qui permette de jouer au jeu
"deviner un nombre". Le jeu s'effectue maintenant dans la page HTML : l'utilisateur saisit ses propositions dans un élément
INPUT et le résultat est affiché sur la page elle-même. Comme dans la version de la leçon 6, il faut pouvoir jouer plusieurs
parties de suite et afficher les statistiques après chaque partie :
- le nombre total de parties jouées
- le nombre moyen d'essais sur toutes les parties jouées
- le nombre d'essais de la meilleure partie (de la partie dans laquelle l'utilisateur a deviné le nombre avec le moins d'essais)
Contrairement à la version de la leçon 6, ces statistiques doivent être affichées :
- dans la page HTML elle-même
- après chaque partie
Après chaque partie, une fenêtre de confirmation (affichée par la fonction confirm) demande à l'utilisateur s'il
veut jouer une nouvelle partie.
Contrairement aux exercices précédents, aucun squelette n'est fourni pour cet exercice et vous devez le concevoir entièrement ! Pour la
partie HTML, vous pouvez vous inspirer du fichier HTML de l'exercice précédent que vous adapterez. Enfin, vous pouvez bien sûr partir de la
solution de l'exercice 10 de la leçon 6 !
Fichier(s)
exo6.html
Exercice 7
Cet exercice est une nouvelle version de l'exercice 3. Dans cette nouvelle version, on ne connaît pas à l'avance le nombre de notes à saisir. Autrement dit,
le même code JavaScript doit pouvoir fonctionner avec différents fichiers HTML, fichiers contenant un nombre différent d'éléments INPUT
de type texte destinés à saisir une note. Pour tester votre code, vous pouvez utiliser les fichiers exo7.1.html et exo7.2.html,
identiques en tout point mais contenant un nombre de notes à saisir différents. Remarquez que dans ces fichiers, on a supprimé l'attribut name
dans les éléments INPUT de type texte destinés à saisir une note.
Fichier(s)
exo7.1.html
, exo7.2.html