iPhone - fnac-static.com · Si vous chargez dynamiquement des pages externes, le navigateur...
Transcript of iPhone - fnac-static.com · Si vous chargez dynamiquement des pages externes, le navigateur...
ApplicationsiPhone
avec HTML, CSS et JavaScript
Conversion en natifsavec PhoneGap
J o n a t h a n S t a r k
© Groupe Eyrolles, 2010, pour la présente édition, ISBN : 978-2-212-12745-4
Table des matières
Avant-propos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 1
CHAPITRE 1
Démarrage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 5
Applications web et applications natives� . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 5
Qu’est-ce�qu’une�application�web ?� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 5
Qu’est-ce�qu’une�application�native ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 6
Avantages�et�inconvénients�� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 6
Quelle�approche�vous�convient ?� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 7
Cours accéléré de programmation web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 7
Introduction�à�HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 7
Introduction�aux�CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 10
Introduction�à�JavaScript� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 13
CHAPITRE 2
Mise en forme iPhone simple� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 17
Premiers pas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 18
Préparer�une�feuille�de�styles�distincte�pour�l’iPhone� . . . . . . . . . . . . . . . . . . . � 21
Contrôler�la�mise�à�l’échelle�de�la�page� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 22
Ajouter les styles CSS pour l’iPhone� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 23
Créer le look iPhone� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 26
Une touche d’interactivité avec jQuery� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 28
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 34
Stark Livre.indb 5 30/04/10 14:40
VIApplications iPhone avec HTML, CSS et Javascript
CHAPITRE 3
Mise en forme iPhone avancée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 35
Avec une pincée d’Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 35
Agent de la circulation� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 36
Petits gadgets simples� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 40
Développer votre propre bouton de retour� . . . . . . . . . . . . . . . . . . . . . . . . . . � 47
Ajouter une icône à l’écran d’accueil� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 54
Mode plein écran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 56
Changer�la�barre�d’état�� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 57
Fournir�une�image�de�démarrage�personnalisée� . . . . . . . . . . . . . . . . . . . . . . . � 58
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 58
CHAPITRE 4
Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 61
Une aide précieuse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 61
Glissements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 62
Ajouter le panneau Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 66
Ajouter le panneau Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 67
Ajouter le panneau Nouvelle entrée� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 70
Ajouter le panneau Réglages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 73
Assembler le tout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 75
Personnaliser jQTouch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 77
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 80
CHAPITRE 5
Stockage de données côté client� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 81
localStorage et sessionStorage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 81
Enregistrer�des�réglages�utilisateur�dans�localStorage . . . . . . . . . . . . . . . . . . . � 83
Enregistrer�la�date�sélectionnée�dans�sessionStorage . . . . . . . . . . . . . . . . . . . . � 85
Base de données côté client� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 88
Créer�une�base�de�données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 89
Stark Livre.indb 6 30/04/10 14:40
VII Table des matières
Insérer�des�lignes� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 93
Sélectionner�des�lignes�et�gérer�des�jeux�de�résultats . . . . . . . . . . . . . . . . . . . . � 96
Supprimer�des�lignes� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 100
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 104
CHAPITRE 6
Passer en mode hors connexion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 105
Le cache d’application hors connexion� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 105
Liste blanche et options de remplacement . . . . . . . . . . . . . . . . . . . . . . . . . . . � 108
Créer un fichier de manifeste dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . � 112
Débogage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 117
La�console�JavaScript�� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 118
La�base�de�données�du�cache�d’application� . . . . . . . . . . . . . . . . . . . . . . . . . . . � 121
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 128
CHAPITRE 7
Passer en version native . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 129
Introduction à PhoneGap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 129
Utiliser�la�hauteur�entière�de�l’écran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 135
Personnaliser�le�titre�et�l’icône . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 137
Créer�un�écran�de�démarrage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 145
Installer votre application sur l’iPhone� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� .� . � 148
Contrôler l’iPhone en JavaScript� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 153
Bips,�vibrations�et�alertes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 153
Géolocalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 157
Accéléromètre� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 163
Ce que vous avez appris� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 167
CHAPITRE 8
Envoyer votre application à iTunes� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 169
Créer un profil d’approvisionnement iPhone de distribution� . . . . . . . . . . � 170
Installer le profil d’approvisionnement iPhone de distribution . . . . . . . . . � 171
Renommer le projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 173
Stark Livre.indb 7 30/04/10 14:40
VIIIApplications iPhone avec HTML, CSS et Javascript
Préparer le binaire de l’application� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 175
Envoyer votre application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 176
Pendant l’attente� . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 177
Autres ressources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 177
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . � 179
Stark Livre.indb 8 30/04/10 14:40
3Mise en forme iPhone avancée
Afin�de�construire�notre�application�iPhone�sans�Objective-C,�nous�venons�de�voir�comment�uti-liser�des�CSS�pour�mettre�en�forme�une�série�de�pages�HTML�et�leur�donner�l’apparence�d’une�application�iPhone .�Dans�ce�chapitre,�nous�allons�réaliser�le�travail�de�fond�qui�permettra�à�ces�mêmes�pages�de�se�comporter comme�une�application�iPhone .�En�particulier,�nous�verrons�com-ment�utiliser�Ajax�pour�transformer�un�site�web�complet�en�une�application�monopage,�comment�créer�un�bouton�Précédent�avec�un�historique�en�JavaScript�et�comment�tirer�parti�des�fonction-nalités�des�icônes�de�clips�web�et�du�mode�plein�écran�de�l’iPhone,�pour�lancer�l’application�sans�que�Mobile�Safari�n’interfère�au�niveau�de�l’interface .
Avec une pincée d’AjaxLe�terme�Ajax�est�devenu�si�populaire�que�je�ne�suis�même�plus�sûr�de�savoir�encore�ce�qu’il�veut�dire .�Dans�ce�livre,�je�l’utiliserai�pour�faire�référence�à�la�technique�qui�consiste�à�utiliser�du�JavaScript�pour�transmettre�des�requêtes�à�un�serveur�web�sans�recharger�la�page�active�(par�exemple,�pour�récupérer�du�HTML,�poster�un�formulaire,�etc .) .�Cette�approche�rend�l’applica-tion�très�fluide�du�point�de�vue�de�l’utilisateur,�mais�elle�requiert�un�certain�nombre�d’efforts,�puisqu’elle�oblige�en�quelque�sorte�à�réinventer�la�roue .
Si�vous�chargez�dynamiquement�des�pages�externes,� le�navigateur�n’offre�aucune�indication�concernant�l’avancement�du�processus�ou�l’apparition�d’éventuelles�erreurs�aux�utilisateurs .�En�outre,�le�bouton�Précédent�ne�fonctionne�pas�comme�on�s’y�attendrait,�à�moins�que�vous�ne�fas-siez�l’effort�de�le�programmer�vous-même .�Il�faut�donc�se�remonter�les�manches�pour�créer�une�bonne�application�Ajax .�On�peut�toutefois�avoir�de�très�bonnes�raisons�de�faire�ces�efforts .�En�particulier,�il�devient�ainsi�possible�de�créer�des�applications�iPhone�qui�peuvent�s’exécuter�en�mode�plein�écran�(voir�la�section�Mode�plein�écran)�et�même�hors�connexion�(voir�chapitre 6) .
Stark Livre.indb 35 30/04/10 14:40
36Applications iPhone avec HTML, CSS et Javascript
Agent de la circulationPour�la�prochaine�série�d’exemples,�nous�allons�créer�une�page�unique�appelée�iphone.html�qui�se�postera�au�devant�de�toutes�les�autres�pages�du�site�et�gérera�les�requêtes,�à�la�manière�d’un�agent�de�la�circulation .�Le�principe�de�fonctionnement�est�le�suivant :�au�premier�chargement,�iphone.html�présente�à�l’utilisateur�une�version�soigneusement�mise�en�forme�de�la�navigation�du�site .�Ensuite,�nous�utilisons�jQuery�pour�dérouter�les�actions�onclick�sur�les�liens�nav,�de�manière�que�lorsque�l’utilisateur�clique�sur�l’un�d’entre�eux,�le�navigateur�n’accède�pas�au�lien�cible .�Au�lieu�de�cela,�jQuery�charge�une�portion�du�code�HTML�de�la�page�distante�et�transmet�les�données�à�l’utilisateur�en�mettant�à�jour�la�page�actuelle .�Je�commencerai�par�la�version�fonc-tionnelle�la�plus�simple�du�code,�que�j’améliorerai�ensuite�progressivement .
Le�code�HTML�de�la�page�interface�iphone.html�est�extrêmement�simple�(voir�exemple 3-1) .�Dans�la�section�head,�je�définis�les�options�title�et�viewport�et�j’inclus�les�liens�vers�une�feuille�de�styles�(iphone.css)�et�deux�fichiers�JavaScript :�jquery.js�et�un�fichier�JavaScript�personnel�nommé�iphone.js .
InfoPour plus d’informations sur l’endroit où récupérer le fichier jquery.js et pour savoir quoi faire avec, consultez la section « Introduction à JavaScript » du chapitre 1.
La�section�body�contient�deux�div�conteneurs :�une�div�header�dont�le�titre�initial�se�trouve�dans�une�balise�h1�et�un�div�vide�container,�qui�contiendra�les�fragments�de�HTML�récupérés�dans�d’autres�pages .
Exemple 3-1. Ce code HTML simple de structure se placera au devant de toutes les autres pages du site
<html><head> <title>Jonathan Stark</title> <meta name="viewport" content="user-scalable=no, width=device-width" /> <link rel="stylesheet" href="iphone.css" type="text/css" media="screen" /> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="iphone.js"></script></head><body> <div id="header"><h1>Jonathan Stark</h1></div> <div id="container"></div></body></html>
Passons�à�iphone.css .�Comme�le�montre�l’exemple 3-2,�j’ai�réorganisé�certaines�propriétés�des�précédents�exemples�(certaines�des�propriétés�#header h1�ont�été�remontées�vers�#header) .�Dans�l’ensemble,�tout�devrait�cependant�vous�être�familier�(sinon,�relisez�le�chapitre 2) .
Stark Livre.indb 36 30/04/10 14:40
37 Mise en forme iPhone avancée
Chapitre3
Exemple 3-2. Les styles CSS de base de la page ne sont qu’une version réorganisée des exemples précédents
body { background-color: #ddd; color: #222; font-family: Helvetica; font-size: 14px; margin: 0; padding: 0;}#header { background-color: #ccc; background-image: -webkit-gradient(linear, left top, left bottom, from(#ccc), ➥ to(#999)); border-color: #666; border-style: solid; border-width: 0 0 1px 0;}#header h1 { color: #222; font-size: 20px; font-weight: bold; margin: 0 auto; padding: 10px 0; text-align: center; text-shadow: 0px 1px 0px #fff;}ul { list-style: none; margin: 10px; padding: 0;}ul li a { background-color: #FFF; border: 1px solid #999; color: #222; display: block; font-size: 17px; font-weight: bold; margin-bottom: -1px; padding: 12px 10px; text-decoration: none;}ul li:first-child a { -webkit-border-top-left-radius: 8px; -webkit-border-top-right-radius: 8px;}ul li:last-child a { -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px;
Stark Livre.indb 37 30/04/10 14:40
38Applications iPhone avec HTML, CSS et Javascript
}ul li a:active,ul li a:hover { background-color:blue; color:white;}#content { padding: 10px; text-shadow: 0px 1px 0px #fff;}#content a { color: blue;}
Le�code�JavaScript�dans�iphone.js�est�l’antre�où�sont�réalisées�toutes�les�opérations�de�magie�de�cet�exemple .�Référez-vous�à�l’exemple 3-3�pendant�que�je�le�parcours�ligne�par�ligne .
InfoCe code JavaScript charge un document appelé index.html sans lequel il ne peut fonctionner. Vous devez réutiliser le fichier HTML du chapitre 2, en vous assurant de l’enregistrer sous le nom index.html dans le même répertoire que le fichier iphone.html que vous avez créé précédemment dans ce chapitre. Toutefois, aucun des liens qui y figurent ne pourra fonctionner si les cibles des liens n’existent pas. Vous pouvez créer ces fichiers vous-même ou télécharger le code d’exemple du site web du livre. En créant about.html, blog.html et consulting-clinic.html, vous dispose-rez de quelques liens avec lesquels vous amuser. Pour cela, contentez-vous de dupliquer index.html plusieurs fois et changez le nom de fichier de chaque copie pour le faire correspondre au lien qui s’y rapporte. Pour plus d’effet, vous pouvez modifier le contenu de la balise h2 dans chaque fichier pour le faire correspondre au nom du fichier. Par exemple, l’élément h2 de blog.html peut être <h2>Blog</h2>.
Exemple 3-3. Ce fragment de JavaScript dans iphone.js convertit les liens de la page en requêtes Ajax
$(document).ready(function(){ loadPage();});function loadPage(url) { if (url == undefined) { $('#container').load('index.html #header ul', hijackLinks); } else { $('#container').load(url + ' #content', hijackLinks); }}function hijackLinks() { $('#container a').click(function(e){ e.preventDefault(); loadPage(e.target.href); });}
Stark Livre.indb 38 30/04/10 14:40
39 Mise en forme iPhone avancée
Chapitre3
�Ici,�j’utilise�la�fonction�$(document).ready()�de�jQuery�pour�amener�le�navigateur�à�exécuter�la�fonction�loadPage()�lorsque�le�DOM�est�complètement�chargé .
�La�fonction�loadPage()�prend�un�unique�paramètre�appelé�url,�puis�vérifie�(à�la�ligne�sui-vante)�si�une�valeur�a�été�envoyée .
�Si�aucune�valeur�n’est�envoyée�dans�la�fonction,�url�est� indéfinie�et�cette�ligne�s’exécute .�Cette�ligne�et�la�suivante�sont�des�exemples�de�la�fonction�load()�de�jQuery .�Cette�fonction�est�parfaite�pour�ajouter�des�fonctionnalités�Ajax�simples�et�rapides�à�une�page .�En�français,�on�pourrait�traduire�cette�ligne�ainsi :�« Récupérer�tous�les�éléments�ul�de�l’élément�#header�d’index.hml�et� les�insérer�dans�l’élément�#container�de�la�page�actuelle .�Enfin,�exécuter�la�fonction�hijackLinks() » .�Notez�qu’index.html�fait�référence�à�la�page�d’accueil�du�site .�Si�votre�page�d’accueil�porte�un�nom�différent,�utilisez-le�à�la�place .
�Cette�ligne�est�exécutée�si�le�paramètre�url�possède�une�valeur .�Elle�dit�en�somme :�« Récu-pérer�l’élément�#content�de�l’url�qui�a�été�passée�à�la�fonction�loadPagest()�et�l’insérer�dans�l’élément�#content�de�la�page�actuelle .�Enfin,�exécuter�la�fonction�hijackLinks() » .
�Une�fois�que�la�fonction�load()�a�terminé,�l’élément�#container�de�la�page�actuelle�contient�le�fragment�HTML�récupéré .�Ensuite,�load()�exécute�la�fonction�hijackLinks() .
�Dans�cette�ligne,�hijackLinks()� trouve�tous�les�liens�dans�le�nouveau�code�HTML�et�leur�associe�un�gestionnaire�de�clic�avec�les�lignes�de�code�qui�suivent .�Les�gestionnaires�de�clic�se�voient�passer�de�manière�automatique�un�objet�événement,�que�je�capture�sous�la�forme�d’un�paramètre�de�fonction�e .�L’objet�événement�d’un�lien�cliqué�contient�l’URL�de�la�page�distante�dans�e.target.href .
�Normalement,�le�navigateur�web�se�rend�sur�la�nouvelle�page�quand�l’utilisateur�clique�sur�un�lien .�C’est�ce�qu’on�peut�appeler�le�« comportement�par�défaut »�du�lien .�Ici,�comme�nous�gérons�manuellement�les�clics�et�le�chargement�des�pages,�nous�devons�bloquer�ce�compor-tement .�C’est�ce�que�fait�cette�ligne,�en�appelant�la�méthode�prédéfinie�preventDefault()�de�l’objet�événement .�Si�je�l’avais�omise,�le�navigateur�aurait�accompli�son�devoir�en�quittant�la�page�actuelle�et�en�accédant�à�l’URL�du�lien�cliqué .
�Lorsque�l’utilisateur�clique,�nous�passons�l’URL�de�la�page�distante�à�la�fonction�loadPage()�et�le�cycle�recommence .
InfoL’une des caractéristiques les plus intéressantes du JavaScript tient à la possibilité qui vous est offerte de passer une fonction en paramètre à une autre fonction. Cela peut paraître étrange au premier abord, mais c’est en vérité très utile pour créer du code modulaire et réutilisable.
Les�gestionnaires�de�clic�ne�s’exécutent�pas�quand�la�page�se�charge�au�départ .�Ils�le�font�lorsque�l’utilisateur�a�lu�une�partie�de�la�page�et�décide�de�cliquer�sur�un�lien .�Cette�manière�d’attribuer�les�gestionnaires�de�clic�s’apparente�à�la�pose�de�pièges ;�vous�devez�réaliser�un�travail�de�prépa-ration�initial�pour�quelque�chose�qui�peut�être,�ou�pas,�déclenché�par�la�suite .
Stark Livre.indb 39 30/04/10 14:40
40Applications iPhone avec HTML, CSS et Javascript
InfoIl peut être utile de prendre quelques minutes pour lire les propriétés de l’objet événement que le JavaScript crée en réponse aux actions de l’utilisateur dans le navigateur. Vous trouverez des informations de références à l’adresse http://www.w3schools.com/htmldom/dom_obj_event.asp.
Petits gadgets simplesAvec�ces�petits�bouts�de�HTML,�de�CSS�et�de�JavaScript,�nous�avons�transformé�un�site�web�complet�en�une�application�monopage .�Il�reste�cependant�beaucoup�à�faire .�Tâchons�de�peaufi-ner�cette�première�ébauche .
Comme�nous�ne�permettons�pas�au�navigateur�d’aller�de�page�en�page,� l’utilisateur�ne�voit�aucune�indication�de�l’état�d’avancement�pendant�que�les�données�se�chargent .�Il�faut�un�moyen�de�lui�faire�savoir�qu’il�se�passe�quelque�chose .�Sans�cela,�il�se�demandera�s’il�a�bien�cliqué�sur�le�lien�ou�s’il�l’a�manqué,�et�se�mettra�certainement�à�cliquer�à�tout�va�en�se�frustrant .�La�charge�serveur�peut�être�alourdie�et�l’application�devenir�instable�(crasher) .
InfoSi vous testez cette application web sur un réseau local, les vitesses réseau seront si rapides que vous ne verrez pas l’indicateur de progression. Si vous utilisez Mac OS X, vous pouvez ralentir tout le trafic web entrant en tapant deux commandes ipfw dans le terminal. Par exemple, les com-mandes suivantes ralentissent tout le trafic web à 4 kilooctets par seconde :
sudo ipfw pipe 1 config bw 4KByte/ssudo ipfw add 100 pipe 1 tcp from any to me 80
Si vous employez le navigateur Safari de bureau pour observer les pages, vous devez utiliser le nom d’hôte de votre Mac ou une adresse IP externe dans l’URL (par exemple, monmac.local plutôt que localhost). Lorsque vous avez fini vos tests, supprimez la règle avec sudo ipfw delete 100 (vous pouvez supprimer toutes les règles personnalisées avec ipfw flush).
Grâce�à�jQuery,�il�suffit�de�deux�lignes�de�code�pour�livrer�ce�genre�d’information .�Nous�allons�donc�simplement�ajouter�une�div�de�chargement�à�l’élément�body� lorsque�loadPage()�démarre,�puis�supprimer�la�div�de�chargement�lorsque�hijackLinks()�a�terminé .�L’exemple 3-4�présente�une�version�modifiée�de�l’exemple 3-3 .�Les�lignes�que�vous�devez�ajouter�à�iphone.js�sont�affi-chées�en�gras .
Exemple 3-4. Ajout d’un indicateur de progression à la page
$(document).ready(function(){ loadPage();});function loadPage(url) { $('body').append('<div id="progress">Loading...</div>');
Stark Livre.indb 40 30/04/10 14:40
41 Mise en forme iPhone avancée
Chapitre3
if (url == undefined) { $('#container').load('index.html #header ul', hijackLinks); } else { $('#container').load(url + ' #content', hijackLinks); }}function hijackLinks() { $('#container a').click(function(e){ e.preventDefault(); loadPage(e.target.href); }); $('#progress').remove(); }
L’exemple 3-5�indique�les�instructions�CSS�qui�doivent�être�ajoutées�à�iphone.css�pour�mettre�en�forme�la�div�de�progression .�Le�résultat�est�présenté�figure 3-1 .
Figure 3-1
Sans indicateur de progression, votre application paraîtra manquer de réactivité et vos utilisateurs se sentiront frustrés.
Stark Livre.indb 41 30/04/10 14:40
42Applications iPhone avec HTML, CSS et Javascript
Exemple 3-5. Règles CSS ajoutées à iphone.css pour mettre en forme l’indicateur de progression
#progress { -webkit-border-radius: 10px; background-color: rgba(0,0,0,.7); color: white; font-size: 18px; font-weight: bold; height: 80px; left: 60px; line-height: 80px; margin: 0 auto; position: absolute; text-align: center; top: 120px; width: 200px;}
Chaque�page�de�mon�site�possède�un�unique�titre�h2�tout�en�haut,�qui�conviendrait�bien�comme�titre�de�page�(voir�figure 3-2) .�Vous�le�remarquerez�dans�le�code�HTML�source�présenté�au�chapitre 2 .
Figure 3-2
Avant que le titre de la page ne soit reporté dans la barre d’outils…
Stark Livre.indb 42 30/04/10 14:40
43 Mise en forme iPhone avancée
Chapitre3
Pour�donner�à�ce�titre�un�aspect�plus�propre�à�l’iPhone,�je�vais�l’extraire�du�contenu�et�le�placer�dans�l’en-tête�(voir�figure 3-3) .�Cette�fois�encore,�c’est�jQuery�qui�va�m’y�aider :�il�suffit�d’ajouter�trois�lignes�à�la�fonction�hijackLinks()�pour�que�le�miracle�se�produise .�L’exemple 3-6�présente�la�fonction�hijackLinks�avec�ces�changements .
Figure 3-3
Après que le titre de la page a été reporté dans la barre d’outils…
Exemple 3-6. Utilisation du titre h2 de la page cible comme titre de la barre d’outils
function hijackLinks() { $('#container a').click(function(e){ e.preventDefault(); loadPage(e.target.href); }); var title = $('h2').html() || 'Hello!'; $('h1').html(title); $('h2').remove(); $('#progress').remove();}
Stark Livre.indb 43 30/04/10 14:40
44Applications iPhone avec HTML, CSS et Javascript
InfoNotez que j’ai ajouté les lignes avant celle qui supprime l’indicateur de progression. Je préfère ôter l’indicateur de progression à la toute dernière étape, car l’application paraît ainsi plus réactive.
La�double�barre�verticale�(||)�dans�la�première�ligne�du�code�inséré�(signalé�en�gras)�correspond�à�l’opérateur�logique�OR�en�JavaScript .�En�français,�cette�ligne�se�traduirait�ainsi :�« attribuer�à�la�variable�de�titre�le�contenu�HTML�de�l’élément�h2�ou�la�chaîne�“Hello !”�à�défaut » .�C’est�important,�car�la�première�page�ne�contient�pas�de�h2,�puisque�nous�ne�faisons�que�récupérer�les�ul�de�navigation .
InfoCe point mérite quelque explication. Lorsque les utilisateurs chargent au départ l’URL iphone.html, ils ne voient que les éléments de la navigation générale du site et non le contenu du site lui-même. Celui-ci n’apparaît qu’après qu’ils ont appuyé sur un lien dans la page de navigation initiale.
Figure 3-4
Le texte qui revient à la ligne dans la barre d’outils ne fait pas très « iPhone »…
Stark Livre.indb 44 30/04/10 14:40
45 Mise en forme iPhone avancée
Chapitre3
Certaines�pages�du�site�possèdent�des�titres�trop�longs�pour�tenir�dans�la�barre�d’en-tête�(voir�figure 3-4) .�Je�pourrais�laisser�le�texte�revenir�à�la�ligne,�mais�cela�ne�fait�pas�trop�« iPhone » .�À la�place,� j’ai�donc�mis�à�jour�les�styles�#header h1�de�manière�que�le�texte�long�soit� tron-qué�avec�trois�points�de�suspension�(voir�figure 3-5�et�exemple 3-7) .�Parmi�les�astuces�CSS��méconnues,�il�s’agit�de�l’une�de�mes�favorites .
Figure 3-5
…mais on peut l’embellir avec des points de suspension en CSS.
Exemple 3-7. Ajout de trois points de suspension au texte trop long pour son conteneur
#header h1 { color: #222; font-size: 20px; font-weight: bold; margin: 0 auto; padding: 10px 0; text-align: center; text-shadow: 0px 1px 0px #fff; max-width: 160px; overflow: hidden; white-space: nowrap;
Stark Livre.indb 45 30/04/10 14:40
46Applications iPhone avec HTML, CSS et Javascript
text-overflow: ellipsis;}
La�synthèse�est�simple :�max-width: 160px�demande�au�navigateur�de�ne�pas�permettre�à�l’élé-ment�h1�de�s’étendre�au-delà�de�160�pixels .�Ensuite,�overflow: hidden�demande�au�navigateur�de�tronquer�tout�le�contenu�qui�s’étend�en�dehors�des�bordures�de�l’élément .�white-space: nowrap�empêche�alors�le�navigateur�de�décomposer�la�ligne�en�deux .�Sans�cette�ligne,�le�titre�h1�s’éti-rerait�simplement�en�hauteur�pour�adapter�le�texte�à�la�largeur�définie .�Pour�finir,�text-overflow: ellipsis�ajoute�trois�points�de�suspension�à�la�fin�de�tout�texte�tronqué�afin�d’indiquer�aux�utili-sateurs�qu’ils�ne�voient�pas�la�chaîne�entière .
Considérez�le�cas�d’une�page�À�propos�qui�serait�plus�longue�que�la�zone�visible�sur�l’iPhone .�L’utilisateur�consulte�cette�page,�la�fait�défiler�vers�le�bas�pour�la�lire�et�clique�ensuite�sur�un�lien�vers�votre�page�Contact .�Si�la�page�Contact�contient�un�texte�très�long,�les�nouvelles�données�apparaîtront�mais�la�fenêtre�restera�calée�en�bas�comme�si�l’utilisateur�l’avait�fait�défiler .
Techniquement,�c’est�assez�logique,�car�nous�ne�quittons�pas�notre�page�actuelle�(que�l’utili-sateur�a�fait�défiler),�mais�pour�l’utilisateur,�c’est�forcément�déroutant .�Pour�corriger�cela,�j’ai�ajouté�une�commande�scrollTo()�à�la�fonction�loadPage()�(voir�l’exemple 3-8) .
Maintenant,�à�chaque�fois�qu’un�utilisateur�clique�sur�un�lien,�il�revient�en�haut�de�la�page .�Ce�mécanisme�a�également�l’avantage�d’assurer�que�l’image�qui�se�charge�est�visible�si�l’utilisateur�clique�sur�un�lien�en�bas�d’une�longue�page .
Exemple 3-8. Il est judicieux de revenir en haut de la page lorsqu’un utilisateur navigue vers une nouvelle page
function loadPage(url) { $('body').append('<div id="progress">Loading...</div>'); scrollTo(0,0); if (url == undefined) { $('#container').load('index.html #header ul', hijackLinks); } else { $('#container').load(url + ' #content', hijackLinks); }}
Comme�la�plupart�des�sites,�le�mien�possède�des�liens�vers�des�pages�externes�(hébergées�sur�d’autres�domaines) .
Je�ne�souhaite�pas�détourner�ces� liens,�parce�qu’il�ne�serait�pas� logique�d’injecter� leur�code�HTML�à�l’intérieur�de�ma�mise�en�page�spécifique�à�l’iPhone .�Dans�l’exemple 3-9,�j’ai�ajouté�une�instruction�conditionnelle�qui�vérifie�que�mon�nom�de�domaine�figure�dans�l’URL .�S’il�s’y�trouve,�le�lien�est�piraté�et�le�contenu�chargé�directement�dans�la�page�courante ;�Ajax�fait�son�œuvre .�Sinon,�le�navigateur�conduit�normalement�à�l’URL�de�destination .
InfoVous devez remplacer jonathanstark.com par le nom de domaine ou d’hébergement approprié pour votre site web, sans quoi les liens vers les pages de votre site ne seront pas détournées.
Stark Livre.indb 46 30/04/10 14:40
47 Mise en forme iPhone avancée
Chapitre3
Exemple 3-9. Vous pouvez permettre aux pages externes de se charger normalement en vérifiant le nom de domaine de l’URL
function hijackLinks() { $('#container a').click(function(e){ var url = e.target.href; if (url.match(/jonathanstark.com/)) { e.preventDefault(); loadPage(url); } }); var title = $('h2').html() || 'Hello!'; $('h1').html(title); $('h2').remove(); $('#progress').remove();}
InfoLa fonction url.match utilise un langage appelé « expressions régulières », qui est souvent incorporé dans les autres langages de programmation comme JavaScript, PHP ou Perl. Cette expression régulière est simple, mais d’autres, plus complexes, peuvent être intimidantes ; il vaut cependant la peine de vous y accoutumer. Ma page favorite sur le sujet se trouve à l’adresse http://www.regular-expressions.info/javascriptexample.html.
Développer votre propre bouton de retourLe�gros�hic,�en�l’état�actuel�des�choses,�est�que�l’utilisateur�ne�dispose�d’aucun�moyen�de�navi-guer�vers�les�pages�précédentes�(rappelez-vous�que�nous�avons�détourné�tous�les�liens,�si�bien�que�l’historique�des�pages�de�Safari�ne�fonctionne�plus) .�Pour�résoudre�ce�problème,�ajoutez�un�bouton�de�retour�(une�sorte�de�bouton�Précédent)�en�haut�à�gauche�de�l’écran .�Pour�commencer,�nous�allons�mettre�à�jour�le�code�JavaScript,�puis�nous�occuper�des�CSS .
Pour�ajouter�un�bouton�de�retour�standard�de�style�iPhone�à�l’application,�il�faut�tenir�un�registre�de�l’historique�des�clics�de�l’utilisateur .�Pour�cela,�nous�devons�d’abord�stocker�l’URL�de�la�page�précédente�afin�de�savoir�où�revenir,�et�ensuite�stocker�le�titre�de�la�page�précédente�afin�de�savoir�quel�intitulé�donner�au�bouton�de�retour .
L’ajout�de�cette�fonctionnalité�affecte�la�plupart�du�code�JavaScript�que�nous�avons�écrit�jusque-là,�dans�ce�chapitre ;�je�vais�donc�commenter�la�nouvelle�version�d’iphone.js�ligne�par�ligne�(voir�l’exemple 3-10) .�Le�résultat�ressemblera�à�celui�de�la�figure 3-6 .
Stark Livre.indb 47 30/04/10 14:40
48Applications iPhone avec HTML, CSS et Javascript
Figure 3-6
Pourrait-on vraiment parler d’application iPhone sans ce beau bouton luisant, en forme de flèche qui pointe vers la gauche ?
Exemple 3-10. Exemple JavaScript existant, étendu pour la prise en charge du bouton de retour
var hist = []; var startUrl = 'index.html'; $(document).ready(function(){ loadPage(startUrl);});function loadPage(url) { $('body').append('<div id="progress">Loading...</div>'); scrollTo(0,0); if (url == startUrl) { var element = ' #header ul'; } else { var element = ' #content'; } $('#container').load(url + element, function(){ var title = $('h2').html() || 'Hello!'; $('h1').html(title); $('h2').remove();
Stark Livre.indb 48 30/04/10 14:40
49 Mise en forme iPhone avancée
Chapitre3
$('.leftButton').remove(); hist.unshift({'url':url, 'title':title}); if (hist.length > 1) { $('#header').append('<div class="leftButton">'+hist[1].title+'</div>'); $('#header .leftButton').click(function(){ var thisPage = hist.shift(); var previousPage = hist.shift(); loadPage(previousPage.url); }); } $('#container a').click(function(e){ var url = e.target.href; if (url.match(/jonathanstark.com/)) { e.preventDefault(); loadPage(url); } }); $('#progress').remove(); });}
�Dans�cette�ligne,�j’initialise�une�variable�nommée�hist�sous�forme�de�tableau�vide .�Comme�je�l’ai�définie�en�dehors�de�toute�fonction,�elle�possède�une�portée�globale�et�sera�disponible�partout�dans�la�page .�Notez�que�je�n’ai�pas�utilisé�le�mot�complet�history�comme�nom�de�variable,�car�il�s’agit�d’une�propriété�d’objet�en�JavaScript,�qui�doit�donc�être�évitée�dans�votre�propre�code .
�Ici,�je�définis�l’URL�relative�de�la�page�distante�à�charger�lorsque�l’utilisateur�consulte�iphone.html�la�première�fois .�Vous�vous�rappelez�sans�doute�que,�dans�les�précédents�exemples,�j’ai�vérifié�url == undefined�afin�de�gérer� le�chargement�de�la�première�page,�mais,�dans�cet�exemple,�nous�allons�utiliser�la�page�de�départ�à�plusieurs�endroits .�Il�est�donc�judicieux�de�la�définir�de�manière�globale .
�Cette�ligne�et�la�suivante�composent�la�définition�de�la�fonction�$(document).ready() .�Notez�qu’à� la�différence�des�précédents�exemples,� je� transmets� la�page�de�départ�à� la� fonction�loadPage() .
�Nous�voici�passés�à�la�fonction�loadPage() .�Cette�ligne�et� la�suivante�sont�identiques�aux�précédents�exemples .
�Cette� instruction�if...else�détermine� les�éléments�à�charger�dans� la�page�distante .�Par�exemple,�si�nous�souhaitons�la�page�de�démarrage,�nous�récupérons�les�ul�de�header .�Sinon,�nous�récupérons�la�div�content .
�Dans�cette� ligne,� le�paramètre�d’URL�et� l’élément� source�approprié� sont� concaténés� et�passés�comme�premier�paramètre�à� la�fonction�load .�Pour� le�second�paramètre,� je�passe�directement�une�fonction�anonyme�(une�fonction�sans�nom�qui�est�définie�à�l’intérieur) .�En�examinant�la�fonction�anonyme,�vous�constaterez�de�grandes�ressemblances�avec�la�fonction�hijackLinks()�qu’elle�est�venue�remplacer .�Les�trois�lignes�qui�suivent�sont�identiques�aux�précédents�exemples .
Stark Livre.indb 49 30/04/10 14:40
50Applications iPhone avec HTML, CSS et Javascript
�Dans�cette�ligne,�je�supprime�l’objet�.leftButton�de�la�page�(cela�peut�sembler�étrange,�parce�que�je�ne�l’ai�pas�encore�ajouté�à�la�page,�mais�nous�le�ferons�quelques�étapes�plus�loin) .
�Ici,� j’utilise�la�méthode�prédéfinie�unshift�du�tableau�JavaScript�pour�ajouter�un�objet�au�début�du�tableau�hist .�L’objet�que�j’ajoute�possède�deux�propriétés,�url�et�title,�qui�sont�les�deux�éléments�d’information�dont�nous�avons�besoin�pour�prendre�en�charge�l’affichage�et�le�comportement�du�bouton�de�retour .
�Dans�cette�ligne,�j’utilise�la�méthode�prédéfinie�length�du�tableau�JavaScript�pour�détermi-ner�combien�d’objets�se�trouvent�dans�le�tableau�d’historique .�S’il�n’y�a�qu’un�objet�dans�le�tableau,�cela�signifie�que�l’utilisateur�se�trouve�sur�la�première�page,�si�bien�que�nous�n’avons�pas�besoin�d’afficher�un�bouton�de�retour .�S’il�y�a�plus�d’un�objet�dans�le�tableau�hist,�nous�devons�ajouter�un�bouton�à�l’en-tête .
�Ensuite,�j’ajoute�le�bouton�.leftButton�que�j’ai�mentionné�précédemment .�Le�texte�du�bouton�correspondra�au�titre�de�la�page�qui�précède�la�page�courante,�auquel�j’accède�avec�le�code�hist[1].title .�Les�tableaux�JavaScript�sont�indicés�à�partir�de�zéro,�si�bien�que�le�premier�élément�du�tableau�(la�page�courante)�possède�l’index�0 .�L’index�0�correspond�ainsi�à�la�page�courante,�l’index�1�à�la�page�précédente,�l’index�2�à�la�page�encore�antérieure,�et�ainsi�de�suite .
�Dans�ce�bloc�de�code,�je�lie�une�fonction�anonyme�au�gestionnaire�de�clic�du�bouton�Précé-dent .�Rappelez-vous�que�le�code�de�gestionnaire�de�clic�s’exécute�lorsque�l’utilisateur�clique,�et�non�lorsque�la�page�se�charge .�Ainsi,�une�fois�que�la�page�se�charge�et�que�l’utilisateur�clique�pour�revenir�en�arrière,�le�code�à�l’intérieur�de�cette�fonction�s’exécute .
�Cette�ligne�et�la�suivante�utilisent�la�méthode�prédéfinie�shift�du�tableau�pour�supprimer�les�deux�premiers�éléments�du�tableau�hist,�et�la�dernière�ligne�dans�la�fonction�envoie�l’URL�de�la�page�précédente�à�la�fonction�loadPage() .
�Les�lignes�qui�restent�sont�reprises�des�précédents�exemples ;�inutile�de�les�passer�en�revue�ici .
�Voici�le�code�de�correspondance�d’URL�présenté�précédemment�dans�ce�chapitre .�N’oubliez�pas�de�remplacer�jonathanstark.com�par�le�nom�de�domaine�ou�le�nom�d’hôte�de�votre�site�web,�sans�quoi�aucun�des�liens�locaux�ne�sera�détourné�et�chargé�dans�la�page .
InfoConsultez la page http://www.hunlock.com/blogs/Mastering_Javascript_Arrays pour une liste complète des fonctions de tableau JavaScript avec des descriptions et des exemples.
Maintenant�que�nous�disposons�d’un�bouton�de�retour,�il�ne�reste�plus�qu’à�modifier�son�appa-rence�avec�un�peu�de�CSS�(voir�exemple 3-11) .�Je�commence�par�mettre�en�forme�le�texte�avec�font-weight,�text-align,�lineheight,�color�et�text-shadow .�Je�continue�en�plaçant�la�div�préci-sément�où�je�le�souhaite�sur�la�page�avec�position,�top�et�left .�Ensuite,�je�m’assure�que�le�texte�long�sur�l’étiquette�du�bouton�est�tronqué�avec�des�points�de�suspension�en�utilisant�max-width,�white-space,�overflow�et�textoverflow .�Pour�finir,�j’applique�une�image�avec�border-width�et�-web-kit-border-image .�À�la�différence�de�mon�précédent�exemple�d’image�de�bordure,�cette�image-ci�
Stark Livre.indb 50 30/04/10 14:40
51 Mise en forme iPhone avancée
Chapitre3
possède�une�largeur�différente�pour�les�côtés�gauche�et�droit,�car�elle�est�rendue�asymétrique�du�fait�que�la�flèche�pointe�vers�la�gauche .
InfoN’oubliez pas que vous aurez besoin d’une image pour ce bouton. Vous devrez l’enregistrer sous le nom back_button.png dans le dossier images du répertoire qui contient votre fichier HTML. Consultez la section « Ajouter un comportement simple avec jQuery » du chapitre 2 pour des astuces qui vous aideront à trouver ou créer vos propres images de bouton.
Exemple 3-11. Ajoutez le code suivant à iphone.css pour embellir le bouton de retour avec une image de bordure
#header div.leftButton { font-weight: bold; text-align: center; line-height: 28px; color: white; text-shadow: rgba(0,0,0,0.6) 0px -1px 0px; position: absolute; top: 7px; left: 6px; max-width: 50px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-width: 0 8px 0 14px; -webkit-border-image: url(images/back_button.png) 0 8 0 14;}
Par�défaut,�Mobile�Safari�affiche�brièvement�une�boîte�grise�translucide�au-dessus�des�objets�cliquables�qui�ont�été�touchés�(voir�figure 3-7) .�Comme�notre�bouton�de�retour�n’est�pas�rec-tangulaire,�cet�effet�est�un�peu�bancal,�mais�on�peut�aisément�le�supprimer�et�donner�meilleure�apparence�à�l’application .�Mobile�Safari�prend�en�charge�une�propriété�nommée�-webkit-tap-highlight-color�qui�vous�permet�de�changer�la�couleur�par�défaut�en�la�remplaçant�par�celle�de�votre�choix .�Comme�jene�souhaite�pas�de�mise�en�valeur,�je�choisis�ici�une�couleur�entièrement�transparente�(voir�exemple 3-12) .
Exemple 3-12. Ajoutez ces lignes à iphone.css pour supprimer la mise en surbrillance de Mobile Safari
#header div.leftButton { font-weight: bold; text-align: center; line-height: 28px; color: white; text-shadow: rgba(0,0,0,0.6) 0px -1px 0px; position: absolute;
Stark Livre.indb 51 30/04/10 14:40
52Applications iPhone avec HTML, CSS et Javascript
top: 7px; left: 6px; max-width: 50px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-width: 0 8px 0 14px; -webkit-border-image: url(images/back_button.png) 0 8 0 14; -webkit-tap-highlight-color: rgba(0,0,0,0);}
Figure 3-7
Par défaut, Mobile Safari affiche un rectangle translucide gris par-dessus les objets cliquables sur lesquels l’utilisateur a déjà appuyé.
Dans�le�cas�du�bouton�de�retour,� il�peut�y�avoir�une�ou�deux�secondes�de�délai�avant�que�le�contenu�de�la�page�précédente�n’apparaisse .�Pour�éviter�toute�frustration,�je�souhaite�que�le bou-ton�ait�l’air�enfoncé�au�moment�où�l’on�appuie�dessus .�Dans�un�navigateur�de�bureau,�ce�processus�serait�simple ;�il�suffirait�d’ajouter�une�déclaration�aux�CSS�en�utilisant�la�pseudo-classe�:active�pour�spécifier�un�autre�style�pour�l’objet�cliqué .�Je�ne�sais�pas�s’il�s’agit�d’un�bogue�ou�d’un�choix�délibéré,�mais�cela�ne�fonctionne�pas�sur�l’iPhone .�Le�style�:active�est�ignoré .
Stark Livre.indb 52 30/04/10 14:40
53 Mise en forme iPhone avancée
Chapitre3
Je�me�suis�amusé�avec�une�série�de�combinaisons�de�:active�et�:hover,�qui�m’ont�permis�d’arri-ver�à�mes�fins�avec�des�applications�non-Ajax .�Mais�avec�les�applications�Ajax�comme�celle�dont�il�est�question�ici,�le�style�:hover�reste�actif�après�coup�(autrement�dit,�le�bouton�semble�rester�cliqué�même�après�que�le�doigt�l’a�relâché) .
Heureusement,�le�correctif�est�assez�simple .�Avec�jQuery,�on�peut�ajouter�la�classe�clicked�au�bouton�lorsque�l’utilisateur�clique�dessus .�Pour�cet�exemple,�j’ai�choisi�d’appliquer�une�version�plus�sombre�de�l’image�du�bouton�(voir�figure 3-8�et�exemple 3-13) .�Assurez-vous�de�placer�une�image�de�bouton�appelée�back_button_clicked.png�dans�le�sous-dossier�images .�Consultez�la�sec-tion�« Ajouter�un�comportement�simple�avec�jQuery »�pour�des�astuces�qui�vous�permettront�de�trouver�ou�de�créer�vos�propres�images�de�bouton .
Figure 3-8
La différence est subtile, mais le bouton Précédent cliqué est un peu plus sombre que son état par défaut
Exemple 3-13. Ajoutez les lignes suivantes à iphone.css pour donner l’impression que le bouton Précédent est enfoncé quand l’utilisateur tape dessus
#header div.leftButton.clicked { -webkit-border-image: url(images/back_button_clicked.png) 0 8 0 14;}
Stark Livre.indb 53 30/04/10 14:40
54Applications iPhone avec HTML, CSS et Javascript
InfoComme j’utilise une image pour le style cliqué, il est intéressant de la précharger. Sans cela, l’image du bouton non-cliqué disparaît la première fois que l’on appuie dessus alors que l’image de l’état cliqué est encore en train de se télécharger. Je traiterai du préchargement des images au chapitre suivant.
Une�fois�les�CSS�en�place,�je�peux�maintenant�mettre�à�jour�la�portion�d’iphone.js�qui�associe�le�gestionnaire�de�clic�au�bouton�de�retour .�Pour�commencer,�j’ajoute�une�variable�e�à�la�fonction�anonyme�afin�de�capturer�l’événement�de�clic�entrant .�Ensuite,�je�place�la�cible�événement�dans�un�sélecteur�jQuery�et� j’appelle�la�fonction�jQuery�addClass()�pour�attribuer�ma�classe�CSS�clicked�au�bouton :
$('#header .leftButton').click(function(e){ $(e.target).addClass('clicked'); var thisPage = hist.shift(); var previousPage = hist.shift(); loadPage(previousPage.url);});
InfoUne note spéciale pour les experts en CSS : la technique des sprites CSS (popularisée par A List Apart) ne peut être utilisée dans ce cas, parce qu’elle requiert de définir des décalages pour l’image. Or les décalages d’image ne sont pas pris en charge par la propriété -webkit-border-image.
Ajouter une icône à l’écran d’accueilAvec�un�peu�de�chance,�les�utilisateurs�souhaiteront�ajouter�une�icône�pour�votre�application�web�(appelée�« icône�de�clip�web »)�à�leur�écran�d’accueil .�Pour�cela,�ils�peuvent�appuyer�sur�le�bouton�+�en�bas�de�la�fenêtre�Safari�(voir�figure 3-9),�taper�sur�Ajouter�à�l’écran�d’accueil�(voir�figure 3-10)�et�cliquer�sur�le�bouton�Ajouter�(voir�figure 3-11) .�Par�défaut,� l’iPhone�crée�cette�icône�en�générant�une�vignette�de�la�page�courante�(avec�sa�position�et�son�niveau�de�zoom�actuels)�à�laquelle�il�applique�des�bords�arrondis�et�un�reflet�(voir�figure 3-12) .
Les�développeurs�à�la�page�se�piquent�toujours�de�personnaliser�l’image�de�l’écran�d’accueil�et,�pour�cela,�fournissent�une�icône�de�clip�web�personnalisée .�Le�moyen�le�plus�simple�de�procéder�consiste�à�spécifier�une�icône�pour�votre�site�entier�en�plaçant�un�fichier�nommé�apple-touch-icon.png�à�la�racine�du�site�web .�Le�fichier�doit�faire�57 pixels�sur�57,�sans�reflet�ni�bord�arrondi,�car�l’iPhone�les�ajoute�automatiquement .�Si�vous�ne�souhaitez�pas�que�l’iPhone�ajoute�des�effets�à�votre�icône�de�clip�web,�changez�le�nom�du�fichier�en�l’appelant�apple-touch-icon-precom-posed.png .
Stark Livre.indb 54 30/04/10 14:40
55 Mise en forme iPhone avancée
Chapitre3
Figure 3-9
Ajout d’une icône de clip web à votre écran d’accueil, étape 1 : cliquez sur le bouton + en bas de la fenêtre Safari.
Figure 3-10
Étape 2 : cliquez sur le bouton Ajouter à l’écran d’accueil dans la boîte de dialogue.
Stark Livre.indb 55 30/04/10 14:40
56Applications iPhone avec HTML, CSS et Javascript
Figure 3-11
Étape 3 : cliquez sur le bouton Ajouter dans le panneau Ajouter à l’accueil.
Figure 3-12
Étape 4 : une image de 57 × 57 pixels s’affiche sur l’écran d’accueil.
Dans�certains�cas,�il�peut�arriver�que�vous�souhaitiez�fournir�une�icône�de�clip�web�différente�pour�une�page�spécifique�du�site .�Vous�pouvez�le�faire�en�ajoutant�l’une�des�lignes�suivantes�à�la�section�head�de�notre�document�HTML�« agent�de�la�circulation »,�iphone.html�(en�remplaçant�myCustomIcon.png�par�le�chemin�absolu�ou�relatif�vers�l’image) :
<link rel="apple-touch-icon" href="myCustomIcon.png" /><link rel="apple-touch-icon-precomposed" href="myCustomIcon.png" />
InfoSi vous devez utiliser des images précomposées, optez pour un rayon d’arrondi de 10 pixels ou plus ; sans cela, l’iPhone arrondira les bords à 10 pixels. Dans un cas comme dans l’autre, l’utilisa-tion des images précomposées supprime entièrement le reflet.
Mode plein écranVous�aimeriez�récupérer�un�quart�de�l’espace�vertical�de�Mobile�Safari�(104 pixels,�pour�être�précis) ?�Ajoutez�la�ligne�suivante�à�la�section�head�du�document�« agent�de�circulation »�iphone.
Stark Livre.indb 56 30/04/10 14:40
57 Mise en forme iPhone avancée
Chapitre3
html,�et�votre�application�web�s’affichera�en�mode�plein�écran�lorsqu’elle�sera�lancée�à�partir�de�son�icône�de�clip�web :
<meta name="apple-mobile-web-app-capable" content="yes" />
J’aurais�pu�traiter�de�cette�fonctionnalité�auparavant,�mais�elle�n’est�utile�qu’une�fois�que�vous�avez�détourné�tous�vos�liens�hypertextes�avec�Ajax .�Dès�qu’un�utilisateur�clique�sur�un�lien�non�détourné�–�qui�conduit�effectivement�vers�une�nouvelle�page�–�Mobile�Safari�lance�et�charge�la�page�normalement .�Ce�comportement�est�parfait�pour�l’exemple�avec�lequel�nous�avons�tra-vaillé,�parce�que�les�liens�externes�(Amazon,�Twitter,�Facebook,�etc .)�s’ouvrent�dans�Safari .
Changer la barre d’état Une� fois� que� vous� avez� ajouté� la� balise� méta� apple-mobile-web-app-capable,� vous� avez� la�possibilité�de�contrôler�la�couleur�de�l’arrière-plan�de�la�barre�d’état�de�20 pixels�en�haut�de�l’écran,�en�utilisant�la�balise�méta�apple-mobile-web-app-status-bar-style .�Par�défaut,�c’est�la�barre�d’état�grise�de�Safari,�mais�vous�pouvez�changer�sa�couleur�en�noir�(voir�figure 3-13) .�
Figure 3-13
Le mode plein écran offre environ 25 % d’espace écran supplémentaire et permet de personnaliser l’apparence de la barre d’état.
Stark Livre.indb 57 30/04/10 14:40
58Applications iPhone avec HTML, CSS et Javascript
Vous�pouvez�également�la�rendre�noire�translucide,�pour�qu’elle�soit�partiellement�transparente,�ce�qui�la�supprime,�en�outre,�du�flot�du�document .�En�d’autres�termes,�votre�contenu�est�remonté�vers�le�haut�de�20 pixels�et�sous�la�barre�d’état�lorsque�la�page�se�charge,�si�bien�qu’il�peut�être�nécessaire�de�positionner�votre�en-tête�un�peu�plus�bas�pour�compenser :
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
InfoLes changements de style de la barre d’état ne prendront effet que lorsque l’application sera lan-cée en mode plein écran.
Fournir une image de démarrage personnalisée Lorsqu’une�application�se�lance�en�mode�plein�écran,�l’utilisateur�en�voit�apparaître�une�capture�d’écran�pendant�que�la�première�page�se�charge .�Cet�effet�ne�me�plaît�pas�trop .�En�effet,�cela�donne�l’impression�que�l’on�peut�interagir�avec�l’application,�alors�qu’en�réalité,�si�on�appuie�sur�un�lien,�rien�ne�se�passe .�En�outre,�la�capture�d’écran�est�réalisée�à�partir�de�la�dernière�page�de�la�précédente�visite�de�l’utilisateur,�au�point�de�défilement�où�celui-ci�l’avait�laissée�–�pas�très�affriolant !
Heureusement,�Mobile�Safari�permet�de�définir�une�image�de�démarrage�qui�s’affichera�pen-dant�le�chargement�de�la�page .�Pour�ajouter�une�image�de�démarrage�personnalisée,�créez�un�fichier�PNG�de�320 × 460 pixels�et�placez-le�dans�le�même�répertoire�que�le�fichier�iphone.html .�Ensuite,�ajoutez�la�ligne�suivante�à�la�section�head�d’iphone.html�(et�remplacez�myCustomStartup-Graphic.png�par�le�chemin�absolu�ou�relatif�vers�votre�image) :
<link rel="apple-touch-startup-image" href="myCustomStartupGraphic.png" />
La�prochaine�fois�que�vous�lancez�votre�application�depuis�l’icône�de�clip�web,�le�comporte-ment�de�chargement�par�défaut�s’enclenche�pendant�que�la�nouvelle� image�personnalisée�se�télécharge .�L’image�de�démarrage�personnalisée�s’affiche�au�lancement�suivant�(figure 3-14) .
Ce que vous avez apprisDans�ce�chapitre,�vous�avez�appris�à�convertir�un�site�web�standard�en�une�application�Ajax�plein�écran,�avec�des�indicateurs�de�progression,�un�bouton�de�retour�intégré�dans�le�style�iPhone,�et�une�icône�de�clip�web�personnalisée .�Au�chapitre�suivant,�vous�allez�découvrir�comment�don-ner�vie�à�votre�application�en�ajoutant�des�animations�d’interface�utilisateur�natives .�Eh�oui,�le�moment�est�venu�de�s’amuser !
Stark Livre.indb 58 30/04/10 14:40
59 Mise en forme iPhone avancée
Chapitre3
Figure 3-14
Chargement d’une image de démarrage personnalisée pour une application lancée en mode plein écran.
Stark Livre.indb 59 30/04/10 14:40