Conception de serveurs et de services sur internet
pour l'enseignement des sciences de la vie et de la Terre

Université d'été, CRDP de Versailles, 20-24 juillet 1998


Atelier JavaScript/DHTML
Benjamin Lupu - Luis Espinosa

Avertissement

Le fichier ci-dessous a été conçu pour fonctionner avec le navigateur Netscape Communicator 4.x dans un souci de clarté du code. Il est cependant simple de le rendre compatible pour Microsoft Internet Explorer 4.x. On pourra pour cela consulter le livre suivant : Heinle N., Designing with JavaScript : Creating Dynamic Web Pages, O’Reilly, 1997. A part le navigateur, aucun autre outil n’est nécessaire pour pouvoir lire dino.htm. Pour une bonne compréhension du tutoriel, il est souhaitable de se reporter à une référence du langage JavaScript (McFarlane N., Instant JavaScript, Wrox Press, 1997 par exemple).

Légende

Ce document utilise la légende suivante :

Code HTML (bleu)

Code JavaScript (rouge)

Commentaires

Sur la trace des dinosaures...

Sur la trace des dinosaures est une simple page de démonstration des possibilités qu’apporte le Dynamic HTML mêlé au JavaScript 1.2.

Voir la page HTML de l'exercice

Le menu de navigation : un menu de navigation se trouve en haut de page. Ses boutons doivent s’allumer au glissé du curseur de la souris.

La scène : l’élément principal et central de la page est une scène représentant un décor préhistorique. Au chargement de la page, le décor est remplacé par une phrase de bienvenue.

Les contrôles de navigation : la scène est pourvue de trois boutons pour allumer et éteindre la scène, pour faire apparaître et disparaître les acteurs sur la scène.

Les acteurs : les contrôles de navigation doivent permettre à l’utilisateur de faire apparaître successivement trois dinosaures (deux sont terrestres, le dernier vole) sur la scène. Au chargement de la page, les acteurs sont cachés. Lorsque l’on clique sur un acteur visible, une fenêtre avec sa description s’ouvre.

La barre de chronologie : à droite de la scène, se trouve une barre qui évoque les différentes époques de la préhistoire. Elle permet lorsque la scène est allumée, de faire apparaître les acteurs. A chaque époque correspond un dinosaure.

<HTML>

La balise <HTML> ouvre un document HTML. Elle avertit le navigateur qu’il doit interpréter ce qui suit comme de l’HTML.

<HEAD>

<TITLE>Sur les traces des dinosaures...</TITLE>

La balise <HEAD> marque le début de l’entête de la page HTML. On précise grâce à la balise <TITLE> le titre que le navigateur va afficher dans sa barre de titre.

L’ensemble des balises et des scripts situés dans l’entête sont interprétés avant l’affichage de la page.

<STYLE TYPE="text/css">

Avec la balise <STYLE TYPE="text/css">, on annonce que l’on va définir des modèles de calque dont se servira le navigateur pour afficher correctement les calques de la page. Un calque est une couche indépendante de la page HTML avec des coordonnées (left et top), une hauteur (height), une largeur (width), un état par défaut (visibility) et une profondeur (z-index).

On doit nommer un modèle en faisant précéder son nom d’un # (Ex. #moncalque). La définition du modèle est encadrer par des {...}. Chaque rubrique de la définition doit être séparée par des ;. Les espaces et les retours chariots (caractères invisibles générés lorsque vous appuyez sur la touche Entrée) n’ont pas d’importance. Par contre il est préférable d’écrire les définitions de modèle en minuscules.

Les coordonnées et les dimensions du modèle sont données en pixels (px) ou en pourcentages (%). L’état du modèle peut être soit à visible (visible et actif) soit à hidden (caché et inactif). La profondeur est calculée par étage de 1 (le plus bas) à l’infini (le plus haut).

On prépare le découpage de la page en plusieurs calques :

#decor {position: absolute;

left:100px;

top: 160px;

width: 230px;

height: 200px;

