Anda di halaman 1dari 280

Christian Wenz

LE GUIDE DE SURVIE

JavaScript

LESSENTIEL DU CODE ET DES COMMANDES

JavaScript
Christian Wenz

CampusPress a apport le plus grand soin la ralisation de ce livre an de vous fournir une information complte et able. Cependant, CampusPress nassume de responsabilits, ni pour son utilisation, ni pour les contrefaons de brevets ou atteintes aux droits de tierces personnes qui pourraient rsulter de cette utilisation. Les exemples ou les programmes prsents dans cet ouvrage sont fournis pour illustrer les descriptions thoriques. Ils ne sont en aucun cas destins une utilisation commerciale ou professionnelle. CampusPress ne pourra en aucun cas tre tenu pour responsable des prjudices ou dommages de quelque nature que ce soit pouvant rsulter de lutilisation de ces exemples ou programmes.

Tous les noms de produits ou autres marques cits dans ce livre sont des marques dposes par leurs propritaires respectifs.
Publi par CampusPress 47 bis, rue des Vinaigriers 75010 PARIS Tl : 01 72 74 90 00 Ralisation PAO : La B Auteur : Christian Wenz
ISBN : 978-2-7440-4003-0 Copyright 2009 CampusPress est une marque de Pearson Education France

Titre original : JavaScript Phrasebook Traduit de lamricain par : Nathalie Le Guillou de Penanros ISBN original : 0-672-32880-1 Copyright 2007 by Sams Publishing www.samspublishing.com Tous droits rservs Sams Publishing 800 East 96th, Indianapolis, Indiana 46240 USA

Tous droits rservs

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. Aucune reprsentation ou reproduction, mme partielle, autre que celles prvues larticle L. 122-5 2 et 3 a) du code de la proprit intellectuelle ne peut tre faite sans lautorisation expresse de Pearson Education France ou, le cas chant, sans le respect des modalits prvues larticle L. 122-10 dudit code.

Table des matires

Introduction 1 Les bases de JavaScript Comprhension de JavaScript (et de son histoire) Etablissement d'un systme de test Configuration de navigateurs Web Inclusion du code JavaScript Utilisation de fichier(s) JavaScript externe(s) Chargement dynamique de fichiers JavaScript Pseudo-URL dans JavaScript Excution de JavaScript avec des gestionnaires d'vnements Navigateurs sans JavaScript 2 Expressions communes Dtection du type de navigateur Vrification des capacits du navigateur Empcher la mise en cache Redirection du navigateur Rechargement de la page Cration d'un nombre alatoire

1 5 5 7 10 11 12 13 14 16 17 21 22 25 26 26 27 28

IV

JavaScript

Informations de date et d'heure Recherche avec des expressions rgulires Remplacement du texte Navigation dans l'historique d'un navigateur Affichage de la date de modification de la page Rcupration des paramtres GET Demande de confirmation l'utilisateur Demande de donnes utilisateur 3 Images et animations 39 Cration de boutons sensibles Prchargement d'images Animation des graphiques Etirement des graphiques Visualisation de l'tat de chargement de la page avec une barre de progression Visualisation du chargement de la page avec une barre de progression 4 CSS Accs aux styles CSS Accs aux classes CSS Accs aux feuilles de style individuelles Accs aux rgles de CSS individuelles Laisser disparatre le contenu d'un site Web Application de JavaScript aux slecteurs CSS Modification du curseur de la souris

28 32 33 33 34 34 36 36

40 43 45 46 48 49 53 54 56 57 58 61 64 66

Table des matires

DOM et DHTML DOM DHTML Accs des lments spcifiques Accs aux balises Dtermination des informations de nud Suppression d'lments Ajout d'lments Cration d'lments de texte Travail avec les attributs Clonage d'lments Remplacement d'lments Cration d'une liste puces partir de donnes JavaScript Cration d'un tableau partir de donnes JavaScript Modifications de fragments HTML Positionnement des lments Dplacement d'lments Cration d'une navigation toujours apparente Cration d'une publicit contextuelle en Flash

69 69 71 72 73 75 77 78 81 82 83 85 86 87 89 90 92 94 96 99 100 100 103 106 107 110 111 113

Programmation oriente objet et vnements Cration d'une classe Accs aux membres des classes Hritage de classes Extension d'objets JavaScript intgrs Raction aux vnements JavaScript Evnements de clavier Envoi d'un formulaire avec la touche Entre Evnements de souris

VI

JavaScript

Les cookies Les cookies Paramtrage des cookies Lecture des cookies Etablissement d'une date d'expiration Autres options de cookies Suppression de cookies Vrification de la prise en charge des cookies Enregistrement de plusieurs informations dans un cookie

117 118 120 121 124 125 126 127 129 131 132 133 135 136 137 139 142 145 145 146 149 149 152 153 155 155 157

Les formulaires Formulaires HTML avec JavaScript Accs aux champs de texte Accs aux cases cocher Accs des boutons radio Accs des listes de slection Accs une liste choix multiple Dsactivation des lments de formulaire Envoi d'un formulaire Empcher l'envoi Eviter les envois rpts de formulaires Donner le focus un champ Slection de texte dans un champ Vider les champs de texte en cas de clic Validation des champs de texte Validation de cases cocher Validation de boutons radio Validation des listes de slection

Table des matires

VII

Validation automatique d'un formulaire Implmentation de la navigation avec une liste de slection Implmentation d'une navigation hirarchique avec une liste de slection Dslection d'un ensemble de boutons radio Cration de listes de slection de date prremplies Cration de listes de slection de date de validation 9 Fentres et cadres Options de fentres Ouverture d'une fentre modale Dtermination de la taille de l'cran Dtermination de la taille de la fentre Redimensionnement d'une fentre Repositionnement d'une fentre Ouverture d'une fentre contextuelle centre Ouverture d'une fentre en plein cran Ouverture d'une nouvelle fentre dans un coin de l'cran Cration d'une carte de site Fermeture d'une fentre Vrification de la prsence d'un systme de blocage des fentres contextuelles Vrification de la prsence d'un systme de blocage des fentres Modification du contenu de deux cadres en mme temps Utilisation des cadres intgrs

159 163 164 167 167 169 173 174 177 179 180 182 183 184 186 186 188 189 190 191 194 197

VIII

JavaScript

10 Services Web Cration d'un service Web avec PHP Cration d'un service Web avec ASP.NET Appel d'un service Web partir d'Internet Explorer Appel d'un service Web partir d'un navigateur Mozilla Appel d'un service Web ASP.NET partir d'un navigateur Mozilla 11 AJAX et sujets annexes Initialisation d'une application AJAX Envoi d'une requte GET Envoi d'une requte POST Envoi d'une requte synchrone Rception de donnes multiples du serveur Interruption d'une requte HTTP Rcupration d'en-ttes HTTP Rception de XML en provenance du serveur Utilisation de JSON pour la (d)srialisation de donnes Cration d'un cran d'attente Rsolution du problme de signet Rsolution du problme du bouton Prcdent XSLT Utilisation d'une bibliothque XML Utilisation du service Web Yahoo!

199 202 204 205 208 211 213 215 217 219 220 222 224 225 226 231 232 235 236 238 241 244

Table des matires

IX

12 Mdias intgrs Accs aux mdias intgrs Vrification des modules complmentaires dynamiques Gestion des versions rcentes d'Internet Explorer Accs au contenu multimdia Accs au contenu Java Accs au contenu Flash Index

249 249 250 252 254 255 257 259

A propos de l'auteur
Christian Wenz est un orateur professionnel, auteur, formateur et consultant, spcialis dans les technologies du Web. Il a rdig ou a particip l'criture de plus de quarante ouvrages. Il collabore rgulirement des magazines d'informatique rputs et participe des confrences dans le monde entier. Christian Wenz a contribu l'laboration de plusieurs paquetages PHP dans le dpt PEAR et assure par ailleurs la maintenance d'un module Perl CPAN. Il a obtenu un diplme d'informatique l'universit technique de Munich, en Allemagne, o il vit et travaille actuellement. C'est galement le premier professionnel europen avoir obtenu la certification Zend et le principal fondateur du Consortium sur la scurit PHP.

Introduction
En 1999, j'ai crit un livre sur JavaScript. Au tout dbut, il s'est trs bien vendu, puis les ventes ont commenc diminuer. Elles se sont pourtant suffisamment stabilises pour parvenir la septime dition cet automne, mme si un lger dclin se faisait toujours sentir. Tout a considrablement chang la fin de l'anne dernire : les ventes ont soudain remont, tout comme celles des autres titres du mme segment. Cette volution tient en partie AJAX. La technologie en elle-mme n'est pas nouvelle mais le terme l'est. En fvrier 2005, Jesse James Garrett tablit l'acronyme ; depuis lors, le monde du Web semble comme pris de folie. Et mme s'il est possible d'expliquer AJAX en deux minutes, il faut une bonne connaissance des divers aspects de JavaScript pour le comprendre. Cela explique la demande croissante d'informations pousses sur JavaScript et a aussi men l'criture de ce Guide de survie JavaScript. Lorsque nous avons cr la srie d'ouvrages en 2005, nous c'est--dire Damon Jordan, Mark Taber et moi-mme, nous voulions crer une sorte de version adapte des lexiques de langue : ici, les phrases et les expressions communes sont traduites dans une langue trangre, le JavaScript. Mais la diffrence des lexiques ordinaires, cet ouvrage propose galement des explications sur le code. Sans cela, vous risqueriez fort de vous trouver dans des situations embarrassantes, quelle que soit la langue.

Introduction

Cet ouvrage n'est pas une introduction JavaScript. Les fonctions lmentaires y sont traites mais nous avons tent de mettre l'accent sur des informations de niveau intermdiaire avanc. L'ide est que, notamment si vos connaissances de JavaScript sont un peu rouilles, vous puissiez trouver les principaux problmes et leurs solutions dans cet ouvrage. Il vous servira donc de rfrence pour surmonter rapidement les problmes que vous rencontrez lors du dveloppement. N'hsitez pas le parcourir pour dcouvrir des fonctions JavaScript auxquelles vous n'auriez peut-tre pas pens auparavant. Ce livre n'est pas non plus un livre de recettes prsentant des solutions interminables et inflexibles des problmes sans importance. Notre objectif tait de limiter autant que possible les extraits de code pour une approche pratique. Cela vous permet d'adapter la technique prsente vos propres applications et un scnario spcifique. Pour y parvenir, nous ne prsentons que les lments de code essentiels l'exemple. Le code est gnralement constitu d'lments <script> et de quelques autres balises HTML pour lier le tout. Une application Web moderne doit au moins tre compatible avec le XHTML, mais ce n'est pas l'objet de notre ouvrage. Nous avons pris grand soin ce que le code fonctionne sur autant de navigateurs que possible. Et mme si Internet Explorer et diverses moutures de Mozilla (y compris Firefox) dominent le march, Opera, Safari et Konqueror y ont aussi leur place. Ainsi, mme si l'accent est mis sur les deux premiers types de navigateurs, nous prciserons les incompatibilits ou les problmes existant avec des navigateurs moins importants. Et en ce qui concerne les parts de march, seuls les navigateurs toujours actuels seront traits ; ainsi, nous ne ferons jamais mention des versions 4 de Netscape ou d'Internet Explorer.

Introduction

Les squences de code de ce titre ainsi que les mises jour se trouvent sur le site http://JavaScript.phrasebook.org/. Un nom est associ la plupart des listings, pour que vous puissiez rapidement retrouver les fichiers correspondant chaque extrait. Si vous souhaitez nous faire part de vos commentaires ou si vous rencontrez une erreur, faites-nous le savoir ! Si une expression que vous souhaitiez trouver n'est pas mentionne, n'hsitez pas nous contacter. Dites-nous si vous pensez des lments qui pourraient apparatre dans les prochaines ditions de cet ouvrage, mais vous pouvez galement nous faire part de celles qui vous semblent superflues. La liste des expressions potentielles tait bien plus longue que ce que nous avons conserv, nous avons donc d passer par une phase pnible qui a consist sacrifier du contenu ; nous esprons que le rsultat vous satisfera. Christian Wenz

1
Les bases de JavaScript
Ce chapitre traite de certaines bases concernant JavaScript. Il ne s'intresse pas explicitement la syntaxe du langage, un aspect abord dans suffisamment de didacticiels et d'ouvrages et qui n'entre pas dans l'objectif de cet ouvrage. Toutefois, nous expliquerons en dtail des aspects essentiels comme l'insertion de code JavaScript dans une page. Nous ferons galement un peu d'histoire et relaterons les faits de guerre des navigateurs pour vous prparer au chapitre suivant.

Comprhension de JavaScript (et de son histoire)


JavaScript est un langage de script ct client, ce qui signifie qu'il s'excute ct client, dans un navigateur Web. JavaScript peut aussi tre employ ct serveur et en dehors d'un navigateur, mais ce n'est pas l'objet de cet ouvrage. Si le navigateur est compatible, JavaScript donne

CHAPITRE 1 Les bases de JavaScript

accs la page en cours et permet au script de dterminer les proprits du client, de rediriger l'utilisateur vers une autre page, d'accder aux cookies, etc. JavaScript nat en septembre 1995, paralllement la sortie de la version 2.0 du navigateur Netscape, la premire tre dote du langage de script. A cette poque, le langage s'appelle Mocha puis, sa sortie, LiveScript ; Netscape conclut ensuite un accord marketing avec Sun (le crateur de Java) et dcide de renommer le langage en dcembre de cette anne, il devient JavaScript. Le concept connat immdiatement du succs : Microsoft en intgre une prise en charge dans Internet Explorer versions 3 et suivantes (au milieu de l'anne 1996). Pour des raisons lgales, une mouture de Microsoft du langage est alors appele JScript. JScript tait plus ou moins compatible avec JavaScript mais a commenc inclure des fonctions supplmentaires, spcifiques Internet Explorer (ce qui, quelques exceptions prs, ne s'est jamais vritablement install). En 1997, est publie la norme ECMAScript (ECMA-262) ; JavaScript en est donc la premire implmentation. La norme ne prcise que le langage et non les fonctions des htes environnants (par exemple, comment accder la fentre courante du navigateur ou en ouvrir une nouvelle). ECMAScript devient norme ISO en 1998. Aux alentours de 1997 ou 1998, la guerre des navigateurs entre Netscape et Microsoft atteint son apoge, les deux fournisseurs ajoutant une nouvelle fonctionnalit incompatible la version 5 de leurs navigateurs. Le reste n'est qu'histoire : Netscape abandonne l'ide de publier une version 5 du navigateur et dcide de tout recommencer avec Netscape 6 ; Internet Explorer peut ainsi augmenter ses parts de march, passant plus de 90 %.

Etablissement d'un systme de test

Il a d'ailleurs fallu plusieurs annes au projet Mozilla, alors en cours de cration, pour revenir la vie. A noter que le navigateur Firefox est fond sur Mozilla et commence alors gagner des parts de march sur Microsoft. Du point de vue de JavaScript, peu de choses ont volu au cours de ces dernires annes. Firefox 1.5, sorti fin 2005, prend en charge la nouvelle version JavaScript 1.6, mais les modifications sont assez limites et Internet Explorer est loin de les prendre en charge. Mais avec Internet Explorer 7 et Firefox 2.0 bientt paratre (et dj disponibles en version test), l'poque est intressante pour les dveloppeurs Web. D'autres navigateurs prennent en charge JavaScript. Les diffrences sont subtiles mais peuvent parfois tre trs embarrassantes lors du dveloppement avec une application Web indiffrente aux navigateurs. Parmi les navigateurs qui acceptent actuellement JavaScript, on trouve : b Internet Explorer ; b Mozilla et ses drivs (Firefox, Epiphany, Camino, Galeon, etc.) ; b Opera ; b Konqueror ; b Safari.

Etablissement d'un systme de test


Nous venons de le mentionner, plusieurs navigateurs acceptent JavaScript. Il faut gnralement assurer une prise en charge pour la plupart d'entre eux. Ainsi, par exemple, le site Web http://marketshare.hitslink.co/ report.apsx?qprid=3 montre qu'en mars 2006, Internet

CHAPITRE 1 Les bases de JavaScript

Explorer et Firefox ensemble comptaient pour prs de 95 % de la part de march des navigateurs, suivis par Safari (un peu plus de 3 %). Les navigateurs Netscape dtenaient environ 1 % et Opera 0,5 %, peu prs la mme chose que tous les autres navigateurs runis (y compris Konqueror). Quelle est donc la meilleure stratgie pour tester un site Web sur un maximum de systmes, avec le moins d'efforts possible ? En fait, tout dpend du public auquel s'adresse votre site Web. Si vous ciblez principalement des utilisateurs de Mac, vous devrez procder un test important sur le navigateur Safari, puisqu'il est livr par dfaut avec les versions rcentes de Mac OS X. Quel que soit le type de site Web utilis, Internet Explorer bnficie toujours d'une trs forte part de march, mme sur des sites Web plutt centrs sur l'open source. Pour le test, il vous faut donc Internet Explorer et un systme Windows (ou au moins un lment du style Virtual PC ou VMware, avec une machine virtuelle Windows). Tous les navigateurs Mozilla partagent la mme base de code pour le rendu et pour JavaScript, peu importe donc la plate-forme que vous utilisez (mme s'il existe des diffrences minimes). Vous pourriez, par exemple, utiliser Firefox sur la machine Windows sur laquelle rside galement votre installation Internet Explorer. Opera s'excute aussi sous Windows (et quelques autres systmes, notamment Linux et Mac), la part de Windows comprend donc un navigateur de plus. Les deux seuls grands navigateurs restants sont Safari et Konqueror, ce dernier tant le navigateur par dfaut pour l'utilisation du gestionnaire de fentres KDE.

Etablissement d'un systme de test

Par chance, tous deux partagent plus ou moins la mme base de code : Safari utilise le moteur KHTML, au cur du rendu de Konqueror. Deux options sont alors possibles : b tablir une bote Linux (ou une machine virtuelle Linux) avec KDE et Konqueror ; b tablir un systme Mac (ou acheter un Mac Intel avec BootCamp pour avoir un double dmarrage sous Windows et OS X). Vous devriez ainsi obtenir un bon systme pour commencer le test. Plus le site Web grandit, plus grand sera le nombre des systmes cible que vous devrez prendre en charge ; partir d'un certain point, vous n'aurez pas d'autre choix que d'installer et de tester tous les navigateurs que vous souhaitez utiliser. En ce qui concerne Internet Explorer, la version 6 est la principale, la version 5.x a presque disparu et les versions 4 et antrieures n'existent plus depuis longtemps. Le test sous IE 6 convient donc la plupart du temps. Disposer de versions diffrentes est bien entendu assez souhaitable mais ncessite gnralement un systme Windows pour chacun d'entre eux, Windows ne pouvant tre install qu'une fois sur un systme. Une solution a t dcouverte par accident, pour l'installation parallle de plusieurs versions d'IE. Vous en trouverez la description originale l'adresse http://labs.insert-title .com/labs/Multiple-IEs-in-Windows_article795.aspx et de plus amples informations l'adresse http://www .positioniserything.net/articles/multiIE.html. Enfin, testez votre site Web lorsque JavaScript est activ et dsactiv dans les navigateurs.

10

CHAPITRE 1 Les bases de JavaScript

Conguration de navigateurs Web


Par dfaut, la plupart des navigateurs Web activs pour JavaScript prennent en charge ce langage. D'ailleurs, la toute premire version de Netscape accepter JavaScript ne disposait mme pas d'une fonction pour le dsactiver ! Il est toutefois possible de le dsactiver, vous devez donc trouver comment simuler cette situation (et comment demander aux utilisateurs de l'activer). Cela dpend non seulement des navigateurs utiliss mais parfois aussi de la version du navigateur. Dans le navigateur Firefox 1.5, JavaScript peut tre activ dans le menu Outils, Options, Contenu, Activer JavaScript. Sous Internet Explorer 6, vous devez creuser un peu plus. Cliquez sur Outils, Options Internet, Scurit, zone Internet, Personnaliser le niveau, Script, Active Scripting, Activer.
Astuce Internet Explorer versions 6.0 et 7.0 (sous Windows XP, 2003 et Vista uniquement) possde une fonction de scurit qui empche l'excution de JavaScript sur les pages locales (voir la Figure 1.1). Cela est en fait assez utile mais peut se rvler ennuyeux lorsque vous testez une application. Il existe deux contournements : utilisez un serveur Web local pour tester votre application ou dsactivez simplement le message d'erreur en choisissant Outils, Options Internet, Avanc, Scurit, Autoriser le contenu actif s'excuter dans les fichiers de la zone Ordinateur local.

Inclusion du code JavaScript

11

Figure 1.1 : Message d'erreur assez ennuyeux avec JavaScript sur les pages locales.

Inclusion du code JavaScript


<script type="text/JavaScript"> window.alert("Welcome to JavaScript!"); </script>

Le code JavaScript peut se prsenter de deux manires : intgr dans une page HTML ou intgr dans un fichier externe. La manire la plus frquente de l'inclure consiste utiliser les lments <script>. Vous pouvez le placer n'importe o, il est alors excut aprs que cette partie de la page HTML a t charge et analyse. Le code qui prcde (ficher script.html dans l'archive tlcharger) ouvre une fentre modale et affiche un texte plutt simple. L'attribut type prvoit le type MIME pour JavaScript. Prcdemment, on utilisait language="JavaScript" ; toutefois, puisque ce n'tait pas standardis, il vaut mieux utiliser type et le type MIME la place. Dans cet ouvrage, nous suivons la mthode adopte par de nombreux sites Web de nos jours : on utilise la fois type et language.

12

CHAPITRE 1 Les bases de JavaScript

De mme, par le pass, il tait possible de cibler un script sur un numro de version spcifique de JavaScript, comme ceci : <script language="JavaScript1.6"> window.alert("Only with JavaScript 1.6 !"); </script> Ce n'est quasiment plus usit. L'implmentation de cette fonction gnre un certain nombre de bogues dans les navigateurs, et il existe de meilleures manires de tester les capacits JavaScript d'un navigateur.
Info Dans certains anciens didacticiels, vous trouverez des conseils pour utiliser les commentaires HTML prsents de la faon suivante :

<script language="JavaScript"><!-// ... //--></script>


Cela servait auparavant grer les navigateurs qui ne savaient rien de JavaScript. Or, mme ceux qui n'acceptent pas JavaScript connaissent l'lment <script> et savent l'ignorer (lui et son contenu). Ces commentaires HTML ne sont donc plus ncessaires.

Utilisation de chier(s) JavaScript externe(s)


<script language="JavaScript" type="text/JavaScript" src="script.js"></script>

Il est trs pratique d'utiliser un fichier JavaScript externe (ou plusieurs), notamment lorsque vous rutilisez du code JavaScript dans votre site Web. Il ne contient que le

Chargement dynamique de fichiers JavaScript

13

code JavaScript et pas d'lments <script>. Un lment <script> est toutefois utilis pour le charger, comme on le voit dans le listing prcdent (fichier scriptsrc.html). L'attribut src contient l'URL du script externe ; les URL absolues (et donc les serveurs distants) sont galement possibles.
Attention Sachez que le code du fichier externe n'est disponible qu'aprs le chargement complet du fichier externe. Ainsi, notamment lorsque vous appelez cette fonctionnalit du fichier externe partir de la page locale, n'oubliez pas que le fichier externe risque de ne pas tre encore disponible.

Chargement dynamique de chiers JavaScript


var s = document.createElement("script");

Il est parfois ncessaire de charger du code JavaScript la demande, alors mme qu'un site s'excute. Par exemple, selon ce que saisit l'utilisateur, il faudra peut-tre charger un fichier JavaScript externe. Une manire consiste utiliser document.write() pour ajouter dynamiquement un nouvel lment <script> la page, mais cela ne fonctionne pas avec certains navigateurs et n'est donc pas recommand. Une bien meilleure solution consiste utiliser DOM (voir Chapitre 5). Vous crez d'abord un nouvel lment <script> et dfinissez les attributs appropris. Vous ajoutez ensuite cet lment au DOM de la page. Le code est gnralement plac dans la section <head>. Le listing suivant montre l'ensemble du code ;

14

CHAPITRE 1 Les bases de JavaScript

notez qu'il y a un lment <head> pour faire fonctionner le code. La Figure 1.2 montre le rsultat de ce code.
<html> <head> <title>JavaScript</title> </head> <body> <script language="JavaScript" type="text/JavaScript"> var s = document.createElement("script"); s.setAttribute("type", "text/JavaScript"); s.setAttribute("language", "JavaScript"); s.setAttribute("src", "script.js"); document.getElementsByTagName("head")[0].appendChild(s); </script> </body> </html>
Ajout dynamique d'un script (scriptdynamic.html)

Pseudo-URL dans JavaScript


<a href="JavaScript:window.alert('Welcome to JavaScript!'); ">click here for a surprise</a>

Une autre manire d'appeler du code JavaScript consiste utiliser une pseudo-URL. Lorsqu'une URL qui commence par JavaScript: est charge, le code qui se trouve derrire est excut, comme on le voit dans le code prcdent (fichier url.html). Il existe plusieurs manires d'utiliser cette URL, sous la forme d'une image, d'un lien ou d'une CSS (Cascading Style Sheets, feuilles de style en cascade) mais on utilise gnralement un lien. Sachez toutefois que ce lien fonc-

Pseudo-URL dans JavaScript

15

Figure 1.2 : La fentre modale provient du chier externe qui a t charg de manire dynamique.

tionne uniquement avec un navigateur compatible JavaScript et sur lequel il est activ.
Attention Lorsque le code suivant le prfixe d'URL JavaScript: renvoie quelque chose, le rsultat est affich l'cran, ce qui n'est gnralement pas souhaitable. Vous pouvez utiliser la fonction spciale de JavaScript void() pour l'viter :

JavaScript:void(code_qui_renvoie_quelquechose());

16

CHAPITRE 1 Les bases de JavaScript

Excution de JavaScript avec des gestionnaires d'vnements


<body onload="showText();">

La troisime manire d'excuter du code JavaScript (les deux premires tant les lments <script> et les pseudo-URL JavaScript:) se fait par l'intermdiaire d'un gestionnaire d'vnements. La plupart des lments HTML acceptent quelques vnements ; par exemple, la balise <body> accepte l'lment de chargement. En utilisant le prfixe on, vous pouvez joindre le code cet vnement (vous trouverez plus d'options au Chapitre 6, "Programmation oriente objet et vnements"). Ainsi, le code suivant excute la fonction showText() aprs que le document a t totalement charg (par rapport au marquage HTML de la page, et non des images ou d'autres donnes externes).
<html> <head> <title>JavaScript</title> <script language="JavaScript" type="text/JavaScript"> function showText() { window.alert("Welcome to JavaScript!"); } </script> </head> <body onload="showText();"> </body> </html>
Utilisation d'un gestionnaire d'vnements JavaScript (event.html)

Navigateurs sans JavaScript

17

Attention Une erreur commune consiste croire que le prfixe URL JavaScript: peut tre utilis avec les gestionnaires d'vnements, de la manire suivante :

<body onload="JavaScript:showText();">
Mais c'est une lgende : en effet, pourrait-il en tre autrement si le code JavaScript ne pouvait avoir la valeur d'un attribut de gestionnaire d'vnements ? Omettez donc JavaScript: et fournissez simplement le code excuter lorsque l'vnement associ est dclench.

Navigateurs sans JavaScript


<script type="text/JavaScript"> document.write("Welcome to JavaScript!"); </script> <noscript> Welcome to plain HTML! </noscript>

Selon des tudes rcentes, jusqu' 10 % des utilisateurs ont dsactiv JavaScript dans leurs navigateurs, du fait des rglements des entreprises, de la crainte des vulnrabilits de scurit et pour d'autres raisons. Vous devez donc vous assurer que votre site Web puisse tre utilis galement sans JavaScript. Pour y parvenir, vous pouvez utiliser l'lment <noscript>. Les navigateurs dans lesquels JavaScript est activ ignorent cet lment et son contenu, tandis que ceux dans lesquels il est dsactiv en affichent le contenu. Le code qui prcde (fichier noscript.html) gnre le rsultat prsent la Figure 1.3 lorsqu'on utilise un navigateur sans JavaScript (comme le navigateur texte Lynx) ; la Figure 1.4 montre un navigateur qui prend en charge le langage de script.

18

CHAPITRE 1 Les bases de JavaScript

Figure 1.3 : Le code prcdent dans un navigateur sans JavaScript.

Figure 1.4 : Le code prcdent dans un navigateur avec JavaScript.

Navigateurs sans JavaScript

19

Lorsque JavaScript est utilis avec des liens, l'extrait suivant ne fonctionne pas comme prvu :
<a href="#" onclick="window.alert('Welcome to JavaScript!'); ">click here</a>

A premire vue, tout est correct : les utilisateurs possdant JavaScript obtiennent la fentre modale, ceux qui ne l'ont pas cliquent sur un lien menant vers une tiquette de texte vide ; rien d'inattendu ne survient. Toutefois, cela prsente un petit inconvnient : lorsque l'utilisateur a cliqu sur le lien JavaScript, un navigateur activ pour JavaScript affiche la fentre, mais suit tout de mme le lien. Gnralement, cela n'a aucun effet, mais le navigateur passe en haut de la page car l'tiquette de texte n'a pas t trouve. Pour viter cela, vrifiez simplement que le code du gestionnaire d'vnements renvoie false. Cela annule tous les autres effets que l'vnement actuel peut avoir ; ici, le lien ne sera pas suivi :
<a href="#" onclick="window.alert('Welcome to JavaScript!'); return false;">click here</a>
Eviter que les navigateurs activs pour JavaScript suivent le lien (link.html)

2
Expressions communes
Certaines tches JavaScript rcurrentes doivent tre ralises quasiment chaque jour. Elles sont la base de nombreuses applications JavaScript mais n'entrent dans aucune catgorie particulire. Nous prsentons donc au cours de ce chapitre une suite de problmes frquents, avec leurs solutions.

22

CHAPITRE 2 Expressions communes

Dtection du type de navigateur


window.alert(navigator.appName);

Mme si les implmentations de navigateurs par JavaScript sont, de nos jours, assez compatibles les unes avec les autres (en particulier si on se souvient de l'poque de la guerre des navigateurs, la fin des annes 1990), la dtection du type de navigateur constitue une partie essentielle de la bote outils du dveloppeur JavaScript. L'objet JavaScript navigator propose des informations sur le navigateur. Sa proprit userAgent, qui contient la chane d'identification complte du navigateur, est trs utile mais parfois difficile analyser. Elle est aussi envoye dans l'en-tte User-Agent HTTP de chaque requte. Pour dterminer simplement le type d'un navigateur, il suffit d'employer la proprit appName, comme le montre le code prcdent. Le Tableau 2.1 contient les valeurs appName des navigateurs les plus importants.
Tableau 2.1 : Valeurs appName pour divers navigateurs
Navigateur

appName Microsoft Internet Explorer Netscape Konqueror Netscape Opera

Internet Explorer Navigateurs Mozilla Konqueror (KDE) Apple Safari Navigateur Opera

Dtection du type de navigateur

23

Vous le voyez, le navigateur Safari renvoie un nom incorrect. Pour contrebalancer cet effet, vous pouvez rechercher navigator.userAgent pour certains types de navigateurs. Et puisque le navigateur Opera risque d'tre mal identifi (bien qu'il stocke "Opera" dans navigator.userAgent), il convient de le vrifier en premier.
<script language="JavaScript" type="text/JavaScript"> var uA = navigator.userAgent; var browserType = "unknown"; if (uA.indexOf("Opera") > -1) { browserType = "Opera"; } else if (uA.indexOf("Safari") > -1) { browserType = "Safari"; } else if (uA.indexOf("Konqueror") > -1) { browserType = "Konqueror"; } else if (uA.indexOf("Gecko") > -1) { browserType = "Mozilla"; } else if (uA.indexOf("MSIE") > -1) { browserType = "Internet Explorer"; } window.alert(browserType); </script>
Dtermination du type de navigateur (browser.html)

Avec quelques efforts de plus, ce script peut tre prolong pour distinguer les drivs de Mozilla (Firefox, Epiphany, Galeon, Camino, SeaMonkey, etc.).

24

CHAPITRE 2 Expressions communes

Dtection du numro de version du navigateur


Pour dterminer le numro de version du navigateur, il existe plusieurs manires. La plupart du temps, vous devez rechercher navigator.userAgent, ce qui peut ressembler ceci :
Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.8.0.3) Gecko/20060426 Firefox 1.5.0.3 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030619 Netscape/7.1 (ax) Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727) Mozilla/5.0 (compatible; Konqueror/3.4; FreeBSD) KHTML/3.4.2 (like Gecko) Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418 (KHTML, like Gecko) Safari/417.9.3 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.8 (KHTML, like Gecko) Safari/312.6 Opera/9.00 (Windows NT 5.1; U; en) Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1 en) Opera 9.00

Vous le voyez, selon le type du navigateur, le numro de version est enfoui ailleurs dans la valeur de navigator.userAgent. Vous aurez alors la tche fastidieuse de traiter tous les navigateurs et de vous tenir au courant des nouvelles mthodes. Il existe toutefois quelques ressources Web pour implmenter une dtection des navigateurs et qui sont assez bien faites. Vous trouverez de la documentation et des codes sur ces sites Web : http://www.webreference.com/tools/browser/ JavaScript.html ; http://www.gemal.dk/browserspy/basic.html.

Vrification des capacits du navigateur

25

Vrication des capacits du navigateur


