LP
IMApp

Scripts
Clients

Leçon 07

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 : 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 :

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 : 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 :

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