JavaScript

Transcription

JavaScript
Techniques à Objets et Internet
Le Web et sa programmation
Jean-François Perrot
Université Pierre et Marie Curie (Paris 6)
Cours n° 6 : Introduction à Javascript-4
• Objets en Javascript
• Application au contrôle des formulaires
Jean-François Perrot
JavaScript 4
1
Sommaire
Objets : 3 - 8
Communication : 9 - 20
Le modèle objet de la page : 21 - 26
window et document : 27 - 36
Conclusion : 37 - 38
Jean-François Perrot
JavaScript 4
2
1
"Objets" en JavaScript
• Avec les objets COM de Visual Basic et les (vrais) objets Java,
encore une autre notion d'objet informatique...
• Les objets de Javascript sont en fait des "tableaux associatifs"
(c-à-d. des tableaux indexés par des chaînes), avec une une
syntaxe pointée (y compris l'instruction with, absente en
Java) pour les utiliser et une primitive new pour les créer.
• Comme les "vrais" objets ils ont des propriétés (champs =
données) et des comportements (méthodes = procédures)
– propriétés et comportements sont traités de la même façon
car en Javascript les fonctions sont des données !
• Mais il n'y a ni classes, ni héritage...
Jean-François Perrot
JavaScript 4
3
"Objets" prédéfinis en JavaScript
• La notation pointée permet de manipuler aisément une grande
quantité d'objets dont le type est prédéfini : String, Date, etc.
• Dans le jargon (le "métalangage") employé pour parler de
JavaScript, on dit "l'objet String", " l'objet Date", etc. (et
même de "l'objet Math" !!!).
Il vaudrait certes mieux parler de classes, mais il n'y a pas de
classes en JavaScript... On préfère donc dire "n'importe quoi" !
• Exemple : les chaînes de caractères sont des "objets"
"abc".length --> 3 // length est une "propriété"
"abc".toUpper() --> "ABC" // toUpper est une "méthode"
"abc".toUpper().length --> 3
Jean-François Perrot
JavaScript 4
4
2
<html> <head> <title> Essai de date </title> </head>
<body> <p>Debut</p> <p>
<script type="text/javascript">
var aujourdHui = new Date();
var
var
var
var
var
var
var
leQuantieme = aujourdHui.getDate();
leJourDeLaSemaine = aujourdHui.getDay();
leMois = aujourdHui.getMonth();
lAnnee = aujourdHui.getFullYear();
lHeure = aujourdHui.getHours();
laMinute = aujourdHui.getMinutes();
laSeconde = aujourdHui.getSeconds();
Les Dates
en JavaScript
date.html
document.write("<h3> Nous sommes le jour : " + leQuantieme);
document.write(" du mois : " + leMois);
document.write(" de l\'ann&eacute;e : " + lAnnee + ".<br /> />");
document.write("Ce jour est un : " + leJourDeLaSemaine + ".<br /> />");
document.write("Il est : " + lHeure + " heures ");
document.write(laMinute + " minutes " + laSeconde + " secondes </h3>");
document.write("<h1>Bonne Ann&eacute;e, Heureux Si&egrave;cle, Excellent _
Mill&eacute;naire </h1>");
</script>
</p><p>Fin</p> </body></html>
Jean-François Perrot
JavaScript 4
5
Une Date particulière
Jean-François Perrot
JavaScript 4
6
3
Constantes & fonctions "mathématiques"
• Comme en Java, un certain nombr />e de constantes (p.ex.
PI) et de fonctions à caractère "mathématique" sont
regroupées en un "module" appelé Math.
Par analogie avec Java, on emploie la notation pointée
" Math.xxx" pour les désigner :
Math.abs(-5) --> 5 ;
Math.max(5, 7) --> 7 ;
Math.PI --> 3.1416... ; Math.random() --> ???
• Puisqu'il n'y a pas de classes en JavaScript, on ne peut pas
parler comme en Java de la classe Math et de ses attributs
et méthodes de classe (alias static members).
On est donc amené pour expliquer cette notation à proférer
une monstruosité : the Math Object... que je préfère ne pas
traduire en français !
Jean-François Perrot
JavaScript 4
7
Couleurs en JavaScript
• La notation normale pour désigner une couleur en Javascript
est une chaîne en format RGB (6 chiffres hexadécimaux
RRGGBB représentant les trois composantes rouge, vert, bleu,
chacune entre 0 et 255).
rouge = "FF0000", vert = "00FF00", bleu = "0000FF"
• On peut ainsi affecter par programme les différentes couleurs
qui apparaissent dans une page. Par exemple, la couleur de
fond :
document.bgColor="FF0000"
• La valeur numérique fait aussi bien l'affaire que la chaîne en
hexadécimal : document.bgColor=14102802...
Jean-François Perrot
JavaScript 4
8
4
Problème de communication
• La réalisation de scripts un tant soit peu élaborés requiert
l'écriture de fonctions.
– Ces fonctions sont normalement déclarées dans l'en-tête
de la page.
– Dans l'en-tête aucun des noms des différents composants
qui apparaissent dans le corps n'est connu !
– Toute l'information communiquée aux fonctions est donc
portée par les arguments.
• Conclusions :
– il faut pouvoir passer comme arguments les objets
adéquats.
– il faut choisir les fonctions à placer dans l'en-tête en
conséquence !
Jean-François Perrot
JavaScript 4
9
Problèmes de communication
exemple
Exercice "faire défiler les photos en cliquant", en plaçant la photo
courante dans un lien et en utilisant l'événement Click pour
recalculer son chemin d'accès.
Dans l'état actuel de nos connaissances :
Le nom de la photo n'est pas connu dans l'en-tête, par conséquent on
ne peut pas l'utiliser dans une fonction auxiliaire. L'essentiel du
travail doit donc s'écrire dans le handler onClick :
– incrémentation du numéro courant (qui est nécessairement
contenu dans une variable globale)
– affectation du nouveau chemin à la propriété photo.src
– sans oublier de renvoyer faux pour inhiber l'ouverture du lien !
Le calcul du chemin à partir du numéro courant, en revanche, se fait
avantageusement par une fonction...
Jean-François Perrot
JavaScript 4
10
5
<html>
<head>
<title>PourExplorer</title>
<script type="text/javascript">
Idée de solution
var k = 0;
function chemin(i) {...
Photo2.html
}
function avancer(photo) {...
}
Idée : recourir à
</script>
onLoad
</head>
<body onLoad="avancer(flip);">
Moyen : le nom
<p>Debut</p> <p>
flip est connu
<a onclick=
'if ( confirm(" Voulez-vous changer ? ") ) { dans tout le
avancer(flip);
document,
}
c'est-à-dire entre
return false;'>
<img name="flip" />
les balises
</a>
<body> et
</p><p>Fin</p> </body>
</body>
</html>
Défilé des photos
Jean-François Perrot
JavaScript 4
11
Défilé des photos
détail de la solution
Jean-François Perrot
<script type="text/javascript">
var k = 1; // le numéro
var res = "../Jour2pm/PhotJPG/";
function chemin(i) {
if (i <10) {
return(res + "0"+i+".jpg");
} else {
return(res + i+".jpg");
}
}
function avancer(photo) {
if ( k == 13 ) k = 0;
k++;
photo.src = chemin(k);
}
</script> JavaScript 4
12
6
Utilisation du "modèle-objet"
• Le fond du problème de communication : un nom est connu
dans le contexte d'un objet.
– Exemple : le nom flip est connu dans le contexte de
l'objet document
• Les objets de JavaScript servent à construire un "modèleobjet" pour les pages Web et pour les fenêtres des
navigateurs où elles s'affichent.
• Nous allons explorer (en partie) ce modèle.
– d'abord, le modèle des formulaires
– ensuite celui des fenêtres et des documents
– enfin celui de la composition et des cadres
Jean-François Perrot
JavaScript 4
13
Le formulaire comme "objet"
Chaque balise <form...>...</form> donne naissance à
un "objet" form.
• Un tel objet possède les propriétés suivantes :
– individuellement, en tant qu'objet, chacun de ses éléments
nommés (propriété = le nom)
– collectivement, le tableau de ses éléments (elements)
– son nom (name)
– son action (action) = l'URL où le formulaire envoie
son contenu (en principe un script CGI)
– et quelques autres propriétés de service...
• Il réagit aux événements Submit et Reset par les handlers
onsubmit et onreset.
• Il a deux méthodes submit()et reset() simulant lesdits
événements.
Jean-François Perrot
JavaScript 4
14
7
Exemple de formulaires nommés (1)
• Utilité d'avoir plusieurs formulaires dans la même page :
– un formulaire envoie au serveur CGI les valeurs de tous
ses champs.
– on peut souhaiter différencier la structure utilisée pour
saisir l'information et le format employé pour l'envoyer :
le formulaire de saisie va renseigner un second formulaire
chargé de l'expédition.
• Exemple : le formulaire ci-contre
employé pour synthétiser l'information en
une ligne :
M. (Mme ou Melle) <Prénom> <Nom>,
[musicien] [sportif]
Jean-François Perrot
JavaScript 4
15
Exemple de formulaires nommés (2)
<form onsubmit=
"Synthese.leResume.value = synthetiser(this);
return false;">
<p> Nom : <input type="text" name="leNom"/> </p>
<p> Pr&eacute;nom : <input type="text" name="lePrenom"/> </p>
<p> Sexe : <br />
<input type="radio" name="leSexe" value="M"/> M <br />
<input type="radio" name="leSexe" value="F"/> F <br /> </p>
<p> &Acirc;ge : <input type="text" name="Age"/> </p>
<p> Activit&eacute;s favorites : <br />
<input type="checkbox" name="laMusique"
value="Oui" checked="checked"/> Musique <br />
<input type="checkbox" name="leSport"
Deuxform.html
value="Oui"/> Sport <br /></p>
<input type="submit" value="Envoi"/> <br /> </p>
</form>
<form name="Synthese">
<p> en somme : <input type="text" name="leResume" size="60"/> </p>
</form>
Jean-François Perrot
JavaScript 4
16
8
Exemple de formulaires nommés (3)
Jean-François Perrot
JavaScript 4
La fonction de
synthèse
Deuxform.html
<head>
<title>Essai avec deux formulaires</title>
<script type="text/javascript">
function synthetiser(formulaire) {
var res="";
with (formulaire) {
// deux conventions preliminaires
var mus;
if ( leSexe[0].checked ) {
mus = "musicien";
} else {
mus = "musicienne";
}
var sport;
if ( leSexe[0].checked ) {
sport = "sportif";
} else {
sport = "sportive";
}
Jean-François Perrot
17
// calcul de la chaine-resultat
if ( leSexe[0].checked ) {
res += "M. ";
} else {
if ( parseInt(Age.value) < 20 ) {
res += "Melle ";
} else {
res += "Mme ";
}
} // terminé pour M., Mme ou Melle
res += lePrenom.value; res += " ";
res += leNom.value;
if ( laMusique.checked ) {
res += ", "+mus;
if ( leSport.checked ) {
res += " et "+sport+".";
} else {
res += ".";
}
} else {
if ( leSport.checked ) {
res += ", "+sport+".";
} else {
res += ".";
}
} // et c'est tout !
}// fin du with
return res;
}
</script>
</head>
JavaScript 4
18
9
Exemple de formulaires nommés (4)
Commentaire
• La solution retenue a pour principe de communiquer à la fonction
synthetiser l'objet formulaire tout entier :
synthetiser(this)
• Elle a l'avantage de ne modifier le formulaire original que dans la
balise <form...> (ajout d'un handler onSubmit).
• Elle a l'inconvénient d'invoquer un pseudo-submit : nécessité
d'un return false dans le handler pour inhiber l'envoi au
serveur.
• Il serait plus naturel d'utiliser un push button pour déclencher
l'action de synthèse :
<input type="button" value="Envoi"
onClick = "Synthese.leResume.value= synthetiser(???")>
Jean-François Perrot
JavaScript 4
19
De l'élément au formulaire
Le problème est alors de passer du bouton au formulaire !
• Chaque objet-élément elt d'un formulaire "connaît"
l'objet-formulaire dont il fait partie (il détient son adresse
comme propriété).
• Ce dernier est accessible sous le nom de propriété form :
le formulaire dont fait partie elt est elt.form.
• Application à notre exemple :
<input type="button" value="Envoi"
onClick = "Synthese.leResume.value=
synthetiser(this.form)">
Jean-François Perrot
JavaScript 4
20
10
Objets "fenêtres" vs. objets "documents"
• JavaScript distingue dans le fonctionnement d'une page
– ce qui concerne son cadre (la fenêtre : dimensions, position,
bordures, affichage de différents attributs, outils et autres)
– ce qui concerne son contenu (le document : ce qui est
affiché dans la page).
• Ces deux ordres de préoccupations sont pris en compte par
deux genres d'objets : les fenêtres (Window) et les
Documents.
• La difficulté est de savoir exactement à qui on doit s'adresser
pour réaliser telle ou telle tâche...
Jean-François Perrot
JavaScript 4
21
La fenêtre comme "objet fondamental"
(1) L'espace des noms
L'unité fondamentale dans le modèle-objet de JavaScript est la
fenêtre du navigateur, représentée par un "objet Window".
(1) Toutes les entités JavaScript lui appartiennent (on dit qu'il
définit l'espace des noms - name space)
• Toutes les fonctions (standard comme alert, confirm, etc.
ou définies par l'utilisateur) sont en fait des méthodes de l'objet
Window où elles sont déclarées.
• Toutes les variables globales sont en fait des propriétés de
l'objet Window où elles sont déclarées.
• Il s'ensuit que deux fonctions ou deux variables globales
différentes pourront porter le même nom, à condition d'être
déclarées dans des fenêtres différentes.
Jean-François Perrot
JavaScript 4
22
11
La fenêtre comme "objet fondamental"
(2) La hiérarchie de composition
(2) La fenêtre est la racine de l'arbre d'objets représentant la page :
• p. ex. elle détient comme propriété l'objet document...
• esquisse de cet arbre :
elements[ ]
forms[ ]
Button
Checkbox
Hidden
Password
Radio
Reset
Select
Submit
Text
textarea
navigator
La fenêtre
Window
history
location
anchors[ ]
links[ ]
images[ ]
document
applets[ ]
options[ ]
Pour chaque objet o dans la page, il y a un chemin unique de la fenêtre à o.
Jean-François Perrot
JavaScript 4
23
Questions de désignation : contexte
• Tout fragment de code JavaScript s'exécute dans le contexte
d'un objet.
– tous les objets dont les noms sont connus dans ce contexte
peuvent être désignés directement :
ainsi par exemple : alert("bla bla")
• Exemple : soit un handler d'un objet Button, élément d'un
formulaire :
– la place du bouton dans l'arbre des objets de la page est
La fenêtre
document
form
button
– dans le handler, on peut donc utiliser les noms définis dans
la fenêtre, dans le document, dans le formulaire qui
contient le bouton, et enfin dans le bouton lui-même.
Jean-François Perrot
JavaScript 4
24
12
Ex. Désignations
<html> <head> <script type="text/javascript">
var vb = "la value de ce bouton est : "
var frc = "le formulaire contient "
var elts = " elements\n"
var dc = "le document contient "
var frs = " formulaires\n"
var tlf = "la taille de la fenêtre est : "
var pxs = " pixels"
</script></head>
<body> <form>
<p> <textarea name="Aff" rows=5 cols=50> </textarea></p>
<input type="button" value="Pour voir"
Designation.html
onClick =
"Aff.value=vb+value+'\n'+frc+elements.length+elts+dc+
forms.length+frs+tlf+innerHeight+' x '+innerWidth+pxs">
</form> </body> </html>
La fenêtre
Jean-François Perrot
document
form
button
JavaScript 4
25
Questions de désignation : ambiguïté ?
• Quid si le même nom est défini à deux niveaux différents ?
– l'évolution du système tend à éliminer ces situations
• C'est la désignation la plus locale qui prime, mais il vaut mieux
lever l'ambiguïté, en désignant explicitement l'objet visé
– l'objet Window représentant la fenêtre active est accessible
par la propriété implicite window, aussi appelée self
– dans notre exemple, les noms complets seraient :
window.document.forms[0].elements[1].value
window.document.forms[0].elements.length
window.document.forms.length
window.innerHeight
window.innerWidth
Jean-François Perrot
JavaScript 4
26
13
Deux fonctionnalités des objets Window
(il y en a bien d'autres !)
• La status line gérée à travers deux propriétés
– status (déjà vu) pour messages transitoires
– defaultStatus pour messages permanents
• La gestion du temps :
– setTimeout(uneChaînedeCode, unDélai)
exécute l'action spécifiée par la chaîne
uneChaînedeCode
après unDélai compté en millisecondes :
setTimeout("alert('Avez-vous fini ?')", 5000)
SetTimeout.html
Jean-François Perrot
JavaScript 4
27
Exemple : une horloge
<html> <head>
<script type="text/javascript">
function showtime(){
var now = new Date()
var hours = now.getHours()
var minutes = now.getMinutes()
var seconds = now.getSeconds()
var timevalue = "" + ((hours > 12) ? hours - 12 : hours)
timevalue += ((minutes < 10) ? ":0" : ":") + minutes
timevalue += ((seconds < 10) ? ":0" : ":") + seconds
timevalue += (hours >= 12) ? " P.M." : " A.M."
document.clock.face.value = timevalue
<body onLoad="showtime()">
defaultStatus = timevalue
<form name="clock">
setTimeout("showtime()",1000)
<input type="text"
}
name="face" size="15" />
</script>
</form>
</head>
Showtime.html
</body> </html>
Jean-François Perrot
JavaScript 4
28
14
Fenêtres : ouverture et fermeture
• Les objets Window possèdent (entre autres) une méthode
open() et une méthode close()
– les objets Document aussi, avec des significations
différentes ! Il faut donc préciser...
• window.close() ferme la fenêtre courante
– setTimeout("window.close()", 5000)
• window.open()ouvre une nouvelle fenêtre !!!
– il lui faut comme arguments
• une URL où trouver un document à y charger (éventuellt. vide)
• un nom désignant la fenêtre en question (voir plus loin)
• différentes caractéristiques optionnelles
– renvoie comme résultat un pointeur sur la fenêtre créée.
Jean-François Perrot
JavaScript 4
29
Application : solution du problème
"document.write"
• Nous avons vu que "document.write" ne pouvait pas
être employé à bon droit dans des handlers d'événements
associés à des formulaires.
• La bonne solution est d'écrire dans le document d'une
nouvelle fenêtre !
function montrer(clr) {// nouvelle version améliorée
var newwin = window.open("", "nov","width=350, height=100");
newwin.document.write ("<p><B><FONT SIZE=7 COLOR="
+clr+">D&eacute;monstration</FONT></B></p>");
newwin.document.close(); // pour réutilisation
newwin.setTimeout("window.close()", 5000);
}
Jean-François Perrot
JavaScript 4
30
15
La fenêtre comme cible (target)
pour un lien ou pour un formulaire
• Les liens et les formulaires peuvent avoir un champ target
qui spécifie la fenêtre où
–le contenu du lien (URL) sera affiché
–le retour du script CGI sera écrit
• La valeur de ce champ doit être un nom de fenêtre au sens de
window.open()
–mais, contrairement à l'usage, ce nom doit être donné par
une constante de chaîne
"The target property cannot be assigned the value of a JavaScript
expression or variable." dit la doc !
–si la fenêtre ainsi désignée n'est pas encore créée, elle le
sera...
Jean-François Perrot
JavaScript 4
<html>
<head>
<title>DefileNouvFen</title>
<script type="text/javascript">
var k = 0;
var res = "../../PHOTOS-JPG/";
function chemin(i) {
if (i <10) {
return(res + "0"+i+".jpg");
} else {
return(res + i+".jpg");
}
}
function chemsuiv() {
if ( k == 13 ) k = 0;
k++;
return chemin(k);
}
</script>
</head>
Jean-François Perrot
31
Le défilé des photos
dans une fenêtre à part
Le code
JavaScript 4
Photo3.html
<body>
<p>Debut</p>
<p>
<a href=""
onclick = "href=chemsuiv();"
target="photo">
Photo suivante
</a>
</p>
<p>Fin</p>
</body> </html>
32
16
Le défilé
des photos
dans une
fenêtre à
part
-----------Le
spectacle !
Jean-François Perrot
JavaScript 4
33
Rediriger le résultat d'un formulaire
<form action="http://www-poleia.lip6.fr/~jfp/php/photo.cgi"
target="photo">
Jean-François Perrot
JavaScript 4
34
17
Le document comme "objet"
• Un objet document représente le contenu d'une page html
simple (c-à-d. non composée, voir plus loin). Il se matérialise
dans le code html par la balise <body...>...</body>
et par son contenu.
• Il possède une série de propriétés, qui traduisent les diverses
indications portées dans le code.
• Son activité principale est l'écriture d'un contenu codé (la
plupart du temps) comme un texte html, par la méthode
write(...).
• L'objet représentant le document courant est connu sous le
nom de document. En fait c'est la propriété document de
l'objet window actif (= la fenêtre courante).
On a donc pratiquement les équivalences :
document = window.document = self.document
Jean-François Perrot
JavaScript 4
35
Quelques propriétés des objets document
• Propriétés descriptives : couleurs
– bgColor = la couleur de fond (html : affaire de style...)
– etc.
• Propriétés stucturelles :
tous les éléments nommés sont accessibles comme propriétés
du document (avec leurs noms),
et en outre on peut accéder aux éléments essentiels du contenu
(même non nommés), en autant de tableaux
anchors links images forms
• Ex. :Au lieu de désigner un formulaire par son nom, on peut le
trouver par son indice dans le tableau forms
Dans l'exemple "à 2 formulaires"
Synthese == forms[1]
Idem, dans le "défilé des photos", flip == images[0]
Jean-François Perrot
JavaScript 4
36
18
Solution complète
au problème de communication
• Chaque objet de la page peut être désigné en tout endroit du code
– par son nom (s'il a un attribut name)
– par son numéro (index) dans la collection dont il fait partie
(elements d'un formulaire, images, links, et c. d'un document)
Ex.
Ex flip = images[0]
• Selon la "distance" qui sépare le lieu de déclaration du ieu
d'invocation, il faudra compléter ce nom par un fragment de
chemin :
Ex. dans l'en-tête, flip est inconnu, et son synonyme
images[0] aussi : seul window est accessible, il faut donc
dire (window).document.flip
ou (window).document.images[0]
Jean-François Perrot
JavaScript 4
37
Note sur l'interprétation
• L'exemple de la référence document.flip dans l'en-tête
met en évidence le caractère interprété de JavaScript :
– au moment où cette référence est lue (au cours du traitement de l'en-tête
de la page par le navigateur) le nom flip n'est pas encore déclaré (il
ne le sera que lorsque le cops de la page aura été traité)
– JavaScript doit donc "faire confiance" à l'objet document en faisant
l'hypothèse que ce dernier possèdera effectivement un attribut nommé
flip.
• Cette "mise en attente" interdit une compilation (génération de
code assembleur) qui supposerait que l'on traduise flip en un
déplacement en mémoire.
• Après le traitement de l'en-tête, JavaScript conserve donc la
"forme abstraite" document.flip et ne pourra l'interpréter
qu'à l'exécution…
en détectant peut-être une erreur, trop tard !
Jean-François Perrot
JavaScript 4
38
19

Documents pareils