if (document.getElementById) { // ...

Vous le voyez dans l'exemple prcdent, se fier aux numros de version des navigateurs n'est pas seulement difficile, c'est galement gager les possibilits d'volution. Il vaut mieux vrifier spcifiquement la prise en charge des objets spciaux. Par exemple, pour utiliser DOM (voir Chapitre 5, "DOM et DHTML"), vous pourrez tenter d'utiliser le code prcdent. Si la mthode getElementById() est implmente, document.getElementById (sans parenthses) renvoie une rfrence la fonction. Si elle est utilise dans une condition, elle renvoie true. Le code associ est alors excut. Autre exemple : Internet Explorer accepte les objets ActiveX pour certaines applications, par exemple la prise en charge du XML. Toutefois, seules les versions Windows de IE connaissent ActiveX. La vrification systmatique pour Internet Explorer gnre donc des problmes pour les utilisateurs de Mac. Ds lors, si vous vrifiez spcifiquement la prise en charge d'ActiveX, vous viterez ces problmes :
if (window.ActiveXObject) { // ... }

26

CHAPITRE 2 Expressions communes

Empcher la mise en cache


document.write("<img src=\"image.png?" + Math.random() + "\" />");

Grce aux en-ttes ct serveur, il est possible d'viter la mise en cache d'images de type "contenu dynamique" ainsi que de pages HTML. Mais, la mthode n'est pas infaillible, puisque certains navigateurs ou serveurs proxy peuvent ignorer ces paramtres. Pour y remdier, ajoutez un paramtre de chane de requte insignifiant l'URL, comme dans l'extrait suivant : Math.random() renvoie un nombre alatoire compris entre 0 et 1, par exemple 0,1296601696732852. L'annexer une image ne modifie gnralement pas les donnes envoyes du serveur, mais la requte est totalement nouvelle pour le navigateur. L'image (ou les autres donnes) n'est donc pas mise en cache.

Redirection du navigateur
location.href = "newPage.html";

La proprit location.href permet un accs en lecture et en criture l'URL de la page en cours. Consquence, rgler location.href sur une autre valeur redirige le navigateur, qui charge alors la nouvelle page, comme le montre le code prcdent. La page prcdente arrive ensuite dans l'historique du navigateur. Si vous souhaitez remplacer l'ancienne page dans l'historique (pour que le bouton Prcdent ne fonctionne pas comme l'on s'y attendrait ici), utilisez la mthode location.replace() :
location.replace("newPage.html");

Rechargement de la page

27

Astuce Cela peut galement tre ralis avec du HTML :

<meta http-equiv="Refresh" content="X; URL=Y" />


L'emplacement X dsigne le nombre de secondes patienter avant que la nouvelle page ne soit charge ; Y indique la nouvelle URL.

Rechargement de la page
location.reload();

La mthode reload() de l'objet location recharge la page en cours, l'quivalent de location.href = location.href. Si vous apportez le paramtre true, la mise en cache est dsactive et le navigateur procde un rechargement "dur" partir du serveur. Toutefois, ce n'est pas non plus infaillible puisqu'il peut exister un serveur proxy, plac entre deux, qui peut disposer d'une copie en cache de la page demande. Vous pourriez donc utiliser la technique dcrite dans ce chapitre et qui consiste empcher la mise en cache :
location.search = "?" + Math.random();

L'expression modifie la chane de requte (location.search) de la page en cours, en rechargeant efficacement le reload() de l'URL.

28

CHAPITRE 2 Expressions communes

Cration d'un nombre alatoire


var rand = min + Math.floor((max min + 1) * Math.random());

La mthode random() de l'objet Math calcule un nombre pseudo-alatoire entre 0 et 1 (non compris). On prfre gnralement un nombre alatoire compris entre 1 et 10 par exemple. Avec un petit calcul mathmatique, l'opration est possible. Pour l'exemple, multipliez le rsultat de Math.random() par 10, ce qui gnre bien un nombre entre 0 et 10 (exclus). Si vous arrondissez ensuite cette valeur, vous obtenez un nombre entier compris entre 0 et 9 (inclus). Ajoutez 1 et vous obtenez un nombre compris entre 1 et 10. Le code qui prcde gnralise cette option et cre un nombre compris entre min et max.

Informations de date et d'heure


var d = new Date(); var mdy = (d.getMonth()+1) + "/" + d.getDate() +

L'objet Date de JavaScript permet d'accder la date du jour et peut aussi effectuer certains calculs de date (en utilisant la valeur "epoch", c'est--dire le nombre de millisecondes depuis le 1er janvier 1970). Le Tableau 2.2 contient les mthodes les plus importantes de la classe Date. Le code qui prcde cre une date au format mois/jour/anne.

Informations de date et d'heure

29

Tableau 2.2 : quelques proprits de Date


Mthode Description

getDate() getFullYear() getHours() getMinutes() getMonth() getSeconds() getTime()

Jour du mois Anne quatre chiffres Heures Minutes Mois moins 1 (!) Secondes Valeur "epoch" (date de dbut de mesure du temps sur un systme d'exploitation) Reprsentation en chane Reprsentation en chane UTC

toString() toUTCString()

30

CHAPITRE 2 Expressions communes

Comprendre les expressions rgulires


Les expressions rgulires sont, pour le dire simplement, des motifs qui peuvent tre mis en correspondance avec des chanes. Un motif dans une expression rgulire contient une chane sur laquelle peut porter une recherche dans une chane plus importante. Mais cela peut aussi tre ralis (plus rapidement) en utilisant indexOf(). L'avantage des expressions rgulires rside dans le fait que certaines fonctions spciales, comme les caractres de remplacement, sont disponibles. Le Tableau 2.3 prsente quelques caractres spciaux, accompagns de leurs signications.
Tableau 2.3 : Caractres spciaux dans les expressions rgulires
Caractre spcial Description Exemple

^ $ ?

Dbut de la chane Fin de la chane 0 ou 1 fois (fait rfrence au caractre ou l'expression prcdent) 0 fois ou plus (fait rfrence au caractre ou l'expression prcdent) 1 ou plusieurs fois (fait rfrence au caractre ou l'expression prcdent)

^a dsigne une chane qui commence par a a$ dsigne une chane qui se termine par a ab? signifie a ou ab

ab* signifie a ou ab ou abb ou ab+ signifie ab ou abb ou abbb ou

Comprendre les expressions rgulires

31

Tableau 2.3 : Caractres spciaux dans les expressions rgulires (suite)


Caractre spcial Description Exemple

[] - (utilis entre crochets) ^ (utilis entre crochets) |

Caractres alternatifs Une suite de valeurs

PHP[45] signifie PHP4 ou PHP5 ECMAScript [3-5] signifie ECMAScript 3 ou ECMAScript 4 ou ECMAScript 5 [^A-C] dsigne D ou E ou F ou ECMAScript 3|ECMAScript 4 dsigne ECMAScript 3 ou ECMAScript 4, tout comme ECMAScript (3|4) (a)(b) signifie ab, mais avec deux sous-motifs (a et b) . signifie a, b, c, 0, 1, 2, $, ^, a {1, 3} signifie a, aa ou aaa. a{,3} signifie une chane vide, a, aa ou aaa. a{1,} signifie a, aa, aaa, \. dsigne .

Correspond tout sauf aux caractres suivants Motifs alternatifs

(...)

Dfinit un sous-motif

N'importe quel caractre

{min, max}

Nombre minimal et maximal d'occurrences ; si min ou max est omis, cela signifie 0 ou infinite
Echappement du caractre suivant

D'autres caractres spciaux et expressions sont disponibles, notamment le caractre qui fait rfrence un chiffre (\d).

32

CHAPITRE 2 Expressions communes

Recherche avec des expressions rgulires


zip.test("Indianapolis, IN 46240");

La dfinition d'une expression rgulire dans JavaScript peut s'effectuer de deux manires : b var zip = new RegEx("\\d{5}"); b var zip = /\d{5}/; Il n'y a pas de diffrence fonctionnelle entre les deux ; vous devez simplement prendre en compte l'chappement du caractre. La mthode test() de l'expression vrifie ensuite si une chane contient l'expression rgulire :
var found = zip.test("Indianapolis, IN 46240"); //vrai

Pour obtenir la correspondance relle, utilisez la fonction exec(). La mthode renvoie un tableau. Son premier lment est la correspondance entire et les lments suivants sont toutes les sous-correspondances (si on utilise des parenthses dans l'expression rgulire).
var matches = zip.exec("Indianapolis, IN 46240"); // ["46240"]
Astuce La mthode match() renvoie toutes les correspondances ; exec() ne renvoie que l'expression courante, gnralement la premire. Toutefois, si vous appelez exec() plusieurs fois, toutes les correspondances sont renvoyes.

Remplacement du texte

33

Remplacement du texte
var address = /(\w+), ([A-Z]{2}) (\d{5})/; var sams = "Indianapolis, IN 46240"; var result = sams.replace(address, "$3 $1, $2");

La mthode replace(), que prend en charge chaque chane JavaScript, peut remplacer du texte. Elle recherche une expression rgulire et remplace la chane trouve par une autre chane. Dans cette chane de remplacement, il est possible de procder une rfrence de retour sur les souscorrespondances. $0 pointe vers la premire correspondance, $1 rfrence la premire sous-correspondance (sans parenthses), $2 la deuxime sous-correspondance, etc. Le code qui prcde recherche la ville, l'Etat des Etats-Unis et le code postal, puis les ragence. Le rsultat est "46240 Indianapolis, IN".

Navigation dans l'historique d'un navigateur


window.history.back(); window.history.forward();

L'historique du navigateur est reprsent par l'objet history (une proprit de l'objet window) et contient une liste de pages Web visites pralablement (et, si possible aprs) la page en cours. Et mme s'il est techniquement possible de dplacer quelques lments d'historique, les contraintes

34

CHAPITRE 2 Expressions communes

de scurit ne laissent qu'une manire pratique de procder : reculer d'une page et avancer d'une page. Les deux mthodes suivantes l'implmentent : b back() passe la page prcdente de l'historique (comme le fait le bouton Prcdent). b forward() passe la page suivante de l'historique (comme le fait le bouton Suivant).

Afchage de la date de modication de la page


document.write(document.lastModified);

Ds qu'un serveur Web envoie une ressource au client, il envoie galement la date laquelle le document a t modifi pour la dernire fois. Gnralement, le serveur Web extrait ces informations du systme de fichiers, mais cet en-tte peut aussi tre modifi ou tout simplement ne pas tre envoy. De toutes les faons, vous pouvez utiliser ces informations, par exemple comme c'est indiqu dans le code prcdent. Vous pouvez donc disposer d'une date de modification plus ou moins raliste sur votre page.

Rcupration des paramtres GET


var ls = location.search.substring(1); var namevalue = ls.split("&");

Habituellement, les informations GET sont values ct serveur mais JavaScript a galement accs ces informations via sa proprit location.search. Toutefois, les donnes qui s'y trouvent rsident dans des paires nom-valeur.

Rcupration des paramtres GET

35

Le code suivant dcode ces donnes en utilisant la mthode split() de JavaScript. Le tableau associatif qui en rsulte est ensuite prsent, simplement pour montrer qu'il fonctionne comme on s'y attend ; reportez-vous la Figure 2.1 pour connatre le rsultat.
<script language="JavaScript" type="text/JavaScript"> var getdata = []; if (location.search.length > 1) { var ls = location.search.substring(1); var namevalue = ls.split("&"); for (var i=0; i<namevalue.length; i++) { var data = namevalue[i].split("="); getdata[data[0]] = data[1]; } } var s = ""; for (var el in getdata) { s += el + ": " + getdata... + "\n"; } alert(s); </script>
Analyse de la chane de requte (querystring.html)

Figure 2.1 : Les donnes de la chane de requte sont analyses et afches.

36

CHAPITRE 2 Expressions communes

Demande de conrmation l'utilisateur


<a href="anyPage.html" onclick="return window.confirm('Do you really want to do this?');">Click here</a>

JavaScript propose une prise en charge limite des fentres modales. La mthode window.alert() est assez commune mais il existe d'autres options. Avec window.confirm(), l'utilisateur se voit prsenter une fentre de type Oui/Non. S'il clique sur Oui, window.confirm() renvoie true, et false dans le cas contraire. Le code qui prcde (fichier confirm.html) l'utilise comme valeur de retour pour un lien. Ainsi, si l'utilisateur clique sur Non, le navigateur ne suit pas le lien.
Attention Sachez que cette bote de dialogue est traduite par les navigateurs, vous devez donc viter d'inscrire un texte du style "Cliquez sur Oui pour..." car les personnes disposant d'un systme tranger risquent de ne pas voir s'afficher de bouton Oui.

Demande de donnes utilisateur


var name = window.prompt("Enter your name!", "<Your name>");

La mthode window.prompt() permet aux utilisateurs de saisir du texte dans un champ de texte d'une seule ligne (voir Figure 2.2). Ces informations correspondent la valeur de retour de l'appel de mthode et peuvent ensuite tre utilises dans le script.

Demande de donnes utilisateur

37

<script language="JavaScript" type="text/JavaScript"> var name = window.prompt("Enter your name!", "<Your name>"); if (name != null) { window.alert("Hello, " + name + "!"); } </script>
Demande de donnes utilisateur (prompt.html)

Figure 2.2 : La bote de saisie gnre par window.prompt().

Info Sachez que si l'utilisateur clique sur le bouton Annuler ou appuie sur la touche d'chappement, window.prompt() renvoie null. Le code qui prcde vrifie que, si l'utilisateur clique sur le bouton OK, les donnes saisies sont affiches.

3
Images et animations
Aux dbuts du Web, l'un des premiers effets obtenus avec JavaScript concernait la manipulation d'images, avec, par exemple, les images sensibles : l'utilisateur dplace le pointeur de la souris sur une image qui change alors d'apparence. Netscape a introduit l'accs JavaScript pour les images dans son navigateur version 3. A l'poque, Internet Explorer 3 pour Windows en tait sa version bta, il tait donc trop tard pour y intgrer cette fonctionnalit. En revanche, Internet Explorer 3 pour Macintosh, sorti aprs la version Windows, a pu bnficier de l'accs aux images JavaScript. Internet Explorer pour Windows a attendu la version 4 pour pouvoir accder son tour aux images. Cela permet d'obtenir non seulement de jolis effets graphiques, mais aussi des applications plus sophistiques, comme les diaporamas.

40

CHAPITRE 3 Images et animations

Cration de boutons sensibles


<img src="inactive.gif" onmouseover="this.src='active.gif';" onmouseover="this.src='inactive.gif';" />

L'un des plus anciens effets du World Wide Web consiste modifier l'apparence d'un graphique lorsque le curseur de la souris passe dessus. Aussi appele "effet de survol", cette technique s'obtient avec la pseudo-classe CSS hover non standard, prise en charge par certains navigateurs. Pour modifier un graphique, il faut d'abord y accder, puis modifier sa proprit src. A noter que les navigateurs acceptent plusieurs mthodes pour accder aux graphiques, mais les exemples suivants fonctionnent en toute cohrence dans les navigateurs modernes : b Dfinir l'attribut name de l'image et y accder via document.images["name"].

b Dfinir l'attribut name de l'image et y accder via document.images.name (certains caractres spciaux comme les espaces ou les tirets ne sont pas autoriss dans l'attribut name). b Accder l'image en utilisant sa position dans la page, via le tableau document.images : document.images[0] pour la premire image, document.images[1] pour la deuxime image, etc. b Dfinir l'attribut id de l'image et y accder via document.getElementById("id"). L'vnement qui se dclenche lorsque le curseur passe sur une image s'intitule mouseover. Il faut alors rinitialiser l'image sur son tat d'origine. Le code qui prcde y parvient et place le tout dans l'lment <img> ; vous pourriez

Cration de boutons sensibles

41

galement utiliser une fonction JavaScript personnalise gnrique. Le code suivant cre une fonction qui attend le nom de l'image et son URL dans une fonction, puis l'appelle en utilisant onmouserover/onmouseout :
<script language="JavaScript" type="text/JavaScript"> function changeImage(name, url) { if (document.images[name]) { document.images[name].src = url; } } </script> <img name="myImage" src="inactive.gif" onmouseover="changeImage('myImage', 'active.gif');" onmouseout="changeImage('myImage', 'inactive.gif');" />
Un bouton de survol (hover.html)

La Figure 3.1 montre deux boutons : le pointeur de la souris se trouve sur celui de droite.
Attention Les anciens navigateurs (y compris Netscape 4.x) ne prennent pas en charge onmouseover/onmouseout pour des lments autres que les liens. Dans ce cas, vous devez intgrer l'image dans un lien HTML et utiliser onmouserover/onmouseout dans la balise <a> :

<a href="#" onmouseover="..." onmouseout=""> <img src="..." /> </a>

42

CHAPITRE 3 Images et animations

Figure 3.1 : Les boutons changent d'aspect lorsque le pointeur passe dessus.

Prchargement d'images

43

Prchargement d'images
var i = new Image(); i.src = "";

Mme si l'effet de survol du curseur, mentionn la section prcdente, est facile mettre en place et joli regarder, il prsente un inconvnient structurel. Lorsque le pointeur passe sur une image, le graphique de remplacement est charg partir du serveur, ce qui peut tre assez long et gner les utilisateurs. Il est donc souhaitable de prcharger ces images une fois que la page elle-mme a t charge. Avec JavaScript, vous pouvez demander au navigateur de le faire. Elles sont alors places dans son cache ( moins que la mise en cache ne soit dsactive dans le navigateur ou que le serveur Web n'envoie des en-ttes HTTP interdisant la mise en cache locale) et charges instantanment lorsque l'effet de survol est dclench. Pour parvenir cet effet, vous devez instancier l'objet Image de JavaScript et rgler sa proprit src. L'opration charge l'image en arrire-plan, sans mme l'afficher. Il faut alors simplement vrifier que le prchargement est excut lorsque la page HTML a t totalement charge, comme le montre le listing suivant :
<script language="JavaScript" type="text/JavaScript"> function preloadImage(url) { var i = new Image(); i.src = url; } </script> <body onload="preloadImage('active.gif');"> </body>
Prchargement d'images (preload.html)

44

CHAPITRE 3 Images et animations

Si plusieurs images doivent tre prcharges simultanment (par exemple si les lments de navigation emploient un effet de survol), vous pouvez utiliser une fonction plus gnrique acceptant un tableau avec des images :
<script language="JavaScript" type="text/JavaScript"> function preloadImages(urls) { var img = new Array(); for (var i=0; i<urls.length; i++) { img[img.length] = new Image(); img[img.length - 1].src = urls[i]; } } window.onload = function() { var img = new Array( "active.gif", "inactive.gif", "other.gif"); preloadImages(img); } </script>
Prchargement de plusieurs images (preload-array.html)

Astuce Grce au HTML standard, vous pouvez prcharger des images sans avoir les afficher :

<div style="display:none;"> <img src="active.gif" height="1" width="1" /> <img src="inactive.gif" height="1" width="1" /> <img src="other.gif" height="1" width="1" /> </div>
Toutefois, lorsque ces images ne servent que pour les effets JavaScript, ne les prchargez qu'en utilisant JavaScript, faute de quoi les utilisateurs sans JavaScript prchargeront galement les fichiers, sans obtenir les effets visuels.

Animation des graphiques

45

Animation des graphiques


document.images["animation"].src = urls[pos]; window.setTimeout("animate(" + (pos + 1) + ");", 500);

Le format de fichier GIF, initialement produit par Compuserve, est le seul accepter l'animation et tre accept par la plupart des grands navigateurs. Il prsente cependant des limites importantes, notamment sa palette de couleurs 8 bits qui n'autorise que 256 couleurs. A noter qu'une norme PNG-24 est en cours de cration mais ne possde malheureusement pas de capacits d'animation. Dans ce cas, le mieux faire consiste utiliser JavaScript. La modification d'un graphique est possible comme cela a t montr au cours des sections prcdentes, le seul ingrdient manquant est setInterval() ou setTimeout(). Le code suivant parcourt un tableau d'images et passe l'image suivante au bout de 500 millisecondes (une demi-seconde) :
<script language="JavaScript" type="text/JavaScript"> var urls; function animate(pos) { pos %= urls.length; document.images["animation"].src = urls[pos]; window.setTimeout("animate(" + (pos + 1) + ");", 500); } window.onload = function() { urls = new Array( "0.png", "1.png", "2.png", "3.png", "4.png", "5.png", "6.png"); animate(0); } </script> <img src="0.png" name="animation" />
Animation par les images (animate.html)

46

CHAPITRE 3 Images et animations

La fonction animate() prend un paramtre : la position de l'image suivante afficher. La liste des images parcourir est enregistre dans une variable globale, puisque setTimeout() ne peut pas utiliser les variables locales qui ne sont pas disponibles pour tous. Avec pos %= urls.length, le pointeur ciblant la liste d'images est paramtr au dbut, aprs que la dernire image a t affiche, ce qui permet de gnrer une boucle infinie. Si l'animation doit s'arrter aprs la dernire image, remplacez cette ligne par le code suivant :
if (pos == urls.length) { return false; }

Etirement des graphiques


document.images["bar"].width += 5;

Il n'est parfois mme pas ncessaire de crer plusieurs graphiques pour construire une animation. Ainsi, le simple fait d'tirer une image peut crer un effet saisissant. Ce n'est gnralement pas trs bien peru sur le Web, puisque seuls les formats de fichiers bitmap sont pris en charge ( l'exception de Flash ou de SVG, qui n'est pas disponible dans les navigateurs, dans leur configuration par dfaut). L'tirement d'un graphique exige donc du navigateur qu'il calcule des informations d'image supplmentaires, gnralement en copiant des pixels. Dans le cas d'une barre de progression, un simple graphique peut suffire. Dans un exemple simple, vous utiliserez une image de 1 1 pixel. S'il est utilis dans la page HTML avec une largeur de 20 pixels et une hauteur de 10 pixels, vous obtenez une image de 20 10 pixels.

Etirement des graphiques

47

En animant la largeur de l'image avec JavaScript, vous avez l'impression que la barre de progression est en mouvement. La largeur et la hauteur d'une image sont accessibles par JavaScript grce aux proprits width et height, qui peuvent tre lues et crites. Le code suivant dplace la barre de progression l'aide d'un simple graphique de 1 1 pixel, black.gif.
<script language="JavaScript" type="text/JavaScript"> function progress() { if (document.images["bar"].width < 200) { document.images["bar"].width += 5; document.images["bar"].height = 5; } else { clearInterval(ID); } } var ID; window.onload = function() { ID = setInterval("progress();", 500); } </script> <img src="black.gif" name="bar" />
Une barre de progression anime (progress.html)

La Figure 3.2 prsente l'exemple en application : l'image 1 1 a t tire dynamiquement par JavaScript. La fonction progress() est appele toutes les 500 millisecondes, grce l'appel setInterval(). Une fois que la barre de progression a atteint sa longueur maximale (dans cet exemple, environ 200 pixels), l'animation est arrte avec clearInterval().

48

CHAPITRE 3 Images et animations

Figure 3.2 : Le graphique est anim pour ressembler une barre de progression.

Attention Si vous ne rglez pas explicitement la hauteur de l'image de la barre de progression, le fait d'tirer sa largeur tirera galement sa hauteur, ce qui gche l'effet souhait.

Visualisation de l'tat de chargement de la page avec une barre de progression


if (document.images[i].complete) { loaded++; }

Savoir si la page a t ou non compltement charge ne peut pas tre dtermin avec du JavaScript uniquement, mais il est possible d'en faire une estimation assez juste.

Visualisation du chargement de la page avec une barre de progression


Visualisation du chargement de la page avec une barre de progression

49

La proprit complete d'une image fournit une valeur boolenne indiquant si l'image s'est totalement charge. De mme, une image accepte l'vnement load, de sorte que onload puisse tre utilis pour dclencher l'excution du code une fois l'image charge. Le code suivant parcourt toutes les images de la page et compte combien d'entre elles ont t totalement charges. Cela gnre une estimation en pourcentage de la part de la page totalement charge (bien entendu, sans inclure les applets et les mdias intgrs, ni les tailles des fichiers image).
<script language="JavaScript" type="text/JavaScript"> function showprogress() { if (document.images.length == 0) { return false; } var loaded = 0; for (var i=0; i<document.images.length; i++) { if (document.images[i].complete) { loaded++; } } var percentage = Math.round( 100 * loaded / document.images.length); document.getElementById("progress").innerHTML = percentage + "% loaded"; if (percentage == 100) { window.clearInterval(ID); } } var ID = window.setInterval("showprogress();", 500); </script> <p name="progress">0% loaded</p>
La marque de progression du chargement (loadprogress.html)

50

CHAPITRE 3 Images et animations

Pour rellement reproduire cet effet, vous devez intgrer dans votre page les images qui prennent du temps charger, soit parce qu'elles sont trs volumineuses, soit parce que le serveur subit une charge lourde. Les tlchargements de code pour ce livre comprennent le script PHP gfx.php qui repose sur l'extension GD de PHP et cre une image colore alatoirement, avec un dlai allant jusqu' quinze secondes. La Figure 3.3 montre le rsultat lorsque deux des trois graphiques ont t chargs.
Info D'autres vnements intressants signaler pour les images sont abort (lorsque le chargement de l'image est interrompu par l'utilisateur) et error (lorsqu'il y a une erreur lors du chargement des images, par exemple quand le fichier n'existe pas). Ils peuvent tre utiliss avec les gestionnaires d'vnements onabort et onerror.

Figure 3.3 : Le troisime graphique continue se charger.

Utilisation des images ractives

51

Utilisation des images ractives


JavaScript peut aussi tre utilis dans des images ractives ct client, mais dans quelques cas seulement : Chaque lien dans l'image ractive peut tre un lien JavaScript:, ce qui permet au navigateur d'appeler JavaScript lorsque l'utilisateur clique sur une zone sensible de l'image. Des vnements comme mouseover, mouseout et load sont galement disponibles dans les images ractives pour les formes dnies dans les lments <map>. L'image ractive peut tre dnie via JavaScript, en utilisant la proprit useMap. Toutefois, il existe gnralement une seule image ractive convenant pour une seule image donne.

4
CSS
Aux premiers temps du World Wide Web, le contenu tait roi et la mise en page plutt dlaisse. Le Web a ensuite dvelopp un certain ct commercial, amenant les dveloppeurs abuser du HTML. Ce langage de marquage s'est alors transform en un outil de conception inadapt. Grce aux CSS (feuilles de style en cascade), la situation s'est un peu amliore : une page HTML a ainsi pu recevoir un style et le HTML redevenir un langage de marquage qui dfinit le contenu et la structure d'une page, et non plus son aspect. Grce JavaScript, les effets des CSS peuvent tre appliqus la vole. La plupart des sections de ce chapitre sont trs gnriques, permettant d'appliquer ces techniques n'importe quel objectif de conception. Certaines rsolvent des problmes plus spcifiques.

54

CHAPITRE 4 CSS

Accs aux styles CSS


document.getElementById("para").style.fontWeight ="strong";

JavaScript peut dfinir n'importe quelle commande CSS et utilise "presque" comme proprit le nom de la commande CSS. Un problme demeure toutefois : certains caractres, comme le tiret, ne sont pas autoriss dans une proprit JavaScript. Mais de nombreuses commandes CSS (font-weight par exemple) contiennent des tirets. Le langage JavaScript utilise alors une syntaxe de type majusculeDeuximeMot : l'exception du premier, chaque mot commence par une lettre majuscule. Ainsi, la commande CSS font-weight peut tre dfinie l'aide de la proprit fontWeight. Toutes les commandes CSS sont accessibles l'aide de la proprit de style de chaque lment HTML de style de la page. Il existe deux manires communes pour accder ces lments : b utiliser les gestionnaires d'vnements sous la forme d'attributs HTML et envoyer une rfrence l'lment actuel comme paramtre : <p onmouseover="handlerFunction(this);" /> ; b utiliser document.getElementById(). Le listing suivant montre la seconde mthode. L'lment
<p> est slectionn l'aide de document.getElementById();, puis la commande CSS font-weight est paramtre :
<script language="JavaScript" type="text/JavaScript"> function makeBold() { document.getElementById("para").style.fontWeight ="bold"; window.setTimeout("makeLighter();", 1000);

Accs aux styles CSS

55

} function makeLighter() { document.getElementById("para").style.fontWeight = "lighter"; window.setTimeout("makeBold();", 1000); } window.onload = makeBold; </script> <p id="para">CSS and JavaScript</p>
Modification d'une commande CSS (style.html)

Astuce La console JavaScript, avec le navigateur Mozilla, affiche une erreur lorsqu'une valeur inadquate est applique au style choisi, comme le montre la Figure 4.1. Cela est extrmement commode pour le dbogage.

Figure 4.1 : Les navigateurs Mozilla (ici, Firefox) refusent les valeurs CSS inadquates.

56

CHAPITRE 4 CSS

Accs aux classes CSS


document.getElementById("para").className = "strong";

La manire la plus usite d'appliquer du CSS une page HTML consiste utiliser les classes. Avec JavaScript, la classe de chaque lment est accessible avec la proprit className. Le code suivant implmente l'expression prcdente avec la mthode par classe :
<script language="JavaScript" type="text/JavaScript"> function makeBold() { document.getElementById("para").className ="strong"; window.setTimeout("makeLighter();", 1000); } function makeLighter() { document.getElementById("para").className ="weak"; window.setTimeout("makeBold();", 1000); } window.onload = makeBold; </script> <style type="text/css"> .strong { font-weight: bold; } .weak { font-weight: lighter; } </style> <p id="para">CSS and JavaScript</p>
Modification de la classe CSS (classname.html)

Le code qui prcde modifie la classe pour le texte chaque seconde.

Accs aux feuilles de style individuelles

57

Accs aux feuilles de style individuelles


document.styleSheets[0].disabled = true;

Lorsqu'une page se compose de plusieurs feuilles de style (lment <style> avec un style intgr ou une feuille de style externe), vous pouvez utiliser JavaScript pour basculer entre elles, les activer et les dsactiver, ainsi que les combiner. La proprit styleSheets de l'objet document contient toutes les feuilles de style de la page, dans l'ordre dans lequel elles sont charges ou dans lequel elles apparaissent sur cette page. La proprit la plus importante de chaque feuille de style s'intitule disabled. Si elle est rgle sur true, elle devient invisible et n'affecte plus la mise en page. Vous pouvez accder une feuille de style spcifique de deux faons : b en utilisant l'identifiant de la feuille de style comme indice pour le tableau styleSheets ; b en utilisant le numro de la feuille de style (qui commence par 0) comme indice pour le tableau styleSheets. La premire manire ne fonctionne pas correctement avec les navigateurs Mozilla, utilisez donc l'indice numrique, comme le montre le code suivant :
<script language="JavaScript" type="text/JavaScript"> function makeBold() { document.styleSheets[0].disabled = false;

58

CHAPITRE 4 CSS

document.styleSheets[1].disabled = true; window.setTimeout("makeLighter();", 1000); } function makeLighter() { document.styleSheets[0].disabled = true; document.styleSheets[1].disabled = false; window.setTimeout("makeBold();", 1000); } window.onload = makeBold; </script> <style type="text/css" id="strong"> p { font-weight: bold; } </style> <style type="text/css" id="weak"> p { font-weight: lighter; } </style> <p>CSS and JavaScript</p>
Modification de la feuille de style (stylesheets.html)

Accs aux rgles de CSS individuelles


document.styleSheets[0].rules[0].style.color = randomColor(); document.styleSheets[0].cssRules[0].style.color = randomColor();

Les rgles individuelles d'une feuille de style sont galement accessibles par la voie de la programmation, mais les navigateurs Web diffrent les uns des autres. Internet Explorer accepte la proprit rules, tandis que tous les autres navigateurs utilisent la proprit cssRules. La seule exception revient au navigateur Opera, qui n'accepte ni l'une ni l'autre.

Accs aux rgles de CSS individuelles

59

Sachez que vous pouvez accder aux rgles puis, par exemple, les modifier. Chaque rgle se comporte comme un lment HTML gnrique : vous utilisez la proprit style pour accder tous les styles, puis pour les modifier ou en ajouter. Pour l'exemple suivant, une fonction d'aide gnre une couleur alatoire au format RVB :
function randomColor() { var chars = "0123456789abcdef"; var color = "#"; for (var i=0; i<6; i++) { var rnd = Math.floor(16 * Math.random()); color += chars.charAt(rnd); } return color; }

L'expression prcdente est ensuite tendue. Tout d'abord, chaque feuille de style contient les rgles pour les lments <p> et <span>. Ces deux rgles reoivent ensuite une commande CSS supplmentaire : la couleur est rgle sur une valeur alatoire. L'utilit de cet exemple simple peut ne pas paratre vidente dans un cas concret, mais il est possible d'adapter la technologie sous-jacente de manire assez flexible.
<script language="JavaScript" type="text/JavaScript"> function makeBold() { document.styleSheets[0].disabled = false; document.styleSheets[1].disabled = true; if (document.styleSheets[0].rules) { document.styleSheets[0].rules[0].style.color = randomColor(); document.styleSheets[0].rules[1].style.color = randomColor();

60

CHAPITRE 4 CSS

} else if (document.styleSheets[0].cssRules) { document.styleSheets[0].cssRules[0].style.color = randomColor(); document.styleSheets[0].cssRules[1].style.color = randomColor(); } window.setTimeout("makeLighter();", 1000); } function makeLighter() { document.styleSheets[0].disabled = true; document.styleSheets[1].disabled = false; if (document.styleSheets[0].rules) { document.styleSheets[1].rules[0].style.color = randomColor(); document.styleSheets[1].rules[1].style.color = randomColor(); } else if (document.styleSheets[0].cssRules) { document.styleSheets[1].cssRules[0].style.color = randomColor(); document.styleSheets[1].cssRules[1].style.color = randomColor(); } window.setTimeout("makeBold();", 1000); } window.onload = makeBold; </script> <style type="text/css" id="strong"> p { font-weight: bold; } span { font-style: italic; } </style> <style type="text/css" id="weak"> p { font-weight: lighter; } span { font-style: normal; } </style> <p>CSS <span>and</span> JavaScript</p>
Accs aux rgles CSS (rules.html)

Laisser disparatre le contenu d'un site Web

61

La Figure 4.2 montre le rsultat : mme si l'ouvrage est imprim en gris, vous constaterez diffrentes couleurs (ou plutt niveaux de gris) dans le paragraphe et dans l'lment <span> qui s'y trouve.

Figure 4.2 : Les couleurs du texte sont appliques de manire alatoire aux rgles CSS individuelles.

Laisser disparatre le contenu d'un site Web


document.getElementById(show).style.display = "block"; document.getElementById(hide).style.display = "none";

Un effet JavaScript assez commun sur le Web, et qui utilise les CSS, consiste laisser les lments d'une page apparatre ou disparatre la demande. Certaines pages affichent un cran d'attente sur une page qui se charge lentement. Une fois la page charge, l'cran d'attente disparat. Un autre exemple consiste fournir plusieurs onglets, un seul affich la fois, et passer de l'un l'autre en utilisant JavaScript, sans qu'il soit besoin d'adresser au serveur de longues requtes.

62

CHAPITRE 4 CSS

Il existe plusieurs manires de procder avec JavaScript. Vous pouvez utiliser DOM (vous trouverez certaines expressions pour faire apparatre ou disparatre des lments DOM au Chapitre 5, "DOM et DHTML"). Deux possibilits sont prsentes dans l'expression. On trouve d'abord la commande CSS visibility, que vous pouvez rgler sur visible ou hidden pour faire apparatre ou disparatre l'lment associ, ce qui se traduit en une proprit JavaScript visibility. En voici le code :
<script language="JavaScript" type="text/JavaScript"> function showHide(show, hide) { document.getElementById(show).style.visibility = "visible"; document.getElementById(hide).style.visibility = "hidden"; } </script> <p>&nbsp;<br />&nbsp;</p> <p id="tab1" style="position: absolute; top: 5px; left: 5px;"> Tab 1 </p> <p id="tab2" style="position: absolute; top: 5px; left: 5px; visibility: hidden;"> Tab 2 </p> <input type="button" value="Tab 1" onclick="showHide('tab1', 'tab2');" /> <input type="button" value="Tab 2" onclick="showHide('tab2', 'tab1');" />
Rglage de la visibilit d'un lment (visibility.html)

Toutefois, comme vous le verrez, le positionnement absolu entrane des diffrences subtiles selon les navigateurs.

Laisser disparatre le contenu d'un site Web

63

Il vaut mieux utiliser une mise en page par blocs et dfinir la proprit display de l'lment sur block ou none :
<script language="JavaScript" type="text/JavaScript"> function showHide(show, hide) { document.getElementById(show).style.display = "block"; document.getElementById(hide).style.display = "none"; } </script> <p id="tab1"> Tab 1 </p> <p id="tab2" style="display: none;"> Tab 2 </p> <input type="button" value="Tab 1" onclick="showHide('tab1', 'tab2');" /> <input type="button" value="Tab 2" onclick="showHide('tab2', 'tab1');" />
Rglage du mode d'affichage d'un lment (display.html)

La Figure 4.3 montre le rsultat : cliquer sur le second bouton fait apparatre le second onglet.

Figure 4.3 : Cliquer sur un bouton afche l'onglet associ.

64

CHAPITRE 4 CSS

Application de JavaScript aux slecteurs CSS


Behaviour.register(cssrules);

En 1999, le W3C proposait des "extensions comportementales aux CSS" (http://w3.org/TR/1999/WD-becss -19990804), une mthode consistant lier du code JavaScript des comportements CSS. L'ide de base tait d'viter l'utilisation des attributs HTML bien connus de type onxxx. Aprs 1999, ce domaine n'avait pas beaucoup progress, mais Ben Nolan russit proposer un contournement (ou plutt un piratage) pour permettre un concept analogue. Pour cela, il faut employer la bibliothque JavaScript (http://www.bennolan.com/behaviour/) sous la forme du fichier behaviour.js. Cette collection de code permet de fournir des rgles contenant du code JavaScript sous la forme de slecteurs CSS. Pour que cela fonctionne, il faut d'abord un fichier JavaScript externe qui dfinisse les rgles CSS. Pour l'essentiel, vous crez un objet avec des slecteurs CSS sous forme de cls, puis les fonctions de gestion d'vnements JavaScript sous forme de valeurs. Ensuite, vous appelez la mthode Behaviour.register() pour signaler ces rgles la bibliothque de comportements :
var cssrules = { "p.para" : function(e){ e.onmouseover = function(){ this.style.fontWeight = "bold"; } e.onmouseout = function(){ this.style.fontWeight = "normal"; }

Application de JavaScript aux slecteurs CSS

65

}, "#term" : function(e){ e.onmouseover = function(){ this.style.fontStyle = "oblique"; }, e.onmouseout = function(){ this.style.fontStyle = "normal"; } } }; Behaviour.register(cssrules);
Rgles CSS/JavaScript (rules.js)

Il reste charger la bibliothque JavaScript et le prcdent fichier JavaScript de rgles. Le code JavaScript est ensuite excut lorsque les vnements associs (dans l'exemple : mouseover et mouseout) sont dclenchs.
<script language="JavaScript" type="text/JavaScript" src="behaviour.js"> </script> <script language="JavaScript" type="text/JavaScript" src="rules.js"> </script> <p class="para">CSS <span id="term">and</span> JavaScript</p>
Utilisation de la bibliothque de comportements JavaScript (behaviour.html)

La Figure 4.4 montre le rsultat : lorsque le pointeur de la souris passe sur l'lment <span>, deux gestionnaires d'vnements sont appels.

66

CHAPITRE 4 CSS

Figure 4.4 : Le code JavaScript est excut. Info Le principal avantage de cette mthode rside dans le fait que le code JavaScript se trouve dans des fichiers externes et qu'il n'encombre pas le marquage HTML de la page. Du point de vue de l'architecture, l'ide est assez brillante et fonctionne dans tous les navigateurs.

Modication du curseur de la souris


document.getElementById("button").style.cursor = "help";

Tous les systmes d'exploitation sont livrs avec un certain jeu de curseurs de souris et CSS en accepte un sous-ensemble. L'apparence est un peu diffrente selon les systmes d'exploitation, mais la mise en page gnrale est assez similaire.

Modification du curseur de la souris

67

La commande CSS en question est cursor, et elle est galement disponible partir de JavaScript, comme le montre le code suivant :
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { document.getElementById("helpButton").style.cursor = "help"; }; </script> <input type="submit" id="helpButton" value="Get help" />
Modification du curseur (cursor.html)

Vous voyez le rsultat la Figure 4.5 : le curseur de la souris comprend maintenant un point d'interrogation pour prciser que le bouton permet d'obtenir de l'aide.

Figure 4.5 : Le curseur de la souris est modi. Attention Chaque curseur de souris ralise un objectif. Rflchissez donc bien avant de modifier l'apparence d'un curseur, vous ne devez pas irriter vos utilisateurs !

68

CHAPITRE 4 CSS

Styles de curseur CSS


Voici les valeurs autorises pour la proprit cursor de JavaScript/CSS :
auto crosshair default e-resize help move n-resize ne-resize nw-resize pointer s-resize se-resize sw-resize test w-resize wait

5
DOM et DHTML
Ce chapitre traite de deux techniques JavaScript vaguement lies : DOM et DHTML. Ces deux aspects de JavaScript existent depuis de nombreuses annes, mais ce n'est que depuis la chute des parts de march de Netscape 4.x, passant en dessous de celle de Mozilla il y a quelques annes, qu'il a t possible de les utiliser conjointement. A l'origine, pourtant, ils n'avaient pas grand-chose en commun. Ce chapitre traite de DOM, puisque de nombreuses expressions de cet ouvrage peuvent tre plus ou moins classes sous la catgorie "DHTML".

DOM
DOM (Document Object Model, modle objet de document) est assez explicite : il propose un modle d'objet (et, avec lui, une API, une interface de programmation d'applications) pour un document. Dans le contexte du Web, on fait videmment rfrence un document HTML.

70

CHAPITRE 5 DOM et DHTML

L'une des meilleures manires de le visualiser consiste utiliser l'inspecteur DOM livr avec les navigateurs Mozilla. Dans le DOM, tous les lments de page sont placs dans une hirarchie arborescente. Chaque balise HTML correspond un nud de l'arborescence, avec des nuds infrieurs et des nuds parent. De mme, chaque partie de texte correspond son propre nud DOM (un nud de texte, pour tre exact). La Figure 5.1 montre l'inspecteur DOM pour un simple chantillon de document.

Figure 5.1 : L'inspecteur DOM montre tous les nuds d'un document.

Bien entendu, l'API DOM accepte les mthodes pour accder aux lments de l'arborescence DOM, mais galement pour ajouter ou supprimer des lments. Il est donc possible de modifier quasiment n'importe quel lment d'une page. Une question demeure : que vaut-il mieux faire, utiliser DOM ou des objets JavaScript standard comme forms

DHTML

71

ou images ? Gnralement, DOM est plus flexible mais aussi parfois plus difficile. Ainsi, si vous pouvez utiliser un raccourci JavaScript, faites-le. Sinon, familiarisez-vous avec DOM.
Info Vous trouverez de plus amples informations sur DOM l'adresse du consortium W3C (World Wide Web Consortium) : http://w3c.org/DOM.

DHTML
DOM est un "vrai " terme technique, alors que DHTML (le HTML dynamique) ne l'est pas. C'est un terme de marketing pur. Lorsqu'il a t cr, il signifiait en fait "JavaScript pour les navigateurs de version 4 et suprieure". A cette poque, Netscape Navigator et Internet Explorer se battaient dans la clbre guerre des navigateurs et, avec leur version 4, les deux diteurs ont inclus des fonctions JavaScript plus dynamiques, malheureusement assez incompatibles les unes avec les autres. La plupart des effets DHTML couvrent le positionnement des lments et leur modification en cas d'action de l'utilisateur. Netscape 4 et Internet Explorer 4 ayant disparu depuis longtemps, les versions rcentes des deux marques (n'oubliez pas que Netscape 4 a t suivi par Netscape 6, qui se fonde sur le moteur Gecko de Mozilla) acceptent raisonnablement bien DOM (mme s'il manque encore certains lments). DHTML est donc ren de ses cendres, puisque les effets du JavaScript dynamique sont dsormais possibles avec une petite quantit de code spcifique au navigateur et de recherche du client.

72

CHAPITRE 5 DOM et DHTML

Accs des lments spciques


document.getElementById("para")

Lorsque vous travaillez avec DOM, la meilleure manire d'accder par la suite un lment sur la page consiste lui donner un identifiant unique, ou ID. La mthode DOM document.getElementById() accde ensuite l'lment donn et vous permet de poursuivre : modifier les lments, ajouter des sous-lments ou encore naviguer dans l'arborescence DOM. Dans l'exemple suivant, on accde l'lment <p>. Selon le type du navigateur, la reprsentation en chane de la classe d'lment est diffrente. Tandis qu'Internet Explorer produit simplement [object], les navigateurs Mozilla sont plus verbeux et donnent plus d'informations : [object HTMLParagraphElement].
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { window.alert(document.getElementById("para")); } </script> <p id="para">JavaScript Phrasebook</p>
Accs un lment par son identifiant (getelementbyid.html)

Attention DOM n'est accessible que lorsque l'ensemble du document a t charg. C'est la raison pour laquelle son code d'accs n'est excut qu'aprs que l'vnement load a t dclench.

Accs aux balises

73

Accs aux balises


document.getElementsByTagName("p")

Une autre manire d'accder aux lments de la page en cours consiste passer par leurs noms de balise. Ds que vous devez travailler sur un jeu d'lments reprsent par des balises HTML identiques (par exemple, tous les lments de liste ou tous les paragraphes, tout ce qui n'est pas reprsent par une autre proprit de l'objet document JavaScript), la mthode document.getElementsByTagName() peut tre utilise. Vous apportez le nom de la balise et vous obtenez un tableau de tous les lments, que vous pouvez ensuite traiter. Le code suivant accde simplement tous les lments <p> et les compte :
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { window.alert( document.getElementsByTagName("p") + " (" + document.getElementsByTagName("p").length + " elements)"); } </script> <p>JavaScript Phrasebook</p> <p>Sams Publishing</p>
Accs aux lments par nom de balise (getelementsbytagname.html)

La sortie du code prcdent est [object HTMLCollection] (2 elements) ; Internet Explorer une fois de plus donne moins d'informations, en produisant seulement [object] (2 elements).

74

CHAPITRE 5 DOM et DHTML

Navigation dans l'arborescence DOM


Une fois l'intrieur de DOM, vous pouvez naviguer dans la structure, monter et descendre ou aller droite et gauche. Voici une liste des proprits les plus importantes que possde chaque nud DOM : firstChild : premier nud enfant ; lastChild : dernier nud enfant ; childNodes : tous les nuds enfant (sous forme de tableau) ; parentNode : nud parent ; nextSibling : nud suivant au mme niveau ( droite) ; previousSibling : nud prcdent au mme niveau ( gauche). De mme, nodeName renvoie le nom de la balise du nud (ou #text pour les nuds de texte) tandis que nodeValue renvoie la valeur d'un nud (fonction utile avec les nuds de texte).

Dtermination des informations de nud

75

Dtermination des informations de nud


s += nodeName + ": " + nodeValue + " (" + nodeType + ")\n";

Nous l'avons indiqu la section prcdente, il est possible de rassembler des informations sur un nud, ce qui est extrmement utile lorsqu'on travaille avec des donnes DOM arbitraires.
nodeName donne des informations sur le nom du nud (nom de balise ou #text pour les nuds de texte), mais nodeValue ne sert que pour les nuds de texte et renvoie

le texte rel du nud. La troisime catgorie d'informations provient de la proprit nodeType, qui donne des informations sur le type du nud. Le Tableau 5.1 contient une liste de toutes les valeurs possibles de nodeType.
Tableau 5.1 : Types de nuds
Type de nud Description

1 2 3 8 9 10 11

Balise Attribut Texte (espaces compris) Commentaire HTML Document DTD Fragment

76

CHAPITRE 5 DOM et DHTML

Le code suivant analyse ensuite une simple structure DOM et produit des informations concernant tous les nuds enfant. La Figure 5.2 prsente le rsultat dans le navigateur.
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { var s = ""; with (document.getElementById("para")) { for (var i=0; i<childNodes.length; i++) { with (childNodes[i]) { s += nodeName + ": " + nodeValue + " (" + nodeType + ")\n"; } } } window.alert(s); } </script> <p id="para"><em>JavaScript</em> Phrasebook</p>
Rcupration des informations de nud (nodeinfo.html)

Figure 5.2 : Informations sur tous les nuds enfant.

Suppression d'lments

77

Suppression d'lments
list.removeChild(list.lastChild);

La mthode removeChild() que possde chaque nud peut servir liminer un nud de l'arborescence DOM. Sachez que vous devez appeler cette mthode partir de l'lment parent du nud effacer et fournir le nud en paramtre. L'exemple suivant prsente une liste et supprime le dernier lment chaque fois que l'utilisateur clique sur le bouton ; reportez-vous la Figure 5.3 pour voir le rsultat dans le navigateur.
<script language="JavaScript" type="text/JavaScript"> function removeItem() { var list = document.getElementById("list"); if (list.childNodes.length > 0) { list.removeChild(list.lastChild); } } </script> <ol id="list"> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ol> <input type="button" onclick="removeItem();" value="Remove item" />
Suppression de nuds (remove.html)

78

CHAPITRE 5 DOM et DHTML

Figure 5.3 : Le dernier nud est supprim.

Astuce Lorsque vous n'avez qu'un accs direct au nud supprimer (curNode dans le code suivant), cette mthode fonctionne :

curNode.parentNode.removeChild(curNode);
Si vous appelez ce code dans une fonction gestionnaire pour le nud, vous pouvez remplacer curNode par this.

Ajout d'lments
list.appendChild(newNode);

Les nouveaux nuds DOM sont crs l'aide de la mthode document.createElement(). Elle gnre un nouvel lment, en utilisant le nom de balise fourni en paramtre.

Ajout d'lments

79

Cet lment peut ensuite tre insr dans l'arborescence DOM. La mthode (node) utilise le plus souvent est appendChild(). Elle ajoute un nouvel enfant la fin de la liste. Le code suivant ajoute un nouvel lment de liste vide (<li>) la fin de la liste ds que l'utilisateur clique sur le bouton :
<script language="JavaScript" type="text/JavaScript"> function addItem() { var list = document.getElementById("list"); var newNode = document.createElement("li"); list.appendChild(newNode); } </script> <ul id="list"><li>Item</li></ul> <input type="button" onclick="addItem();" value="Add item" />
Ajout de nuds (add.html)

L'inconvnient de cette approche rside dans le fait que le nouvel lment est toujours ajout la fin de la liste des enfants. Pour y remdier, utilisez la mthode insertBefore() qui permet d'insrer un nouveau nud avant tout autre nud (pour l'insrer n'importe o, sauf la fin de la liste). Comme pour les paramtres, vous donnez d'abord le nouveau nud, puis le nouvel lment de mme niveau. Le code suivant insre un nouvel lment <li> au dbut de la liste chaque fois que l'utilisateur clique sur le bouton (voir Figure 5.4).

80

CHAPITRE 5 DOM et DHTML

<script language="JavaScript" type="text/JavaScript"> function addItem() { var list = document.getElementById("list"); var newNode = document.createElement("li"); list.insertBefore(newNode, list.firstChild); } </script> <ul id="list"><li>Item</li></ul> <input type="button" onclick=vaddItem();" value="Add item" />
Ajout de nuds au dbut de la liste des enfants (addbefore.html)

Figure 5.4 : Les lments de liste sont ajouts au dbut de la liste.

Cration d'lments de texte

81

Cration d'lments de texte


var newTextNode = document.createTextNode("Item " + nr);

Pour placer du texte dans un lment, il faut un nud de texte qui soit un sous-lment du nud rel. La mthode createTextNode() cre ce nud de texte ; il vous suffit de fournir le texte lui-mme. Dans le code suivant, les lments de liste sont nouveau ajouts mais, cette fois-ci, ils contiennent du texte. Vous crez donc d'abord un nud de texte, puis vous l'ajoutez un autre nud (qui peut ensuite tre ajout un autre nud, qui peut ensuite tre ajout un autre nud Vous avez compris l'ide).
<script language="JavaScript" type="text/JavaScript"> var nr = 1; function addItem() { var list = document.getElementById("list"); var newNode = document.createElement("li"); nr++; var newTextNode = document.createTextNode("Item " + nr); newNode.appendChild(newTextNode); list.appendChild(newNode); } </script> <ul id="list"><li>Item 1</li></ul> <input type="button" onclick="addItem();" value="Add item" />
Cration (et ajout) d'un nud de texte (textnode.html)

82

CHAPITRE 5 DOM et DHTML

Travail avec les attributs


newLink.setAttribute("href", "http://www.samspublishing.com/");

Jusqu' prsent, ce chapitre s'est intress aux balises et aux nuds de texte ordinaires. Il manque toujours un lment majeur, les attributs. Vous pouvez y accder sous la forme de nuds mais la manire la plus commode est d'utiliser la mthode setAttribute() : il vous suffit de fournir le nom de l'attribut et sa valeur. Dans le code suivant, le contenu des nouveaux lments <li> est un lien hypertexte, avec un jeu d'attributs href :
<script language="JavaScript" type="text/JavaScript"> var nr = 1; function addItem() { var list = document.getElementById("list"); var newNode = document.createElement("li"); var newLink = document.createElement("a"); newLink.setAttribute("href", "http://www.samspublishing.com/"); nr++; var newTextNode = document.createTextNode("Item " + nr); newLink.appendChild(newTextNode); newNode.appendChild(newLink); list.appendChild(newNode); } </script> <ul id="list"><li>Item 1</li></ul> <input type="button" onclick="addItem();" value="Add item" />
Rglage des attributs (attributes.html)

Clonage d'lments

83

La Figure 5.5 montre que tous les liens ajouts la liste pointent vers l'URL fournie.

Figure 5.5 : Liens hypertexte gnrs de manire dynamique.

Clonage d'lments
var newItem = oldItem.cloneNode(true);

Au lieu de crer de nouveaux nuds chaque fois, vous pouvez galement cloner un nud existant. La mthode cloneNode(), accessible pour chaque nud, le fait pour vous. Vous pouvez dcider de ne cloner que le nud et son attribut ou de cloner tous les nuds enfant (et leurs nuds enfant, etc.). Si vous fournissez true en paramtre cloneNode(), une "copie en profondeur" est effectue, laquelle prend en compte galement les enfants ; false ne copie que le nud lui-mme.

84

CHAPITRE 5 DOM et DHTML

<script language="JavaScript" type="text/JavaScript"> var nr = 1; function addItem(cloneMode) { var list = document.getElementById("list"); var oldItem = list.firstChild; var newItem = oldItem.cloneNode(cloneMode); list.appendChild(newItem); } </script> <ul id="list"><li><a href="http://www.samspublishing.com/"> Item 1</a></li></ul> <input type="button" onclick="addItem(true);" value="Clone all" /> <input type="button" onclick="addItem(false);" value="Clone node only" />
Clonage de nuds (clone.html)

Lorsque vous cliquez sur le premier bouton, l'ensemble du nud (y compris les sous-lments, comme le lien et le texte de l'lment du lien) est copi ; le second bouton ne clone que le nud, ce qui gnre un nouvel lment de liste vide. Etudiez la Figure 5.6 pour voir la diffrence.

Figure 5.6 : Deux manires de copier les nuds.

Remplacement d'lments

85

Remplacement d'lments
list.replaceChild(newNode, list.firstChild);

Si vous supprimez un nud et que vous en insriez un autre la mme place, la mthode replaceChild() vous vite d'insrer une partie du codage. Vous indiquez le nouveau et l'ancien nud et JavaScript fait le reste pour vous. N'oubliez pas que vous devez appeler cette mthode partir de l'lment parent de l'ancien et du nouveau nud !
<script language="JavaScript" type="text/JavaScript"> var nr = 1; function addItem() { var list = document.getElementById("list"); var newNode = document.createElement("li"); nr++; var newTextNode = document.createTextNode("Item " + nr); newNode.appendChild(newTextNode); list.replaceChild(newNode, list.firstChild); } </script> <ul id="list"><li>Item 1</li></ul> <input type="button" onclick="addItem();" value="Replace item" />
Remplacement des nuds (replace.html)

Le code qui prcde remplace le premier enfant (nud) de la liste par un nouveau nud.

86

CHAPITRE 5 DOM et DHTML

Cration d'une liste puces partir de donnes JavaScript


var newItem = document.createElement("li"); var newText = document.createTextNode(data[i]); newItem.appendChild(newText); list.appendChild(newItem);

Notamment dans le contexte des services Web et AJAX (voir Chapitres 10 et 11), il arrive souvent qu'on doive afficher de manire dynamique les donnes reues du serveur. Une bonne technique consiste utiliser une liste HTML. L'exemple de code suivant propose une fonction createList() qui attend un tableau, contenant des valeurs pour le transformer en liste.
<script language="JavaScript" type="text/JavaScript"> function createList(data) { var list = document.createElement("ul"); for (var i = 0; i < data.length; i++) { var newItem = document.createElement("li"); var newText = document.createTextNode(data[i]); newItem.appendChild(newText); list.appendChild(newItem); } return list; } window.onload = function() { var list = createList( ["one", "two", "three", "four", "five"]); document.body.appendChild(list); } </script>
Cration d'une liste (list.html)

Cration d'un tableau partir de donnes JavaScript

87

Notez que document.body est un raccourci de l'lment <body> (autrement, vous pourriez utiliser document.getElementByTagName("body")[0]) ; appendChild() ajoute ensuite la liste HTML la fin de la page.

Cration d'un tableau partir de donnes JavaScript


var td = document.createElement("td"); var newText = document.createTextNode(data[i][j]); td.appendChild(newText); tr.appendChild(td);

Le tableau se situe un niveau de complexit suprieur celui de la liste. Vous devez d'abord utiliser l'lment <tbody> (et peut-tre aussi <tbody> et/ou <tfoot>). Vous risqueriez sinon de ne rien voir dans Internet Explorer. La fonction d'aide createTable() attend un tableau plusieurs dimensions. Chaque lment correspond une liste de valeurs afficher. Le premier lment de tableau contient le texte de l'en-tte de chaque colonne. On le voit, le code devient de plus en plus long mais la conception de base reste la mme : vous crez des nuds et des nuds de texte, puis vous les annexez les uns aux autres dans l'ordre qui convient. La Figure 5.7 montre le tableau qui en rsulte.
<script language="JavaScript" type="text/JavaScript"> function createTable(data) { var table = document.createElement("table"); var thead = document.createElement("thead"); var tr = document.createElement("tr");

88

CHAPITRE 5 DOM et DHTML

for (var i = 0; i < data[0].length; i++) { var th = document.createElement("th"); var newText = document.createTextNode(data[0][i]); th.appendChild(newText); tr.appendChild(th); } thead.appendChild(tr); table.appendChild(thead); var tbody = document.createElement("tbody"); for (var i = 1; i < data.length; i++) { var tr = document.createElement("tr"); for (var j=0; j < data[i].length; j++) { var td = document.createElement("td"); var newText = document.createTextNode(data[i][j]); td.appendChild(newText); tr.appendChild(td); } tbody.appendChild(tr); } table.appendChild(tbody); return table; } window.onload = function() { var table = createTable([ ["1", "2", "3", "4", "5"], ["one", "two", "three", "four", "five"], ["un", "deux", "trois", "quatre", "cinq"], ["eins", "zwei", "drei", "vier", "fnf"]]); document.body.appendChild(table); } </script>
Cration d'un tableau (table.html)

Modifications de fragments HTML

89

Figure 5.7 : Tableau gnr dynamiquement.

Modications de fragments HTML


list.innerHTML += newNode;

Quand vous modifiez des nuds de texte (soit en les remplaant, soit en utilisant la proprit nodeValue), la modification ne porte que sur le texte lui-mme, mais pas sur des fragments HTML complets, notamment des sous-lments. Pour ce faire, la proprit innerHTML de chaque lment peut se rvler utile. Mme si elle n'est pas standardise et ne fait pas partie d'une spcification DOM, elle fonctionne bien. Avec elle, vous pouvez modifier le code HTML interne de n'importe quel lment HTML, voire fournir de nouveaux sous-lments, comme le montre le listing suivant :
<script language="JavaScript" type="text/JavaScript"> var nr = 1;

90

CHAPITRE 5 DOM et DHTML

function addItem() { var list = document.getElementById("list"); nr++; var newNode = "<li>Item " + nr + "</li>"; list.innerHTML += newNode; } </script> <ul id="list"><li>Item 1</li></ul> <input type="button" onclick="addItem();" value="Add item" />
Ajout d'lments via innerHTML (innerhtml.html)

Ainsi, au lieu d'utiliser la faon propre et pratique de DOM, innerHTML crit simplement le code HTML dans un lment. Les deux mthodes prsentent leurs avantages et leurs inconvnients : innerHTML ncessite que vous vous occupiez du codage des caractres par vous-mme, mais vous permet par ailleurs d'ajouter ou de modifier plusieurs lments la fois.

Positionnement des lments


el.style.left = "0px"; el.style.posLeft = 0; el.style.top = "0px"; el.style.posTop = 0;

Les CSS permettent de placer des lments de deux manires : absolue et relative. Peu importe la mthode que vous choisissez, grce JavaScript vous pouvez rgler les valeurs de positionnement. Gnralement, le positionnement absolu est plus pratique puisque vous n'avez pas besoin de calculer les positions relatives des lments imbriqus.

Positionnement des lments

91

Dans la plupart des navigateurs, la proprit left dfinit la coordonne x de l'lment et la proprit top sert pour la coordonne y. Les valeurs ne sont pas numriques mais, comme c'est l'habitude dans les CSS, incluent une unit, gnralement px pour pixels. Pour Internet Explorer, il vous faut pratiquer diffremment. Les proprits posLeft et posTop dfinissent les positions horizontale et verticale, pour lesquelles, cette fois-ci, vous fournissez simplement une valeur numrique et non une unit. La faon la plus commode consiste dfinir toutes ces proprits, puisqu'il n'y a pas d'effets secondaires. Cela vous vite d'avoir rechercher le client. Le code suivant place les lments <div> dans le coin suprieur gauche. Notez que cet lment se trouve maintenant sur le texte de la page.
<script language="JavaScript" type="text/JavaScript"> function position() { var el = document.getElementById("element"); el.style.left = "0px"; el.style.posLeft = 0; el.style.top = "0px"; el.style.posTop = 0; } window.onload = position; </script> <h1>My Portal</h1> <p>Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. Some sample text. </p>

92

CHAPITRE 5 DOM et DHTML

<div id="element" style="position: absolute; background-color: #eee; border: 1px solid"> JavaScript Phrasebook </div>
Positionnement d'un lment (position.html)

Dplacement d'lments
id = window.setInterval("animate();", 100);

Un scnario DHTML plutt rare, mais encore utilis, consiste positionner un lment, mais galement le dplacer et donc l'animer. Pour ce faire, les mthodes window.setTimeout() et window.setInterval() sont assez pratiques. Le code suivant anime une bannire publicitaire sur la diagonale de la page. Le seul problme potentiel rside dans la manire d'animer la position. Pour les proprits Internet Explorer (posLeft, posTop), il suffit d'ajouter une valeur. Pour left et top, vous devez d'abord dterminer l'ancienne position, puis lui ajouter une valeur. La fonction JavaScript parseInt() extrait le contenu numrique d'une chane comme "123px". Toutefois, parseInt() renvoie NaN si aucune valeur n'est trouve dans left ou top. La fonction d'aide suivante s'occupe donc de cette situation ; dans ce cas, elle renvoie plutt 0 :
function myParseInt(s) { var ret = parseInt(s); return (isNaN(ret) ? 0 : ret); }

Dplacement d'lments

93

Ensuite, le code suivant anime la bannire et s'arrte aprs 50 itrations :


<script language="JavaScript" type="text/JavaScript"> var nr = 0; var id = null; function animate() { nr++; if (nr > 50) { window.clearInterval(id); document.getElementById("element").style .visibility = "hidden"; } else { var el = document.getElementById("element"); el.style.left = (myParseInt(el.style.left) + 5) + "px"; el.style.posLeft += 5; el.style.top = (myParseInt(el.style.top) + 5) + "px"; el.style.posTop += 5; } } window.onload = function() { id = window.setInterval("animate();", 100); }; </script> <h1>My Portal</h1> <div id="element" style="position: absolute; background-color: #eee; border: 1px solid"> JavaScript Phrasebook </div>
Animation d'un lment (animation.html, extrait)

94

CHAPITRE 5 DOM et DHTML

Cration d'une navigation toujours apparente


window.onload = positionNavigation; window.onscroll = positionNavigation;

Il est parfois important qu'une partie d'une page soit toujours visible. Selon la nature du site, il peut s'agir d'une bannire publicitaire (Geocities, qui fait maintenant partie de Yahoo!, a t parmi les premiers mettre cela en place) ou des lments de navigation. Une fois de plus, on intgre pour cela un lment <div>. Avec une navigation toujours apparente, la position des lments reste la mme, quand bien mme l'utilisateur fait dfiler la page. Ainsi, le code qui prcde sert appeler le code de positionnement la fois lorsque la page se charge et lorsqu'elle dfile. Pour calculer la nouvelle position, il faut calculer le dcalage actuel du dfilement. Internet Explorer propose pour cela document.body.scrollLeft et document.body.scrollTop ; les anciens navigateurs utilisent window.pageXOffset et window.pageYOffset. Le code suivant maintient la position des lments de navigation et la Figure 5.8 montre le rsultat.
<script language="JavaScript" type="text/JavaScript"> function positionNavigation() { var nav = document.getElementById("navigation"); var x, y; var navwidth = 155; if (window.innerWidth) { x = window.innerWidth + window.pageXOffset navwidth; y = window.pageYOffset + 10; } else { with (document.body) { x = clientWidth + scrollLeft - navwidth;

Cration d'une navigation toujours apparente

95

y = scrollTop + 10; } } nav.style.left = x + "px"; nav.style.posLeft = x; nav.style.top = y + "px"; nav.style.posTop = y; } window.onload = positionNavigation; window.onscroll = positionNavigation; </script> <h1>My Portal</h1> <div id="navigation" style="position: absolute; background-color: #eee; border: 1px solid"> <a href="http://www.samspublishing.com/">Sams Publishing </a><br /> <a href="http://www.amazon.com/gp/product/0672328801"> This book at Amazon</a><br /> <a href="http://www.hauser-wenz.de/blog/">Author's weblog </a> </div>
Maintien de la position d'un lment (sticky.html, extrait)

Figure 5.8 : Une navigation toujours apparente avec JavaScript.

96

CHAPITRE 5 DOM et DHTML

Cration d'une publicit contextuelle en Flash


<param name="wmode" value="transparent" />

Les systmes de blocage des fentres contextuelles devenant de plus en plus communs dans les navigateurs, les publicistes sont de plus en plus cratifs. Une fonction nglige des animations Flash intgres dans la page peut tre employe : lorsque vous dfinissez le paramtre wmode sur "transparent", comme dans le code prcdent, l'animation Flash est transparente, vous pouvez donc la placer sur le contenu de la page, ce qui cre une fentre contextuelle. Le fichier flashad.swf est une simple animation Flash qui comprend un bouton faisant disparatre la publicit lorsque l'utilisateur clique dessus. Le code ActionScript suivant (un langage galement fond sur ECMAScript) y parvient en appelant le code JavaScript dans le navigateur :
on (release) { getURL("JavaScript:void(document.getElementById( 'banner').style.visibility='hidden');"); }

Le code de la page lui-mme est assez comparable au code de la section prcdente : comme dans une navigation toujours apparente, l'annonce Flash doit toujours tre visible.
if (window.innerWidth) { x = window.pageXOffset + Math.round((window.innerWidth - navwidth) / 2); y = window.pageYOffset + 10; } else {

Cration d'une publicit contextuelle en Flash

97

with (document.body) { x = scrollLeft + Math.round((clientWidth - navwidth) / 2); y = scrollTop + 10; } }


Bannire publicitaire Flash transparente, section JavaScript (flashad.html, extrait)

La bannire en elle-mme se trouve dans un lment <div>. Attention, l'identifiant de la bannire doit correspondre l'identifiant du code ActionScript qui tente de la rendre invisible.
<div id="banner" style="position: absolute;"> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/ shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="400" height="550" id="flashad"> <param name="movie" value="flashad.swf" /> <param name="quality" value="high" /> <param name="wmode" value="transparent" /> <param name="bgcolor" value="#ffffff" /> <embed src="flashad.swf" quality="high" wmode="transparent" bgcolor="#ffffff" width="400" height="550" name="flashad" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/ getflashplayer" /> </object> </div>
Une bannire publicitaire Flash transparente, section HTML (flashad.html, extrait)

98

CHAPITRE 5 DOM et DHTML

La Figure 5.9 montre le rsultat : la bannire rside sur le contenu de la plage ; de plus, le fond de l'animation Flash est transparent.

Figure 5.9 : Une bannire Flash transparente.

Attention Le fait que les annonces Flash n'utilisent pas de fentres contextuelles ne signifie pas que les utilisateurs soient plus indulgents leur gard. Utilisez donc cette technique avec parcimonie et vrifiez qu'il soit bien possible d'afficher la publicit, sinon le contenu de la page est invisible et l'utilisateur et client potentiel risque galement de disparatre !

6
Programmation oriente objet et vnements
Plus les applications JavaScript sont avances, plus il est ncessaire de structurer le code. Une manire de procder consiste utiliser la programmation oriente objet. JavaScript en lui-mme n'est pas un langage orient objet, mais plutt un langage fond sur les objets. La prise en charge de ce style de programmation est donc assure, mme si elle est assez limite. Le chapitre aborde ensuite la gestion gnrale des vnements dans JavaScript. Outre les bases, vous dcouvrirez des vnements spciaux (clavier et souris).

100 CHAPITRE 6 Programmation oriente objet et vnements

Cration d'une classe


function UniversalClass() { }

Il n'existe pas de mot cl distinctif pour les classes dans JavaScript, chacune se dfinissant sous forme de fonction. La diffrence entre une fonction ordinaire et ce type de fonction rside dans la manire dont elle est ensuite appele, avec le mot cl new. Le listing suivant implmente une classe simple ; aprs instanciation, la bote window.alert() s'affiche.
<script language="JavaScript" type="text/JavaScript"> function UniversalClass() { window.alert("Welcome to my class!"); } var uc = new UniversalClass(); </script>
Une classe simple (class.html)

Accs aux membres des classes


this.Count = count;

Lorsque vous travaillez avec des membres de classe, il est primordial de tous les dfinir explicitement. Pour qu'un code externe puisse accder aux membres des classes (les proprits et les mthodes), il faut utiliser le mot cl this. Ainsi, si vous dfinissez une fonction XYZ() dans la classe, sachez qu'elle devient disponible sous forme de mthode de classe, mais uniquement si vous ajoutez ce code :
this.XYZ = XYZ;

Accs aux membres des classes

101

Dans cette mthode, vous pouvez galement accder aux proprits de classe en utilisant this, mais elles doivent aussi tre dfinies. Pour accder aux membres de classe la fois en interne et en externe, sparez le nom d'instance du nom de membre par un point (.). Le code suivant implmente une classe simple. La seule mthode de classe, Count() (nom interne : count()), prend un paramtre, puis compte dans la langue donne. La Figure 6.1 montre le rsultat.
<script language="JavaScript" type="text/JavaScript"> function UniversalCounter() { this.copyright = "(C) 2006 JavaScript Phrasebook"; this.Count = count; var numbers = { "en": "one, two, three", "fr": "un, deux, trois", "de": "eins, zwei, drei" }; function count(language) { if (numbers[language]) { window.alert(numbers[language]); } else { window.alert("Unknown language"); } } } var uc = new UniversalCounter(); uc.Count("fr"); </script>
Une classe avec des membres (members.html)

102 CHAPITRE 6 Programmation oriente objet et vnements

Figure 6.1 : Le "compteur universel".

Info Un autre moyen de crer des objets consiste utiliser le constructeur Object, de la manire suivante :

var uc = new Object(); uc.copyright = "(C) 2006 JavaScript Phrasebook "; uc.printCopyright = function() { window.alert(this.copyright); };

Emulation de membres de classes prives

103

Emulation de membres de classes prives


JavaScript ne possde pas de modicateurs de classe comme public, protected et private pour choisir les personnes pouvant accder aux membres de classes et celles qui ne le peuvent pas. Toutefois, on le voit la section prcdente, il existe une manire assez simple d'muler des membres de classes prives : si vous "n'enregistrez" pas une variable ou une fonction dans la classe en utilisant le mot cl this, elle n'est visible qu'en interne. Section prcdente, l'objet numbers est inaccessible depuis l'extrieur mais il est utilis en interne par la mthode Count()/count().

Hritage de classes
UniversalCounter.prototype = new UniversalTranslator();

JavaScript ne bnficie d'aucun systme d'hritage pour les classes. Cependant, il est nouveau possible d'muler un lment analogue en utilisant le mot cl prototype, avec lequel vous pouvez fournir des membres de classes valables pour tous les objets, y compris les objets hrits. Lorsque JavaScript doit rechercher une proprit ou une mthode (par exemple lorsque object.methodname() sera excut), il recherche d'abord dans la classe, puis dans l'objet prototype. Cela permet une sorte d'hritage. Dans l'exemple suivant, la classe UniversalTranslator dfinit un membre (copyright). La classe UniversalCounter est ensuite implmente de manire analogue ce qui a t prsent prcdemment. La commande suivante dfinit la proprit prototype de la classe UniversalCounter sur une nouvelle instance de la classe UniversalTranslator.

104 CHAPITRE 6 Programmation oriente objet et vnements

Consquence, la classe UniversalCounter hrite de toutes les proprits de la classe UniversalTranslator et peut y accder :
<script language="JavaScript" type="text/JavaScript"> function UniversalTranslator() { this.copyright = "(C) 2006 JavaScript Phrasebook"; } function UniversalCounter() { this.Count = count; var numbers = { "en": "one, two, three", "fr": "un, deux, trois", "de": "eins, zwei, drei" }; function count(language) { if (numbers[language]) { window.alert(numbers[language] + " [" + this.copyright + "]"); } else { window.alert("Unknown language"); } } } UniversalCounter.prototype = new UniversalTranslator(); var uc = new UniversalCounter(); uc.Count("de"); </script>
Hritage de classe avec prototype (inheritance.html)

Hritage de classes

105

La Figure 6.2 montre que cela fonctionne vritablement : la proprit copyright est accessible depuis la classe UniversalCounter, mme si elle est dfinie dans la classe UniversalTranslator.

Figure 6.2 : La proprit de classe hrite est prsente.

Attention Seuls les membres de classe sont hrits, mais pas le code du constructeur de classe. Pour que ce soit le cas, vous devez dfinir une mthode spcifique comme constructeur de classe et l'appeler manuellement dans la classe drive.

106 CHAPITRE 6 Programmation oriente objet et vnements

Extension d'objets JavaScript intgrs


Date.prototype.isLeapYear = isLeapYear;

La proprit prototype peut aussi servir pour prolonger les classes JavaScript intgres. Dans le code suivant, une fonction isLeapYear() est implmente. Elle dtermine si la valeur de retour de getFullYear() est une anne bissextile. Notez que la mthode getFullYear() n'est pas implmente ; grce prototype, isLeapYear() devient une mthode de l'objet Date et a donc accs Date.getFullYear().
<script language="JavaScript" type="text/JavaScript"> function isLeapYear() { var y = this.getFullYear(); return (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)); } Date.prototype.isLeapYear = isLeapYear; var d = new Date(); window.alert(d.isLeapYear()); </script>
Extension de la classe Date (extend.html)

Raction aux vnements JavaScript


Raction aux vnements JavaScript

107

Amliorations orientes objet apportes JavaScript dans Microsoft Atlas


Le cadre d'aplications Microsoft AJAX Atlas (http:// atlas.asp.net/) implmente galement plusieurs nouvelles extensions orientes objet pour JavaScript, qui simplient la mise en place de quelques techniques orientes objet standard. Parmi ces fonctionnalits, on trouve : les espaces de nom ; l'hritage et l'accs aux mthodes de base ; les classes et les mthodes abstraites ; les interfaces. AJAX faisant actuellement beaucoup d'mules, de plus en plus de bibliothques, assorties d'une prise en charge oriente objet par JavaScript, mergent. Une autre option qui prsente bien le systme oriente objet de JavaScript est prototype.js (http://prototype.conio.net/).

Raction aux vnements JavaScript


button.addEventListener("click", eventHandler, false); button.attachEvent("onclick", eventHandler);

La raction aux vnements JavaScript peut tre ralise de deux manires : b avec l'attribut HTML : <body onload="xyz();"> ; b avec l'attribut JavaScript onXXX : window.onload = xyz;. Il existe toutefois plusieurs mcanismes d'vnements concurrentiels dans les diffrents navigateurs. Internet Explorer accepte que des vnements soient attachs un lment l'aide de la mthode attachEvent(). Le nom de

108 CHAPITRE 6 Programmation oriente objet et vnements

l'vnement ici est gal l'attribut HTML, pour que vous puissiez utiliser "onload", par exemple (mme si l'vnement est appel "load"). Tous les autres grands navigateurs acceptent la mthode addEventListener(), qui fait partie du modle W3C. Ici, vous apportez le nom de l'vnement, donc juste "load" au lieu d'"onload". L'exemple suivant montre comment attacher un vnement un bouton de manire que cela fonctionne dans tous les navigateurs :
<script language="JavaScript" type="text/JavaScript"> function eventHandler() { window.alert("Event fired!"); } window.onload = function() { var button = document.getElementById("eventButton"); if (button.addEventListener) { button.addEventListener("click", eventHandler, false); } else if (button.attachEvent) { button.attachEvent("onclick", eventHandler); } }; </script> <input type="button" id="eventButton" value="Click me!" />
Attachement d'un vnement (attach.html)

Info Vous pouvez galement supprimer les gestionnaires d'vnements. Internet Explorer utilise detachEvent(), tandis que d'autres navigateurs suivent les recommandations du W3C et nomment leurs fonctions removeEventListener().

Comprendre le "bouillonnement" des vnements

109

Comprendre le "bouillonnement" des vnements


En matire de gestion des vnements, les navigateurs actuels optent pour l'un de ces deux concepts. Internet Explorer opre selon ce qu'on appelle le "bouillonnement d'vnements" : un vnement est dclench depuis l'lment dans lequel il survient, puis il remonte la structure DOM. Il est donc possible de le capturer et d'y ragir diffrents endroits. Imaginons le marquage suivant :
<div><p><em>JavaScript</em> Phrasebook</p></div>

Si le curseur de la souris survole le texte JavaScript, l'vnement mouseover est dclench dans l'lment <em>, puis remonte dans les lments <p> et <div>. L'autre modle est celui du W3C, pris en charge par les navigateurs Mozilla, Opera et Safari/Konqueror. Ici, les vnements sont tout d'abord envoys vers le bas, vers l'lment cible, puis ils remontent. Ainsi, dans l'exemple prcdent, l'vnement "visite" les lments <div>, <p> et <em>, puis remonte via les lments <p> et <div>. Lorsque vous ajoutez un couteur d'vnements, vous pouvez indiquer, dans le troisime paramtre de addEventListener(), si l'vnement sera intercept lors de sa descente (true) ou lors de sa remonte (false). Lorsqu'un vnement a t intercept, il est aussi possible de l'empcher de replonger ou de remonter. Dans Internet Explorer, rglez la proprit cancelBubble de l'vnement sur false :
window.event.cancelBubble = false;

Le modle du W3C accepte la mthode stopPropagation().


e.stopPropagation();

Vous le voyez, dans Internet Explorer, l'vnement actuel est toujours disponible via window.event, tandis que d'autres navigateurs reoivent automatiquement l'vnement sous forme de paramtre (ici appel e) pour l'couteur d'vnements.

110 CHAPITRE 6 Programmation oriente objet et vnements

Evnements de clavier
document.onkeydown = showKey;

Les vnements du clavier ne font pas partie de DOM niveau 1 ou 2, mais ils sont implments dans les navigateurs rcents. L'accs aux vnements diffre de la mthode gnrale (window.event dans Internet Explorer ; l'vnement servant de paramtre automatique de la fonction dans tous les autres navigateurs). Mais alors, la proprit keyCode renvoie le code ASCII de la touche, qui peut ensuite tre trait, comme dans le code suivant :
done. Christian<script language="JavaScript" type="text/JavaScript"> function showKey(e) { var key; if (window.event) { key = window.event.keyCode; } else { key = e.keyCode; } key = String.fromCharCode(key); document.getElementById("para").innerHTML += key; } window.onload = function() { document.onkeydown = showKey; } </script> <p id="para">Click and type here: </p>
Ecoute des vnements du clavier (key.html)

La Figure 6.3 prsente les touches qui sont actives.

Envoi d'un formulaire avec la touche Entre

111

Figure 6.3 : Les touches actives sont afches.

Info Tous les caractres de la Figure 6.3 sont prsents en majuscules car JavaScript prend en compte la touche sur laquelle l'utilisateur a appuy, mais non s'il s'agit d'une majuscule ou d'une minuscule. Vous pouvez toutefois savoir si des touches spciales ont t enfonces en tudiant les proprits altKey, ctrlKey et shiftKey.

Envoi d'un formulaire avec la touche Entre


if (key == 13) {document.forms[0].submit(); }

Selon le type et la configuration du navigateur, le fait d'appuyer sur la touche Entre dans un champ de formulaire ne permet pas toujours d'envoyer le formulaire.

112 CHAPITRE 6 Programmation oriente objet et vnements

Quelquefois, par exemple, le bouton qui envoie le formulaire se trouve dans un autre cadre. Dans ce cas, vous pouvez ajouter un peu de code JavaScript pour vous assurer que la touche Entre permet d'envoyer les donnes du formulaire. Il suffit, pour implmenter cette fonctionnalit, d'utiliser l'couteur d'vnement de touche standard de la section prcdente. Le code de la touche Entre est 13. Ainsi, la prsence de ce code indique que le formulaire est envoy :
<script language="JavaScript" type="text/JavaScript"> function checkKey(e) { var key; if (window.event) { key = window.event.keyCode; } else { key = e.keyCode; } if (key == 13) { document.forms[0].submit(); } } window.onload = function() { document.forms[0].elements["field"].onkeydown = checkKey; } </script> <form> <input name="field" type="text" /> </form>
Envoi d'un formulaire lorsque la touche Entre a t active (formsubmit.html)

Evnements de souris

113

Evnements de souris
document.onmousemove = showPosition;

L'utilisation de la souris donne lieu un vnement assez intressant couter (en dehors de click, bien entendu) : mousemove. La position de la souris peut en effet tre dtermine si l'on tudie certaines de ses proprits. Une fois de plus, ces proprits dpendent du groupe de navigateurs auquel appartient le client, Internet Explorer ou le reste du monde : b clientX et clientY pour Internet Explorer ; b pageX et pageY pour tous les autres navigateurs. Voici un listing complet montrant la position actuelle de la souris dans la barre d'tat du navigateur (s'il y en a) :
<script language="JavaScript" type="text/JavaScript"> function showPosition(e) { var x, y; if (window.event) { x = window.event.clientX; y = window.event.clientY; } else { x = e.pageX; y = e.pageY; } window.status = "x: " + x + ", y: " + y; } window.onload = function() { document.onmousemove = showPosition; } </script>
Suivi des mouvements de la souris (mouse.html)

114 CHAPITRE 6 Programmation oriente objet et vnements

Attention Certains navigateurs n'autorisent pas JavaScript actualiser la barre d'tat, notamment les rcentes versions de Firefox. Vous n'obtenez pas de message d'erreur mais la barre d'tat reste inchange. La Figure 6.4 montre le rsultat dans un navigateur qui accepte la modification du texte dans la barre d'tat.

Figure 6.4 : La position de la souris est sans cesse mise jour.

Distinguer les boutons de souris

115

Distinguer les boutons de souris


Pour savoir lequel des boutons de souris a t activ (lorsque vous coutez l'vnement click), les navigateurs proposent, une fois de plus, deux solutions diffrentes. Les deux utilisent la proprit button de la proprit de l'vnement mais les valeurs sont diffrentes. Mozilla se conforme au standard du W3C : 0 dsigne le bouton gauche, 1 le bouton mdian, 2 le bouton droit. Toutefois, le reste du monde, dont Microsoft et d'autres navigateurs, adopte une mthode plus logique : 1 dsigne le bouton gauche, 2 le bouton droit et 4 le bouton du milieu. Comme vous le voyez, ces chiffres sont tous des puissances de 2.Vous pouvez donc associer ces valeurs. Par exemple, la valeur 3 indique que les boutons droite et gauche ont t enfoncs en mme temps.

7
Les cookies
JavaScript est une pure technologie ct client. En thorie, elle peut tre utilise sur le serveur, mais cela n'a rien voir avec une excution dans le navigateur ; la syntaxe est similaire mais le contexte totalement diffrent. JavaScript se limite gnralement la page en cours et n'a pas accs aux lments provenant du serveur. Il existe toutefois quelques trs rares exceptions cette rgle. L'une d'elles est explique au Chapitre 11, "AJAX et sujets annexes". Une autre est traite ici. Les cookies ne sont pas une technologie spcifique au navigateur, mais bien un mcanisme du modle client/ serveur visant surmonter une limitation importante du protocole HTTP. HTTP ne possde pas d'tat, ce qui signifie qu'il ne possde pas de mmoire. Un client ouvre une connexion vers un serveur, rcupre un document (une image ou d'autres donnes), puis ferme la connexion. Par la suite, mme si le serveur envoie des donnes ce client spcifique, il le fera sans le reconnatre.

118 CHAPITRE 7 Les cookies

Les cookies peuvent aider surmonter cette restriction. Un serveur envoie des informations de texte courtes au client, appeles cookie. Si et seulement si ces donnes sont acceptes et enregistres localement, le client les renvoie avec chaque requte adresse au mme serveur. L'application du serveur reconnat alors l'utilisateur. L'aspect intressant, c'est que JavaScript peut la fois obtenir (lire) et dfinir (crire) des cookies, ce qui permet de contourner le protocole HTTP. De nouveaux scnarios apparaissent, jusqu'alors impossibles avec le HTTP simple. Les autres mcanismes permettant d'obtenir un rsultat similaire sont les sessions, mais elles doivent tre implmentes par la technologie ct serveur et ne concernent pas JavaScript.

Les cookies
Lorsqu'un serveur Web envoie un cookie un client, il utilise une entre d'en-tte HTTP ressemblant ceci :
Set-Cookie: session=abcd1234; expires=Tue, 20-Feb-2007 12:10:52 GMT; path=/; domain=.samspublishing.com

Le client reoit ensuite les informations de cookie et, selon ses capacits ou sa configuration, ralise l'une des quatre actions suivantes : b Il ignore le cookie. b Il accepte le cookie. b Il demande l'utilisateur s'il veut accepter le cookie. b Il refuse le cookie.

Les cookies

119

Les premire et dernire actions sont identiques. Il est impossible au serveur Web de savoir si un cookie a t refus par l'utilisateur, refus par la configuration du client ou ignor par le client du fait de l'absence de prise en charge des cookies. S'ils sont accepts, les cookies sont ensuite renvoys au serveur, si une srie de conditions est respecte. L'entre d'en-tte HTTP associe ressemble alors ceci :
Cookie: session=abcd1234

Un cookie peut tre li un domaine et un chemin. Il est donc gnralement renvoy uniquement au serveur metteur. Sachez qu'il est possible d'craser la valeur de domaine dans un cookie, mais certains navigateurs le refusent alors automatiquement. De mme, les cookies prsentent certaines limites. Tous les navigateurs ne les prennent pas en charge de la mme manire, mais les configurations minimales suivantes sont obligatoires : b 4 Ko (4 096 octets) par cookie ; b 20 cookies par domaine ; b 300 cookies au total.
Info Il n'existe pas de spcification officielle des cookies pris en charge dans les navigateurs, mais tous les clients importants acceptent une spcification "prliminaire" et propritaire publie par Netscape dans les annes 1990. Elle est toujours disponible pour consultation l'adresse http://wp.netscape.com/newsrf/ std/cookie_spec.html.

120 CHAPITRE 7 Les cookies

Paramtrage des cookies


document.cookie = "myLanguage=JavaScript";

Le paramtrage d'un cookie avec JavaScript revient paramtrer la proprit cookie de l'objet document. Il est important d'utiliser le mme format que celui du protocole HTTP pour envoyer un cookie au client. Pour les "cookies ordinaires" (sans date d'expiration ni autres restrictions, comme indiqu aux sections suivantes), le nom et la valeur du cookie doivent tre spars par un signe gal (=). Le nom du cookie ne doit pas contenir de caractres spciaux comme des espaces, des points-virgules et des espaces blancs ; ces caractres spciaux doivent tre cods en URL (par exemple, un espace se transforme en %20, la reprsentation hexadcimale de sa valeur ASCII). La spcification recommande le codage, sans le rendre obligatoire. Vous le voyez dans le listing suivant, paramtrer plusieurs cookies peut se faire en rglant plusieurs valeurs sur document.cookie. Ainsi, crire sur document.cookie n'crase pas les cookies prcdents mais en ajoute. Seule exception cette rgle, s'il existe dj un cookie du mme nom, le client tente de l'craser.
<script language="JavaScript" type="text/JavaScript"> document.cookie = "myLanguage=JavaScript"; document.cookie = "myOtherLanguage=PHP:%20Hypertext%20Preprocessor" </script>
Paramtrage d'un cookie avec JavaScript (setcookie.html)

Lecture des cookies

121

La Figure 7.1 montre le rsultat dans le navigateur s'il est configur pour interroger l'utilisateur avant de paramtrer un cookie.

Figure 7.1 : Le navigateur tente de paramtrer le cookie envoy par JavaScript.

Lecture des cookies


var cookies = document.cookie.split(/; /g);

Lorsqu'il accde document.cookie, JavaScript rcupre une liste de tous les cookies que le navigateur doit envoyer au serveur actuel. Malheureusement, cet accs n'est pas disponible sous forme de tableau mais de chane. Par exemple, la section prcdente gnrerait la valeur suivante pour document.cookie :
myLanguage=JavaScript; myOtherLanguage=PHP:%20Hypertext%20Preprocessor

122 CHAPITRE 7 Les cookies

Ainsi, pour rcuprer les cookies de cette valeur, il faudrait suivre les tapes suivantes : 1. Sparer la chane de cookie "; " (pour obtenir des cookies individuels). 2. Identifier le premier signe gal (=) dans chaque cookie comme dlimiteur de valeur et de nom. Puisque les valeurs de cookie peuvent contenir des signes gal, c'est la premire occurrence du signe qui doit tre utilise. Le code suivant affiche tous les cookies sous la forme d'un tableau HTML. Avant d'tre crits dans la page, les caractres spciaux HTML sont correctement chapps grce la fonction HtmlEscape().
<script language="JavaScript" type="text/JavaScript"> document.write("<table><tr><th>Name</th> <th>Value</th></tr>"); var cookies = document.cookie.split(/; /g); for (var i=0; i<cookies.length; i++) { var cookie = cookies[i]; if (cookie.indexOf("=") == -1) { continue; } var name = cookie.substring(0, cookie.indexOf("=")); var value = cookie.substring(cookie.indexOf("=") + 1); document.write("<tr><td>" + HtmlEscape(name) + "</td><td>" + HtmlEscape(unescape(value)) + "</td></tr>"); } document.write("</table>"); </script>
Lecture de cookies (getcookies.html, extrait)

Lecture des cookies

123

La Figure 7.2 montre la sortie possible du listing prcdent.

Figure 7.2 : Tous les cookies du systme sont afchs dans le navigateur.

Lorsque la valeur d'un cookie spcifique est exige, une fonction d'aide peut tre pratique. Elle recherche le nom du cookie donn et renvoie la valeur (tout ce qui se trouve droite du nom du cookie, jusqu'au prochain point-virgule la fin de la chane) :
function getCookie(name) { var pos = document.cookie.indexOf(name + "="); if (pos == -1) { return null; } else { var pos2 = document.cookie.indexOf(";", pos); if (pos2 == -1) { return unescape( document.cookie.substring(pos + name.length + 1)); } else { return unescape( document.cookie.substring(pos + name.length + 1, pos2)); } } }
Lecture d'un seul cookie (getsinglecookie.html)

124 CHAPITRE 7 Les cookies

Astuce N'oubliez jamais d'enlever l'chappement sur les donnes de valeur des cookies. Dans l'exemple donn, cela a t ralis avec unescape() car les cookies originaux ont t chapps l'aide d'escape(). Avec un autre schma d'chappement, vous devez utiliser le mcanisme d'annulation d'chappement adquat dans votre code.

Etablissement d'une date d'expiration


document.cookie="myLanguage=JavaScript; expires=Tue, 25-Dec-2007 12:34:56 GMT"

Par dfaut, les cookies expirent lorsque l'utilisateur ferme le navigateur. Ils sont ensuite appels "cookies temporaires". A l'inverse, on trouve les cookies persistants, qui survivent la fermeture de la session du navigateur. Ils existent toujours lorsque le navigateur est redmarr. Pour que cela fonctionne, le cookie a besoin d'une date d'expiration indiquant la priode pendant laquelle il peut demeurer dans le navigateur. La spcification des cookies exige que la date d'expiration soit indique en GMT (heure de Greenwich) et que le format utilis soit le suivant :
Wdy, JJ-Moi-AAAA HH:MM:SS GMT

Voici une valeur possible :


Tue, 25-Dec-2007 12:34:56 GMT

Le format complique singulirement la dtermination d'informations de date correctes (en particulier pour le jour de la semaine) ; noter que des bibliothques externes peuvent vous venir en aide.

Autres options de cookies

125

Lorsque la date est dtermine, elle doit tre utilise dans la valeur document.cookie, comme l'a montr le code du dbut de cette section (voir expirecookie.html). La Figure 7.3 montre le rsultat de ce code sur un systme utilisant le fuseau horaire GMT +1, donc d'une heure en avance sur l'horaire GMT. Bien entendu, ces informations ne sont affiches que lorsque le navigateur est configur pour interroger l'utilisateur lorsqu'un cookie arrive.

Figure 7.3 : Ce cookie est livr avec une date d'expiration.

Autres options de cookies


document.cookie="myLanguage=JavaScript; expires=Tue, 25-Dec-2007 12:34:56 GMT; path=/; domain=.example.com; secure"

Mme si la date d'expiration d'un cookie est de loin la fonction la plus utilise, il en existe d'autres : b path. Dfinit le chemin pour accder au cookie. La valeur par dfaut correspond au chemin en cours. Si elle est rgle sur /, l'ensemble du site reoit le cookie.

126 CHAPITRE 7 Les cookies

b domain. Prcise le(s) domaine(s) utiliser. Selon la spcification, au moins deux points sont ncessaires dans le nom de domaine, mais de nombreux navigateurs ignorent cette spcificit. Si elle est rgle sur .exemple.com, www.exemple.com et sousdomaine.exemple.com reoivent le cookie. b secure. Si cette fonction est configure, c'est--dire simplement place dans la chane du cookie, celui-ci n'est transmis que par une connexion scurise (HTTPS). Le code qui prcde paramtre un cookie li au domaine .exemple.com et sera transmis par des connexions HTTPS uniquement. Notez que le listing associ (cookieoptions .html) ne fonctionnera probablement pas sur votre systme moins que ne vous modifiiez le nom de domaine, pour utiliser le vritable nom de domaine employ.
Attention Pour craser un cookie, assurez-vous d'utiliser les mmes fonctions (name, path, domain, secure) que lors de sa dfinition ; sa date d'expiration et sa valeur peuvent bien entendu changer. Le navigateur cre alors un nouveau cookie.

Suppression de cookies
document.cookie="myLanguage=JavaScript; expires=Thu, 25-Dec-1980 12:34:56 GMT"

Le paramtrage d'une valeur de cookie sur une chane vide dtruit efficacement les donnes du cookie mais n'limine pas le cookie lui-mme. Pour s'en dbarrasser, il faut dfinir sa date d'expiration sur une date passe. Puisque la mesure

Vrification de la prise en charge des cookies

127

Utilisation de cookies HTTP uniquement


Les versions rcentes du navigateur Web Internet Explorer de Microsoft prennent en charge une option supplmentaire pour les cookies : HttpOnly. Si elle est dnie, le cookie est transmis par HTTP uniquement mais ne peut pas tre lu avec JavaScript. Cette option permet d'viter certains problmes de scurit de quelques sites Web qui autorisent le vol de donnes de cookies sensibles avec JavaScript. Toutefois, HttpOnly est une option propritaire et n'est prise en charge que par les navigateurs Microsoft. Vous en saurez plus l'adresse http://msdn.microsoft .com/workshop/author/dhtml/httponly_cookies.asp.

du temps UNIX commence le 1er janvier 1970, optez pour une date proche de ce jour. Le code qui prcde (voir deletecookie.html) utilise la date de Nol 1980. Le navigateur Web constate que cette date est passe ( moins que l'utilisateur n'ait modifi les paramtres rgionaux) et supprime le cookie. Une fois de plus, utilisez les mmes fonctions de cookie que celles de son paramtrage.

Vrication de la prise en charge des cookies


document.cookie="CookieTestTemp=success" document.cookie="CookieTestPers=success; expires=Tue, 25-Dec-2012 12:34:56 GMT"

La seule manire de dcouvrir si un cookie a t paramtr consiste le rechercher lors de la prochaine requte

128 CHAPITRE 7 Les cookies

au serveur. Avec JavaScript, l'opration peut tre ralise instantanment dans une page. Le code suivant dfinit d'abord deux cookies (l'un temporaire et l'autre persistant) et vrifie si ces deux actions ont russi. Les cookies de test sont nouveau effacs, uniquement si leur paramtrage a russi.
<script language="JavaScript" type="text/JavaScript"> document.cookie="CookieTestTemp=success" document.cookie="CookieTestPers=success; expires= Tue, 25-Dec-2012 12:34:56 GMT" if (document.cookie.indexOf( "CookieTestTemp=success") != -1) { window.alert("Temporary cookies are supported!") document.cookie="CookieTestTemp=JavaScript; expires=Thu, 25-Dec-1980 12:34:56 GMT" } else { window.alert( "Temporary cookies are not supported!") } if (document.cookie.indexOf( "CookieTestPers=success") != -1) { window.alert("Persistent cookies are supported!") document.cookie="CookieTestPers=JavaScript; expires=Thu, 25-Dec-1980 12:34:56 GMT" } else { window.alert( "Persistent cookies are not supported!") } </script>
Vrification de la prise en charge des cookies par le navigateur (checkcookie.html)

Enregistrement de plusieurs informations dans un cookie

129

Enregistrement de plusieurs informations dans un cookie


for (var el in data) {namevalue += "&" + escape(el) + "=" + escape(data[el]); }

N'oubliez pas que des restrictions s'imposent un site dirig par les cookies : seuls 20 cookies par domaine sont autoriss. Si les utilisateurs reoivent un avertissement l'arrive d'un cookie, plus vous en envoyez et plus vous risquez de les ennuyer. Stocker plusieurs informations dans un seul cookie peut donc tre intelligent. Pour cela, il faut srialiser les donnes du cookie. Il existe diffrentes manires, dont certaines sont trs avances. Toutefois, pour stocker une liste de paires nom/valeur, le plus simple reste le codage URL :
function serialize(data) { var namevalue = ""; for (var el in data) { namevalue += "&" + escape(el) + "=" + escape(data[el]); } return namevalue.substring(1); }
Srialisation d'un objet (serialize.html, extrait)

Lorsqu'un cookie contient des donnes complexes, on peut utiliser un code comparable celui-ci :
document.cookie = "data=" + serialize(myComplexData)

130 CHAPITRE 7 Les cookies

L'opration inverse ncessite un peu plus de code, mais consiste principalement sparer les donnes en paires individuelles et extraire les noms et les valeurs du rsultat :
function unserialize(data) { var object = new Array(); var pairs = data.split(/&/g); for (var i=0; i<pairs.length; i++) { if (pairs[i].indexOf("=") > -1) { object[unescape(pairs[i].substring( 0, pairs[i].indexOf("=")))] = unescape(pairs[i].substring( pairs[i].indexOf("=") + 1)); } } return object; }
Dsrialisation d'un objet (serialize.html, extrait)

Le fichier de code serialize.html srialise et dsrialise un objet, sans utiliser de cookies pour raccourcir un peu le code.
Info Vous trouverez l'adresse http://www.iconico.com/workshop/ jsSerialiszer/ un srialiseur plus complexe, qui transforme un objet en XML. Le Chapitre 11, "AJAX et sujets annexes", propose aussi de plus amples informations, dans sa partie consacre au JSON.

8
Les formulaires

Les formulaires sont un aspect trs utile du HTML lorsqu'on travaille avec les technologies ct serveur car ils permettent de "communiquer" avec le serveur : des donnes sont saisies dans le formulaire qui est ensuite envoy au serveur. Les formulaires HTML sont galement trs intressants pour JavaScript. Leurs options sont quelque peu limites, mais JavaScript apporte son aide. Attention, les donnes utilisateur devront tre valides, les formulaires peuvent n'accepter que certains types d'entres, l'envoi de formulaires peut n'tre possible que lorsque certaines exigences sont respectes, etc. Tout cela, et bien d'autres choses, est rendu possible par JavaScript, comme vous allez le voir.

132 CHAPITRE 8 Les formulaires

Formulaires HTML avec JavaScript


document.forms[0]

Gnralement, on accde un lment HTML grce son identifiant, puis avec document.getElementById(). Toutefois, pour les formulaires HTML, on utilisera document.forms. En effet, on fait appel l'attribut de nom de chaque lment de formulaire pour l'envoyer au serveur.
document.forms reprsente un tableau de tous les formulaires de la page en cours. Ainsi, si la page ne contient qu'un formulaire, on y accde par document.forms[0]. Les formulaires peuvent aussi obtenir un nom : <form name="mainForm"> ... </form> On accde alors au formulaire avec document.forms ["mainForm"].

Tous les lments du formulaire sont galement rfrencs par leurs noms, qui servent d'indices de tableau pour sa proprit elements. Imaginons que le premier formulaire d'une page possde un lment portant l'attribut name="element1". Le code JavaScript suivant y accde : document.forms[0].elements["element1"] Il existe d'autres manires, plus courtes, d'accder ces informations. Ainsi, un formulaire nomm "mainForm" et un lment "element1" permettent ce raccourci : document.mainForm.element1 On emploie habituellement la manire plus dtaille qui fait appel au tableau forms et plus particulirement au tableau elements, car elle n'est autorise qu'avec un accs automatis aux lments de formulaire.

Accs aux champs de texte

133

JavaScript est capable de modifier les lments de formulaire, d'agir sur certains vnements dclenchs et d'envoyer le formulaire (ou d'empcher son envoi). De mme, il montre toute son utilit dans le domaine de la validation des donnes de formulaire mais gardez toujours l'esprit qu'il peut tre dsactiv : le formulaire doit donc galement fonctionner sans JavaScript.
Astuce Chaque lment de formulaire accepte la proprit form, qui pointe vers le formulaire dans lequel il rside. Ainsi, this.form est souvent employ dans le code pour que des lments de champ de formulaire accordent un accs facile au formulaire de l'lment, sans avoir parcourir le tableau document.forms.

Accs aux champs de texte


window.alert(f.elements["textfield"].value);

HTML accepte trois types de champs : b des champs de texte sur une seule ligne : <input type="text" /> ; b des champs de texte sur plusieurs lignes : <textarea></textarea> ; b des champs de mot de passe : <input type="password" />. Ces champs se comportent diffremment dans un navigateur Web, mais l'accs depuis JavaScript est assez similaire pour les trois. Leur attribut value contient le texte du champ. Il peut servir pour lire et pour crire le texte du champ.

134 CHAPITRE 8 Les formulaires

Le code suivant montre deux choses : comment accder la proprit du champ, puis comment utiliser this.form pour offrir un accs facile au formulaire du champ.
<script language="JavaScript" type="text/JavaScript"> function showText(f) { window.alert(f.elements["textfield"].value); } </script> <form> <input type="text" name="textfield" /> <input type="button" value="Show text" onclick="showText(this.form);" /> </form>
Accs un champ de texte (textfield.html)

La Figure 8.1 montre ce qui se passe si un utilisateur entre du texte dans le champ puis clique sur le bouton.

Figure 8.1 : Le texte apparat aprs que l'utilisateur a cliqu sur le bouton.

Accs aux cases cocher

135

Info Cette mthode, qui utilise la proprit value pour accder aux donnes du champ de formulaire, fonctionne galement pour les champs masqus (<input type="hidden" />).

Accs aux cases cocher


f.elements["chkbox"].checked ? "checked." : "not checked."

Une case cocher HTML ne connat que deux tats, coche ou non coche. Lorsque vous travaillez avec JavaScript, le scnario le plus commun consiste accder cet tat. La proprit checked de la case cocher est une valeur boolenne renvoyant true si la case est coche et false dans le cas contraire. Le code suivant illustre cela :
<script language="JavaScript" type="text/JavaScript"> function showStatus(f) { window.alert("The checkbox is " + (f.elements["chkbox"].checked ? "checked." : "not checked.")); } </script> <form> <input type="checkbox" name="chkbox" /> <input type="button" value="Show status" onclick="showStatus(this.form);" /> </form>
Accs une case cocher (checkbox.html)

136 CHAPITRE 8 Les formulaires

Accs des boutons radio


var btn = f.elements["radiobutton"][i]; s += btn.value + ": " + btn.checked + "\n";

A la diffrence des cases cocher, les boutons radio HTML sont toujours prsents par groupe. Cela signifie que plusieurs boutons radio peuvent avoir le mme attribut name, mais que leurs attributs value diffrent. Ainsi,
document.forms[nombre].elements[groupeboutonsradio]

accde l'ensemble du groupe de boutons radio, c'est--dire un tableau. Chaque sous-lment de ce tableau correspond un bouton radio et accepte la proprit checked, laquelle fonctionne de la mme manire que celle de la case cocher : true signifie que le bouton radio est activ et false le contraire. L'accs la valeur de chaque bouton est galement possible : c'est la proprit value qui s'en occupe. Le code suivant analyse tous les boutons radio et donne leur tat :
<script language="JavaScript" type="text/JavaScript"> function showStatus(f) { var s = ""; for (var i=0; i<f.elements["radiobutton"].length; i++) { var btn = f.elements["radiobutton"][i]; s += btn.value + ": " + btn.checked + "\n"; } window.alert(s); } </script> <form> <input type="radio" name="radiobutton" value="R" />red

Accs des listes de slection

137

<input type="radio" name="radiobutton" value="G" />green <input type="radio" name="radiobutton" value="B" />blue <input type="button" value="Show status" onclick="showStatus(this.form);" /> </form>
Accs un groupe de boutons radio (radiobutton.html)

Accs des listes de slection


var index = f.elements["selectionlist"].selectedIndex;

Une liste de slection HTML comprend un lment <select>, qui pose les bases de la liste et fournit son nom complet (dans son attribut name). Les lments de liste sont reprsents par deux sections <option> et contiennent une lgende (les donnes prsentes dans le navigateur) et une valeur (les donnes envoyes au serveur lorsque le formulaire est envoy). Lorsque vous travaillez avec JavaScript, deux manires d'accder aux donnes de liste sont possibles : b selectedIndex. Fournit l'indice (en commenant par 0) de l'lment de liste actuellement slectionn ; une valeur de -1 signifie qu'aucune valeur n'a t slectionne (applicable uniquement pour les listes dont la taille est suprieure 1). b options. Reprsente un tableau comptant toutes les options de liste. Chaque option accepte la proprit selected. Lorsqu'elle renvoie true, cela signifie que l'option de liste est slectionne.

138 CHAPITRE 8 Les formulaires

Gnralement, selectedIndex suffit pour la validation. La mthode avec options est assez pratique lorsqu'on accde galement l'lment de liste slectionn. Ensuite, l'attribut value de l'option slectionne fournit des donnes envoyes au serveur et la proprit text renvoie la lgende visible dans le navigateur. Le listing suivant accde toutes les informations importantes concernant l'option slectionne :
<script language="JavaScript" type="text/JavaScript"> function showStatus(f) { var index = f.elements["selectionlist"].selectedIndex; if (index == -1) { window.alert("No element selected"); } else { var element = f.elements["selectionlist"] .options[index]; window.alert("Element #" + index + " (caption: " + element.text + ", value: " + element.value + ") selected"); } } </script> <form> <select name="selectionlist" size="3"> <option value="R">red</option> <option value="G">green</option> <option value="B">blue</option> </select> <input type="button" value="Show status" onclick="showStatus(this.form);" /> </form>
Accs une liste de slection (selectionlist.html)

Accs une liste choix multiple

139

Info Les navigateurs rcents acceptent galement le raccourci suivant pour accder la valeur de l'lment de liste actuellement slectionn :

f.elements["selectionlist"].value
Toutefois, pour assurer la compatibilit maximale avec le navigateur, la technique suivante ncessite un peu plus de saisie, mais fonctionne galement sur les navigateurs plus anciens :

f.elements["selectionlist"].options[ f.elements["selectionlist"].selectedIndex].value

Accs une liste choix multiple


s += "Element #" + i + " (" + option.text + "/" + option.value + ") " + (option.selected ? "selected." : "not selected.") + "\n";

Lorsqu'une liste de slection HTML rcupre l'attribut multiple="multiple", il est possible de slectionner plusieurs lments. Dans ce cas, la proprit selectedIndex n'est plus trs utile car elle informe uniquement sur le premier lment slectionn dans la liste. Il faut alors utiliser une boucle for pour parcourir tous les lments de la liste. Lorsque la proprit selected vaut true, cela signifie que l'lment de liste est slectionn. Le code suivant donne des informations sur tous les lments de liste et indique notamment s'ils sont slectionns :
<script language="JavaScript" type="text/JavaScript"> function showStatus(f) { var s = "";

140 CHAPITRE 8 Les formulaires

var list = f.elements["selectionlist"]; for (var i=0; i<list.options.length; i++) { var option = list.options[i]; s += "Element #" + i + " (" + option.text + "/" + option.value + ") " + (option.selected ? "selected." : "not selected.") + "\n"; } window.alert(s); } </script> <form> <select name="selectionlist" size="3" multiple="multiple"> <option value="R">red</option> <option value="G">green</option> <option value="B">blue</option> </select> <input type="button" value="Show status" onclick="showStatus(this.form);" /> </form>
Accs une liste choix multiples (selectionlistmultiple.html)

Figure 8.2, seuls quelques lments sont slectionns.

Figure 8.2 : Certains lments sont slectionns.

JavaScript et l'envoi de fichiers

141

JavaScript et l'envoi de chiers


JavaScript permet aussi d'accder aux lments HTML pour l'envoi de chiers (<input type="file" />). Toutefois, au cours de ces dernires annes, les dveloppeurs de navigateurs Web ont de plus en plus restreint l'accs JavaScript ce type de champ de formulaire. Et il existe une bonne raison cela. Imaginez un code JavaScript hostile qui dnisse la valeur du champ de chargement de chiers sur /etc/passwd par exemple, puis envoie automatiquement le formulaire. Cela n'est gnralement plus possible. De mme, certains navigateurs afchent un message ds que les chiers sont chargs avec un formulaire (voir la Figure 8.3). Vous devez donc viter de contrler les champs d'envoi de formulaires avec JavaScript ; ils fonctionnent correctement avec le HTML de base et la technologie ct serveur.

Figure 8.3 : Konqueror vous avertit que des chiers sont envoys avec le formulaire.

142 CHAPITRE 8 Les formulaires

Dsactivation des lments de formulaire


f.elements["password"].disabled = true;

Parfois, il est important que les lments de formulaire ne puissent pas tre modifis. Les scnarios suivants n'en sont que quelques exemples : b des lments de formulaires permettant d'afficher des donnes, par exemple de longs contrats de licence emballs dans un champ <textarea> ; b des lments activs ou dsactivs par interaction de l'utilisateur ; b des donnes sous forme d'lments "verrouills", utilises lorsque le formulaire est envoy. JavaScript propose plusieurs options pour parvenir cet effet. Chaque lment de formulaire prend en charge la proprit disabled. Lorsqu'elle est dfinie sur true, l'lment devient gris et ne peut plus tre modifi. Le listing suivant prsente un formulaire pour s'identifier et qui peut aussi tre utilis pour s'inscrire ; si l'utilisateur souhaite s'inscrire, on ne lui demande plus son mot de passe. Le champ du mot de passe peut donc tre gris lorsque le formulaire passe en mode inscription :
<script language="JavaScript" type="text/JavaScript"> function enable(f) { f.elements["password"].disabled = false; } function disable(f) { f.elements["password"].disabled = true;

Dsactivation des lments de formulaire

143

} </script> <form> <input type="radio" name="radiobutton" value="login"checked="checked" onclick="enable(this.form);" />Login <input type="radio" name="radiobutton" value="register" onclick="disable(this.form);" />Register<br /> Username <input type="text" name="username" /> <br /> Password <input type="password" name="password" /><br /> </form>
Dsactivation des lments de formulaire (disabled.html)

A la Figure 8.4, on peut constater les effets de ce code : le champ de texte est gris lorsque le bouton radio Register est slectionn.

Figure 8.4 : Le champ de mot de passe est maintenant dsactiv.

144 CHAPITRE 8 Les formulaires

Il n'est parfois pas souhaitable qu'un champ soit gris. Pour dsactiver un lment de formulaire, on peut galement utiliser sa proprit JavaScript readOnly. Lorsqu'elle est rgle sur true, l'apparence du champ de formulaire reste la mme mais le champ ne peut plus tre modifi. Voici le code qui l'implmente :
function enable(f) { f.elements["password"].readOnly = false; } function disable(f) { f.elements["password"].readOnly = true; }
Cration d'lments de formulaire en lecture seule (readonly.html, extrait)

Info Les anciens navigateurs faisaient appel une autre astuce simple pour mettre les champs de texte en lecture seule. Une fois que le champ obtenait le focus, celui-ci disparaissait immdiatement :

<input type="text" onfocus="this.blur();" />

Attention Vous pouvez utiliser JavaScript pour dsactiver un champ de formulaire ou le mettre en lecture seule, mais sachez que JavaScript peut facilement tre dsactiv et qu'une requte HTTP peut galement tre contrefaite. Ne vous fiez donc pas cet effet de JavaScript et validez toujours vos donnes ct serveur !

Envoi d'un formulaire

145

Envoi d'un formulaire


document.forms[0].submit();

Gnralement, un bouton d'envoi (<input type="submit" />) ou une image d'envoi (<input type="image" />) permet d'envoyer les donnes du formulaire au serveur Web. JavaScript peut aussi employer sa mthode submit(). Cela permet au programmeur d'utiliser un lien HTML mais aussi d'augmenter la flexibilit pour le concepteur. N'oubliez pas que le code suivant ne fonctionne que lorsque JavaScript est activ :
<form> <input type="hidden" name="field" value="data" /> </form> <a href="JavaScript:document.forms[0].submit();"> Submit form</a>
Envoi d'un formulaire (submit.html)

Empcher l'envoi
<form onsubmit="return checkform(this);">

Il existe de bonnes raisons d'empcher le navigateur d'envoyer un formulaire, par exemple lorsque certains champs obligatoires n'ont pas t remplis. Pour ce faire, il faut renvoyer false dans le code de gestion de l'vnement submit du formulaire : <form onsubmit="return false;"> Bien entendu, le code doit dcider, en fonction des donnes entres, si le formulaire peut tre envoy. C'est gnralement une fonction personnalise qui s'en occupe et renvoie, au final, true ou false.

146 CHAPITRE 8 Les formulaires

Le formulaire suivant ne peut tre envoy que s'il existe une valeur dans le champ de texte :
<script language="JavaScript" type="text/JavaScript"> function checkform(f) { if (f.elements["textfield"].value == "") { return false; } else { return true; } } </script> <form onsubmit="return checkform(this);"> Username <input type="text" name="textfield" /> <input type="submit" value="Submit data" /> </form>
Le formulaire ne peut tre envoy que lorsque le champ de texte est rempli (nosubmit.html)

Une fois de plus, cela ne fonctionne que lorsque JavaScript est activ, raison de plus pour valider toutes les donnes ct serveur !

Eviter les envois rpts de formulaires


<form action="delay.php"> <input type="submit" value="Submit data" onclick="this.disabled = true;"/> </form>

Lorsque le script qui analyse les donnes de formulaire est long s'excuter, les utilisateurs ont tendance essayer d'acclrer les choses en cliquant de nouveau sur le bouton

Eviter les envois rpts de formulaires

147

d'envoi. Or, notamment pendant des oprations d'achat en ligne, paiements par carte de crdit et autres transactions importantes, le rsultat peut tre assez onreux. La page Web doit donc interdire d'elle-mme les envois rpts de formulaires. Le code qui prcde (dans le fichier prevent.html des tlchargements de code de cet ouvrage) en est un exemple : lorsque l'utilisateur clique sur le bouton d'envoi, sa proprit disabled est rgle sur true, ce qui interdit de cliquer nouveau sur le bouton (si JavaScript est activ). La Figure 8.5 en montre le rsultat dans le navigateur. Le bouton est gris.

Figure 8.5 : Il est impossible de cliquer deux fois sur le bouton.

Le listing prcdent et le listing suivant envoient tous deux les donnes de formulaire vers un script PHP appel delay.php, lequel attend cinq secondes avant d'envoyer les donnes. Cela mule une connexion ou un serveur lent, le scnario adopt dans cette section.

148 CHAPITRE 8 Les formulaires

Une autre manire consiste maintenir le bouton actif, mais dterminer si l'utilisateur a dj cliqu dessus, comme le montre le listing suivant :
<script language="JavaScript" type="text/JavaScript"> var submitted = false; function checkform(f) { if (submitted) { window.alert("Form has already been submitted!"); return false; } else { submitted = true; return true; } } </script> <form action="delay.php" onsubmit="return checkform(this);"> <input type="submit" value="Submit data" /> </form>
Empcher l'envoi rpt d'un formulaire en maintenant le bouton d'envoi actif (prevent-status.html)

Attention Mme si ce procd est assez commode, vous devez savoir que, parfois, le serveur ferme la connexion au client de manire inattendue (ou vice versa). Le transfert de donnes s'arrte alors mais le code JavaScript ne le sait pas. Consquence, il est impossible de cliquer deux fois sur le bouton (comme prvu initialement) mais les donnes n'ont pas t correctement transmises. L'utilisateur doit donc recharger le formulaire pour pouvoir nouveau envoyer les donnes.

Donner le focus un champ

149

Donner le focus un champ


document.forms[0].elements["textfield"].focus();

La plupart des sites Web de recherche, comme Google, possdent une fonction pratique : ds que la page est charge, le curseur se place automatiquement dans le champ de recherche. L'opration est assez facile raliser grce au code prcdent ; la mthode focus() donne le focus au champ de formulaire. Le listing complet est disponible dans le fichier focus.html.
Attention Sachez que plus votre page est importante, plus elle contient de champs de formulaire et plus cette fonction peut tre inadapte. Imaginez une page qui se charge lentement. Pendant ce temps, l'utilisateur peut avoir dj avanc dans un autre champ. A la fin du chargement, ce code met le focus sur le premier champ, en l'tant du champ dans lequel se trouve actuellement l'utilisateur.

Slection de texte dans un champ


field.setSelectionRange(0, field.value.length);

Les champs de texte sont parfois prremplis d'une mention expliquant l'utilisateur ce qu'il doit faire, comme ceci :
<input type="text" name="textfield" value="&lt;Enter data here&gt;" />

C'est un peu gnant lorsque l'utilisateur tente de saisir quelque chose dans le champ : il doit d'abord slectionner cette mention pour pouvoir l'craser. Si le texte tait prslectionn, l'opration serait plus facile.

150 CHAPITRE 8 Les formulaires

Les principaux navigateurs acceptent la slection d'un texte dans un champ, mais une autre faon d'oprer existe. Avec Internet Explorer, il faut appeler la mthode createTextRange() du champ, qui cre une plage de slection. Les mthodes moveStart() et moveEnd() en dfinissent les limites ; la mthode select() slectionne ensuite le texte. Les navigateurs Mozilla d'une part et les navigateurs Opera et Konqueror/KDE d'autre part disposent d'une autre interface pour cette fonctionnalit. La mthode setSelectionRange() slectionne le contenu d'un champ. Elle attend comme second paramtre la longueur de la plage, tandis que moveEnd() dans Internet Explorer attend la position du dernier caractre slectionner. Le listing suivant slectionne l'ensemble du texte dans les principaux navigateurs puis tablit le focus sur le champ. Ainsi, si l'utilisateur commence taper du texte, la mention de dpart est immdiatement remplace.
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { var field = document.forms[0] .elements["textfield"]; if (field.createTextRange) { var range = field.createTextRange(); range.moveStart("character", .0); range.moveEnd("character", field.value.length - 1); range.select(); } else if (field.setSelectionRange) { field.setSelectionRange(0, field.value.length); } field.focus(); }; </script> <form> <input type="text" name="textfield" value="&lt;Enter data here&gt;" /> </form>
Prslection de texte dans un champ (selecttext.html)

Slection de texte dans un champ

151

La Figure 8.6 montre le rsultat. Lorsque ce champ de formulaire sera valid, la valeur par dfaut ne sera pas considre comme une donne valable.

Figure 8.6 : Le texte est sectionn et le champ a le focus.

Astuce Vous pouvez envisager de ne prremplir le champ que si JavaScript est disponible ; dans le cas contraire, les utilisateurs devront slectionner manuellement (et supprimer) la mention pralable du champ de texte, ce que permet le code suivant :

field.value = "<Enter data here>";

152 CHAPITRE 8 Les formulaires

Vider les champs de texte en cas de clic


if (this.value == originaldata) { this.value = ""; }

Une autre fonction utile de l'expression prcdente consiste effacer le champ de texte si l'utilisateur clique dedans (la prslection du texte est efface dans ce cas). Toutefois, il ne suffit pas d'ajouter onclick="this.value"='';" la balise <input>. Imaginez que l'utilisateur ait saisi des donnes personnalises dans le champ, puis dcid de le quitter, le texte disparatrait et l'utilisateur probablement aussi. Il faut donc enregistrer le texte original lors du chargement de la page. Ainsi, lorsque l'utilisateur clique dans le champ de texte et que le texte qui s'y trouve est le texte original, le champ peut tre vid, comme le montre le listing suivant :
<script language="JavaScript" type="text/JavaScript"> var originaldata; window.onload = function() { var field = document.forms[0] .elements["textfield"]; originaldata = field.value; if (field.createTextRange) { var range = field.createTextRange(); range.moveStart("character", .0); range.moveEnd("character", field.value.length - 1); range.select(); } else if (field.setSelectionRange) { field.setSelectionRange(0, field.value.length); } field.focus(); field.onclick = function() {

Validation des champs de texte

153

if (this.value == originaldata) { this.value = ""; } }; } </script> <form> <input type="text" name="textfield" value="&lt;Enter data here&gt;" /> </form>
Effacement du champ (clear.html)

Notez que l'vnement focus ne peut pas tre utilis pour cette tche ; Internet Explorer effacerait immdiatement le champ en cas de chargement du document (mme si l'appel focus() survient avant que le gestionnaire d'vnements ne soit paramtr).

Validation des champs de texte


if (field.value.replace(/\s/g, "") == "") { window.alert("Invalid data!"); field.focus();

La validation des donnes fournies par l'utilisateur peut prendre plusieurs aspects. Quelquefois, il est important de vrifier qu'un champ obligatoire a t rempli, d'autres moments, il convient de procder une validation prcise des donnes. Le code prcdent (fichier mandatory.html) vrifie les donnes d'un champ de texte. La mthode JavaScript replace() supprime l'espace blanc (expression rgulire /\s/g) dans la chane puis vrifie s'il reste quelque chose, de sorte que les caractres d'espacement ne satisfassent pas eux seuls la condition "vider ce champ".

154 CHAPITRE 8 Les formulaires

Validation de formulaires
JavaScript est un trs bon outil pour valider les formulaires la vole. Il permet de communiquer des commentaires immdiats aux utilisateurs sur les donnes saisies (par exemple, en utilisant un lment du style onblur="validateData (this);"), mais vous devez toujours envisager que JavaScript puisse tre dsactiv et les requtes HTTP ne doivent pas provenir d'un navigateur Web. Ainsi, avant d'utiliser les donnes du client, validez-les galement sur le serveur. Vriez galement que le formulaire lui-mme fonctionne lorsque JavaScript est dsactiv, puisque environ 10 % des utilisateurs ne peuvent pas utiliser ce langage de script (ou ne le veulent pas). Enn, la validation elle-mme ne doit tre qu'une fonction de commodit pour les utilisateurs et non un outil nervant, masquant les informations pour le visiteur. Utilisez-la donc avec mesure.

Dans le listing suivant, les donnes du champ de texte sont valides par rapport une expression rgulire identifiant un code postal amricain :
<script language="JavaScript" type="text/JavaScript"> function validate(field) { var regex = /^\d{5}$/; if (!regex.test(field.value)) { window.alert("Invalid postal code!"); field.value = ""; field.focus(); } } </script>

Validation de cases cocher

155

<form onsubmit="return checkform(this);"> US postal code <input type="text" name="code" onblur="validate(this);" /> </form>
Validation d'un champ par rapport une expression rgulire (mandatory-regex.html)

Validation de cases cocher


if (!f.elements["terms"].checked) { window.alert("Terms &amp; conditions must be accepted!"); f.elements["terms"].focus(); return false; } else { return true; }

Lorsqu'une case doit tre coche, sa proprit checked doit valoir true, faute de quoi le formulaire ne doit pas pouvoir tre envoy. Le code qui prcde, disponible dans un listing complet (fichier mandatory-checkbox.html), montre le code qui pourrait tre appel au dclenchement de l'vnement submit du formulaire.

Validation de boutons radio


if (radio.checked) { return true; }

Lorsqu'un groupe de boutons radio est obligatoire, il suffit que l'un de ses boutons soit activ (en fait, il n'est pas possible d'activer plusieurs boutons par groupe, mais il est toujours possible qu'aucun ne le soit). Grce au tableau elements du formulaire, le groupe de boutons radio peut

156 CHAPITRE 8 Les formulaires

tre slectionn sous forme de tableau, dans lequel il est ncessaire qu'il y ait au moins un bouton radio dans lequel checked vaut true pour que le groupe soit considr rempli. Le listing suivant implmente cette vrification :
<script language="JavaScript" type="text/JavaScript"> function checkform(f) { for (var i=0; i<f.elements["colors"].length; i++) { var radio = f.elements["colors"][i]; if (radio.checked) { return true; } } // aucun bouton coch window.alert("No color selected!"); f.elements["colors"][0].focus(); return false; } </script> <form onsubmit="return checkform(this);"> <input type="radio" name="colors" value="R" /> red<br /> <input type="radio" name="colors" value="G" /> green<br /> <input type="radio" name="colors" value="B" /> blue<br /> <input type="submit" value="Submit data" /> </form>
Validation d'un groupe de boutons radio (mandatory-radio.html)

Validation des listes de slection

157

Info Vous pouvez envisager une manire moins ostentatoire d'avertir l'utilisateur d'une erreur dans le formulaire. Vous pourriez par exemple utiliser DOM ou l'objet Image pour afficher une petite icne d'erreur prs de tous les champs n'ayant pas t correctement remplis. Cela convient bien sr pour toutes les expressions de validation de ce chapitre.

Validation des listes de slection


if (f.elements["colors"].selectedIndex == -1) { window.alert("No color selected!"); f.elements["colors"].focus(); return false; } else { return true; }

Il existe plusieurs manires de valider une liste de slection. La plus simple consiste vrifier sa proprit selectedIndex. Si sa valeur est -1, cela signifie qu'aucun lment n'a t slectionn et que le formulaire n'a donc pas t suffisamment rempli. Le code qui prcde en est une illustration (version complte dans le fichier mandatory-list.html). Cependant, cette mthode ne fonctionne que lorsque la liste de slection possde un attribut size paramtr sur une valeur suprieure 1 et ne contient pas d'lment vide ( des fins de dmonstration). Mieux encore, vous pouvez rechercher les attributs value de tous les lments slectionns. Si la valeur est une chane vide, l'lment n'est pas pris en compte. Une boucle for passe en revue tous les lments de la liste la recherche des lments slectionns affichant une valeur relle. Cette procdure possde aussi l'avantage de fonctionner avec plusieurs listes de slection.

158 CHAPITRE 8 Les formulaires

<script language="JavaScript" type="text/JavaScript"> function checkform(f) { for (var i=0; i<f.elements["colors"].options.length; i++) { var element = f.elements["colors"].options[i]; if (element.selected && element.value != "") { return true; } } window.alert("No color selected!"); f.elements["colors"].focus(); return false; } </script> <form onsubmit="return checkform(this);"> <select name="colors" size="9" multiple="mul tiple"> <option value="">Select a color</option> <option value="R">red</option> <option value="G">green</option> <option value="B">blue</option> <option value="">-</option> <option value="C">cyan</option> <option value="M">magenta</option> <option value="Y">yellow</option> <option value="K">black</option> </select> <input type="submit" value="Submit data" /> </form>
Validation d'une liste de slection (mandatory-list-loop.html)

Vous le voyez la Figure 8.7, les deux lments slectionns ne comptent pas.

Validation automatique d'un formulaire

159

Figure 8.7 : Le formulaire ne peut tre envoy que si un lment "rel" a t slectionn.

Validation automatique d'un formulaire


switch (element.type)

En intensifiant un peu ses efforts, le programmeur peut amener JavaScript valider automatiquement un formulaire, condition que tous ses champs soient obligatoires. Il suffit alors de les passer tous en revue. Chaque proprit type de l'lment renvoie le type du champ ; le Tableau 8.1 montre une liste des plus importants. Ainsi, la validation survient en fonction du type de champ.

160 CHAPITRE 8 Les formulaires

Tableau 8.1 : Types de champs de formulaires de JavaScript


Type Description

button checkbox password radio reset select-one select-multiple submit text textarea

Bouton HTML Case cocher Champ de mot de passe Bouton radio Bouton de rinitialisation Liste de slection Liste choix multiples Bouton d'envoi Champ de texte sur une seule ligne Champ de texte sur plusieurs lignes

Le code suivant traite tout particulirement les groupes de boutons radio. Puisque la boucle qui parcourt les lments de formulaire tudie chacun d'entre eux, c'est-dire chaque bouton radio, elle conserve une liste des groupes de boutons dj cochs. Si ce n'tait pas le cas, un groupe de trois boutons radio serait coch trois fois, et trois messages d'erreur seraient gnrs si aucun bouton n'tait slectionn.

Validation automatique d'un formulaire

161

<script language="JavaScript" type="text/JavaScript"> function checkform(f) { var errortext = ""; var checkedgroups = ""; for (var i=0; i<f.elements.length; i++) { var element = f.elements[i]; switch (element.type) { case "text": case "textarea": case "password": if (element.value.replace(/\s/g, "") == "") { errortext += element.name + "\n"; } break; case "checkbox": if (!element.checked) { errortext += element.name + "\n"; } break; case "radio": var group = f.elements[element.name]; if (checkedgroups.indexOf("[" + element.name + "]") > -1) { continue; } else { checkedgroups += "[" + element.name + "]"; } var groupok = false; for (var j=0; j<group.length; j++) { if (group[j].checked) { groupok = true; } } if (!groupok) { errortext += element.name + "\n"; } b k

162 CHAPITRE 8 Les formulaires

break; case "select-one": case "select-multiple": var selectok = false; for (var j=0; j<element.options.length; j++) { var item = element.options[j]; if (item.selected && item.value != "") { selectok = true; } } if (!selectok) { errortext += element.name + "\n"; } break; } } if (errortext == "") { return true; } else { window.alert( "The following fields have not been correctly filled out:\n\n" + errortext); return false; } } </script>
Validation automatique d'un formulaire (validate.html, extrait)

La Figure 8.8 prsente le rsultat : aucun des champs du formulaire ne contient de contenu appropri. Notez cependant que vous pouvez modifier ce script et peut-tre exclure les cases cocher de la liste, puisque ces lments de formulaire sont, la plupart du temps, optionnels.

Implmentation de la navigation avec une liste de slection

163

Figure 8.8 : Le formulaire est automatiquement valid.

Implmentation de la navigation avec une liste de slection


var url = list.options[list.selectedIndex].value;

Une navigation dite de "liaison rapide" (quick link) prsente une liste de slection contenant deux lments de navigation. Lorsque l'utilisateur en slectionne un, le navigateur charge la page associe. En matire d'implmentation, cet effet plaisant et trs souvent utilis est assez drisoire. Les URL de destination de tous les lments de navigation sont stockes dans les attributs value ; une fonction JavaScript vrifie

164 CHAPITRE 8 Les formulaires

d'abord si un lment "rel" a t slectionn, puis charge l'URL :


<script language="JavaScript" type="text/JavaScript"> function loadURL(list) { var url = list.options[list.selectedIndex].value; if (url != "") { location.href = url; } } </script> <form> <select name="urls" onchange="loadURL(this);"> <option value="">Please select...</option> <option value="http://www.samspublishing.com/"> SAMS</option> <option value="http://www.hauser-wenz.de/blog/"> H&amp;W blog</option> <option value="http://www.damonjordan.com/"> Damon</option> </select> </form>
Une navigation par liaison rapide (quicklink.html)

Implmentation d'une navigation hirarchique avec une liste de slection


for (var i=0; i<links.length; i++) { elements["urls"].options[ elements["urls"].options.length] = new Option(links[i].title, links[i].url); }

Deux listes de slection peuvent tre apparies afin de fournir une navigation hirarchique sur un site. La premire

Implmentation d'une navigation hirarchique avec une liste de slection

165

contient plusieurs catgories ; lorsque l'utilisateur en slectionne une, la seconde liste affiche l'ensemble de ses lments. Pour JavaScript, il convient de stocker la liste des lments ; d'autre part, les listes doivent tre remplies en fonction de la premire slection. Voici la liste de liens, au format JSON (voir le Chapitre 11, "AJAX et sujets annexes", pour en savoir plus sur cette notation).
var data = { "search" : [ {"title": "Google", "url":"http://www.google.com/"}, {"title": "MSN", "url":"http://search.msn.com/"} ], "browsers" : [ {"title": "Firefox", "url": "http://www.mozilla.com/ firefox/"}, {"title": "Opera", "url": "http://www.opera.com/"} ] };

Ensuite, le code suivant ajoute des options la seconde liste de slection, en employant le constructeur Option (syntaxe : d'abord la lgende, ensuite la valeur) :
<script language="JavaScript" type="text/JavaScript"> function loadElements(f) { with (f) { var category = elements["categories"].options[ elements["categories"].selectedIndex].value; if (category != "") { var links = data[category]; elements["urls"].options.length = 0; elements["urls"].options[0] = new Option("Please select...", "#"); for (var i=0; i<links.length; i++) { elements["urls"].options[

166 CHAPITRE 8 Les formulaires

elements["urls"].options.length] = new Option(links[i].title, links[i].url);

} } } } </script> <form> <select name="categories" onchange="loadElements(this.form);"> <option value="">Please select...</option> <option value="search">Search Engines</option> <option value="browsers">Browsers</option> </select> <select name="urls" onchange="loadURL(this);"> </select> </form>
Une navigation hirarchique (navigation.html, extrait)

La Figure 8.9 montre ce qui survient lorsque la premire catgorie ("Search Engines", des moteurs de recherche) est slectionne. La seconde liste se remplit avec les options disponibles.

Figure 8.9 : Le choix d'une option dans la premire liste conditionne le contenu de la seconde.

Dslection d'un ensemble de boutons radio

167

Dslection d'un ensemble de boutons radio


for (var i=0; i<f.elements["colors"].length; i++) { f.elements["colors"][i].checked = false; }

Les boutons radio prsentent un inconvnient souvent cit : lorsque l'utilisateur clique sur bouton d'un groupe, il ne peut annuler cette slection, un bouton au moins restant toujours slectionn. Avec un peu de JavaScript et un bouton d'annulation, cet effet peut tre mitig. Le code prcdent passe en revue le groupe de boutons radio et dfinit la proprit checked de tous les lments sur false (code complet dans le fichier emptyradio.html).
Astuce Ce problme peut aussi tre rsolu par du HTML pur : proposez simplement un bouton radio (slectionn par dfaut) qui indique "Aucune slection", de la manire suivante :

<input type="radio" <input type="radio" <input type="radio" checked="checked"

name="answer" value="Y" />yes name="answer" value="N" />no name="answer" value="" />no answer

Bien entendu, vous devez ensuite modifier le code de validation.

Cration de listes de slection de date prremplies


elements["day"].selectedIndex = d.getDate() - 1;

La plupart des sites de rservation possdent un ensemble de trois listes de slection permettant aux utilisateurs de

168 CHAPITRE 8 Les formulaires

saisir une date : une liste pour le jour, une pour le mois et une pour l'anne. La gnration de ces listes, que ce soit en HTML statique ou ct serveur, est une tche plutt simple, mais leur prslection exige un moyen ct serveur (voir le Guide de Survie PHP et MySQL pour obtenir une solution en PHP) ou un peu de JavaScript. L'ide consiste dfinir la proprit selectedIndex de chaque liste sur la valeur de date approprie, comme indiqu dans le listing suivant (les listes de slection sont bien entendu abrges) :
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { with (document.forms[0]) { var d = new Date(); elements["day"].selectedIndex = d.getDate() - 1; elements["month"].selectedIndex = d.getMonth(); elements["year"].selectedIndex = 2006 d.getFullYear(); } } </script> <form> <select name="day"> <option value="1">1</option> <! ... > </select> <select name="month"> <option value="1">January</option> <! ... > </select> <select name="year"> <option value="2006">2006</option> <! ... > </select> </form>
Prremplissage d'une liste de dates (autodate.html, extrait)

Cration de listes de slection de date de validation

169

Attention Dans l'exemple, la premire anne de la liste est 2006 ; cette valeur est galement utilise pour calculer la valeur selectedIndex obligatoire pour cette date. Si vous la modifiez, par exemple que vous ajoutez l'anne 2007, vous devrez changer la formule pour elements["year"].selectedIndex en consquence.

Cration de listes de slection de date de validation


f.elements["day"].options.length = maxDays;

La prochaine tape, pour les listes de slection de dates et en partant de la section prcdente, consiste s'occuper des utilisateurs qui saisissent une date valide. Ainsi, ds qu'il y a changement du mois ou de l'anne, la liste de slection du jour doit tre actualise en consquence :
<select name="month" onchange="updateDay(this.form);"> <select name="year" onchange="updateDay(this.form);">

Pour ce faire, une fonction d'aide (voir le Chapitre 6) dtermine si l'anne est une anne bissextile :
function isLeapYear(y) { return (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)); }

Grce ces informations, la liste de slection du jour peut tre actualise. S'il y a trop d'entres, la liste est raccourcie. S'il y a trop peu d'entres, la liste reoit des entres supplmentaires. Tout cela permet de maintenir

170 CHAPITRE 8 Les formulaires

la valeur selectedIndex, si possible, de sorte que la slection de l'utilisateur soit maintenue ( moins, par exemple, que le jour 30 ne soit slectionn et que le mois ne passe fvrier).
<script language="JavaScript" type="text/JavaScript"> function updateDay(f) { var oldDays = f.elements["day"].options.length; var month = parseInt(f.elements["month"].value); var year = parseInt(f.elements["year"].value); var maxDays = 30; switch (month) { case 1: case 3: case 5: case 7: case 9: case 11: maxDays = 31; break; case 2: maxDays = (isLeapYear(year) ? 29 : 28); break; } f.elements["day"].options.length = maxDays; if (maxDays > oldDays) { for (var i=oldDays; i<maxDays; i++) { f.elements["day"].options[i] = new Option(i+1, i+1); } } } </script>
Mise jour automatique de la liste (date.html, extrait)

Cration de listes de slection de date de validation

171

A la Figure 8.10, vous voyez le rsultat : le mois de fvrier de l'anne 2000 possde 29 jours.

Figure 8.10 : La liste des jours est actualise en fonction du mois et de l'anne.

9
Fentres et cadres
Les fentres jouent un rle important dans JavaScript. L'objet window est l'objet par dfaut et il est utilis assez souvent (pensez simplement la mthode windows.alert()). De plus, JavaScript peut fonctionner avec les fentres (par exemple en en ouvrant de nouvelles) ainsi qu'avec les cadres et les cadres intgrs, qui sont galement trs proches des objets window.
window.open("http://www.samspublishing.com/", "samsWindow", "");

La mthode window.open() ouvre une nouvelle fentre et prend au moins trois paramtres pour que l'appel soit utile : l'URL ouvrir, le nouveau nom de la fentre et ses options. Avec le code prcdent (fichier open.html), une nouvelle fentre s'ouvre, affichant la page d'accueil de l'diteur. Le deuxime paramtre de la mthode window.open() fournit le nom de la nouvelle fentre. Cela fonctionne exactement comme un nom de cadre : si vous utilisez le nom de fentre comme attribut cible d'un lien, le lien

174 CHAPITRE 9 Fentres et cadres

s'ouvre dans la nouvelle fentre. Ainsi, le fichier d'exemple open.html contient galement un lien qui utilise le nouveau nom de la fentre :
<a href="http://www.amazon.com/gp/product/0672328801" target="samsWindow">This book at Amazon</a>

Lorsque vous cliquez sur ce lien, aucune nouvelle fentre n'est ouverte mais l'ancienne, prcdemment ouverte par JavaScript, est rutilise. Sachez que la valeur de retour de window.open() est un objet de fentre JavaScript qui pointe vers la nouvelle fentre. Ainsi, un code ressemblant ceci ne donne pas le rsultat souhait :
<a href="JavaScript:window.open(...)">Open window</a>

Puisque la mthode renvoie un objet fentre, ce lien crirait sur la page un lment du type [object] (Internet Explorer) ou [object Window] (navigateurs Mozilla). Vous devez donc vous assurer que le code JavaScript ne renvoie rien. Pour cela, utilisez le code suivant :
<a href="JavaScript:void(window.open(...))">Open window</a>

Options de fentres
window.open("http://www.samspublishing.com/", "samsWindow", "width=640,height=480,directories=no,menubar=no, toolbar=no,scrollbars=yes");

Le troisime paramtre de window.open() est une liste de valeurs, spares par des virgules, qui dfinissent l'aspect de la nouvelle fentre. Vous pouvez dfinir la taille ( condition que la largeur et la hauteur soient au moins de 100 pixels), basculer certaines fonctions de la fentre

Options de fentres

175

comme la barre d'tat, etc. Le Tableau 9.1 montre les options les plus importantes (la liste n'est pas complte, elle laisse plusieurs options au navigateur). Le code prcdent utilise quelques-unes de ces options. Certaines prennent des valeurs numriques, d'autres yes ou no. Veillez ne pas insrer d'espaces entre elles.
Tableau 9.1 : Options de fentre
Option Description

dependent directories height innerHeight innerWidth left location menubar outerHeight outerWidth resizeable

Ferme la nouvelle fentre si la fentre parent est ferme Bascule la barre d'outils personnelle Hauteur de la fentre Hauteur de la fentre, en excluant sa dcoration (navigateurs sauf IE) Largeur de la fentre, en excluant sa dcoration (navigateurs sauf IE) Position horizontale de la fentre (IE uniquement) Bascule la barre d'emplacement Bascule la barre de menus Hauteur de la fentre (navigateurs sauf IE) Largeur de la fentre (navigateurs sauf IE) Lorsque la fentre peut tre redimensionne par l'utilisateur

176 CHAPITRE 9 Fentres et cadres

Tableau 9.1 : Options de fentre (suite)


Option Description

screenX screenY scrollbars status toolbar top width z-lock

Position horizontale de la fentre (navigateurs sauf IE) Position verticale de la fentre (navigateurs sauf IE) Bascule les barres de dfilement Bascule la barre d'tat Bascule la barre d'outils Position verticale de la fentre (IE uniquement) Largeur de la fentre Donne la fentre une valeur z-lock (position de l'axe des z) infrieure

Attention Tous ces effets ne fonctionneront pas dans tous les navigateurs de la mme manire. Par exemple, le navigateur Opera ouvre une nouvelle fentre, non pas dans une nouvelle fentre de navigateur mais, selon les versions, dans un nouvel onglet qui, bien entendu, possde les ornements et la taille de fentre par dfaut.

La Figure 9.1 montre l'aspect de la fentre nouvellement ouverte (fichier openoptions.html) avec les options donnes.

Ouverture d'une fentre modale

177

Figure 9.1 : La nouvelle fentre n'a que trs peu d'ornements.

Ouverture d'une fentre modale


window.showModalDialog( "http://www.samspublishing.com/","samsWindow", "dialogWidth=640,dialogHeight=480,status=no,center=yes");

Les deux principaux navigateurs acceptent certaines extensions propritaires de l'objet window mais, pour des raisons videntes, nous ne les traiterons pas ici. Il existe toutefois une exception : Internet Explorer peut crer des fentres modales, une chose assez commune dans les applications d'intranet o le type de navigateur peut tre choisi par le personnel informatique. La mthode associe s'appelle window.showModalDialog(), elle prend une URL, un nom et un jeu d'options (que vous trouverez au Tableau 9.2).

178 CHAPITRE 9 Fentres et cadres

Le listing suivant ouvre cette bote de dialogue, la centre et lui attribue une taille de 640 480 pixels.
<script language="JavaScript" type="text/JavaScript"> if (window.showModalDialog) { window.showModalDialog( "http://www.samspublishing.com/", "samsWindow", "dialogWidth=640,dialogHeight=480,status=no, center=yes"); } </script> <a href="http://www.amazon.com/gp/product/ 0672328801" target="samsWindow">This book at Amazon</a>
Ouverture d'une fentre modale (modal.html)

Tableau 9.2 : Options de fentre


Option Description

center dialogHeight dialogLeft dialogTop dialogWidth help status resizeable

Centre la fentre Hauteur de la fentre Position horizontale de la fentre Position verticale de la fentre Largeur de la fentre Bascule le symbole d'aide dans le coin suprieur droit Bascule la barre d'tat Lorsque la fentre peut tre redimensionne par l'utilisateur

Dtermination de la taille de l'cran

179

La Figure 9.2 montre la fentre modale produite par le code prcdent.

Figure 9.2 : La fentre modale (Internet Explorer uniquement).

Dtermination de la taille de l'cran


window.alert(screen.availWidth + " x " + screen.availHeight + " pixels");

Dans une situation idale, toutes les mises en page Web seraient flexibles et s'adapteraient la solution disponible. Malheureusement, ce n'est pas le cas mais, grce JavaScript, vous pouvez vous adapter. L'objet screen (window.screen dans les navigateurs rcents, screen dans les anciens) propose des informations sur la rsolution d'cran actuelle. Les proprits qui vous intresseront sont availableHeight et availableWidth, qui indiquent la hauteur et la largeur disponibles. Cela peut, par exemple, tre utilis pour dterminer la rsolution actuelle et rediriger l'utilisateur vers une page adapte ces dimensions d'cran.

180 CHAPITRE 9 Fentres et cadres

Le code prcdent (fichier screen.html) dtermine l'espace actuellement disponible l'cran. La Figure 9.3 montre le rsultat lorsqu'une solution de 1 024 768 pixels est adopte.

Figure 9.3 : Les dimensions d'cran peuvent ne pas tre celles que vous attendez.

Info Sachez que, dans cet exemple spcifique, il manque 30 pixels ; ils "appartiennent" la barre Microsoft Windows (on obtient des effets similaires lorsque cette squence de code est excute sur d'autres systmes avec des barres systme). Si vous souhaitez connatre la largeur et la hauteur relles, utilisez les proprits width et height de l'objet screen.

Dtermination de la taille de la fentre


with (document.body) { window.alert(clientWidth + " x " + clientHeight + " pixels"); }

L'accs aux proprits de la fentre en cours dpend grandement du navigateur utilis. Comme c'est souvent le cas avec JavaScript, le monde des navigateurs est divis en deux : Internet Explorer et les autres. Avec Internet

Dtermination de la taille de la fentre

181

Explorer, la largeur d'une fentre peut tre dtermine par document.body.clientWidth ; les autres navigateurs utilisent window.innerWidth pour la largeur "interne" (qui exclut les ornements de la fentre) et window.outerWidth pour la largeur "externe" (qui les inclut). Pour dterminer la hauteur, il suffit de remplacer respectivement width et height par Width et Height. Le code suivant produit les dimensions de la fentre en cours :
<script language="JavaScript" type="text/JavaScript"> window.onload = function() { if (window.innerWidth) { window.alert("inner: " + window.innerWidth + " x " + window.innerHeight + " pixels\nouter: " + window.outerWidth + " x " + window.outerHeight + " pixels"); } else { with (document.body) { window.alert(clientWidth + " x " + clientHeight + " pixels"); } } } </script> <body></body>
Dtermination des dimensions de la fentre actuelle (dimensions.html)

Astuce Pour que le code fonctionne dans Internet Explorer, sachez que la page a besoin d'une zone <body> et que le code ne doit pas tre excut avant que la page n'ait t totalement charge.

182 CHAPITRE 9 Fentres et cadres

Redimensionnement d'une fentre


window.resizeTo(640, 480);

Il existe plusieurs manires de dfinir la taille d'une fentre. Lors de son ouverture l'aide de window.open(), il suffit de paramtrer les options width et height. Pour les fentres existantes, JavaScript propose deux mthodes de l'objet window : b resizeTo(). Dfinit la largeur et la hauteur de la fentre sur les valeurs fournies, comme dans le code prcdent (fichier resizeto.html dans l'archive de tlchargement). b resizeBy(). Modifie la largeur et la hauteur de la fentre en ajoutant les valeurs fournies, comme le montre le listing suivant (qui rduit de moiti la largeur et la hauteur) :
<script language="JavaScript" type="text/JavaScript">window.onload = function() { var width, height; if (window.innerWidth) { width = window.outerWidth; height = window.outerHeight; } else { width = document.body.clientWidth; height = document.body.clientHeight; } window.resizeBy( -Math.round(width / 2), -Math.round(height / 2)); } </script> <body></body>
Bissection d'une largeur et d'une hauteur de fentre (resizeby.html)

Repositionnement d'une fentre

183

Attention Le redimensionnement d'une fentre est gnralement considr peu convivial. L'un des principes du Web stipule que la taille du client n'est pas pertinente et qu'elle peut tre ajuste par l'utilisateur. Utilisez donc la technique de cette section avec parcimonie. Sachez galement que vous ne pouvez pas redimensionner la fentre sur une largeur ou une hauteur infrieure 100 pixels.

Repositionnement d'une fentre


window.moveBy(-10, 10);

Lors de l'ouverture d'une nouvelle fentre, vous devez tenir compte de tous les navigateurs : pour Internet Explorer, paramtrez les options left et top ; tous les autres navigateurs fonctionnent avec screenX et screenY. L'appel suivant de window.open() cre une fentre dans le coin suprieur gauche de l'cran.
window.open( "anypage.html", "name", "left=0,top=0,screenX=0,screenY=0");

Toutefois, pour les fentres existantes, deux mthodes, assez analogues la section prcdente, entrent en jeu : b moveTo(). Positionne la fentre l'endroit spcifi, comme le montre le code du dbut de cette section (dans le fichier moveto.html). b moveBy(). Dplace la fentre. Le listing suivant montre la fentre dplace de 10 pixels gauche et de 10 pixels vers le bas.

184 CHAPITRE 9 Fentres et cadres

<script language="JavaScript" type="text/JavaScript"> window.moveBy(-10, 10); </script>


Dplacement d'une fentre (moveby.html)

Attention Le dplacement d'une fentre est presque aussi peu convivial que le redimensionnement. Une fois de plus, utilisez cette fonction sans excs. Sachez galement qu'il est impossible de dplacer la fentre de manire la faire totalement disparatre pour l'utilisateur, pour des raisons de scurit videntes.

Ouverture d'une fentre contextuelle centre


newwin.moveTo( Math.round((screenwidth - windowwidth) / 2), Math.round((screenheight - windowheight) / 2));

La combinaison de ces expressions permet d'ouvrir une fentre, de dterminer ses dimensions ; son repositionnement permet de crer une nouvelle fentre centre sur la page. L'ide est de calculer la largeur et la hauteur de la nouvelle fentre (n'oubliez pas que window.open() renvoie une rfrence la nouvelle fentre) et de dterminer la taille de l'cran ; partir de l, il suffit de calculer la position requise de la fentre, de manire qu'elle soit centre. Toutefois, le dlai est crucial ici. Sous Internet Explorer, vous pouvez accder aux dimensions de la fentre uniquement aprs que l'lment <body> a t analys.

Ouverture d'une fentre contextuelle centre

185

On utilise donc une petite astuce : tout d'abord, la nouvelle fentre est vide. Puis, document.write() cre un lment. La largeur et la hauteur de la fentre peuvent alors tre lues. Enfin, le document souhait est charg dans la nouvelle fentre, qui est ensuite repositionne au centre de l'cran.
<script language="JavaScript" type="text/JavaScript"> var newwin = window.open("", "samsWindow", ""); newwin.document.write("<body></body>"); var windowwidth, windowheight; if (window.innerWidth) { windowwidth = newwin.outerWidth; windowheight = newwin.outerHeight; } else { windowwidth = newwin.document.body.clientWidth; windowheight = newwin.document.body.clientHeight; } var screenwidth = screen.availWidth; var screenheight = screen.availHeight; newwin.moveTo( Math.round((screenwidth - windowwidth) / 2), Math.round((screenheight - windowheight) / 2)); newwin.location.href = "http://www.samspublishing.com/"; </script> <body></body>
Ouverture et centrage d'une fentre (center.html)

Info Parfois, la lecture des proprits de fentre ne fonctionne pas comme prvu dans Internet Explorer et produit des rsultats errons. Dans ce cas, il vaut mieux paramtrer la taille de la nouvelle fentre dans l'appel window.open(), puis utiliser cette valeur (que l'on sait tre vraie) pour centrer la nouvelle fentre.

186 CHAPITRE 9 Fentres et cadres

Ouverture d'une fentre en plein cran


newwin.resizeTo(screen.width, screen.height); newwin.moveTo(0, 0);

Internet Explorer 4 accepte l'option de window.open() nomme fullscreen=yes, mais une mthode plus gnrale consiste bien sr extraire l'objet de l'cran pour obtenir les dimensions du systme, puis redimensionner la fentre en consquence. N'oubliez pas de la repositionner dans le coin suprieur gauche de l'cran !
<script language="JavaScript" type="text/JavaScript"> var newwin = window.open( "http://www.samspublishing.com/", "samsWindow", "directories=no,menubar=no,toolbar=no, scrollbars=yes"); newwin.resizeTo(screen.width, screen.height); newwin.moveTo(0, 0); </script>
Ouverture d'une fentre en plein cran (center.hml)

Ouverture d'une nouvelle fentre dans un coin de l'cran


newwin.moveTo( screenwidth - windowwidth, screenheight - windowheight);

L'ouverture d'une fentre dans le coin suprieur gauche de l'cran est assez simple : il suffit de donner la valeur 0 aux positions horizontale et verticale.

Ouverture d'une nouvelle fentre dans un coin de l'cran

187

<script language="JavaScript" type="text/JavaScript"> var newwin = window.open( "http://www.samspublishing.com/", "samsWindow", "width=640,height=480,directories=no,menubar=no, toolbar=no,scrollbars=yes,left=0,top=0,screenX=0, screenY=0"); </script>
Ouverture d'une fentre dans le coin suprieur gauche (open_topleft.html)

Tous les autres coins de l'cran sont un peu plus difficiles obtenir car vous devez en calculer les positions. Grce l'objet screen, ce dilemme peut tre rsolu avec une petite quantit de code. L'extrait suivant place la nouvelle fentre dans le coin infrieur droit ; les listings pour les deux autres coins sont disponibles dans les fichiers open_topright.html et open_bottomleft.html.
<script language="JavaScript" type="text/JavaScript"> var newwin = window.open( "http://www.samspublishing.com/", "samsWindow", "width=640,height=480,directories=no,menubar=no, toolbar=no,scrollbars=yes"); var windowwidth = 640; var windowheight = 480; var screenwidth = screen.availWidth; var screenheight = screen.availHeight; newwin.moveTo( screenwidth - windowwidth, screenheight - windowheight); </script>
Ouverture d'une fentre dans le coin infrieur droit (open_bottomright.html)

188 CHAPITRE 9 Fentres et cadres

Cration d'une carte de site


this.opener.name = "mainWindow";

Une carte est un lment trs pratique, quel que soit le site Web. Avec un peu de code JavaScript, cette fonction peut encore s'amliorer. Si vous ouvrez une carte de site dans une nouvelle fentre, tous ses liens doivent galement s'ouvrir dans la fentre initiale. A l'vidence, vous pouvez pour cela paramtrer l'attribut target de tous les liens HTML (ou utiliser <base target="..." />). Toutefois, une question demeure : quel est le nom de la fentre ? Pour rpondre cette question, on peut utiliser JavaScript dans la fentre principale et paramtrer la proprit name de la fentre :
this.name = "mainWindow";

Une autre manire consiste utiliser la carte du site et y rfrencer la fentre d'ouverture. Cela se fait grce la proprit opener de la fentre, paramtre sur la fentre parente de la fentre actuelle, le cas chant. Le code suivant correspond la carte du site complte :
<script language="JavaScript" type="text/JavaScript"> this.opener.name = "mainWindow"; </script> <a href="http://www.samspublishing.com/" target="mainWindow">Publisher</a><br /> <a href="http://www.amazon.com/gp/product/ 0672328801" target="mainWindow">This book at Amazon</a>
Ouverture de la carte du site (sitemap.html, extrait)

Fermeture d'une fentre

189

Fermeture d'une fentre


if (!newwindow.closed) newwindow.close();

La fermeture d'une fentre peut passer par un appel sa mthode close(). Or, cela n'est possible par dfaut que pour les fentres qui ont t ouvertes l'aide de JavaScript. Si vous utilisez la mthode sur d'autres fentres, l'utilisateur obtient un message d'avertissement analogue celui affich la Figure 9.4 (les navigateurs Mozilla possdent un message similaire, mais le masquent dans la console JavaScript).

Figure 9.4 : Fermer uniquement les fentres ouvertes avec JavaScript ou se retrouver face cet effrayant message.

Avec la carte du site de la section prcdente, on peut utiliser un lien pour fermer la fentre :
<script language="JavaScript" type="text/JavaScript"> this.opener.name = "mainWindow"; </script> <a href="http://www.samspublishing.com/" target="mainWindow">Publisher</a><br /> <a href="http://www.amazon.com/gp/product/ 0672328801" target="mainWindow">This book at Amazon</a><br /> <a href="JavaScript:self.close();">Close window</a>
La carte du site avec un lien de fermeture (sitemapwindow.html)

190 CHAPITRE 9 Fentres et cadres

Il est galement conseill de fermer la carte du site partir de la fentre principale, si une autre page y est charge. Dans l'exemple actuel, le chargement de toute autre page dans la fentre principale redirige le navigateur vers un autre serveur Web ; vous pouvez donc fermer immdiatement la carte du site. Mais avant cela, vrifiez si la fentre est dj ferme, en tudiant sa proprit closed :
<script language="JavaScript" type="text/JavaScript"> var newwindow = window.open( "sitemapwindow.html", "sitemap", "width=320,height=100,directories=no,menubar=no, toolbar=no,scrollbars=yes"); </script> <body onunload="if (!newwindow.closed) newwindow.close();"></body>
Ouverture de la carte du site avec fonction de fermeture automatique (sitemapwindow.html)

Vrication de la prsence d'un systme de blocage des fentres contextuelles


var newwindow = window.open( "", "popupcheck", "width=100,height=100,directories=no,menubar=no, toolbar=no");

Toutes les sections prcdentes supposent que le navigateur est capable d'ouvrir les fentres contextuelles. Par dfaut, la plupart des navigateurs modernes autorisent les fentres

Vrification de la prsence d'un systme de blocage des fentres

191

contextuelles ouvertes partir du serveur local, mais bloquent celles ouvertes partir d'Internet. De plus, diverses barres d'outils possdant leurs propres mcanismes de blocage des fentres contextuelles compliquent la vie des dveloppeurs qui y font appel. D'abord la mauvaise nouvelle : il n'existe pas de manire fiable de s'assurer que les fentres conceptuelles puissent tre toujours ouvertes. Certains systmes acceptent divers niveaux de blocage, d'autres autorisent certaines fentres contextuelles, d'autres encore les dsactivent toutes. La Figure 9.5 montre un cran de configuration d'un navigateur ordinaire.
Vrication de la prsence d'un systme de blocage des fentres

Le code suivant tente de dtecter la prsence d'un systme de blocage des fentres contextuelles : il ouvre une fentre, puis vrifie son existence. Si elle est l, elle est ferme, sinon il existe probablement un systme de blocage des fentres contextuelles :
<script language="JavaScript" type="text/JavaScript"> var newwindow = window.open( "", "popupcheck", "width=100,height=100,directories=no,menubar=no, toolbar=no"); if (newwindow) { newwindow.close(); } else { window.alert("Pop-up blocker detected!"); } </script>
Recherche d'un systme de blocage des fentres contextuelles (popucheck.html)

192 CHAPITRE 9 Fentres et cadres

La Figure 9.6 montre le rsultat lorsqu'une fentre contextuelle est bloque (galement visible partir de la barre de notification en haut de la zone de contenu du navigateur).

Figure 9.6 : Dtection d'un systme de blocage des fentres contextuelles.

Astuce Le comportement par dfaut de la plupart des systmes de blocage des fentres contextuelles prcise que ne sont autorises que celles qui sont dclenches par l'action des utilisateurs. N'essayez donc pas d'appeler window.open() lorsque la page s'est charge, mais plutt lorsque l'utilisateur clique sur quelque chose. Vous n'avez toutefois aucune garantie que la fentre contextuelle apparatra rellement.

Utilisation des cadres JavaScript

193

Utilisation des cadres JavaScript


Travailler avec les cadres dans JavaScript revient un peu travailler avec l'objet window. Sachez qu'il manque aux cadres certaines des fonctions d'un objet window, comme la mthode open(), ou des manires de les redimensionner ou de les repositionner. En revanche, les proprits de base d'un cadre sont les mmes : la proprit document pointe vers l'objet document charg dans le cadre et on compte d'autres proprits, comme location. La proprit frames de la fentre principale (l'endroit o se trouve le document HTML contenant l'lment <frameset>) est un tableau contenant tous les cadres dnis dans ce jeu de cadres. Vous pouvez ensuite accder aux cadres par leurs indices ( partir de 0 : window.frames[0], window.frames[1]) ou par leur attribut name : window.frames["nomDuCadre"]. Il est possible d'accder la structure du cadre partir de chaque document de cadre (c'est--dire des documents chargs dans un cadre, mme s'ils contiennent galement des lments <frameset>) : parent rfrence le document de la structure de cadre parent, tandis que top passe au document principal.

194 CHAPITRE 9 Fentres et cadres

Modication du contenu de deux cadres en mme temps


top.frames[frame1].location.href = url1; top.frames[frame2].location.href = url2;

L'une des questions les plus communes de JavaScript concerne la modification simultane de deux cadres. Mme si les cadres deviennent de moins en moins populaires chez les professionnels du Web, cette question demeure un sujet important. Bien entendu, JavaScript peut encore vous aider dans cette situation. Une fonction prend les noms ou les indices des deux cadres et les deux URL charger. Puisque les cadres individuels se modifient au fil de l'application, cette fonction doit tre place dans le document du jeu de cadres :
<script language="JavaScript" type="text/JavaScript"> function changeFrames(frame1, url1, frame2, url2) { top.frames[frame1].location.href = url1; top.frames[frame2].location.href = url2; } </script> <frameset cols="150,*"> <frame src="frame1a.html" name="navigation" /> <frame src="frame2a.html" name="content" /> </frameset>
Le jeu de cadres avec la fonction JavaScript (frameset.html)

Modification du contenu de deux cadres en mme temps

195

Le cadre gauche de cet exemple correspond au cadre de navigation ; le cadre droit est le cadre de contenu. Lorsque l'utilisateur clique sur un lien du cadre de navigation, les deux cadres changent, chaque page du cadre de droite possdant une page de navigation associe (la page en cours tant surligne) destination du cadre gauche.
Frame 1<br /> <a href="JavaScript:top.changeFrames('navigation', 'frame1b.html', 'content', 'frame2b.html');"> Frame 2</a>
Le jeu de cadres avec les lments de navigation (frame1a.html)

Il existe une mthode plus gnrale qui ne limite pas le nombre de cadres deux, mais accepte un nombre arbitraire de noms de cadres et d'URL :
function changeFrames() { for (var i=0; i < Math.ceil(changeFrames.arguments.length/2); i++) { top.frames[changeFrames.arguments[2 * i]] .location.href = changeFrames.arguments[2 * i + 1]; } }
Jeu de cadres avec la fonction JavaScript plus flexible (frameset.html, extrait)

Le fichier frameset.html, prsent dans les archives de tlchargement, contient les deux versions de changeFrames(), la moins flexible se trouvant dans un commentaire JavaScript.

196 CHAPITRE 9 Fentres et cadres

Astuce Il est bien entendu que cet exemple fonctionne mieux si l'on exclut les utilisateurs n'ayant pas JavaScript. Il serait donc envisageable de charger une nouvelle page dans le cadre de contenu mais d'utiliser JavaScript pour modifier galement le cadre de gauche, si le navigateur l'accepte :

<a href="frame2b" target="content" onclick="top.changeFrames('navigation', 'frame1b.html', 'content', 'frame2b.html'); return false;">Frame 2</a>

Utilisation de cadres masqus pour le stockage des donnes


Une option assez commode pour les cadres consiste utiliser les cadres masqus. Ils peuvent servir, par exemple, stocker des donnes sur les requtes HTTP. Toutes les donnes JavaScript tant perdues si la page n'est pas dcharge, un cadre masqu peut permettre de stocker des donnes, par exemple lors de la cration d'un panier d'achat ct client. Il faut donc crer un cadre dont la hauteur est gale 1 pixel par exemple. Par la suite, ds qu'il y a des donnes mettre de ct, il suft d'accder au cadre et d'enregistrer les donnes requises dans des variables, toutes accessibles sous forme de proprits de cadre.
top.frames["hiddenJsFrame"].variable = "value";

Vous pouvez galement placer des fonctions communes dans ce cadre, puis les appeler de la mme manire :
top.frames["hiddenJsFrame"].functionName();

Utilisation des cadres intgrs

197

Utilisation des cadres intgrs


window.frames["iframe1"].location.href = "iframe1b.html"; document.getElementById("iframe1").src = "iframe1b.html";

Les cadres intgrs facilitent la cration d'une section dans une page, qui pourra tre modifie indpendamment du reste de la page. Comme leur nom le suggre, ils sont trs comparables aux cadres, quelques diffrences prs. Voici le marquage HTML de ce cadre intgr :
<iframe src="iframe1a.html" name="iframe1a" id="iframe1"></iframe>

Un nom et un identifiant sont fournis pour le cadre intgr, puisqu'il existe deux manires d'y accder : b en utilisant le nom et le tableau window.frames ; b en utilisant l'identifiant et document.getElementById(). La premire exige que la proprit location.href modifie l'URL dans le cadre intgr, la seconde renvoie un objet possdant une proprit src pour cette tche : b window.frames["iframe1"].location.href = "iframe1b.html" ; b document.getElementById("iframe1").src = "iframe1b.html".
Attention Mme si les cadres intgrs proposent de nouvelles capacits pour les applications Web, ils prsentent galement des inconvnients. Comme vous le verrez au Chapitre 11, "AJAX et sujets annexes", la cration de signets et le fonctionnement des boutons Prcdent et Suivant ncessitent quelques contournements, qui ne fonctionnent que lorsque JavaScript est activ.

10
Services Web
Les services Web sont une technologie tonnante, ct serveur. Leur lien avec JavaScript tient ce qu'il existe une mthode pour appeler des scripts ct serveur depuis le ct client. En ralit, deux mthodes existent : l'une pour les navigateurs fonds sur Mozilla, l'autre pour Internet Explorer. Ces deux options sont traites dans ce chapitre ; le chapitre suivant propose d'autres solutions intressantes.

200

CHAPITRE 10 Services Web

Comprendre les services Web


Certains disent que les services Web ne sont qu'un vieil outil qui a t remis neuf, mais l'ide qui se cache derrire est loin d'tre nouvelle. Le principe de base est que deux machines se parlent l'une l'autre. A titre d'exemple, une machine contient une logique d'activit ou, plus gnralement, des informations, et l'autre demande ces informations (ou veut utiliser la logique d'activit). Ces oprations sont ralises depuis longtemps, mais ce n'est qu'il y a quelques annes que les principaux acteurs se sont assis autour d'une table pour travailler sur le protocole et placer la communication au-dessus des autres normes. Certaines de ces normes sont maintenant sous l'gide du consortium World Wide Web (W3C), tandis que d'autres sont gres par le consortium OASIS (Organization for the Advancement of Structured Information Standards, organisation pour l'avance des normes d'information structure). Il existe de nombreux ouvrages sur les services Web, tous gnralement assez volumineux. Toutefois, dle au concept de ce guide de survie, ce chapitre tente de simplier les choses, tout en vous donnant tous les lments essentiels. Ainsi, sachez qu'un protocole sert transfrer la requte vers le service Web et sa rponse en retour. Il existe plusieurs possibilits, mais ces trois sont les plus frquentes : XML-RPC. Il s'agit d'un appel de procdure distante XML. XML-RPC utilise un dialecte XML simple pour transfrer des appels de fonction, des paramtres et des valeurs de retour. REST (Representational state transfer, changement d'tat de reprsentation). Il utilise pour l'essentiel des requtes HTTP (GET la plupart du temps mais d'autres verbes

Comprendre les services Web

201

HTTP peuvent aussi tre employs) sous forme d'appel de service Web. Les donnes renvoyes par REST sont du XML brut. SOAP (Simple Object Access Protocol). Le sigle dsignait ses origines un protocole simple d'accs aux objets, or ce protocole n'est pas simple et ne traite pas vraiment de l'accs aux objets, l'acronyme a donc aujourd'hui perdu toute sa signication. Il s'agit d'un protocole plutt complexe mais qui contourne de nombreuses limitations de XML-RPC (qui a d'ailleurs t cr par des personnes ayant travaill sur SOAP). Des dbats houleux ont lieu quant savoir lequel est le meilleur, ce protocole ou le suivant. Pour tout dire, tous ont des avantages et des inconvnients. La plupart du temps, les appels de type REST, XML-RPC ou SOAP sont transports sur du HTTP qui agit comme un protocole de transport. Mais d'autres protocoles peuvent aussi tre utiliss, notamment SMTP (Simple Mail Transfer Protocol, protocole simple de transfert de courrier), voire UDP (User Datagram Protocol, protocole de datagramme utilisateur). Grce SOAP, lorsque vous savez exactement comment est implment un service Web, vous savez galement comment l'appeler (y accder ou l'utiliser). Toutefois, bien souvent, ces informations ne sont pas disponibles, il faut donc qu'il y ait une sorte d'autodescription du service Web contenant toutes les informations importantes, comme les mthodes ou les fonctions exposes, les paramtres et les types de donnes attendus, ainsi que les lments renvoys. Cela peut tre ralis l'aide d'un chier XML cr spciquement dans ce but. La norme utilise est WSDL (Web Service Description Language, langage de description de services Web). De nos jours, elle est utilise pour tous

202

CHAPITRE 10 Services Web

les services Web importants car elle simplie leur emploi. La plupart des technologies ct serveur proposent d'ailleurs un ou plusieurs moyens de lire du WSDL, puis d'accder au service Web comme on accderait une classe disponible localement. L'utilisation de tout ce code XML peut vite devenir assez complexe. Le chapitre suivant traite du XML dans le cadre de la technologie AJAX et propose quelques pistes supplmentaires.Cependant, les navigateurs Mozilla et Microsoft Internet Explorer disposent de leur propre mthode pour accder aux services Web. Cela allge un peu la complexit mais n'est malheureusement pas valable pour tous les navigateurs.

Cration d'un service Web avec PHP


$soap = new SoapServer( 'RandomNumberService.wsdl', array('uri' => 'http://JavaScript.phrasebook.org/') );

Pour utiliser un service Web, il faut d'abord le trouver. La technologie ct serveur la plus populaire pour l'heure s'intitule PHP (Hypertext Preprocessor, prprocesseur hypertexte), c'est donc le choix vident pour implmenter un service Web. Il faut pour cela un serveur Web sur lequel PHP soit install. De nombreux modules d'hbergement Web abordables le contenant existent aujourd'hui, mais PHP peut tre install sur la plupart des serveurs Web. Vous pouvez aussi tlcharger sa distribution et son source sur sa page d'accueil : http://www.php.net/.

Cration d'un service Web avec PHP

203

Pour que tout fonctionne, procurez-vous PHP 5 ou une version ultrieure et activez la bibliothque SOAP livre avec. Sous UNIX/Linux, vous devez complter PHP avec l'argument de configuration ; les utilisateurs de Windows ajouteront la ligne suivante au fichier de configuration php.ini :
extension=php_soap.dll

Il faut galement disposer d'un fichier WSDL, c'est--dire d'une description du service Web comprenant les mthodes qu'il expose et les paramtres qu'il attend. Le fichier RandomNumberService.wsdl contient toutes ces informations. N'oubliez pas de consulter la section <soap:address location="http://localhost/js/webservice.php" /> du WSDL et d'adapter l'URL votre systme local. Le script suivant implmente un service Web SOAP simple avec une mthode (qui renvoie un nombre alatoire dans un intervalle donn) :
<?php $soap = new SoapServer( 'RandomNumberService.wsdl', array('uri' => 'http://JavaScript.phrasebook.org/') ); $soap->setClass('ServiceClass'); $soap->handle(); class ServiceClass { function randomNumber($lower, $upper) { return rand($lower, $upper); } } ?>
Un service Web PHP (webservice.php)

204 CHAPITRE 10 Services Web

Cration d'un service Web avec ASP.NET


<%@ WebService language="C#" class="RandomNumberService" %>

ASP.NET de Microsoft est aujourd'hui l'une des technologies Web dont le dveloppement est parmi les plus rapides. Elle prsente un aspect intressant : elle simplifie considrablement la cration et l'utilisation de services Web. Pour implmenter un service Web, il faut crer un fichier prsentant l'extension .asmx sur le serveur Web. La directive <%@ WebService %> doit ensuite tre place en haut de la page. Toutes les mthodes qui seront exposes comme mthodes de services Web doivent tre prfixes par l'attribut [WebMethod]. En voici un exemple complet :
<%@ WebService language="C#" class="RandomNumberService" %> using System; using System.Web.Services; [WebService(Namespace= "http://JavaScript.phrasebook.org/")] public class RandomNumberService { [WebMethod] public int randomNumber(int lower, int upper) { Random r = new Random(); return r.Next(lower, upper + 1); } }
Un service Web ASP.NET (webservice.asmx)

Appel d'un service Web partir d'Internet Explorer

205

Lorsque vous appelez cette page partir d'un serveur Web activ pour ASP.NET dans votre navigateur Web, vous obtiendrez (selon votre configuration) une jolie page d'informations prsentant des dtails sur le service. Si vous ajoutez ?WSDL l'URL, vous obtenez une description WDSL, automatiquement gnre partir de ASP.NET. La Figure 10.1 montre le rsultat.

Figure 10.1 : Page de dtails automatiquement gnre pour le service Web d'ASP.NET.

Appel d'un service Web partir d'Internet Explorer


WebService.useService("webservice.php?WSDL", "RandomNumberService");

Il y a quelques annes, Microsoft proposait un script d'aide pour accder un service Web depuis une page HTML utilisant JavaScript. Pour que cela fonctionne, le service Web devait se trouver sur le mme serveur que le code JavaScript.

206 CHAPITRE 10 Services Web

Malheureusement, Microsoft a cess de dvelopper ce composant et l'a masqu dans MSDN (rseau des dveloppeurs de Microsoft). Il est pourtant toujours disponible et fonctionne bien. Rendez-vous l'adresse http://msdn .microsoft.com/archive/en-us/samples/Internet/ behaviors/library/webservice/default.asp, tlchargez le fichier webservice.htc et placez-le dans le rpertoire o se trouve votre fichier HTML (le fichier webservice.htc ne fait pas partie du code source tlchargeable pour cet ouvrage). Le marquage suivant charge alors le composant : <div id="WebService" style="behavior:url(webservice.htc);"> Puis, WebService rfrence le composant et permet de charger un service Web distant (mthode useService()), en fournissant sa description WSDL. Le composant permet alors au code JavaScript d'appeler une mthode Web (mthode callService(), en fournissant une fonction de rappel, un nom de mthode et des paramtres). Dans la fonction de rappel, le rsultat peut tre analys ou simplement affich, comme le montre la squence de code suivante :
<html> <head> <title>JavaScript</title> <script language="JavaScript" type="text/JavaScript"> function callWebService(f) { WebService.useService("webservice.php?WSDL", "RandomNumberService"); WebService.RandomNumberService.callService( callbackFunction, "randomNumber", parseInt(f.elements["lower"].value), f l " " l

Appel d'un service Web partir d'Internet Explorer

207

parseInt(f.elements["upper"].value)); } function callbackFunction(result) { document.getElementById("random").innerHTML = result.value; } </script> </head> <body> <div id="WebService" style="behavior:url(webservice.htc);"> </div> <form> A number between <input type="text" name="lower" size="3" value="1" /> and <input type="text" name="upper" size="3" value="49" /> is <span id="random" /><br /> <input type="button" value="Retrieve" onclick="callWebService(this.form);" /> </form> </body> </html>
Appel de services Web partir d'Internet Explorer (webservice-ie-php.html)

La Figure 10.2 montre le rsultat : le nombre alatoire provient du service Web sur le serveur Web.
Info Le listing prcdent traite de l'appel du service Web PHP ; le fichier webservice-ie-aspnet.html traite le service Web ASP.NET. La seule diffrence rside dans le fait que le nom de l'URL du service Web a t modifi ; le reste du code est inchang.

208 CHAPITRE 10 Services Web

Figure 10.2 : Le nombre alatoire provient du service Web.

Appel d'un service Web partir d'un navigateur Mozilla


var soapcall = new SOAPCall();

Les navigateurs Mozilla ont leur propre manire d'appeler des services Web. La classe JavaScript SOAPCall peut d'ailleurs se charger de crer la requte SOAP. Aprs avoir instanci la classe, vous devez paramtrer deux proprits : l'action SOAP (un champ d'en-tte SOAP, souvent l'espace de nom du service Web plus le nom de la mthode) et l'URI (Uniform Resource Identifier) absolue (comprenant le nom du serveur) du service Web.
var soapcall = new SOAPCall(); soapcall.actionURI = "http://JavaScript.phrasebook.org/randomNumber"; soapcall.transportURI = "http://localhost/js/webservice.php";

Vous crez ensuite un tableau de tous les paramtres utiliser dans l'appel du service Web, en instanciant la classe SOAPParameter :
var parameters = [ new SOAPParameter(1, "lower"), new SOAPParameter(49, "upper") ];

Appel d'un service Web partir d'un navigateur Mozilla

209

Puis, la mthode encode() prpare l'appel du service Web. Elle prend les paramtres suivants : b la version SOAP (0 dsigne SOAP 1.1, c'est la valeur recommande) ; b le nom de la mthode du service Web appel ; b l'espace de nom du service Web ; b d'autres en-ttes SOAP envoys (sous forme de tableau) ; b le nombre de paramtres envoyer ; b les paramtres envoyer (sous forme de tableau). La mthode asyncInvoke() appelle le service Web ; vous pouvez fournir une fonction de rappel qui s'excute lorsque les donnes reviennent du service Web. Il s'agit d'un document XML, vous devez donc utiliser DOM pour accder aux informations importantes. Le code suivant fonctionne gnralement bien :
function callbackFunction(result) { var returnData = result.body.firstChild.firstChild.firstChild.data; }

Voici le code complet :


<html> <head> <title>JavaScript</title> <script language="JavaScript" type="text/JavaScript"> function callWebService(f) { var soapcall = new SOAPCall(); soapcall.actionURI = "http://JavaScript.phrasebook.org/randomNumber"; soapcall.transportURI = "http://localhost/js/webservice.php";

210 CHAPITRE 10 Services Web

var parameters = [ new SOAPParameter(parseInt( f.elements["lower"].value), "lower"), new SOAPParameter(parseInt( f.elements["upper"].value), "upper") ]; soapcall.encode( 0, "randomNumber", "http://JavaScript.phrasebook.org/", 0, [], parameters.length, parameters ); soapcall.asyncInvoke(callbackFunction); } function callbackFunction(result) { document.getElementById("random").innerHTML = result.body.firstChild.firstChild.firstChild.data; } </script> </head> <body> <form> A number between <input type="text" name="lower" size="3" value="1" /> and <input type="text" name="upper" size="3" value="49" /> is <span id="random" /><br /> <input type="button" value="Retrieve" onclick="callWebService(this.form);" /> </form> </body> </html>
Appel d'un service Web partir de Mozilla (webservice-mozilla-php.html)

Appel d'un service Web ASP.NET partir d'un navigateur Mozilla

211

Info Une fois de plus, sachez que vous devrez peut-tre modifier l'URL pour l'appel du service Web afin qu'elle corresponde votre systme.

Appel d'un service Web ASP.NET partir d'un navigateur Mozilla


var schematype = schemacoll.getType( "integer", "http://www.w3.org/2001/XMLSchema" );

Il existe un problme potentiel avec le code prcdent : les types de donnes des paramtres envoys au service Web ne sont pas fournis. Malheureusement, certaines implmentations de services Web ncessitent ces informations pour fonctionner. Et surtout, certains services Web .NET ne fonctionnent pas sans ces informations. Il est difficile de dire qui est responsable de la situation, Microsoft ou Mozilla, mais il existe au moins une manire de faire cooprer ces deux systmes. Pour cela, vous devez modifier le moyen de cration des paramtres. Aprs avoir instanci la classe SOAPCall, vous devez charger le codage correct pour chaque paramtre. Dans l'exemple, le type de donnes utilis est integer, c'est donc lui que nous allons employer. Le tableau parameters est maintenant cr de la manire suivante :
var l = new SOAPParameter(parseInt( f.elements["lower"].value), "lower"); var u = new SOAPParameter(parseInt( f.elements["upper"].value), "upper");

212 CHAPITRE 10 Services Web

var soapenc = new SOAPEncoding(); assenc = soapenc.getAssociatedEncoding( "http://schemas.xmlsoap.org/soap/encoding/", false ); var schemacoll = assenc.schemaCollection; var schematype = schemacoll.getType( "integer", "http://www.w3.org/2001/XMLSchema" ); l.schemaType = schematype; u.schemaType = schematype; var parameters = [l, u];
Appel d'un service Web avec des types de donnes distinctifs depuis Mozilla (webservice-mozilla-php.html, extrait)

Astuce Vrifiez d'abord si le service Web fonctionne sans ce codage supplmentaire. Les anciennes versions de Mozilla n'acceptent pas la mthode getAssociatedEncoding(), tandis que certaines versions plus rcentes parviennent cooprer avec certains services Web .NET sans qu'il soit ncessaire de fournir le type de donnes.

11
AJAX et sujets annexes
AJAX (Asynchronous JavaScript And XML) a beaucoup fait parler de lui lorsque le terme a t invent en fvrier 2005. Et mme s'il y a eu beaucoup de critiques (justifies), concernant la fois le terme et le mlange technologique qu'il promet, tout le bruit fait autour d'AJAX a men la renaissance de JavaScript. Non seulement les capacits sous-estimes de JavaScript s'intgrent dans le travail quotidien des dveloppeurs Web, mais les fonctions plus avances sont galement de nouveau la mode. Ce chapitre prsente les faits les plus importants sur JavaScript et les technologies annexes, en particulier la gestion du XML.

214

CHAPITRE 11 AJAX et sujets annexes

Comprendre AJAX
Dans les annes 1990, Microsoft ajoute un nouvel objet ActiveX son navigateur Web Internet Explorer (version 5.0) : XMLHttpRequest. Cet objet pouvait envoyer des requtes HTTP un serveur et valuer les donnes qu'il renvoyait, un peu comme le concept des services Web (mais l'aide d'une autre mthode appele REST, Representational state transfer). L'ide est ne d'une requte de l'quipe Outlook qui travaillait sur la dernire version du frontal Web pour son logiciel. Il y a quelques annes, ce sont les dveloppeurs du projet Mozilla qui ont dcouvert cet objet, dcidant de crer leur propre version de XMLHttpRequest, bien entendu sous forme d'objet JavaScript natif, ActiveX ne fonctionnant pas sur toutes les plates-formes. Les dveloppeurs Safari ont eux aussi implment XMLHttpRequest. Puisque le navigateur tait bas sur le moteur de rendu KHTML de Konqueror, le code (donn par Apple) pourrait aussi tre appliqu au navigateur KDE. Enn, les navigateurs Opera et iCab ont galement ajout une prise en charge de XMLHttpRequest. De plus en plus d'applications Web utilisant XMLHttpRequest, Jesse James Garrett a crit un article en fvrier 2005 intitul "Ajax: A New Approach to Web Applications" (Ajax : une nouvelle approche des applications Web, disponible en ligne l'adresse http://www.adaptivepath.com/publications/ essays/archives/000385.php). Dans cet article, il inventait le terme AJAX qui signie "JavaScript asynchrone + XML". Il avanait que sa socit utilisait XMLHttpRequest et JavaScript, ainsi que DOM, XML, XSLT, XHTML et CSS et qu'il tait de plus en plus difcile de l'expliquer aux clients, en particulier s'ils n'taient pas au fait de la technique. Il a donc invent ce terme global qui a pourtant fait natre de nombreuses critiques (par exemple, aucun

Comprendre AJAX

215

codage XML n'est ncessaire pour AJAX). Toutefois, c'est l'invention du terme "AJAX" qui a donn le dpart de la technologie, c'est partir de l qu'elle a vritablement dcoll. D'un point de vue technique, AJAX consiste utiliser XMLHttpRequest pour envoyer des requtes HTTP au serveur Web (qui doit se trouver dans le mme domaine que le script, pour des raisons de scurit) et utiliser JavaScript pour valuer et afcher les donnes sur le client. Son utilit se limite cela ce qui n'empche pas que se tiennent des confrences entires consacres au sujet.

Initialisation d'une application AJAX


XMLHttp = new XMLHttpRequest(); XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");

La base de toutes les applications AJAX est l'objet XMLHttpRequest dj mentionn. Tous les navigateurs activs pour AJAX le prennent en charge en natif mais, dans Internet Explorer, l'objet ActiveX doit tre prsent. Il existe une exception : Internet Explorer 7 assure la prise en charge native de XMLHttpRequest. La meilleure technique pour crer l'objet consiste utiliser try...catch et instancier d'abord l'objet natif (pour mettre Internet Explorer 7 sur la bonne piste, mme si ce navigateur prend toujours en charge ActiveX), puis la version ActiveX :
if (window.XMLHttpRequest) { // instantie l'objet natif } else if (window.ActiveXObject) { // instantie l'objet ActiveX }

216 CHAPITRE 11 AJAX et sujets annexes

A noter qu'il existe plusieurs possibilits d'instancier l'objet ActiveX : Microsoft commercialise en effet plusieurs versions de sa bibliothque XML dans lesquelles l'objet est cach. Une solution tout fait sre consisterait procder une vrification de toutes les versions, en utilisant une partie de code complique. Toutefois, la solution suivante ne porte que sur les versions les plus importantes et fonctionne avec Internet Explorer versions 5 et suivantes et sur tous les autres navigateurs compatibles avec AJAX.
function getXMLHttp() { var XMLHttp = null; if (window.XMLHttpRequest) { try { XMLHttp = new XMLHttpRequest(); } catch (e) { } } else if (window.ActiveXObject) { try { XMLHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { XMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } } } return XMLHttp; }
Cration de l'objet XMLHttpRequest (xmlhttp.js)

Envoi d'une requte GET

217

Envoi d'une requte GET


XMLHttp.open("GET", "phrasebook.txt"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null);

L'envoi d'une requte HTTP un serveur l'aide de XMLHttpRequest passe par les tapes suivantes : 1. Fournir l'URL et le verbe HTTP utiliser. 2. Dfinir une fonction de rappel lorsque les rsultats arrivent. 3. Envoyer la requte. L'tape 1 peut tre ralise avec la mthode open() de l'objet XMLHttpRequest. A la diffrence de ce que suggre son nom, la mthode n'ouvre pas rellement de connexion HTTP, elle se contente d'initialiser l'objet. Vous fournissez le verbe HTTP utiliser (gnralement GET ou POST) ainsi que l'URL. A l'tape 2, la fonction de rappel est fournie la proprit
onreadystatechange de l'objet. Ds que la proprit readyState de XMLHttpRequest change, cette fonction de rappel est appele. Enfin, la mthode send() envoie la requte

HTTP. Dans la fonction de rappel, la valeur 4 de readyState reprsente l'tat de l'objet que nous souhaitons : l'appel ralis. Dans ce cas, la proprit responseText contient des donnes renvoyes du serveur. En voici un exemple tout fait fonctionnel, l'envoi d'une requte GET au serveur (un fichier appel phrasebook.txt

218 CHAPITRE 11 AJAX et sujets annexes

avec un contenu de texte simple) et l'valuation de la rponse de cet appel :


<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook.txt"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); function handlerFunction() { if (XMLHttp.readyState == 4) { window.alert("Returned data: " + XMLHttp.responseText); } } </script>
Envoi d'une requte GET (xmlhttpget.html)

Comprendre les tats de

XMLHttpRequest

Dans l'ensemble, l'objet XMLHttpRequest accepte cinq tats, indiqus au Tableau 11.1 Selon l'implmentation, tous ces tats peuvent survenir pendant l'excution d'un script AJAX. C'est la raison pour laquelle il est tellement important de toujours interroger l'tat avant d'essayer d'accder d'autres donnes XMLHttpRequest.
Tableau 11.1 : tats de l'objet XMLHttpRequest
Etat Description

0 1

Non initialis Chargement

Comprendre les tats de XMLHttpRequest

219

Tableau 11.1 : tats de l'objet XMLHttpRequest (suite)


Etat Description

2 3 4

Charg En attente Termin

Envoi d'une requte POST


XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); XMLHttp.send("word1=JavaScript&word2=Phrasebook");

Lorsqu'on envoie une requte GET, tous les paramtres font partie de l'URL. Pour POST, toutefois, ces donnes sont envoyes dans le corps de la requte HTTP. Pour procder ainsi avec l'objet XMLHttpRequest, les paramtres doivent tre fournis dans la mthode send(). Un inconvnient apparat : si vous voulez accder ces paramtres ct serveur, il faut dfinir l'en-tte HTTP Content-type correct, avec la mthode setRequestHeader(), de la manire suivante :
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); XMLHttp.open("POST", "post.php"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); XMLHttp.send("word1=JavaScript&word2=Phrasebook");

220 CHAPITRE 11 AJAX et sujets annexes

function handlerFunction() { if (XMLHttp.readyState == 4) { window.alert("Returned data: " + XMLHttp.responseText); } } </script>


Envoi d'une requte POST (xmlhttppost.html)

Le script pointe vers l'URL post.php, un simple script PHP renvoyant les donnes :
<?php if (isset($_POST['word1']) && isset($_POST['word2'])) { echo $_POST['word1'] . ' ' . $_POST['word2']; } else { echo 'No data sent.'; } ?>
Le script PHP cibl par la requte POST (post.php)

Bien entendu, vous pouvez fournir tout autre script de n'importe quelle autre technologie ct serveur ou simplement pointer (POST) vers un fichier de texte brut.

Envoi d'une requte synchrone


XMLHttp.open("GET", "phrasebook.txt", false);

Par dfaut, les requtes HTTP via XMLHttpRequest sont asynchrones, ce qui explique la ncessit d'une fonction de rappel. Toutefois, lorsque vous paramtrez le troisime

Envoi d'une requte synchrone

221

paramtre de la mthode open() sur false, la requte est synchrone, ce qui signifie que l'excution de script est arrte jusqu' ce que les donnes reviennent du serveur. Le code suivant en fait usage :
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> window.onload = function() { var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook.txt", false); XMLHttp.send(null); document.getElementById("output").innerHTML = "Returned data: " + XMLHttp.responseText; } </script> <p id="output">Calling the server ...</p>
Envoi d'une requte synchrone (xmlhttpsync.html)

Sachez que l'ensemble du code n'est excut qu'aprs le chargement complet de la page, faute de quoi l'accs l'lment HTML de rsultat peut chouer.
Attention Les appels synchrones peuvent tre pratiques mais il vaut mieux les viter pour des raisons de simplicit d'utilisation ou de performances. L'excution du script s'arrte totalement lorsque l'appel est ralis, ce qui peut alors se transformer en vritable cauchemar sur des connexions lentes ou des serveurs chargs.

222 CHAPITRE 11 AJAX et sujets annexes

Rception de donnes multiples du serveur


var data = XMLHttp.responseText.split("\n");

Par dfaut, la proprit responseText n'existe qu'une fois ; l'ensemble des donnes renvoyes par le serveur sera donc plac dans la chane. Toutefois, il est souvent ncessaire que plusieurs donnes soient renvoyes par l'appel XMLHttpRequest. Il existe plusieurs solutions ce scnario, la plus simple tant probablement de renvoyer plusieurs donnes et de les sparer l'aide d'un caractre de sparation qui n'apparat pas dans les donnes elles-mmes (par exemple, un tabulateur ou une nouvelle ligne ou le symbole de la barre verticale). Il est alors possible d'utiliser JavaScript pour accder ces informations. Pour cette expression, les fichiers texte suivants, ct serveur, sont interrogs l'aide de HTTP. Dans un scnario concret, il y aurait probablement un script dynamique ct serveur mais, pour la dmonstration, le fichier statique suffit.
JavaScript Phrasebook Sams Publishing
Donnes multiples dans un fichier (phrasebook-multiple.txt)

Le code suivant accde ensuite chaque information des donnes renvoyes ; la Figure 11.1 montre le rsultat.
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript">

Rception de donnes multiples du serveur

223

var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook-multiple.txt"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); function handlerFunction() { if (XMLHttp.readyState == 4) { var data = XMLHttp.responseText.split("\n"); window.alert(data[0] + " " + data[1] + " by " + data[2]); } } </script>
Travailler avec plusieurs donnes partir du serveur (xmlhttpmultiple.html)

Figure 11.1 : Le serveur renvoie plusieurs donnes.

224 CHAPITRE 11 AJAX et sujets annexes

Interruption d'une requte HTTP


XMLHttp.abort();

Selon le navigateur, seul un nombre limit de requtes HTTP peut tre excut au mme moment. Vous risquez d'avoir des problmes, notamment si vous disposez d'une page incluant plusieurs composants AJAX. L'interruption d'une requte HTTP peut donc devenir une ncessit. La mthode utilise pour cela est abort(). Le code suivant interrompt la requte si elle n'a pas t totalement excute au bout de cinq secondes. Pour dmontrer ce comportement, le script PHP delay.php qui est appel par le code demande dix secondes s'excuter. Sachez galement qu'on vrifie en premier la proprit readyState : si elle est gale 0 ou 4, il n'y a rien interrompre.
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "delay.php?" + Math.random()); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); window.setTimeout("timeout();", 5000); function handlerFunction() { if (XMLHttp.readyState == 4) { window.alert("Returned data: " + XMLHttp.responseText); } } function timeout() {

Rcupration d'en-ttes HTTP

225

if (XMLHttp.readyState != 4 && XMLHttp.readyState != 0) { XMLHttp.onreadystatechange = function() { }; XMLHttp.abort(); window.alert("Request aborted"); } } </script>


Interruption de requte HTTP (xmlhttpabort.html)

Cinq secondes aprs le chargement de cette page, la requte est interrompue.


Astuce Ajouter le rsultat de Math.random() l'URL appeler entrane la mise en cache du script delay.php dsactiver, puisque l'URL est diffrente chaque fois.

Rcupration d'en-ttes HTTP


var headers = XMLHttp.getAllResponseHeaders();

La mthode getAllResponseHeaders() (voir le code prcdent) renvoie tous les en-ttes HTTP de la rponse HTTP, tandis que la mthode getResponseHeader() ne renvoie qu'un seul en-tte spcifique. Le code suivant montre comment rcuprer des informations sur le type de serveur Web utilis :
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> ()

226 CHAPITRE 11 AJAX et sujets annexes

var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook.txt"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); function handlerFunction() { if (XMLHttp.readyState == 4) { var servertype = XMLHttp.getResponseHeader("Server"); window.alert("Web server used: " + servertype); } } </script>
Rcupration d'un en-tte de rponse HTTP (responseheader.html)

Sachez que tous les serveurs n'envoient pas cet en-tte, certains y insrent des donnes fausses pour compliquer le profilage du serveur.

Rception de XML en provenance du serveur


var xml = XMLHttp.responseXML;

La proprit responseText fonctionne bien pour une quantit limite de donnes non structures. Une mthode plus lgante pour traiter des donnes complexes et structures dans une application AJAX consiste utiliser la proprit responseXML. Lorsqu'on y accde, la rponse de la requte HTTP se fait sous forme d'objet DOM XML JavaScript, mais uniquement si le serveur renvoie du XML valable. Ce sera null dans le cas contraire.

Rception de XML en provenance du serveur

227

Accder aux dtails de l'objet XML revient en quelque sorte accder aux lments DOM depuis JavaScript. Pour cette section, nous utiliserons l'extrait de fichier XML suivant :
<books> <book pubdate="2006"> <title>JavaScript Phrasebook</title> <publisher>Sams Publishing</publisher> <book> </books>
Exemple de donnes XML (phrasebook.xml)

Pour que les navigateurs Web puissent lire ce code XML (Internet Explorer notamment est trs strict ce sujet), il faut envoyer au client le type MIME correct : text/xml. Si vous passez par Apache, optez plutt pour la configuration suivante dans mime.types, dj prsente par dfaut :
text/xml

Sous Internet Information Services (IIS), vous pouvez configurer les types MIME dans la console d'administration (Start, Run, inetmgr). Vous pouvez aussi permettre un script ct serveur de prsenter le fichier avec le type MIME correct ; c'est gnralement obligatoire si vous utilisez une technologie ct serveur pour gnrer le XML :
<?php header('Content-type: text/xml'); readfile('phrasebook.xml'); ?>
Paramtrage du type MIME correct pour la rponse (phrasebook.xml.php)

228 CHAPITRE 11 AJAX et sujets annexes

Le code suivant accde aux informations du fichier XML, en employant la structure DOM et des mthodes comme getElementsByTagName() et getAttribute(). La Figure 11.2 prsente le rsultat.
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook.xml"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); function handlerFunction() { if (XMLHttp.readyState == 4) { var xml = XMLHttp.responseXML; var book = xml.getElementsByTagName("book")[0]; var pubdate = book.getAttribute("pubdate"); var title, publisher; for (var i=0; i<book.childNodes.length; i++) { if (book.childNodes[i].nodeName == "title") { title = book.childNodes[i].firstChild .nodeValue; } else if (book.childNodes[i].nodeName == "publisher") { publisher = book.childNodes[i].firstChild .nodeValue; } } window.alert(title + " by " + publisher + " (" + pubdate + ")"); } } </script>
Extraction d'informations de la rponse HTTP (xmlhttpxml.html)

Rception de XML en provenance du serveur

229

Figure 11.2 : Les donnes du chier XML.

Astuce Autre proprit utile du document DOM XML : documentElement, qui est un raccourci vers l'lment racine des donnes XML. Ainsi, si le nud racine contient des attributs qui vous intressent (comme le font certains services Web), documentElement est assez pratique.

230

CHAPITRE 11 AJAX et sujets annexes

Comprendre JSON
JSON (JavaScript Object Notation, notation d'objet JavaScript) est, tout comme AJAX, plutt un terme qu'une technologie mais il possde lui sa propre page d'accueil, http://www.json.org/. JSON est une caractristique nglige et sous-estime de JavaScript, une notation assez compacte pour les tableaux et les objets. De nombreux ouvrages dnissent les tableaux JavaScript de la manire suivante, par exemple :
var ajax = new Array( "Asynchronous", "JavaScript", "+", "XML");

Il existe une manire plus courte, qui utilise des crochets :


var ajax = [ "Asynchronous", "JavaScript", "+", "XML"];

Il en va de mme pour les objets (qui sont des tableaux plus ou moins dtaills dans JavaScript), cette fois en utilisant des accolades. Le code suivant dnit un objet avec trois proprits :
var book = { "title": "JavaScript Phrasebook", "publisher": "Sams Publishing", "pubdate": 2006 };

Les deux "raccourcis" peuvent tre associs pour reprsenter des donnes complexes sous forme de chane. Et c'est l l'objet de JSON : puisqu'il peut tre joliment exprim dans une chane, c'est un trs bon format de srialisation de donnes. C'est assez facile de crer une reprsentation JSON d'un objet ct serveur et c'est encore plus simple de transformer cette chane en un objet JavaScript ct client, comme le montre la section suivante.

Utilisation de JSON pour la (d)srialisation de donnes

231

Utilisation de JSON pour la (d)srialisation de donnes


var json = XMLHttp.responseText; var book = eval("(" + json + ")");;

JSON devient de plus en plus frquemment le format d'change de donnes standard pour les applications AJAX. De nombreuses structures AJAX le prennent en charge, de nombreux services Web proposent une interface JSON et PHP 6 assurera probablement une prise en charge de JSON au cur du langage. Utiliser JSON dans JavaScript est galement assez simple. Le code qui prcde value JSON et le transforme en objet JavaScript, une simple fonction eval() y parvient. La notation JSON de l'encadr prcdent, "Comprendre JSON", figure dans un fichier intitul phrasebook.json ; le code suivant lit ce fichier en utilisant XMLHttpRequest, puis en extrait quelques donnes :
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); XMLHttp.open("GET", "phrasebook.json"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); function handlerFunction() { if (XMLHttp.readyState == 4) { var json = XMLHttp.responseText; var book = eval("(" + json + ")"); var pubdate = book.pubdate; var title = book.title;

232 CHAPITRE 11 AJAX et sujets annexes

var publisher = book.publisher; window.alert(title + " by " + publisher + " (" + pubdate + ")"); } } </script>
Utiliser JSON pour la dsrialisation des donnes (xmlhttpjson.html)

Attention Il est gnralement dconseill d'utiliser eval(), car il introduit une vulnrabilit de scurit importante si JSON provient d'une source non fiable. Du fait de la restriction lie au domaine identique de XMLHttpRequest, on peut gnralement faire confiance au code JSON mais, pour plus de scurit, tlchargez la bibliothque JSON json.js l'adresse http://www.json.org/js.html. Le code suivant remplace l'appel eval() :

var book = json.parseJSON();

Cration d'un cran d'attente


document.getElementById("loading").style.visibility = "hidden";

L'un des plus gros obstacles pour les applications Web modernes est l'attente : une opration a lieu, mais en arrire-plan. Or, il vous faut en informer les utilisateurs, faute de quoi ils risquent de s'impatienter. On peut pour cela modifier le curseur de la souris (voir Chapitre 4, "CSS") ; il est aussi possible d'afficher une bannire d'attente. De nombreuses applications font graduellement disparatre une bannire contenant la mention "veuillez patienter" ou "chargement en cours" lors de l'excution d'un appel XMLHttpRequest ; l'un des premiers sites Web utiliser cela a t Google Mail.

Cration d'un cran d'attente

233

En fait, cette expression ncessite plus d'lments DHTML qu'AJAX. Lorsque l'appel (asynchrone !) est envoy au serveur, l'cran de chargement s'affiche, il est plac dans le coin suprieur droit (vous pouvez bien sr utiliser la position que vous prfrez). Lorsque les donnes reviennent du serveur, la bannire disparat nouveau. Le code suivant implmente ceci, indpendamment du navigateur :
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); window.onload = function() { XMLHttp.open("GET", "delay.php?" + Math.random()); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); with (document.getElementById("loading")) { style.visibility = "visible"; if (navigator.appName == "Microsoft Internet Explorer") { style.posLeft = document.body.clientWidth - 75; style.posTop = 0; } else { style.left = (window.innerWidth - 75) + "px"; style.top = "0px"; } } } function handlerFunction() { if (XMLHttp.readyState == 4) { document.getElementById("loading").style .visibility = "hidden"; window.alert("Returned data: " + XMLHttp.responseText);

234 CHAPITRE 11 AJAX et sujets annexes

} } </script> <span id="loading" style="position: absolute; visibility: hidden; background-color: red; width: 75px;">Loading ...</span>
Implmentation d'un cran d'attente (waiting.html)

La Figure 11.3 prsente le navigateur qui attend des rsultats : la bannire apparat (et disparat nouveau lorsque les donnes de la requte HTTP sont arrives).

Figure 11.3 : L'cran d'attente. Attention L'objet XMLHttpRequest ne remarquera pas un ventuel problme avec un lment de votre requte HTTP, y compris avec les temporisations. Utilisez donc le motif prsent la section "Interruption d'une requte HTTP" pour vrifier le statut de la requte aprs une certaine priode. Si la requte ne s'est pas encore termine, redmarrez-la ou affichez un message d'erreur et laissez disparatre la bannire d'attente.

Rsolution du problme de signet

235

Rsolution du problme de signet


var data = unescape(location.hash.substring(1));

L'un des principaux problmes rencontrs avec les applications AJAX actuelles rside dans le fait qu'il est impossible de placer un signet sur une page. Le contenu pouvant changer grce aux appels XMLHttpRequest, mais l'URL restant la mme, le signet ne fonctionne pas. Il existe toutefois un contournement. Attention, ce n'est que l'emballage du code que vous devez crire, le vritable travail faire (selon votre application) consiste faire perdurer les donnes, puis les rappliquer la page. L'astuce se traduit par l'ajout des donnes qui identifient l'tat actuel de la page l'URL, non pas sous la forme d'un paramtre GET (puisque cela rechargerait la page), mais aprs le dise : http://server/file.html#info Les donnes concernes ici par info doivent identifier le statut de la page en cours. Les dtails de l'implmentation dpendent grandement de la manire dont AJAX est employ sur la page. Ds que l'tat actuel de la page change, le dise (location.hash dans JavaScript) doit tre mis jour. L'extrait de code suivant lit ensuite ces informations une fois que la page est charge. Vous devez implmenter la fonction applyData() qui s'occupe de transformer les informations de location.hash en contenu rel sur la page. window.onload = function() { if (location.hash.length >= 2) { var data = unescape(location.hash.substring(1)); applyData(data); } };

236 CHAPITRE 11 AJAX et sujets annexes

Cela augmente bien entendu la quantit de travail raliser mais vos utilisateurs bnficieront grandement de cette fonction commode. Malheureusement, cette mthode ne fonctionne pas (encore) avec Safari et Konqueror car ils grent location.hash d'une manire diffrente.
Attention N'essayez pas de placer simplement JSON aprs le dise, puis d'appeler eval() car un pirate pourrait, par malveillance, placer du code JavaScript dans l'URL qui serait ensuite excute dans le contexte de votre site. Ce type d'attaque est appel Cross-Site Scripting (XSS) et se rvle trs dangereux. Validez donc toujours les donnes avant de les utiliser.

Rsolution du problme du bouton Prcdent


window.frames["loader"].window.location.search = "?" + escape(data);

Il existe un problme li au thme trait la section prcdente et qui concerne le bouton Prcdent (et, bien entendu aussi le bouton Suivant). Lorsque l'URL de la page ne change pas mais que son contenu est modifi, le bouton Prcdent ne fonctionne pas comme prvu. Pour rsoudre ce problme et, une fois de plus, cette section ne prsente qu'une manire gnrique et non une solution complte (de nombreux dtails dpendent de l'implmentation), il faut d'abord traiter deux sous-problmes : b Vrifier qu'au moment du chargement de la page, les informations figurant dans location.hash sont appliques la page (si vous appliquez la section prcdente, ce travail a dj t effectu).

Rsolution du problme du bouton Prcdent

237

b Vous assurer que les diverses pages du nouveau dise se trouvent dans l'historique du navigateur, faute de quoi les boutons Prcdent et Suivant ne fonctionneront pas. Cette tche est effectue automatiquement par les navigateurs Mozilla, mais pas par Internet Explorer. La solution au second sous-problme consiste utiliser un cadre intgr masqu, qui chargera une page invisible, dont le seul but est d'obtenir une entre dans l'historique de la page. Voici le cadre intgr :
<iframe src="loader.html" name="loader" style="display:none"></iframe>

Ds qu'un vnement survient sur la page (li AJAX), vous devez forcer le cadre de chargement se charger nouveau, en ajoutant des donnes l'URL ( la diffrence du code prcdent, ici, le rechargement est obligatoire) :
if (window.ActiveXObject) { window.frames["loader"].window.location.search = "?" + escape(data); }

Enfin, le cadre de chargement doit appliquer toutes les donnes charges au document principal ; l'opration est ncessaire, au moins pour Internet Explorer, car les boutons Prcdent et Suivant y modifient le contenu du cadre intgr !
window.onload = function() { if (location.search.length >= 2) { var data = unescape(location.search.substring(1)); top.applyData(data); } };

238 CHAPITRE 11 AJAX et sujets annexes

Cela complique un peu plus la vie du programmeur, en particulier si plusieurs effets AJAX cohabitent sur la page. Mais, nous l'avons dj dit, vos utilisateurs bnficieront grandement de cette fonction. Et, une fois de plus, ce contournement ne fonctionne pas (encore) avec Safari et Konqueror.

XSLT
var process = new XSLTProcessor();

Les navigateurs Internet Explorer et Mozilla prennent en charge XSLT de JavaScript, selon des procdures trs diffrentes. Pour Microsoft Internet Explorer, il vous faudra une fois de plus ActiveX (avec galement Internet Explorer 7). Vous chargez d'abord le fichier XSLT, puis le XML (provenant bien sr de XMLHttpRequest). Enfin, le rsultat de la transformation XSL est disponible sous forme de chane et peut, par exemple, tre annex la page. Les navigateurs Mozilla, quant eux, adoptent une autre mthode ; ils se reposent exclusivement sur un objet natif. Le rsultat est diffrent de l'implmentation d'Internet Explorer. Au final, vous obtenez un fragment DOM, que vous pouvez ajouter au code DOM de la page en cours.
Comprendre XSLT

Comprendre XSLT

239

Comprendre XSLT
En 1999, le W3C a publi la spcication XSLT 1.0 (eXtended Stylesheet Language Transformations). Le sigle signie transformations XSL. Il s'agit d'un langage fond sur XML pour transformer des donnes sous une autre forme. La plupart du temps, les donnes produites le sont en HTML, mais d'autres formats sont aussi possibles. Sur le Web toutefois, le HTML est gnralement prfrable. XSLT fonctionne avec des modles, grce auxquels vous accdez, entre autres choses, des valeurs de nud et d'attributs du chier source XML. Le code suivant prsente un exemple de chier XSLT :
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <ul> <xsl:for-each select="books/book"> <li> <xsl:value-of select="title" /> by <xsl:value-of select="publisher" /> (<xsl:value-of select="@pubdate" />) </li> </xsl:for-each> </ul> </xsl:template> </xsl:stylesheet>
Le fichier XSLT (phrasebooks.xsl)

240 CHAPITRE 11 AJAX et sujets annexes

Le code suivant couvre les deux principaux types de navigateurs :


<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script language="JavaScript" type="text/JavaScript"> var XMLHttp = getXMLHttp(); window.onload = function() { XMLHttp.open("GET", "phrasebooks.xml"); XMLHttp.onreadystatechange = handlerFunction; XMLHttp.send(null); } function handlerFunction() { if (XMLHttp.readyState == 4) { var xml = XMLHttp.responseXML; if (window.ActiveXObject) { var xslt = new ActiveXObject( "MSXML2.FreeThreadedDOMDocument"); xslt.async = false; xslt.load("phrasebooks.xsl"); var template = new ActiveXObject( "MSXML2.XSLTemplate"); template.stylesheet = xslt; var process = template.createProcessor(); process.input = xml; process.transform(); var para = document.createElement("p"); para.innerHTML = process.output; document.body.appendChild(para); } else if (window.XSLTProcessor) { var xslt = document.implementation .createDocument("", "", null); xslt.async = false; xslt.load("phrasebooks.xsl"); var process = new XSLTProcessor(); i S l h ( l )

Utilisation d'une bibliothque XML

241

process.importStylesheet(xslt); var result = process.transformToFragment( xml, document); document.body.appendChild(result); } } } </script>


Utilisation de XSLT avec JavaScript (xmlhttpxsl.html)

La Figure 11.4 montre le rsultat de la transformation : les donnes du fichier XML sont prsentes sous forme de liste puces.

Figure 11.4 : Le rsultat de la transformation XSL.

Comme le montre galement la Figure 11.4, le navigateur Opera ( partir de la version 9) possde une implmentation XSLT compatible, utilisant la manire Mozilla.

Utilisation d'une bibliothque XML


var result = xsltProcess(xml, xslt);

Vous le voyez, l'utilisation de XSLT partir de JavaScript peut tre assez complique lorsque l'objectif est de la faire fonctionner avec autant de navigateurs que possible.

242 CHAPITRE 11 AJAX et sujets annexes

Dans ce cas, pour gagner du temps et s'pargner des efforts, il est recommand d'utiliser un cadre externe. Google a cr une structure de ce type ("AJAXSLT"), disponible gratuitement (sous licence BSD) l'adresse http://goog-ajaxslt.sourceforge.net/. La section suivante utilise la version 0.4 de la structure, que vous pouvez galement dcouvrir partir des chemins employs dans ce code. La structure elle-mme ne fait pas partie des tlchargements de codes pour cet ouvrage. L'expression suivante procde la transformation XSLT mais repose cette fois-ci sur les fonctionnalits proposes par AJAXSLT.
<script language="JavaScript" type="text/JavaScript" src="xmlhttp.js"></script> <script src="ajaxslt-0.4/misc.js" type="text/JavaScript"></script> <script src="ajaxslt-0.4/dom.js" type="text/JavaScript"></script> <script src="ajaxslt-0.4/xpath.js" type="text/JavaScript"></script> <script src="ajaxslt-0.4/xslt.js" type="text/JavaScript"></script> <script language="JavaScript" type="text/JavaScript"> var xml = null; var xslt = null; var XMLHttp1 = getXMLHttp(); var XMLHttp2 = getXMLHttp(); window.onload = function() { XMLHttp1.open("GET", "phrasebooks.xml"); XMLHttp1.onreadystatechange = handlerFunction1; XMLHttp1.send(null); XMLHttp2.open("GET", "phrasebooks.xsl"); XMLHttp2.onreadystatechange = handlerFunction2; XMLHttp2.send(null); }

Utilisation d'une bibliothque XML

243

function handlerFunction1() { if (XMLHttp1.readyState == 4) { xml = xmlParse(XMLHttp1.responseText); if (xslt != null) { transform(); } } } function handlerFunction2() { if (XMLHttp2.readyState == 4) { xslt = xmlParse(XMLHttp2.responseText); if (xml != null) { transform(); } } } function transform() { var result = xsltProcess(xml, xslt); document.getElementById("output").innerHTML = result; } </script> <div id="output"></div>
Utilisation de XSLT avec JavaScript et AJAXSLT (ajaxslt.html)

Cela fonctionne bien (vous le voyez, la majorit du code s'occupe du tlchargement des fichiers XML et XSL) mais l'opration marche aussi dans plusieurs navigateurs, comme le montre la Figure 11.5 (capture dans Konqueror). Autre avantage, vous pouvez galement utiliser XPath avec cette bibliothque. Les navigateurs Internet Explorer et Mozilla et Opera fonctionnent avec XPath, mais de manire encore plus incompatible qu'avec XSLT. La prise en charge de AJAXSLT par XPath permet aussi de grer des navigateurs plus anciens.

244 CHAPITRE 11 AJAX et sujets annexes

Figure 11.5 : Avec AJAXSLT, la transformation fonctionne mme dans Konqueror.

Utilisation du service Web Yahoo!


<script language="JavaScript" type="text/JavaScript" src="http://api.search.yahoo.com/WebSearchService/V1/ webSearch?appid=XXX&query=JavaScript&output= json&callback=showResults"> </script>

De plus en plus de services Web proposent une interface JSON ; les services Web Yahoo! ont d'ailleurs t parmi les premiers le faire. Aprs une inscription (gratuite) http://api.search.yahoo.com/webservices/register _application, vous recevez votre identifiant personnel. Il est li votre application et doit remplacer les XXX de cette expression. La balise prcdente <script> appelle le service Web et attend du JSON en retour et fournit galement le nom d'une fonction de rappel, appele aprs que les donnes y sont places. Votre application reoit donc le code JavaScript du serveur Yahoo! et l'excute, ce qui signifie que vous devez faire confiance Yahoo! pour l'utiliser. La fonction de rappel rcupre donc un objet JavaScript avec les rsultats de la recherche de Yahoo!.

Utilisation du service Web Yahoo!

245

Le code suivant cre alors une liste puces avec les donnes provenant du service Web. Vous trouverez de plus amples informations sur le format spcifique des donnes renvoyes de Yahoo! dans la documentation en ligne l'adresse http://developer.yahoo.com/search/Web/ V1/webSearch.html. La Figure 11.6 montre le rsultat de ce code.
<script language="JavaScript" type="text/JavaScript"> function showResults(data) { var ul = document.getElementById("output"); for (var i=0; i < data.ResultSet.Result.length; i++) { var text = document.createTextNode( data.ResultSet.Result[i].Title + " - " + data.ResultSet.Result[i].Url); var li = document.createElement("li"); li.appendChild(text); ul.appendChild(li); } } </script> <body> <p><ul id="output"></ul></p> </body> <script language="JavaScript" type="text/JavaScript" src="http://api.search.yahoo.com/WebSearchService/ V1/webSearch?appid=XXXXX&query=JavaScript& output=json&callback=showResults"> </script>
Appel du service Web Yahoo! avec JavaScript (yahoowebservice.html)

246 CHAPITRE 11 AJAX et sujets annexes

Figure 11.6 : Les rsultats de la recherche Yahoo!.

Utiliser un cadre d'applications AJAX


Plus vous utilisez AJAX sur votre site Web, plus vous devez chercher les cadres d'applications AJAX disponibles, susceptibles de vous faciliter la tche avec XMLHttpRequest et d'autres fonctions JavaScript avances. Le cadre d'applications employer dpend largement de la technologie ct serveur. Il existe plusieurs cadres d'applications AJAX pour Java (comme Zimbra, l'adresse http://www.zimbra.com/) et ASP.NET 2.0 (comme Atlas, l'adresse http://atlas.asp.net/) ; PHP connat trop de cadres d'applications pour que nous puissions les numrer (par exemple le package PEAR l'adresse http://pear.php.net/package/HTML_AJAX).

Utiliser un cadre d'applications AJAX

247

Il existe galement des cadres d'applications AJAX assez intressants, indpendants des technologies, et qui se concentrent plutt sur l'aspect JavaScript. Dojo notamment (http://www.dojotoolkit.org/) est assez utile car il propose des contournements analogues ceux mentionns dans ce chapitre pour faire fonctionner les boutons Prcdent et Suivant. On considre que Tibet est l'une des plus anciens cadres d'applications (http://www.technicalpursuit.com/). Le travail a dmarr (au moins du point de vue conceptuel) en 1997 et le produit est sorti en 1999. Choisissez donc votre cadre d'applications avec mesure, selon votre technologie ct serveur : dterminez au pralable si vous utilisez exclusivement une technologie ct serveur ou si vous devez vous conformer aux choix de votre clientle. Selon ces informations, les caractristiques des divers cadres d'applications et notamment l'activit de dveloppement (puisque de nombreux projets ne voient jamais le jour ou meurent au bout de quelques mois), votre choix se portera sur un cadre d'applications ; mais les sections de ce chapitre vous indiqueront souvent les lments ncessaires pour transformer votre application Web en application AJAX.

12
Mdias intgrs
HTML et JavaScript sont une combinaison succs mais qui ne suffit pas toujours crer une application Web moderne. HTML permet donc aux dveloppeurs d'intgrer un contenu diffrent dans un site. Gnralement, il faut pour cela disposer d'un plug-in pour navigateur. Ce chapitre montre comment accder ce contenu et propose plusieurs pointeurs vers les types de contenu les plus largement utiliss. Sachez que la plupart des codes de ce chapitre ne figurent pas dans les tlchargements de code.

Accs aux mdias intgrs


document.media

L'lment HTML "officiel" qui permet d'intgrer les mdias s'intitule <object>. Toutefois, pour que le site fonctionne dans plusieurs navigateurs, il est gnralement conseill d'intgrer un objet <embed> dans l'lment <object>.

250 CHAPITRE 12 Mdias intgrs

Et pour que l'accs l'objet intgr soit aussi simple que possible, l'attribut id de l'lment <object> doit correspondre l'attribut name de l'objet <embed> :
<object classid="..." id="media"> <embed name="media"></embed> </object>

Vous pouvez ensuite accder aux mdias intgrs en utilisant le raccourci figurant au dbut de cette section. Bien entendu, document.getElementById() sert aussi accder l'lment <object> ; tous les lments <embed> se trouvent dans le tableau document.embeds. Vous le voyez, le raccourci est beaucoup plus pratique ici.

Vrication des modules complmentaires dynamiques


if (new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.8")) { }

Dans les navigateurs Mozilla, l'URL spciale about:plugins propose la liste de tous les modules complmentaires (plug-in) disponibles, comme le montre la Figure 12.1 ; cela fonctionne galement dans Opera. Selon le navigateur choisi, il existe deux manires pour vrifier activement la prsence d'un module complmentaire donn : b Dans les navigateurs Mozilla et Opera (qui utilisent la mme API), navigator.plugins donne un tableau contenant tous les modules complmentaires. Chaque lment indique le nom, le nom de fichier et la description de chaque module. De mme, navigator .mimeTypes propose une liste de tous les types MIME pris en charge et accepts par le module.

Vrification des modules complmentaires dynamiques

251

Figure 12.1 : Opera prsente une liste de tous les modules complmentaires installs.

b Sous Internet Explorer (Windows uniquement), vous pouvez essayer d'instancier la classe associe, prsente par le module complmentaire, en utilisant le constructeur ActiveXObject. Le code suivant tente de dtecter le module complmentaire Flash. Pour Internet Explorer, on fait appel au nom de l'objet COM associ, pour les autres navigateurs, le code recherche un module appel "Shockwave Flash".
<script language="JavaScript" type="text/JavaScript"> var hasFlash = false; if (window.ActiveXObject) { try { if (new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.8")) {

252 CHAPITRE 12 Mdias intgrs

hasFlash = true; } } catch (e) { } } else if (navigator.plugins) { if (navigator.plugins["Shockwave Flash"]) { hasFlash = true; } } window.alert(hasFlash); </script>
Dtection du module complmentaire Flash (plugin.html)

Attention Le tableau navigator.plugins est galement disponible sous Internet Explorer, mais il est vide. Vous devez donc d'abord rechercher window.ActiveXObject, puis navigator.plugins. L'opration ne fonctionne pas dans l'autre sens.

Gestion des versions rcentes d'Internet Explorer


Une dcision de justice a oblig Microsoft sortir une mise jour de son navigateur en mars et avril 2006, modifiant le comportement des mdias intgrs. Si l'utilisateur "n'active pas" les donnes intgres en cliquant dessus, de nombreux vnements ne se dclenchent pas et d'autres restrictions apparaissent. La Figure 12.2 montre les informations prsentes par le navigateur dans ce cas. Toutefois, l'adresse http://msdn.microsoft.com/workshop/author/dhtml/overview/activating_activex.asp, Microsoft propose un contournement. L'ide consiste

Gestion des versions rcentes d'Internet Explorer

253

Figure 12.2 : Les mdias intgrs (ici, une animation Flash) sont inactifs.

utiliser JavaScript pour inclure l'lment <object> sur la page. Les prcisions techniques apportes par la dcision de justice stipulent que le code JavaScript qui cre (via la mthode document.write()) l'lment <object> doit rsider dans un fichier externe. Il faut donc d'abord utiliser un lment <script> de la manire suivante :
<script language="JavaScript" type="text/JavaScript" src="externalFile.js"> </script>

puis produire, dans le fichier externalFile.js, le marquage qui charge le fichier mdia intgr :
document.write("<object classid=\"...\" ...></object>");

254 CHAPITRE 12 Mdias intgrs

Astuce Bien entendu, le mdia intgr ne fonctionne que lorsque JavaScript est activ, vous devez donc galement disposer d'une solution dans un lment <noscript>. Du fait du brevet logiciel l'origine de la dcision de justice, il est galement possible que d'autres fournisseurs de navigateurs aient implmenter un nouveau comportement du mme type pour les mdias intgrs.

Accs au contenu multimdia


L'accs au contenu multimdia (donnes audio ou vido) dans le navigateur est assez difficile. Il existe d'ailleurs de nombreux modules complmentaires, et chaque version semble modifier un lment par rapport son prdcesseur. Pour obtenir des informations actualises ou spcifiques une version concernant l'accs aux divers modules, consultez le site Web du fabricant. Le systme prsente tout de mme de bons cts, les principaux modules complmentaires lis aux donnes multimdias, actuellement Windows Media Player, Real Player et Apple QuickTime prsentent des noms de mthode assez similaires. Ainsi, lorsque vous avez accd au module complmentaire, comme cela est indiqu au dbut du chapitre, vous obtenez, grce aux mthodes du Tableau 12.1, la fonctionnalit essentielle dont vous avez besoin pour travailler avec les mdias intgrs.

Accs au contenu Java

255

Tableau 12.1 : Mthodes pour la fonctionnalit multimdia


Action Windows Media Player Real Player QuickTime

Lecture Arrt Pause Volume

play() stop() pause() volume

DoPlay() DoStop() DoPause() GetVolume()/ SetVolume()

play() stop() pause() GetVolume()/ SetVolume()

Accs au contenu Java


document.JavaApplet.setString(field.value);

On a imagin pendant un temps que Java tait le format Web dominant mais sa place est de nos jours plutt en arrire-plan. Toutefois, vous rencontrerez toujours des applets Java intgres dans les pages Web, mme si le module complmentaire Java n'a pas la mme prsence que son homologue Flash. Lorsqu'une applet Java est intgre dans une page, il est possible d'appeler toutes ses mthodes publiques. L'applet suivante, trs simple, prsente sa mthode setString(), qui dfinit une variable prive, puis se redessine :
import java.applet.*; import java.awt.*; public class JavaApplet extends Applet { private String _s = "Welcome!";

256 CHAPITRE 12 Mdias intgrs

public void paint(Graphics g) { g.setColor(Color.black); g.drawString(_s, 20, 20); } public void setString(String s) { this._s = s; this.repaint(); } }
Une applet Java simple (JavaApplet.java)

Une fois cette applet compile dans une classe, le code JavaScript suivant appelle la mthode setString() ds que le contenu du champ de texte est modifi. La Figure 12.3 montre le rsultat.

Figure 12.3 : L'applet change lorsque vous tapez.

Accs au contenu Flash

257

<script language="JavaScript" type="text/JavaScript"> function paint(field) { document.JavaApplet.setString(field.value); } </script> <applet code="JavaApplet.class" name="JavaApplet" width="150" height="75"></applet><br /> <input type="text" onkeyup="paint(this);" />
Accs Java avec JavaScript (java.html)

Accs au contenu Flash


document.flash.Play(); document.flash.Rewind(); document.flash.StopPlay();

Les animations Flash peuvent tre contrles via du JavaScript. Entre autres choses, vous pouvez dmarrer, arrter et mettre en pause l'animation. Le module complmentaire prsente donc les mthodes Play(), Rewind() et StopPlay(). Le listing suivant implmente une simple console de contrle pour l'animation Flash.
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/ shockwave/cabs/flash/swflash.cab #version=7,0,0,0" width="400" height="550" id="flash"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="flash.swf" />

258 CHAPITRE 12 Mdias intgrs

<embed src="flash.swf" width="400" height="550" name="flash" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/ getflashplayer" /> </object> <a href="JavaScript:document.flash.Play();"> Play</a> <a href="JavaScript:document.flash.Rewind();"> Stop</a> <a href="JavaScript:document.flash.StopPlay();"> Pause</a>
Accs une animation Flash partir de JavaScript (flash.html

Info Les options allowScriptAccess dfinies la fois dans les lments <object> et <embed> permettent JavaScript d'accder rellement l'animation Flash.

Index
A
abort() 224 Absolu, positionnement 90 Accs balises 73 boutons radio 136 case cocher 135 champs de texte 133 classes CSS 56 contenu Java 255 CSS 57 lment spcifique 72 formulaires 132 liste choix multiple 139 liste de slection 137 membre d'une classe 100 rgles de CSS 58 Activation de JavaScript 17 AJAX 214, 215, 246 initialisation 215 AJAXSLT 242 Ajout d'lments 78 Alatoire, nombre 28 animate() 46 Animation graphique 45 Appel service Web ASP.NET 211 service Web avec IE 205 service Web avec Mozilla 208 appendChild() 79 Applet Java 255 appName 22 Arborescence DOM 74 ASP.NET 204 Atlas 107 Attente, cran 232 Attributs 82

B
Balise 73 Barre de progression 47, 48 Bibliothque XML 241 Blocage de fentres contextuelles 190 Bouton attacher un vnement 108 radio accder 136 dslectionner 167 valider 155 sensibles 40 souris 115 Bouton Prcdent 236

C
Cache, mise en 26 empcher 26 Cadres 193 intgrs 197 masqus 196 modifier simultanment 194 Capacits du navigateur 25 Caractres spciaux 30 Carte de site 188

260

Case cocher

Case cocher accder 135 valider 155 Champ de texte 133 focus 149 griser 142, 144 slection de texte 149 validation 153 vider en cas de clic 152 Chargement dynamique 13 checked 135, 136 Chemin d'un cookie 125 Classe accder aux membres 100 crer 100 CSS 56 hriter 103 Clavier, vnements 110 Clonage d'lments 83 cloneNode() 83 close() 189 Code excuter 16 intgrer 11 Commande CSS 54 visibility 62 Compatibilit DHTML 71 Configuration des navigateurs 10 Confirmation, demande de 36 Contenu Flash 257 multimdia 254 Contextuelle, fentre 96 Cookie chemin 125 date d'expiration 124

dfinition 117 dsrialiser 130 domaine 126 craser 126 fonctionnement 118 HTTP uniquement 127 informations multiples 129 limitations 119 lire 121 paramtrer 120 prendre en charge 127 scuriser 126 spcification 119 supprimer 126 cookie proprit 120 Correspondance d'images 51 createTextNode() 81 Cration boutons sensibles 40 carte de site 188 classe 100 lments de texte 81 liste puces 86 navigation toujours apparente 94 nombre alatoire 28 service Web 202, 204 tableau 87 CSS accder 57 accder aux rgles 58 classes 56 commandes 54 slecteurs 64 styles 54 Curseur modifier 66 styles 68

INDEX

Evnement

261

D
Date 28 d'expiration pour un cookie 124 et heure 28 listes pr-remplies 167 modification 34 validation 169 Demande de confirmation 36 donnes utilisateur 36 Dplacement d'lments 92 Dsactivation de JavaScript 17 lments de formulaire 142 Dslection d'un bouton radio 167 Dsrialisation d'un cookie 130 Dtection du navigateur 22 DHTML 71 acceptation 71 Disparition d'lments de la page 61 document.forms 132 DOM inspecteur 70 modle d'objet 69 naviguer dans l'arborescence 74 proprits 74 Donnes (d)srialiser avec JSON 231 demander 36 multiples (rception) 222

E
Ecran d'attente 232 taille 179 Ecrasement de cookies 126 Elment 12, 249 ajouter 78 cloner 83 dplacer 92 positionner 90 remplacer 85 spcifique, accder 72 supprimer 77 Emulation (membre d'une classe) 103 Enregistrement dans un cookie 129 En-tte HTTP 225 Entre, touche 111 Envoi empcher 145 fichiers 141 formulaire 145 rpt, viter 146 requte GET 217 POST 219 synchrone 220 Etats de XMLHttpRequest 218 Etirement graphique 46 eval() 231 Evnement attacher un bouton 108 clavier 110 gestionnaire 16 mouseover 40 ragir 107 souris 113

INDEX

262

Excution de code

Excution de code 16 Expiration d'un cookie 124 Expressions rgulires 30 caractres spciaux 30 rechercher 32 Extension d'objets intgrs 106

F
Fentre bloquer 190 centrer 184 contextuelle 96, 184 en coin 186 fermer 189 modale 177 options 174 plein cran 186 recherche de systme de blocage 192 redimensionner 182 repositionner 183 taille 180 window 173 Fermeture d'une fentre 189 Fichier chargement dynamique 13 envoyer 141 externe 12 Flash accder au contenu 257 fentre contextuelle 96 Focus dans un champ 149 focus() 149 Fonction animate() 46 eval() 231 form 133

Formulaire accder 132 dsactiver des lments 142 document.forms 132 empcher l'envoi 145 envoyer 145 viter les envois rpts 146 HTML 132 touche Entre 111 valider 154 valider automatiquement 159 frames 193

G
Gestionnaire d'vnements 16 GET 34 envoyer une requte 217 getAllResponseHeaders() 225 Graphique animer 45 tirer 46 modifier 40 Gris, champ 142, 144

INDEX

H
Hritage de classe 103 Heure 28 Histoire de JavaScript 5 Historique 33 history (objet) 33 HTML formulaires 132 modifier 89 transformations XSLT 239

Mthode

263

HTTP cookies 127 interrompre la requte 224 rcuprer un en-tte 225

K
Konqueror 8

I
IE appeler un service Web 205 mdias intgrs 252 Images correspondance 51 prcharger 43 survol 44 Inclusion de code 11 Informations de n_ud 75 Initialisation d'une application AJAX 215 innerHTML 89 Inspecteur DOM 70 Intgrs, cadres 197 Intgrs, mdias 249 Internet Explorer 8 Interruption d'une requte HTTP 224

L
Lecture d'un cookie 121 Limitation d'un cookie 119 Liste choix multiple 139 puces 86 date de validation 169 pour la navigation 163, 164 pr-remplie 167 slection accder 137 valider 157

INDEX

M
Masquage d'un cadre 196 match() 32 Mdias intgrs 249 dans IE 252 Membre accder 100 muler 103 Mthode abort() 224 appendChild() 79 cloneNode() 83 close() 189 createTextNode() 81 focus() 149 getAllResponseHeaders() 225

J
Java accder au contenu 255 applet 255 JSON 230 (d)srialiser des donnes 231 services Web Yahoo! 244

264

Mthode

Mthode (suite) match() 32 open() 217 random() 28 reload() 27 removeChild() 77 replace() 33 window.alert() 36 window.open() 173 window.prompt() 36 Modale, fentre 177 Modification curseurs 66 date 34 deux cadres simultanment 194 fragment HTML 89 graphique 40 Module complmentaire dynamique 250 Mot cl new 100 this 100 mouseover 40 Mozilla appeler un service Web 208 appeler un service Web ASP.NET 211 Multimdia, accs au contenu 254

Internet Explorer 8 Konqueror 8 mise en cache 26 Opera 8 rediriger 26 Safari 8 vrifier les capacits 25 version 24 Navigation hirarchique 164 liste de slection 164 par liste de slection 163 toujours apparente 94 navigator (objet) 22 new 100 Nombre alatoire 28

INDEX

O
Objet Date 28 DOM 69 history 33 intgr 106 navigator 22 screen 179, 187 window 173, 182 XMLHttpRequest 214 open() 217 opener 188 Opera 8 Options des fentres 174 Ouverture d'une fentre centre 184 dcentre 186 en plein cran 186 modale 177

N
N_ud (informations) 75 Navigateur 17 configurer 10 dtecter 22 historique 33

REST

265

P
Page disparition d'lments 61 recharger 27 Paramtres cookie 120 GET 34 PHP 202 Plein cran 186 Positionnement absolu 90 lments 90 relatif 90 POST, requte 219 Prchargement d'une image 43 Prise en charge d'un cookie 127 Problme du bouton Prcdent 236 Progression, barre 47, 48 Proprit appName 22 checked 135, 136 cookie 120 DOM 74 form 133 frames 193 innerHTML 89 opener 188 responseText 226 styleSheets 57 Protocole dfinition 200 REST 200 SOAP 201 XML-RPC 200 Pseudo URL 14

R
random() 28 Raction d'un vnement 107 Rception donnes multiples 222 XML 226 Rechargement d'une page 27 Recherche expressions rgulires 32 systme de blocage de fentre 192 Rcupration d'une en-tte HTTP 225 Redimensionnement d'une fentre 182 Redirection, navigateur 26 Rgulires, expressions 30 Relatif, positionnement 90 reload() 27 removeChild() 77 Remplacement lments 85 texte 33 replace() 33 Repositionnement d'une fentre 183 Requte GET 217 HTTP 224 POST 219 synchrone 220 Rsolution problme du signet 235 responseText 226 REST 200

INDEX

266

Safari

S
Safari 8 screen 179, 187 Slecteur CSS 64 Slection dans un champ 149 Sensibles, boutons 40 Service Web 200 appeler avec IE 205 appeler avec Mozilla 208, 211 crer avec ASP.NET 204 crer avec PHP 202 Yahoo! 244 Signets 235 Site, carte de 188 SOAP 201 Souris boutons 115 vnements 113 Spcification cookies 119 XSLT 1.0 239 Structure AJAX 246 Styles CSS 54 curseurs 68 styleSheets 57 Suppression cookies 126 lments 77 Survol d'une image 44 Synchrone, requte 220

T
Tableau, crer 87 Taille cran 179 fentre 180 Tester un site Web 7 Texte crer 81 remplacer 33 slectionner dans un champ 149 valider un champ 153 vider un champ en cas de clic 152 this, mot cl 100 Touche Entre 111 Transformation XSLT 239 Transmission scurise d'un cookie 126

INDEX

U
URL, pseudo 14

V
Validation automatique d'un formulaire 159 bouton radio 155 case cocher 155 champ de texte 153 formulaire 154 liste de slection 157 Version d'un navigateur 24 visibility, commande 62

XSLT

267

W
Web, services 200 window 173, 182 window.alert() 36 window.open() 173 window.prompt() 36

X
XML bibliothque 241 recevoir 226 XMLHttpRequest 214 tats 218 open() 217 XML-RPC 200 XSLT 239 Internet Explorer 238 Mozilla 238

INDEX

LE GUIDE DE SURVIE

JavaScript
LESSENTIEL DU CODE ET DES COMMANDES
Ce Guide de survie vous propose lensemble du code JavaScript, Ajax, DHTML et CSS dont vous avez besoin pour crer des applications Web, des pages et des sites interactifs, rapidement et efcacement.

CONCIS ET MANIABLE
Facile transporter, facile utiliser nis les livres encombrants !

PRATIQUE ET FONCTIONNEL
Plus de 100 squences de codes personnalisables pour proter au maximum de JavaScript et dAjax. Christian Wenz est un rdacteur professionnel, mais aussi auteur, formateur et consultant spcialis dans les technologies Web, qui senorgueillit davoir utilis JavaScript avant quil ne soit la mode et Ajax bien avant que le terme ne soit invent !

Niveau : Intermdiaire Catgorie : Web Conguration : Multiplate-forme

Pearson Education France 47 bis, rue des Vinaigriers 75010 Paris Tl. : 01 72 74 90 00 Fax : 01 42 05 22 17 www.pearson.fr

ISBN : 978-2-7440-4003-0

Anda mungkin juga menyukai