visibility: visible;

z-index: 1

}

#barre {position: absolute;

left:400px;

top: 80px;

width: 10px;

height: 10px;

visibility: visible

}

#titre {position: absolute;

left:115px;

top: 0px;

width:200px;

height: 100px;

visibility: visible

}

#dino1 {position: absolute;

left:234px;

top: 209px;

width: 200px;

height: 100px;

visibility: hidden;

z-index: 10

}
 
 

#dino2 {position: absolute;

left:100px;

top: 268px;

width: 200px;

height: 100px;

visibility: hidden;

z-index: 10

}

#dino3 {position: absolute;

left:100px;

top: 160px;

width: 200px;

height: 100px;

visibility: hidden;

z-index: 10

}

La balise </STYLE> marque la fin de la définition des modèles de calque.

</STYLE>

La balise <SCRIPT LANGUAGE="JavaScript"> indique au navigateur qu’il va devoir interpréter du JavaScript.

<SCRIPT LANGUAGE="JavaScript">

On créé deux variables dino_en_cours et cycle. Cette déclaration des variables à l’aide de l’instruction var n’est pas obligatoire mais elle aide à la clarté du code. La variable cycle est dite booléenne, c’est-à-dire qu’elle contient soit la valeur vrai (true) soit la valeur faux (false). Une variable booléenne se déclare à l’aide l’instruction new et du mot clé Boolean. Attention, il convient en JavaScript de respecter les minuscules et les majuscules, on écrira donc Boolean et non boolean.

var dino_en_cours

cycle = new Boolean

On stockera dans dino_en_cours l’acteur affiché à l’écran (par défaut le dinosaure numéro 1) et dans cycle l’état de la scène (par défaut éteinte, false).

dino_en_cours = 1

cycle = false

Au chargement de la page et lorsqu’on clique sur le bouton Aide du menu de navigation, une fenêtre s’ouvre avec une brève explication sur la page.

L’ouverture de la fenêtre va se faire par l’intermédiaire d’une fonction. Les fonctions sont une série d’instructions, de boucles et de tests regroupés sous un même nom. On déclare une fonction à l’aide de l’instruction function suivi du nom qu’on veut lui donner. Pour faire exécuter une fonction, il suffit une fois qu’elle a été définie de l’appeler par son nom.

Ex. mafonction ()

Il est possible de transmettre des informations à la fonction sous la forme de paramètres que l’on place entre les parenthèses qui suivent son nom.

Ex. mafonction(1) = je passe à la fonction mafonction le chiffre un.

Auparavant, on aura pris soin de prévoir le passage de paramètres au moment de la déclaration de la fonction.

Ex. function mafonction (chiffre) {...} = l’information recueillie sera stockée dans la variable chiffre.

Pour passer plusieurs paramètres, il suffit de les séparer par des virgules.

Ex. mafonction (1, " chaine ")

function mafonction (val1,val2) {...}

La série d’instructions de la fonction est délimitée par des {...}.

Il est possible de déclarer des fonctions à n’importe quel endroit du fichier HTML à condition qu’elles précédent leur premier appel. Pour la clarté du code, mieux vaut les regrouper dans l’entête du document HTML.

function affaide () {

open("aide.htm","fenaide","height=400,width=300")

}

open est une méthode (une fonction innée) de l’objet window (c’est-à-dire la fenêtre du navigateur). Elle exécute une série d’instructions qui créée une nouvelle fenêtre du navigateur. Elle accepte trois paramètres :

open(" le fichier à afficher  dans la nouvelle fenêtre ", " le nom de la nouvelle fenêtre ", " les caractéristiques de la nouvelle fenêtre ").

Ici la fonction affaide ouvre une nouvelle fenêtre d’une hauteur (height) de 400 pixels et d’une largeur (width) de 300 pixels et y affiche le fichier d’aide (aide.htm).

function debut () {

if (cycle==false) {

cycle=true

document.dino1.visibility="visible"

}

}

La fonction debut permet d’allumer la scène. On commence par tester si la scène est bien éteinte (cycle==false). Le signe = permet de stocker de l’information dans une variable. Le signe == permet de tester le contenu d’une variable. L’instruction if permet de soumettre l’exécution des instructions qu’elle contient entre ses accolades à un test logique, ici : est-ce que la variable cycle contient false ( ?).

Si la scène est éteinte, on stocke dans la variable cycle la valeur true et on fait apparaître le premier dinosaure en rendant visible son calque, c’est à dire qu’on stocke la valeur visible dans la propriété (c’est à dire une variable innée de l’objet calque) du calque dino1.

La fonction fin ci-dessous fonctionne exactement selon le même principe mais permet au contraire d’éteindre la scène.

function fin () {

if (cycle==true) {

cycle=false

document.dino1.visibility="hidden"

document.dino2.visibility="hidden"

document.dino3.visibility="hidden"

}

}

function suivant () {

if (cycle==true) {

dino_en_cours++

if (dino_en_cours==4) {dino_en_cours=1}

switch (dino_en_cours) {

case 1 :

document.dino1.visibility="visible"

document.dino2.visibility="hidden"

document.dino3.visibility="hidden"

break

case 2 :

document.dino1.visibility="hidden"

document.dino2.visibility="visible"

document.dino3.visibility="hidden"

break

case 3 :

document.dino1.visibility="hidden"

document.dino2.visibility="hidden"

document.dino3.visibility="visible"

break

}

}

}

La fonction suivant va nous permettre de faire apparaître les dinosaures les uns après les autres. On commence par tester que la scène est bien allumée (cycle==true). Puis on ajoute un au contenu de la variable dino_en_cours à l’aide de l’opérateur ++. Donc si dino_en_cours contient un, sa nouvelle valeur va être deux et nous afficherons le second dinosaure. Tout de suite après, on teste si dino_en_cours ne contient pas la valeur quatre car il n’y a que trois dinosaures à afficher. Si dino_en_cours contient quatre, on lui affecte comme nouvelle valeur un afin de créer une boucle dans l’affichage des dinosaures, le premier dinosaure étant affiché tout de suite après le troisième.

L’instruction switch permet ensuite de tester le contenu de la variable dino_en_cours de façon plus élaborée qu’avec if. L’instruction switch enferme entre ses accolades une série d’instructions case qui lui indiquent quelles opérations effectuer en fonction de la valeur contenue dans dino_en_cours. L’instruction case s’emploie comme suit :

case valeur testée :

...

suite d’instructions ...

break

Dans la fonction suivant, pour chaque valeur de dino_en_cours on affiche le dinosaure qui lui correspond et on cache les deux autres afin qu’il n’y qu’un seul dinosaure affiché à la fois à l’écran.

La fonction precedent ci-dessous fonctionne selon le même principe mais en sens inverse puisqu’elle permet d’afficher le dinosaure précédent.

function precedent () {

if (cycle==true) {

dino_en_cours--

if (dino_en_cours==0) {dino_en_cours=3}

switch (dino_en_cours) {

case 1 :

document.dino1.visibility="visible"

document.dino2.visibility="hidden"

document.dino3.visibility="hidden"

break

case 2 :

document.dino1.visibility="hidden"

document.dino2.visibility="visible"

document.dino3.visibility="hidden"

break

case 3 :

document.dino1.visibility="hidden"

document.dino2.visibility="hidden"

document.dino3.visibility="visible"

break

}

}

}

function affdino() {

var fichier

fichier = "dino" + dino_en_cours + ".htm"

open(fichier,"fendino","height=400,width=300")

}

La fonction affdino permet d’afficher la description du dinosaure affiché à l’écran dans une fenêtre à part. Elle utilise pour cela la méthode open. Le premier paramètre d’open (le nom du fichier à afficher) est stocké dans la variable fichier. La variable fichier est déclarée au sien de la fonction affdino et n’existe donc qu’au sein de cette fonction contrairement aux variables déclarées au début du script (dino_en_cours et cycle) qui sont valables pour la page entière.

On compose le contenu de fichier à partir de deux chaînes de caractères (" dino " et " .htm ") et de la variable dino_en_cours à l’aide de l’opérateur + (on parle alors de concaténation) afin d’obtenir soit ""dino1.htm ", soit " dino2.htm " ou " dino3.htm " qui sont les trois fichiers HTML de description des acteurs.
 

function epoque(dino) {

if (cycle==true) {

dino_en_cours = dino

switch (dino) {

case 1 :

document.dino1.visibility="visible"

document.dino2.visibility="hidden"

document.dino3.visibility="hidden"

break

case 2 :

document.dino1.visibility="hidden"

document.dino2.visibility="visible"

document.dino3.visibility="hidden"

break

case 3 :

document.dino1.visibility="hidden"

document.dino2.visibility="hidden"

document.dino3.visibility="visible"

break

}

}

}

La fonction epoque permet d’afficher un dinosaure sur la scène allumée en cliquant sur la barre de chronologie. Elle fonctionne de la même façon que les fonctions suivant et precedent à ceci près qu’elle reçoit un numéro de dinosaure qu’elle va stocker dans la variable dino. La variable dino sert à la fois au test de l’instruction switch et à l’actualisation de la variable dino_en_cours.

</SCRIPT>

La balise </SCRIPT> marque la fin du script JavaScript de l’entête du document HTML. Nous devons à présent :

</HEAD>

<BODY BGCOLOR=black TEXT=black VLINK=blue ALINK=red LINK=blue onLoad="affaide()">

La balise </HEAD> marque la fin de l’entête du document HTML et la balise <BODY...> le début du corps du document HTML. L’ensemble des éléments qui se trouvent dans le corps du document vont être affichés à l’écran (les scripts JavaScript mis à part).

L’aide en ligne s’affiche dans une fenêtre à part au chargement de la page. Au chargement de la page, le navigateur déclenche l’événement chargement (onLoad). Pour indiquer au navigateur ce qu’il doit faire pendant l’événement chargement, on place un nouvel attribut de la balise <BODY> : onLoad. Les événements JavaScript fonctionnent comme suit :

<BALISE événement = "code JavaScript ">

Ici, on appelle la fonction affaide dans l’événement onLoad.

<DIV ID="decor">

<CENTER>

<A HREF="#"onClick="debut();fonddec.src='decors_jour.jpg'"><IMG NAME="fonddec" SRC="decors_nuit.jpg" HEIGHT=200 WIDTH=229 BORDER=0 LOWSRC="decors_nuit_low.jpg"></A>

<A HREF="javascript:precedent()"><IMG SRC="precedent.jpg" HEIGHT=40 WIDTH=40 BORDER=0 LOWSRC="precedent_low.jpg" ALT="Acteur précédent..."></A>

<A HREF="#" onClick="fin();fonddec.src='decors_nuit.jpg'"><IMG SRC="arret.jpg" HEIGHT=40 WIDTH=40 BORDER=0 LOWSRC="arret_low.jpg" ALT="Arrêter l'animation..."></A>

<A HREF="javascript:suivant()"><IMG SRC="suivant.jpg" HEIGHT=40 WIDTH=40 BORDER=0 LOWSRC="suivant_low.jpg" ALT="Acteur suivant..."></A>

</CENTER>

</DIV>

On créé un calque à l’aide de la balise <DIV>. On précise le modèle du calque à l’aide de l’attribut ID, ici decor. Puis on affiche les images du décor et des contrôles de navigation. Tout les éléments qui se trouvent entre les balises <DIV ID= "decor"> et </DIV> vont appartenir au calque decor.

Il est nécessaire de rendre les images du décors et des boutons sensibles aux clics de la souris de l'utilisateur. Pour cela nous sommes obligés de transformer les images en hyperliens car le navigateur ne déclenche l'événement clic que lorsque l'utilisateur clique sur un hyperlien. La mise en place d'un hyperlien se fait à l'aide des balises <A...></A>. Dans l'attribut HREF de la balise <A> on précise le nouveau fichier HTML à afficher lorsque l'utilisateur clique sur l'hyperlien. Cependant dans notre cas, aucun document ne doit venir remplacer la page en cours, mais on doit déclencher un script JavaScript. Il existe deux solutions pour cela :

L'affichage des dinosaures est complètement pris en charge par les fonctions suivant et precedent. Ce n'est pas le cas pour la gestion de la scène. L'affichage de la scène et sa disparition sont gérés au niveau de l'événement JavaScriptonClick. Il est en effet possible d'enchaîner plusieurs instructions JavaScript dans un même événement, il suffit pour cela de les séparer par des ;.

Pour éteindre et allumer la scène, on remplace une image par une autre. L'objet JavaScript image qui est créé lorsqu'on utilise la balise <IMG> pour insérer une image dans une page HTML, ne représente que l'emplacement de l'image (coordonnées, dimensions). Il est possible de modifier ce que contient cet emplacement en changeant le contenu de la propriété src (source) de l'objet image. Pour cela il faut auparavant nommer l'image en utilisant l'attribut NAME de la balise <IMG> comme suit :

<IMG NAME="nom de l'image" ...>

Il suffit ensuite, dans un événement JavaScript ou une fonction JavaScript, de s'adresser à l'objet image comme suit :

nom de l'image.src="nouveau fichier image (.gif ou .jpg)"
 

<MAP NAME="chrono">

<AREA HREF="javascript:epoque(1)" SHAPE="rect" COORDS="0,234,48,299" ALT="epoque3">

<AREA HREF="javascript:epoque(2)" SHAPE="rect" COORDS="0,115,49,232" ALT="epoque2">

<AREA HREF="javascript:epoque(3)" SHAPE="rect" COORDS="0,0,49,114" ALT="epoque1">

</MAP>

La balise <MAP> permet de découper une image en zones sensibles. Cela revient à créer plusieurs hyperliens sur une seule image. La carte doit d'abord être nommée à l'aide de l'attribut NAME :

Ex. <MAP NAME="nom de la carte">

La balise <MAP> contient ensuite autant de balises <AREA> qu'il y aura de zones sensibles dans la carte. Chaque aire possède une forme précisée dans l'attribut SHAPE, ici rect c'est-à-dire rectangulaire, et des coordonnées précisées dans l'attribut COORDS, ici le coin gauche supérieur et le coin droit inférieur du rectangle.

La balise <AREA> se comporte comme la balise <A> et dispose des même événements JavaScript. Il est donc possible d'appeler une fonction JavaScript dans son attribut HREF, ici la fonction epoque avec comme paramètre le numéro du dinosaure à afficher.

Pour découper l'image, on fait ensuite appel à la carte en donnant son nom précédé d'un # dans l'attribut USEMAP de la balise <IMG> :

Ex. USEMAP="#nom de la carte"

<DIV ID="barre">

<IMG SRC="barre.jpg" HEIGHT=300 WIDTH=78 BORDER=0 LOWSRC="barre_low.jpg" usemap="#chrono">

</DIV>

Si l'on ne définit qu'une seule aire pour une carte, on peut détourer une forme sensible au sein d'une image, ici la forme d'un bouton du menu de navigation et plus tard les silhouettes des dinosaures.

<DIV ID="titre">

<MAP NAME="aide">

<AREA HREF="javascript:affaide()" SHAPE="poly" COORDS="16,9,18,8,24,6,28,6,31,6,34,6,38,7,42,8,45,11,47,16,43,19,42,21,38,23,34,25,32,25,26,25,23,24,16,21,13,18,13,14,15,11,16,10,17,9" ALT="Aide en ligne..." onMouseOver="bout1.src='bouttit001o.jpg'" onMouseOut="bout1.src='bouttit001.jpg'">

</MAP>

<MAP NAME="retour">

<AREA HREF="#" SHAPE="circle" COORDS="30,19,15" ALT="Retour &agrave; la page pr&eacute;c&eacute;dente..."onMouseOver="bout2.src='bouttit002o.jpg'" onMouseOut="bout2.src='bouttit002.jpg'">

</MAP>

<MAP NAME="accueil">

<AREA HREF="#" SHAPE="circle" COORDS="17,19,15" ALT="Page d'accueil..." onMouseOver="bout3.src='bouttit003o.jpg'" onMouseOut="bout3.src='bouttit003.jpg'">

</MAP>

<IMG SRC="titre.jpg" HEIGHT=60 WIDTH=200 BORDER=0 LOWSRC="titre_low.jpg">

<IMG SRC="bouttit001.jpg" HEIGHT=40 WIDTH=60 BORDER=0 LOWSRC="bouttit001_low.jpg" ALT="Aide en ligne..." USEMAP="#aide" NAME="bout1">

<IMG SRC="bouttit002.jpg" HEIGHT=40 WIDTH=80 BORDER=0 LOWSRC="bouttit002_low.jpg" ALT="Page précedente..." USEMAP="#retour" NAME="bout2">

<IMG SRC="bouttit003.jpg" HEIGHT=40 WIDTH=60 BORDER=0 LOWSRC="bouttit003_low.jpg" ALT="Page d'accueil..." USEMAP="#accueil" NAME="bout3">

</DIV>

La gestion du glissé du curseur de la souris sur un hyperlien se fait à l'aide des événements JavaScriptonMouseOver et onMouseOut. OnMouseOver gère le passage au-dessus de l'hyperlien et onMouseOut gère la fin du survol de l'hyperlien. Il suffit de changer la source (src) d'un objet image dans ses deux événements pour signaler qu'un élément de la page est actif. C'est la cas pour les boutons du menu de navigation mis à part que les événements onMouseOver et onMouseOut se trouvent en tant qu'attributs des balises <AREA> des différentes cartes. Cela permet de détourer la forme des différents boutons.

<map name="dino1">

<area href="javascript:affdino()" shape="poly" coords="15,58,20,45,31,33,35,23,49,14,58,14,65,26,60,37,52,41,60,52,66,60,71,73,72,80,66,92,59,98,49,101,38,100,35,95,28,91,23,90,22,84,19,76,15,66,15,53" alt="Brontosaure">

</map>

<map name="dino2">

<area href="javascript:affdino()" shape="poly" coords="24,42,32,33,44,26,58,26,67,29,80,29,89,35,87,45,73,52,63,59,56,73,49,78,39,72,29,76,22,73,20,64,14,57,6,46,12,41,20,42,23,42" alt="Brontosaure...">

</map>

<map name="dino3">

<area href="javascript:affdino()" shape="poly" coords="27,17,40,9,54,3,60,0,70,4,78,14,82,22,87,25,95,21,108,21,114,22,114,40,114,66,112,71,103,54,101,47,99,34,85,39,77,42,74,48,62,49,53,49,52,45,60,37,63,36,60,23,52,23,37,31,22,36,12,41,16,28,22,22,27,16,29,16" alt="Brontosaure...">

</map>

<DIV ID="dino1">

<img src="dino1.jpg" height=126 width=95 border=0 lowsrc="dino1_low.jpg" usemap="#dino1">

</DIV>

<DIV ID="dino2">

<IMG SRC="dino2.jpg" HEIGHT=92 WIDTH=102 BORDER=0 LOWSRC="dino2_low.jpg" usemap="#dino2">

</DIV>

<DIV ID="dino3">

<IMG SRC="dino3.jpg" HEIGHT=75 WIDTH=115 BORDER=0 LOWSRC="dino3_low.jpg" usemap="#dino3">

</DIV>

</BODY>

La balise </BODY> marque la fin du corps de la page.

</HTML>

La balise </HTML> marque la fin du document HTML.



Retour au sommaire des actes