Formation html3 css3

  • 1,020 views
Uploaded on

Formation html5 / css3 / js (jquery / jqmobi)

Formation html5 / css3 / js (jquery / jqmobi)

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,020
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
141
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Formation web html5 / css3 Thierry GAYET - Thierry.Gayet@gmail.fr
  • 2. TIMING DE LA FORMATION Timing journalier : ● Matin : 09h00-10h30 : première partie 10h30-10h45 : pause 10h45-13h00 : seconde partie ● Pause déjeuner ● Après-midi : 14h00-15h30 : troisième partie 15h30-15h45 : pause 15h45-17h00 : quatrième partie ● Questions libres. Timing journalier : ● Matin : 09h00-10h30 : première partie 10h30-10h45 : pause 10h45-13h00 : seconde partie ● Pause déjeuner ● Après-midi : 14h00-15h30 : troisième partie 15h30-15h45 : pause 15h45-17h00 : quatrième partie ● Questions libres. merci de signaler toute contrainte de temps sur cette période dès le début
  • 3. PLAN DE LA FORMATION  Historique du web & standards  Nouveaux éléments & attributs  Le formulaires web forms  Les microformats (microdata)  Audio & vidéo  Dessin avec canvas  Géolocalisation  Interraction avec les fichiers  Drap & drop  Push de données  Web messaging  Web sockets  Web storage  Web sql  Web workers  Application hors ligne  Exemples de CSS3  Jquery par l'exemple
  • 4. Historique 4
  • 5. Historique 5 Pour mieux comprendre la transition que le Web vit en ce moment, voici un bref historique de ce changement de cap. → 1998 : En prônant les avantages du XML, le W3C décide de ne plus continuer le développement du HTML (qui en est à la version 4.01) et élabore une première spécification du XHTML (v 1.0). Cette version est un amalgame de la syntaxe du HTML et des normes et standards XML. Ce fut une bonne décision, car le XML étant strict sur ses normes, ça met de l’avant le souci d’un code bien structuré et d’une uniformité entre les sites Web. → 2006 : 8 ans après cette décision, le W3C la remet en question et commence à penser que le XML (et le XHTML) n’est peut être pas la voie du futur en conception Web. Il décide donc de travailler sur une nouvelle spécification du HTML tout en continuant l’évolution du XHTML (v2.0). Plusieurs groupes (Mozilla, Opera, Google, …) viennent à travailler conjointement avec le W3C sur le HTML 5. Fait à noter : certains individus n’ont jamais arrêté de travailler sur le HTML depuis 1998. Pour en savoir plus sur la période 1998-2006, vous pouvez lire sur le groupe WHATWG (www.whatwg.org). → 2009 : Le W3C arrête complètement de travailler sur le XHTML v2.0 et toutes les ressources sont redirigées vers le HTML 5. La philosophie est désormais : pureté du design, par-dessus l’idéologie d’être rétro-compatible Adieu le XHTML ! Les navigateurs restent compatibles avec le XHTML, mais l’emphase est maintenant sur l’implémentation des spécifications du HTML 5. Actuellement, il y a 2 spécifications du HTML 5 qui sont développées en parallèle : ● la version du WHATWG ● la version du W3C Les deux groupes travaillent « relativement » conjointement, mais ils divergent sur certains points. Si vous devez choisir une spécification, je vous conseille celle du W3C, qui est moins expérimentale. Les spécifications du HTML 5 évoluent constamment. Ceci explique même pourquoi WHATWG a même décidé de supprimer le « 5 » de HTML 5. Les navigateurs doivent donc toujours regarder les changements aux spécifications pour se mettre à jour.
  • 6. Historique Quelques dates à retenir : – 1991 HTML – 1994 HTML 2 – 1996 CSS 1 + JavaScript – 1997 HTML 4 – 1998 CSS 2 – 1999 HTML 4.01 – 2000 XHTML 1 – 2002 Tableless design – 2004 WHATWG – 2005 AJAX – 2007 XHTML 2 boudé – 2007 Le W3C récupère les travaux du WHATWG – 2009 Arrêt des travaux sur XHTML 2 – 2010 HTML 5 + JavaScript API + CSS 3 6
  • 7. HISTORIQUE ● Liens : – http://www.zdnet.fr/actualites/html5-petite-histoire-et-promesses-d – http://www.weblife.fr/wp-content/uploads/2012/07/html5-histoire-
  • 8. NOUVEAUX ELEMENTS & ATTRIBUTS 8
  • 9. HTML 5 ● <!DOCTYPE html> & <meta charset="UTF-8"> ● Nouvelles balises ● Balises vidéos et audio ● Nouveaux champs de formulaire ● Nouveaux attributs notamment autofocus, placeholder ● Certaines balises et attributs dépréciés : frame, frameset, big, font, center, acronym, ... ● Intégration de SVG ● MicroData ● ... LES NOUVEAUX ELEMENTS → Nouvelles balises : ● <section> ● <header>/<footer> ● <nav> ● <article> ● <aside> ● <hgroup> ● <time> ● <canvas> ● <audio>/<video> ● Et d’autres…
  • 10. CSS 3 ● Multi-colonnes ● Bordures ● Gradients ● Webfonts ● Manipulation de texte ● Animations & transitions ● Flexible box model ● Nouveaux selecteurs ● Media Queries ● ... LES NOUVEAUX ELEMENTS
  • 11. JavaScript ● Geolocation ● WebWorkers ● WebSockets ● Orientation ● Notification ● sessionStorage & localStorage ● Web SQL database & IndexedDB ● ... LES NOUVEAUX ELEMENTS
  • 12. HTML 5 + JavaScript ● Canvas 2D ● Intégration audio et vidéo ● Mode offline ● Gestion de l'historique ● Edition de contenu ● Drag & Drop ● Custom data attribute ● ... LES NOUVEAUX ELEMENTS
  • 13. CSS 3 + JavaScript ● Selectors ● Classlist LES NOUVEAUX ELEMENTS
  • 14. WebGL ● Avant Chrome 9, lancer chrome avec --enable-webgl ● Sous Firefox 4, about:config puis enable for all sites ● Exemple depuis Learning WebGL ● Body Browser de Google LES NOUVEAUX ELEMENTS
  • 15. A Venir ● Contacts API ● Webcam (Capture API) ● Device Orientation API ● Calendar API ● Speech input ● ... LES NOUVEAUX ELEMENTS
  • 16. LES FORMULAIRES WEB FORMS 16
  • 17. Nouveaux types d'entrées dans HTML5 Ce que nous connaissons aujourd'hui comme étant HTML5 Forms ou HTML5 Web Forms a démarré sous le nom de Web Forms 2.0, une spécification pré-HTML5 créée par un groupe appelé WHATWG (Web Hypertext Applications Technology Working Group). La majeure partie du travail initial du WHATWG est devenue le point de départ ce que nous appelons maintenant HTML5 et l'effort Web Forms 2.0 fait à présent partie de la spécification HTML5 officielle, que vous pouvez consulter à l'adresse suivante : bit.ly/njrWvZ. Une partie non négligeable de la spécification est consacrée à de nouveaux types et attributs de contenu pour l'élément d'entrée, que vous trouverez à l'adresse suivante : Comme je l'ai mentionné précédemment, la spécification introduit 13 nouveaux types d'entrées à utiliser dans des formulaires : recherche, tél., url, e-mail, dateheure, date, mois, semaine, heure, dateheure-locale, numéro, plage, couleur. L'utilisation de ces nouveaux types est simple. Imaginons que je veuille insérer un nouveau champ d'e-mail sur un formulaire de commande. Comme vous pouvez le voir sur la Figure 1, j'ai modifié la page de commande du site Web de modèle Pâtisserie WebMatrix en lui ajoutant des champs, dont e- mail. LES WEBFORMS
  • 18. La balise <input> en HTML4 possède les propriétés suivante : Type Description text A free-form text field, nominally free of line breaks. password A free-form text field for sensitive information, nominally free of line breaks. checkbox A set of zero or more values from a predefined list. radio An enumerated value. submit A free form of button initiates form submission. file An arbitrary file with a MIME type and optionally a file name. image A coordinate, relative to a particular image's size, with the extra semantic that it must be the last value selected and initiates form submission. hidden An arbitrary string that is not normally displayed to the user. select An enumerated value, much like the radio type. textarea A free-form text field, nominally with no line break restrictions. button A free form of button which can initiates any event related to button. Exemple de formulaire : <form action="http://example.com/cgiscript.pl" method="post"> <p> <label for="firstname">first name: </label> <input type="text" id="firstname"><br /> <label for="lastname">last name: </label> <input type="text" id="lastname"><br /> <label for="email">email: </label> <input type="text" id="email"><br> <input type="radio" name="sex" value="male"> Male<br> <input type="radio" name="sex" value="female"> Female<br> <input type="submit" value="send"> <input type="reset"> </p> </form> LES WEBFORMS
  • 19. La balise <input> en HTML5 a évolué en incluant de nouvelles propriétés : Type Description datetime A date and time (year, month, day, hour, minute, second, fractions of a second) encoded according to ISO 8601 with the time zone set to UTC. datetime-local A date and time (year, month, day, hour, minute, second, fractions of a second) encoded according to ISO 8601, with no time zone information. date A date (year, month, day) encoded according to ISO 8601. month A date consisting of a year and a month encoded according to ISO 8601. week A date consisting of a year and a week number encoded according to ISO 8601. time A time (hour, minute, seconds, fractional seconds) encoded according to ISO 8601. number This accepts only numerical value. The step attribute specifies the precision, defaulting to 1. range The range type is used for input fields that should contain a value from a range of numbers. email This accepts only email value. This type is used for input fields that should contain an e-mail address. If you try to submit a simple text, it forces to enter only email address in email@eurogiciel.fr format. url This accepts only URL value. This type is used for input fields that should contain a URL address. If you try to submit a simple text, it forces to enter only URL address either in http://www.eurogiciel.fr format or in http://example.com format. Exemple de formulaire : <form action="demo_form.asp" autocomplete="on"> First name:<input type="text" name="fname"><br> Last name: <input type="text" name="lname"><br> E-mail: <input type="email" name="email" autocomplete="off"><br> <input type="submit"> </form> LES WEBFORMS
  • 20. Quelques exemples de formulaires : <form> <p><label>Customer name: <input></label></p> <fieldset> <legend> Pizza Size </legend> <p><label> <input type=radio name=size> Small </label></p> <p><label> <input type=radio name=size> Medium </label></p> <p><label> <input type=radio name=size> Large </label></p> </fieldset> </form> <form> <p><label>Customer name: <input></label></p> <fieldset> <legend> Pizza Size </legend> <p><label> <input type=radio name=size> Small </label></p> <p><label> <input type=radio name=size> Medium </label></p> <p><label> <input type=radio name=size> Large </label></p> </fieldset> <fieldset> <legend> Pizza Toppings </legend> <p><label> <input type=checkbox> Bacon </label></p> <p><label> <input type=checkbox> Extra Cheese </label></p> <p><label> <input type=checkbox> Onion </label></p> <p><label> <input type=checkbox> Mushroom </label></p> </fieldset> </form> LES WEBFORMS
  • 21. <form> <p><label>Customer name: <input></label></p> <p><label>Telephone: <input type=tel></label></p> <p><label>E-mail address: <input type=email></label></p> <fieldset> <legend> Pizza Size </legend> <p><label> <input type=radio name=size> Small </label></p> <p><label> <input type=radio name=size> Medium </label></p> <p><label> <input type=radio name=size> Large </label></p> </fieldset> <fieldset> <legend> Pizza Toppings </legend> <p><label> <input type=checkbox> Bacon </label></p> <p><label> <input type=checkbox> Extra Cheese </label></p> <p><label> <input type=checkbox> Onion </label></p> <p><label> <input type=checkbox> Mushroom </label></p> </fieldset> <p><label>Preferred delivery time: <input type=time min="11:00" max="21:00" step="900"></label></p> <p><label>Delivery instructions: <textarea></textarea></label></p> </form> LES WEBFORMS
  • 22. <form method="post" enctype="application/x-www-form-urlencoded" action="https://pizza.example.com/order.cgi"> <p><label>Customer name: <input name="custname"></label></p> <p><label>Telephone: <input type=tel name="custtel"></label></p> <p><label>E-mail address: <input type=email name="custemail"></label></p> <fieldset> <legend> Pizza Size </legend> <p><label> <input type=radio name=size value="small"> Small </label></p> <p><label> <input type=radio name=size value="medium"> Medium </label></p> <p><label> <input type=radio name=size value="large"> Large </label></p> </fieldset> <fieldset> <legend> Pizza Toppings </legend> <p><label> <input type=checkbox name="topping" value="bacon"> Bacon </label></p> <p><label> <input type=checkbox name="topping" value="cheese"> Extra Cheese </label></p> <p><label> <input type=checkbox name="topping" value="onion"> Onion </label></p> <p><label> <input type=checkbox name="topping" value="mushroom"> Mushroom </label></p> </fieldset> <p><label>Preferred delivery time: <input type=time min="11:00" max="21:00" step="900" name="delivery"></label></p> <p><label>Delivery instructions: <textarea name="comments"></textarea></label></p> <p><button>Submit order</button></p> </form> LES WEBFORMS
  • 23. <fieldset> <legend>Display</legend> <p><label><input type=radio name=c value=0 checked> Black on White</label> <p><label><input type=radio name=c value=1> White on Black</label> <p><label><input type=checkbox name=g> Use grayscale</label> <p><label>Enhance contrast <input type=range name=e list=contrast min=0 max=100 value=0 step=1></label> <datalist id=contrast> <option label=Normal value=0> <option label=Maximum value=100> </datalist> </fieldset> <fieldset name="clubfields" disabled> <legend> <label> <input type=checkbox name=club onchange="form.clubfields.disabled = !checked"> Use Club Card </label> </legend> <p><label>Name on card: <input name=clubname required></label></p> <p><label>Card number: <input name=clubnum required pattern="[-0-9]+"></label></p> <p><label>Expiry date: <input name=clubexp type=month></label></p> </fieldset> LES WEBFORMS
  • 24. <fieldset name="clubfields" disabled> <legend> <label> <input type=checkbox name=club onchange="form.clubfields.disabled = !checked"> Use Club Card </label> </legend> <p><label>Name on card: <input name=clubname required></label></p> <fieldset name="numfields"> <legend> <label> <input type=radio checked name=clubtype onchange="form.numfields.disabled = !checked"> My card has numbers on it </label> </legend> <p><label>Card number: <input name=clubnum required pattern="[-0-9]+"></label></p> </fieldset> <fieldset name="letfields" disabled> <legend> <label> <input type=radio name=clubtype onchange="form.letfields.disabled = !checked"> My card has letters on it </label> </legend> <p><label>Card code: <input name=clublet required pattern="[A-Za-z]+"></label></p> </fieldset> </fieldset> LES WEBFORMS
  • 25. LES WEBFORMS ● Liens : – http://diveintohtml5.info/forms.html – http://msdn.microsoft.com/fr-fr/magazine/hh547102.aspx – http://smashinghub.com/html5-web-forms-tutorials.htm – http://miketaylr.com/code/input-type-attr.html – http://miketaylr.com/code/html5-forms-ui-support.html – http://miketaylr.com/code/html5-textarea-attribute-support.html – http://www.whatwg.org/specs/web-apps/current-work/#the-textare – http://www.w3schools.com/html/html5_form_attributes.asp – http://www.standardista.com/html5/html5-web-forms/ – http://miketaylr.com/pres/html5/forms2.html – http://estelle.github.io/forms/#slide1
  • 26. LES MICROFORMATS & MICRODATA 26
  • 27. Le microformat propose une syntaxe qui s’apparente à du HTML classique et s’applique bien en dehors de la norme HTML5 puisqu’il est compatible avec HTML4, ou XHTML1.0 par exemple. Il utilise l’attribut class et certaines valeurs bien précises dans le but de “baliser” un contenu afin qu’il soit interprété comme une donnée bien spécifique. Voici un exemple de code un peu plus parlant : <span class="hreview-aggregate"> <span class="item"> <span class="fn">Juiz Smart Mobile Admin</span> </span> <span class="rating"> Note de : <span class="average">90</span> sur <span class="best">100</span> </span> basée sur <span class="count">35</span> votes. </span> Comme vous pouvez le constater, les microformats n’utilisent pas d’attribut ou de syntaxe trop complexe, seulement des valeurs de classe bien précises. Vous trouverez un bon nombre de données et d’outils sur le site microformats.org qui a proposé une tentative de codification des pratiques courantes. Microformats.org a ainsi pu réunir un certain nombre de “profils” XMPD que vous trouverez directement sur le wiki microformats. En plus de simples valeurs de classe, microformat c’est également l’utilisation de l’attribut rel, c’est le format hCard, le format hCalendar, etc... LES MICROFORMATS
  • 28. Les microdonnées : Les microdonnées sont représentées par l’arrivée de nouveaux attributs en HTML5. Il est alors possible de donner la référence du document utilisé pour baliser l’information directement au sein de l’élément porteur de ces informations. Il faut attirer l'attention sur l’arrivée d’un document qui tend à devenir une nouvelle référence pour structurer des données : issu d’un consortium entre Google, Bing, Yahoo et Yandex, cette référence est nommée schema.org. Ce sont d’ailleurs les schémas proposés par schema.org. LES MICROFORMATS
  • 29. Nouveaux attributs : Il n’en existe pas énormément : ● itemscope : il permet de créer un item dont le type peut-être précisé grâce à l’attribut suivant, ● itemtype : couplé à itemscope, il accueille une URL vers la référence du schéma (ex : “http://schema.org/Review”) qui devra respecter les valeurs de ce schéma, ● itemprop : il est porteur d’une valeur permettant de préciser la nature d’une donnée au sein d’un schéma spécifié précédemment. ● itemref : il permet de faire le lien complémentaire entre deux données sans descendance. ● itemid : lorsque l’item possède une référence globale unique, comme par exemple un l’identifiant d’un livre (urn:isbn:0-xxx-xxxxx-x). Il est attribué en même temps que l’attribut itemscope. Ces attributs peuvent être transportés par n’importe quel élément (souvent des span pour injecter une donnée sans mise en forme particulière), bien que certaines exceptions, évidentes, existent. Exemple d’une simple revue : <span itemscope itemtype="http://schema.org/Review"> <span itemprop="itemReviewed">Juiz Smart Mobile Admin</span> <span itemprop="reviewRating"> Note de : 90 sur 100 </span> basée sur 35 votes. </span> Rendu : “Juiz Smart Mobile Admin Note de : 90 sur 100 basée sur 35 votes.” LES MICROFORMATS
  • 30. Exemple d’une notation imbriquée dans une revue : Aussi appelée Embedded Items, l’imbrication de différents types de schéma peut intervenir dans le cas de notre exemple de revue. En effet, notre exemple précédent manque quelque peu de précision, puisque schema.org prévoit également un type de schéma pour les évaluations : <div itemscope itemtype="http://schema.org/Review"> <h1 itemprop="itemReviewed">Juiz Smart Mobile Admin</h1> <!-- Imbrication d’un item --> <p itemprop="reviewRating" itemscope itemtype="http://schema.org/AggregateRating"> Note de : <span itemprop="ratingValue">90</span> sur <span itemprop="bestRating">100</span> basée sur <span itemprop="ratingCount">35</span> votes. </p> <!-- / fin de l’imbrication --> <p itemprop="reviewBody"> Ce plugin proposé pour optimiser l'interface d'administration de[…] </p> </div> Rendu : “Juiz Smart Mobile Admin Note de : 90 sur 100 basée sur 35 votes. Ce plugin proposé pour optimiser l’interface d’administration de[…]” LES MICROFORMATS
  • 31. Création d’une fiche « film » : Je prends volontairement ce dernier exemple pour vous présenter une technique qui permet d’associer des informations sans qu’elles soient forcément imbriquées. En effet il arrive que la mise en page d’un site web ou l’évolution de ses informations ne permette pas d’imbriquer les items comme nous l’avons vu juste avant. La fiche film est divisée en deux mais ses informations sont réunies sous le même item grâce à la propriété itemref qui fait référence à l’élément aside#more-info à travers son identifiant “more-info”. LES MICROFORMATS
  • 32. Cet attribut permet de présenter un même item découpé en plusieur éléments à travers la page. Si les informations de notre item Movie avaient été disséminées dans d’autres éléments de la page, il aurait été possible de les cibler grâce à la valeur de leur attribut id de la sorte : <article itemscope itemtype="http://schema.org/Movie" itemref="more-info id2 id3 id4"> Je ne vous ai pas encore expliqué la présence des éléments meta dans la page. Ceux-ci permettent d’insérer une information qui a souvent besoin d’un formatage précis qui est peu intelligible par une personne non aguerrie. Prenons l’exemple de l’information “duration” qui représente la durée. Cette information doit être formatée en respectant le format ISO 8601 qui définit un format de date ou de temps. Dans notre fiche, il aurait été possible d’écrire : <dd itemprop="duration">PT91M</dd> Mais vous imaginez bien ici que PT91M est quelque peu dérangeant pour définir une durée d’une heure et demi. C’est pourquoi, par convention – et si ce n’en est pas encore une il faudrait que ça le devienne – l’information s’écrit dans un élément meta et à côté de l’information intelligible. LES MICROFORMATS
  • 33. Le code HTML correspondant à cette mise en page pourrait ressembler à cela : <section role="main"> <article itemscope itemtype="http://schema.org/Movie" itemref="more-info"> <h1 itemprop="name">Nom du film de la fiche</h1> <img itemprop="image" src="img/the-film.png" alt="" width="150" height="150"> <section itemprop="video" itemscope itemtype="http://schema.org/VideoObject"> <h2>Trailer : <span itemprop="name">Nom du film de la fiche</span></h2> <meta itemprop="duration" content="T1M33S"> <meta itemprop="thumbnail" content="image-miniature-du-trailer.jpg"> <object …> <param …> <embed type="application/x-shockwave-flash" …> </object> <p itemprop="description">Courte description de la vidéo</p> </section> <section itemprop="description"> <p>Contenu principal de ma fiche film</p> </section> <footer> <dl> <dt>Réalisateur</dt> <dd itemprop="director">Emily Atef</dd> <dt>Acteurs</dt> <dd itemprop="actors">Maria-Victoria Dragus</dd> <dd itemprop="actors">Roeland Wiesnekker</dd> <dd itemprop="actors">Wolfram Koch</dd> LES MICROFORMATS
  • 34. <dd itemprop="actors">Christine Citti</dd> <dd itemprop="actors">Nathalie Boutefeu</dd> <dt>Distributeur</dt> <dd itemprop="provider">Les Films du Losange</dd> <dt>Musique par</dt> <dd itemprop="musicBy">John Smith</dd> <dt>Ratio d'image</dt> <dd>2.35</dd> </dl> </footer> </article> <aside id="more-info"> <dl> <dt>Langues</dt> <dd><meta itemprop="inLanguage" content="fr">Français</dd> <dd><meta itemprop="inLanguage" content="de">Allemand</dd> <dt>Année de production</dt> <dd><time datetime="2011" itemprop="dateCreated">2011</time></dd> <dt>Date de sortie</dt> <dd><time datetime="2011-04-25" itemprop="datePublished">25 avril 2012</time></dd> <dt>Genre</dt> <dd itemprop="genre">Drame</dd> <dt>Durée</dt> <dd><meta itemprop="duration" content="PT91M">91 min</dd> </dl> </aside> </section> LES MICROFORMATS
  • 35. LES MICROFORMATS ● Liens : – http://microformats.org/wiki/html5 – http://html5doctor.com/microformats/ – http://speckyboy.com/2011/01/24/beginners-study-guide-to-html5- – http://www.alsacreations.com/tuto/lire/1224-microformats-html5-m
  • 36. AUDIO & VIDEO 36
  • 37. L'élément <video>, cousin de <audio> offre en HTML5 une solution simple, native pour les navigateurs pour l'intégration d'une vidéo dans une page web. Elle permet également de proposer une alternative à l'utilisation de Flash pour les plate-formes ne le supportant pas (iOS par exemple avec iPhone, iPod, iPad...). La syntaxe de base de la balise video est extrêmement simple : <video controls src="video.ogv">Ici la description alternative</video> L'attribut src définit bien entendu l'adresse du fichier vidéo, tout comme pour la balise img lorsqu'il s'agit d'une image. Si vous indiquez les dimensions avec les attributs height et width, c'est encore mieux, et si tout va bien, un élément devrait s'afficher dans le navigateur... pour peu que celui-ci supporte le format de vidéo indiqué dans la source. AUDIO & VIDEO
  • 38. On peut également proposer plusieurs sources dans plusieurs formats différents en indiquant les types MIME grâce à l'attribut type : <video width="400" height="222" controls="controls"> <source src="video.mp4" type="video/mp4" /> <source src="video.webm" type="video/webm" /> <source src="video.ogv" type="video/ogg" /> Ici l'alternative à la vidéo : un lien de téléchargement, un message, etc. </video> Les navigateurs ne pouvant pas lire le MP4/H.264 ni la version WebM nativement (comme Firefox 3.6 par exemple) prendront la version au format Ogg Theora. Cela vous oblige néanmoins à encoder le fichier avec différents codecs. Particularité de la syntaxe XHTML : il faut ajouter controls="controls" (et pas juste controls comme vous pourrez le voir sur le premier exemple) pour afficher les possibilités de contrôle de la vidéo. Ceci est valable pour tous les attributs (autoplay, etc.). AUDIO & VIDEO
  • 39. ● Attributs : L'attribut controls donne accès aux contrôles de lecture (boutons de navigation, volume, etc, selon les possibilités du navigateur), ou les masque s'il est omis. L'attribut preload="auto" permet de de spécifier au navigateur de débuter le téléchargement de la vidéo tout de suite, en anticipant sur le fait que l'utilisateur lira la vidéo. Attention, cette option est à manier avec prudence (il est préférable que ce soit la seule raison d'être de la page). Note : il s'agit de l'ancien attribut autobuffer qu'il vous faudra laisser pour Firefox 3.5 et 3.6. L'attribut autoplay="true" comme son nom l'indique, permet de lancer la lecture automatiquement. Cela peut également être problématique avec une connexion à faible bande passante ou sur un terminal mobile. De manière générale, évitez d'imposer vos choix à l'utilisateur... et à sa connexion internet. L'attribut poster="image.jpg" permet d'indiquer une image à afficher par défaut dans l'espace réservé par la vidéo, avant que la lecture de celle-ci ne soit lancée. L'attribut loop indique que la lecture doit s'effectuer en boucle. ● Prérequis : Pensez également à préciser les types MIME dans un fichier .htaccess pour être sûr qu'ils soient corrects, les trois lignes suivantes suffisent à s'assurer la tranquilité : AddType video/ogg .ogv AddType video/mp4 .mp4 AddType video/webm .webm AUDIO & VIDEO
  • 40. ● Formats : Plusieurs formats tiennent le devant de la scène : WebM, MP4 et Ogg Theora. Même si le but de ce tutoriel est de proposer une solution d'intégration de la balise video compatible sur le plus de navigateurs possible (et pas de discuter du choix des formats dans un interminable débat), faisons quand même une présentation rapide. → H.264/MP4 : H.264 est supporté par le Moving Picture Experts Group. C'est un format non-libre (soumis à brevets) et non-gratuit. Toutefois, il est gratuit dans certaines utilisations (la diffusion gratuite de vidéos par des sites Web par exemple). Les fichiers MP4 utilisant H.264 sont lisibles nativement sur les navigateurs Apple (Safari, Safari Mobile) ainsi que sur Google Chrome. AUDIO & VIDEO
  • 41. → OGG/Theora : Theora est un format de compression vidéo open-source, sans brevets. Ceci donne le droit à tous d'utiliser Theora (à des fins non commerciales tout comme à des fins commerciales) sans devoir payer de redevance au consortium MPEG. OGG/Theora est lisible sur Firefox, Opéra, et Google Chrome. AUDIO & VIDEO
  • 42. AUDIO & VIDEO → WebM/VP8 : WebM est un format multimédia ouvert qui a été lancé par Google (après rachat de la société On2 Technologies). L'utilisation est en libre et gratuite. Comme on peut le constater, il y a une grande disparité dans le support des codecs, chacun défendant ses intérêts pour le meilleur ou pour le pire (commerciaux ou libres).
  • 43. AUDIO & VIDEO ● Liens : – http://diveintohtml5.info/video.html – http://fr.wikipedia.org/wiki/Theora – http://www.videojs.com/ –
  • 44. CANVAS 44
  • 45. Introduit à l'origine par Apple pour être utilisé dans WebKit pour des logiciels comme Dashboard et le navigateur Safari, canvas a été par la suite adopté par les navigateurs utilisant Gecko (notamment Mozilla Firefox) et Opera, avant d'être standardisé par le groupe de travail WHATWG. Novell a développé une extension activant les XForms dans Internet Explorer1 offrant ainsi une prise en charge des fonctionnalités de canvas. <canvas id="mon_canvas" width="350" height="350"> Texte alternatif pour les navigateurs ne supportant pas Canvas. </canvas> À partir de ce moment, tout se passe du côté de JavaScript, qui va se servir de cet élément HTML pour accéder à la surface de dessin. Pour ceci, deux fonctions sont appelées : getElementById() qui va permettre d'aller chercher et cibler l'élément <canvas> identifié par son attribut id unique (ici mon_canvas),puis la méthode getContext() de l'élément ainsi récupéré pour savoir dans quel contexte de dessin (2D ou 3D) le script va pouvoir agir, et de quelles fonctions il pourra disposer. Le contexte sera l'élément central de gestion de Canvas. <script type="text/javascript"> var c = document.getElementById("mon_canvas"); var ctx = c.getContext("2d"); // Dessine un rectangle rouge ctx.fillStyle = 'red'; ctx.fillRect(30, 30, 50, 50); </script> Canvas
  • 46. Tous les exemples suivants dans ce tutoriel feront appel à cette structure (élément Canvas + élément script + appel à getElementById + getContext) qui ne sera pas reprécisée à chaque fois. Après cette étape préliminaire de mise en place, il faut se plonger dans l'ensemble des méthodes de dessin 2D. Celles-ci vont toutes exploiter le même système de coordonnées : ● Le point de référence (0,0) est situé en haut à gauche ; ● L'axe horizontal (x) est défini par la première coordonnée ; ● L'axe vertical (y) est défini par la seconde coordonnée ; ● Ces valeurs correspondent à la grille entourant les pixels, et non pas aux pixels eux- mêmes. Par exemple le point de coordonnées (4,2) sera situé 4 pixels à droite du coin supérieur gauche, et 2 pixels en-dessous. Canvas Si l'on trace un polygone entre les 3 points présents sur ce schéma, on obtiendra un triangle.
  • 47. Pour commencer, voici un exemple simple qui dessine deux rectangles ayant une intersection, l'un d'entre-eux possédant une transparence alpha : <html> <head> <script type="application/x-javascript"> function draw() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(200,0,0)"; ctx.fillRect (10, 10, 55, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; ctx.fillRect (30, 30, 55, 50); } </script> </head> <body onload="draw()"> <canvas id="canvas" width="300" height="300"></canvas> </body> </html> La fonction draw récupère l'élément canvas, et ensuite son contexte 2d. L'objet ctx peut ensuite être utilisé pour dessiner réellement vers le canevas. L'exemple remplit simplement les deux rectangles, en positionnant fillStyle à deux couleurs différentes à l'aide des spécifications de couleur CSS et d'un appel à fillRect. Le second appel à fillStyle utilise rgba() pour spécifier une valeur alpha parmi les informations de couleur. Les appels à fillRect, strokeRect et clearRect affichent un rectangle plein, surligné ou vide. Pour afficher des formes plus complexes, on utilise des chemins. Canvas
  • 48. La fonction beginPath commence un nouveau chemin, et moveTo, lineTo, arcTo, arc et des méthodes similaires sont utilisées pour ajouter des segments au chemin. Le chemin peut être fermé à l'aide de closePath. Une fois que le chemin est créé, vous pouvez utiliser fill ou stroke pour afficher celui-ci sur le canevas. <html> <head> <script type="application/x-javascript"> function draw() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "red"; ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(150, 150); ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); ctx.lineTo(30, 30); ctx.fill(); } </script> </head> <body onload="draw()"> <canvas id="canvas" width="300" height="300"></canvas> </body> </html> L'appel à fill() ou stroke() provoque l'utilisation du chemin. Pour être rempli ou dessiné à nouveau, le chemin devra être recréé. Canvas
  • 49. Canvas
  • 50. Canvas ● Liens : – http://www.html5canvastutorials.com/ – http://www.lafermeduweb.net/tutorial/l-element-html-5-canvas-p2 – http://en.wikipedia.org/wiki/Canvas_element – http://www.w3schools.com/html/html5_canvas.asp – http://www.whatwg.org/specs/web-apps/current-work/#dynamic – https://developer.mozilla.org/fr/docs/Web/HTML/Canvas?redirect – http://modern-carpentry.com/workshop/html5/waveform/ – http://www.crazyws.fr/dev/20-canvas-html5-pour-vous-inspirer-8I
  • 51. Géolocalisation 51
  • 52. Une des nouveautés introduites par HTML5 est la géolocalisation utilisable via une API d'un navigateur. Cela permet aux pages web d'interroger le navigateur sur la position géographique de l'utilisateur. L'API de base permet d'obtenir les coordonnées en latitude et en longitude ainsi que l'altitude. Celles-ci peuvent alors être exploitées par le biais d'une carte (de type Google Map). Détection du support : if (navigator.geolocation) { //le navigateur supporte la géolocalisation //suite du code ici } else { alert('Votre navigateur ne supporte pas la géolocalisation HTML5'); } Géolocalisation
  • 53. Détail de la méthode getCurrentPosition() : PropertyProperty DescriptionDescription coords.latitude The latitude as a decimal number coords.longitude The longitude as a decimal number coords.accuracy The accuracy of position coords.altitude The altitude in meters above the mean sea level coords.altitudeAccuracy The altitude accuracy of position coords.heading The heading as degrees clockwise from North coords.speed The speed in meters per second timestamp The date/time of the response Géolocalisation
  • 54. Exemple de code pour un client : <script> var x = document.getElementById("demoLoc"); function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition); } else{ x.innerHTML="Geolocation is not supported by this browser.";} } function showPosition(position) { x.innerHTML="Latitude:"+position.coords.latitude + "<br>Longitude: " + position.coords.longitude; } </script> Géolocalisation
  • 55. Gestion des erreurs : function showError(error) { switch(error.code) { case error.PERMISSION_DENIED: x.innerHTML="User denied the request for Geolocation." break; case error.POSITION_UNAVAILABLE: x.innerHTML="Location information is unavailable." break; case error.TIMEOUT: x.innerHTML="The request to get user location timed out." break; case error.UNKNOWN_ERROR: x.innerHTML="An unknown error occurred." break; } } Code d'erreurs : ● Permission denied : l'utilisateur n'est pas autorisé pour utiliser la géolocalisation ● Position unavailable : géolocalisation impossible ● Timeout : timeout pour aller jusqu'au bout de la géolocalisation Géolocalisation
  • 56. Example d'affichage de la position sur une carte : function showPosition(position) { var latlon = position.coords.latitude+","+position.coords.longitude; var img_url = "http://maps.googleapis.com/maps/api/staticmap?center=" +latlon+"&zoom=14&size=400x300&sensor=false"; document.getElementById("mapholder").innerHTML="<img src='" + img_url + "'>"; } Géolocalisation
  • 57. Autre méthodes : ● watchPosition() : retourne la position courante ainsi que le mouvement via une icône (voiture). ● clearWatch() : arrête la méthode watchPosition Example d'utilisation de la méthode watchPosition : <script> var x = document.getElementById("demo"); function getLocation() { if (navigator.geolocation) { navigator.geolocation.watchPosition(showPosition); } else { x.innerHTML="Geolocation is not supported by this browser."; } } function showPosition(position) { x.innerHTML="Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude; } </script> Géolocalisation
  • 58. Géolocalisation ● Liens : – http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geo – http://dev.w3.org/geo/api/spec-source.html – http://www.html5-css3.fr/html5/tutoriel-geolocalisation-html5 – http://debray-jerome.developpez.com/articles/l-api-geolocalisation – http://html5demos.com/geo – http://html5professor.com/tutoriels-6.html –
  • 59. Gérer les fichiers 59
  • 60. L'API offerte aux navigateur web pour gérer les fichiers permet: ● De gérer une liste de fichiers (1:n) sélectionnable depuis la balise <input type="file"> ● Gestion de fichiers raw de type binaires avec autorisations d'accès d'une zone d'octets ● Une interface détaillant le nom du(des) fichier(s), leur type et leur URL ● Une interface permettant de lire un fichier ● Une gestion d'exception permettant la gestion des exceptions Gérer les fichiers
  • 61. Vérifier le support disponible : if (window.File && window.FileReader && window.FileList && window.Blob) { // Accès possible } else { alert('The File APIs are not fully supported in this browser.'); } Création d'un handle sur un fichier : // Récupère le path + nom du fichier var file = document.forms['uploadData']['fileChooser'].files[0]; // Autre moyen de récupérer le path + nom du fichier // var file = document.forms['uploadData']['fileChooser'].files.item(0); if (file) // ou if (file != undefined) { // Traitements sur le fichier . . . } Gérer les fichiers
  • 62. Soit le code HTML suivant : <input type="file" id="files" name="files[]" multiple /> <output id="list"></output> Voici un exemple de code gérant les fichiers : <script> function handleFileSelect(evt) { var files = evt.target.files; // files is a FileList of File objects. List some properties. var output = []; for (var i = 0, f; f = files[i]; i++) { output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>'); } document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>'; } document.getElementById('files').addEventListener('change', handleFileSelect, false); </script> Gérer les fichiers Création d'un handle sur un fichier : // Récupère le path + nom du fichier var file = document.forms['uploadData']['fileChooser'].files[0]; // Autre moyen de récupérer le path + nom du fichier // var file = document.forms['uploadData']['fileChooser'].files.item(0); if (file) // ou if (file != undefined) { // Traitements sur le fichier . . . }
  • 63. Soit le code HTML suivant : <div id="drop_zone">Drop files here</div> <output id="list"></output> Voici un exemple de code gérant les fichiers déposé en drag/drop : <script> function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; var output = []; for (var i = 0, f; f = files[i]; i++) { output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>'); } document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>'; } Gérer les fichiers
  • 64. (...) function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); </script> Gérer les fichiers
  • 65. A aprtir du code html & css suivant : <style> .thumb { height: 75px; border: 1px solid #000; margin: 10px 5px 0 0; } </style> <input type="file" id="files" name="files[]" multiple /> <output id="list"></output> Le code JS permettant de lire le fichier est le suivant : <script> function handleFileSelect(evt) { var files = evt.target.files; // FileList object for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } var reader = new FileReader(); Gérer les fichiers
  • 66. (...) reader.onload = (function(theFile) { return function(e) { var span = document.createElement('span'); span.innerHTML = ['<img class="thumb" src="', e.target.result, '" title="', escape(theFile.name), '"/>'].join(''); document.getElementById('list').insertBefore(span, null); }; })(f); reader.readAsDataURL(f); } } document.getElementById('files').addEventListener('change', handleFileSelect, false); </script> Gérer les fichiers
  • 67. A partir du code html suivant : <style> #byte_content { margin: 5px 0; max-height: 100px; overflow-y: auto; overflow-x: hidden; } #byte_range { margin-top: 5px; } </style> <input type="file" id="files" name="file" /> Read bytes: <span class="readBytesButtons"> <button data-startbyte="0" data-endbyte="4">1-5</button> <button data-startbyte="5" data-endbyte="14">6-15</button> <button data-startbyte="6" data-endbyte="7">7-8</button> <button>entire file</button> </span> <div id="byte_range"></div> <div id="byte_content"></div> Gérer les fichiers
  • 68. Le code Javascript permettant de télécharger un fichier binaire est le suivant : <script> function readBlob(opt_startByte, opt_stopByte) { var files = document.getElementById('files').files; if (!files.length) { alert('Please select a file!'); return; } var file = files[0]; var start = parseInt(opt_startByte) || 0; var stop = parseInt(opt_stopByte) || file.size - 1; var reader = new FileReader(); reader.onloadend = function(evt) { if (evt.target.readyState == FileReader.DONE) { // DONE == 2 document.getElementById('byte_content').textContent = evt.target.result; document.getElementById('byte_range').textContent = ['Read bytes: ', start + 1, ' - ', stop + 1, ' of ', file.size, ' byte file'].join(''); } }; var blob = file.slice(start, stop + 1); reader.readAsBinaryString(blob); } Gérer les fichiers
  • 69. (...) document.querySelector('.readBytesButtons').addEventListener('click', function(evt) { if (evt.target.tagName.toLowerCase() == 'button') { var startByte = evt.target.getAttribute('data-startbyte'); var endByte = evt.target.getAttribute('data-endbyte'); readBlob(startByte, endByte); } }, false); </script> Gérer les fichiers
  • 70. A partir du code html suivant : <style> #progress_bar { margin: 10px 0; padding: 3px; border: 1px solid #000; font-size: 14px; clear: both; opacity: 0; -moz-transition: opacity 1s linear; -o-transition: opacity 1s linear; -webkit-transition: opacity 1s linear; } #progress_bar.loading { opacity: 1.0; } #progress_bar .percent { background-color: #99ccff; height: auto; width: 0; } </style> Gérer les fichiers
  • 71. <input type="file" id="files" name="file" /> <button onclick="abortRead();">Cancel read</button> <div id="progress_bar"><div class="percent">0%</div></div> Le code Javascript permettant de monitorer la progression de la lecture d'un fichier est le suivant : <script> var reader; var progress = document.querySelector('.percent'); function abortRead() { reader.abort(); } function errorHandler(evt) { switch(evt.target.error.code) { case evt.target.error.NOT_FOUND_ERR: alert('File Not Found!'); break; case evt.target.error.NOT_READABLE_ERR: alert('File is not readable'); break; case evt.target.error.ABORT_ERR: break; // noop default: alert('An error occurred reading this file.'); }; } Gérer les fichiers
  • 72. (...) function updateProgress(evt) { // evt is an ProgressEvent. if (evt.lengthComputable) { var percentLoaded = Math.round((evt.loaded / evt.total) * 100); // Increase the progress bar length. if (percentLoaded < 100) { progress.style.width = percentLoaded + '%'; progress.textContent = percentLoaded + '%'; } } } function handleFileSelect(evt) { // Reset progress indicator on new file selection. progress.style.width = '0%'; progress.textContent = '0%'; reader = new FileReader(); reader.onerror = errorHandler; reader.onprogress = updateProgress; reader.onabort = function(e) { alert('File read cancelled'); }; reader.onloadstart = function(e) { document.getElementById('progress_bar').className = 'loading'; }; Gérer les fichiers
  • 73. (...) reader.onload = function(e) { // Ensure that the progress bar displays 100% at the end. progress.style.width = '100%'; progress.textContent = '100%'; setTimeout("document.getElementById('progress_bar').className='';", 2000); } // Read in the image file as a binary string. reader.readAsBinaryString(evt.target.files[0]); } document.getElementById('files').addEventListener('change', handleFileSelect, false); </script> Gérer les fichiers
  • 74. Autre exemple : var file = document.getElementById('file').files[0]; if (file) { // create an identical copy of file // the two calls below are equivalent var fileClone = file.slice(); var fileClone2 = file.slice(0, file.size); var fileChunkFromEnd = file.slice(-(Math.round(file.size/2))); var fileChunkFromStart = file.slice(0, Math.round(file.size/2)); // slice file from beginning till 150 bytes before end var fileNoMetadata = file.slice(0, -150, "application/experimental"); } Gérer les fichiers
  • 75. Création d'un objet blob (Binary Large Object) : var a = new Blob(); // Creation d'un tableau de 10.24 octets var buffer = new ArrayBuffer(1024); var shorts = new Uint16Array(buffer, 512, 128); var bytes = new Uint8Array(buffer, shorts.byteOffset + shorts.byteLength); var b = new Blob([toNativeLineEndings("foobarbazetcetc" + "birdiebirdieboo")], {type: "text/plain;charset=UTF-8"}); var c = new Blob([b, shorts]); var a = new Blob([b, c, bytes]); var d = new Blob([buffer, b, c, bytes]); Gérer les fichiers
  • 76. Gérer les fichiers ● Liens : – http://www.html5rocks.com/en/tutorials/file/dndfiles/ – http://en.wikipedia.org/wiki/File_select – http://www.html5rocks.com/en/tutorials/file/filesystem/?redirect_f – http://dailyjs.com/2009/11/30/html5-file-api/ – http://dret.typepad.com/dretblog/2010/04/html5-file-writer-api.htm – https://developer.mozilla.org/en-US/docs/Using_files_from_web_a – http://dev.w3.org/2006/webapi/FileAPI/ – http://www.filosophy.org/post/27/a_state_of_limbo_the_html5_fil
  • 77. Drag & drop 77
  • 78. Créer un élément pouvant être déplacé : Pour rendre un élément déplaçable, il suffit de lui ajouter l'attribut «draggable » à true: <img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69"> L'attribut draggable positionné à True permet donc d'activer le drag & drop vis à vis de l'image avec l'id « drag1 ». Drag & drop
  • 79. Créer un élément conteneur pouvant reçevoir un élément à déplacer: Pour définir un conteneur, il faut définir 2 callbacks sur les évènements ondrop et ondragover : <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div> Il faudra définir dans le HEAD de la page un style pour le div : <style type="text/css"> #div1 { width:350px;height:70px;padding:10px;border:1px solid #aaaaaa; } </style> Les dimensions sont compatible avec les dimensions de l'image pouvant être déplacer dans le div. Drag & drop
  • 80. Exemple d'implémentation des callbacks de gestion des évenements ondrop et ondragover : <script> function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("Text",ev.target.id); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); } </script> Drag & drop
  • 81. Drag & drop ● Liens : – http://html5demos.com/drag – http://html5demo.braincracking.org/demo/dragNDrop.php – http://www.startyourdev.com/codes/code-drag-drop.php – http://chez-syl.fr/2012/03/drag-and-drop-html5-jquery/ – http://www.html5rocks.com/en/tutorials/dnd/basics/
  • 82. Push de données 82
  • 83. Une des raisons pour lesquels les SSE ont été maintenus dans l'ombre, c'est que des API comme les Web Sockets fournissaient déjà un protocole riche et bi- directionnel en duplex intégral. Avoir un canal bidirectionnel est plus attrayant pour des choses comme des jeux, des applications de messagerie, et pour le cas où vous avez besoin à proximité de mises à jour en temps réel dans les deux sens. Toutefois, dans certains scénarios de données n'a pas besoin d'être envoyé par le client. Vous devez simplement mises à jour de certaines mesures du serveur. Quelques exemples seraient état des mises à jour amis, cours de la Bourse, les fils​​ de nouvelles, ou d'autres mécanismes d'incitation automatisée de données (par exemple, mettre à jour une base de données SQL Web côté client ou un magasin d'objets IndexedDB). Si vous avez besoin d'envoyer des données à un serveur, l'objet XMLHttpRequest est utile. Push server PUSH mono-directionnel
  • 84. Les SSE sont envoyés via du HTTP1.1 traditionnel. Cela signifie qu'ils n'ont pas besoin d'un protocole spécifique ou la mise en œuvre de serveur pour obtenir de travail. Les Web Sockets d'autre part, nécessitent des connexions en duplex intégral et des serveurs de sockets Web dédiés pour gérer ce protocole. En outre, les Server-Sent Events ont une variété de caractéristiques qui manque aux Web sockets tel que : ● la reconnexion automatique ; ● les événements associés à un ID ; ● la possibilité d'envoyer des événements arbitraires Push server
  • 85. Exemple d'enregistrement sur un flux d'évènements serveur : Cela revient à instancier un objet EventSource avec l'url du flux : if (!!window.EventSource) { var source = new EventSource('stream.php'); } else { // Result to xhr polling } Push server
  • 86. Ensuite, il faut déclarer un handle de message pour chaque événement : source.addEventListener('message', function(e) { console.log(e.data); }, false); source.addEventListener('open', function(e) { // Connection was opened. }, false); source.addEventListener('error', function(e) { if (e.readyState == EventSource.CLOSED) { // Connection was closed. } }, false); Push server
  • 87. Il est possible que le serveur envoie des données complexes sous format json : data: {n data: "msg": "hello world",n data: "id": 12345n data: }nn Pour ce faire, un handle de message sera rajouté et le message sera parsé pour reformer l'objet au format de type json : source.addEventListener('message', function(e) { var data = JSON.parse(e.data); console.log(data.id, data.msg); }, false); Le JSON (JavaScript Object Notation) peut et doit être vu comme une structure de Données, ou le résultat d'une sérialiation d'objet. Push server
  • 88. Pour des messages plus complexes : data: {"msg": "First message"}nn event: userlogonn data: {"username": "John123"}nn event: updaten data: {"username": "John123", "emotion": "happy"}nn Le traitement sera le suivant : source.addEventListener('message', function(e) { var data = JSON.parse(e.data); console.log(data.msg); }, false); source.addEventListener('userlogon', function(e) { var data = JSON.parse(e.data); console.log('User login:' + data.username); }, false); source.addEventListener('update', function(e) { var data = JSON.parse(e.data); console.log(data.username + ' is now ' + data.emotion); }, false); Push server
  • 89. Coté serveur une implémentation en PHP est la suivante : <?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); // recommended to prevent caching of event data. /** * Constructs the SSE data format and flushes that data to the client. * * @param string $id Timestamp/id of this connection. * @param string $msg Line of text that should be transmitted. */ function sendMsg($id, $msg) { echo "id: $id" . PHP_EOL; echo "data: $msg" . PHP_EOL; echo PHP_EOL; ob_flush(); flush(); } $serverTime = time(); sendMsg($serverTime, 'server time: ' . date("h:i:s", time())); ?> Push server
  • 90. Autre implémentation en Node.js : var http = require('http'); var sys = require('sys'); var fs = require('fs'); http.createServer(function(req, res) { //debugHeaders(req); if (req.headers.accept && req.headers.accept == 'text/event-stream') { if (req.url == '/events') { sendSSE(req, res); } else { res.writeHead(404); res.end(); } } else { res.writeHead(200, {'Content-Type': 'text/html'}); res.write(fs.readFileSync(__dirname + '/sse-node.html')); res.end(); } }).listen(8000); Push server
  • 91. function sendSSE(req, res) { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); var id = (new Date()).toLocaleTimeString(); // Sends a SSE every 5 seconds on a single connection. setInterval(function() { constructSSE(res, id, (new Date()).toLocaleTimeString()); }, 5000); constructSSE(res, id, (new Date()).toLocaleTimeString()); } Push server
  • 92. Le fichier sse-node.html aura le contenu suivant : <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <script> var source = new EventSource('/events'); source.onmessage = function(e) { document.body.innerHTML += e.data + '<br>'; }; </script> </body> </html> Push server
  • 93. Web socket (WS) vs évènements (SSE pour Server-Sent Events) envoyé depuis le serveur : Advantages de SSE opposé aux Web sockets: ● Tranport via http au lieu d'un protocole dédié ; ● Peut être quand même utilisé via un backport sur des navigateurs ne disposant pas du support ; ● Support intégré incluant des re-connexions et event-id ● Portocol simple Advantages des Web sockets opposé aux SSE : ● Communication temps réelle et bi-directionnelle ● Support natif de plusieurs navigateur web Utilisation idéale des SSE : ● Alimentation de données en continue ; ● Mise à jour des données twitter, fb, chat, … ; ● Notification serveur->browser Push server SSE WEB SOCKETS
  • 94. Push server ● Liens : – http://fr.wikipedia.org/wiki/Server_push – http://html5hacks.com/blog/2013/04/21/push-notifications-to-the-b – http://pusher.com/tutorials/html5_realtime_push_notifications – http://www.w3schools.com/html/html5_serversentevents.asp – http://html5-realtime-push-notifications.eu01.aws.af.cm/examples/ – https://github.com/pusher/html5-realtime-push-notifications – http://boedesign.com/blog/2009/07/11/growl-for-jquery-gritter/ – https://github.com/ehynds/jquery-notify – http://www.erichynds.com/blog/a-jquery-ui-growl-ubuntu-notifica – http://www.erichynds.com/examples/jquery-notify/index.htm – http://dev.w3.org/html5/eventsource/
  • 95. Web messaging 95
  • 96. 96 Web messaging Architecture : Html5 page Iframe XXX (message)
  • 97. Soit une page web contenant une iframe, on récupère son handle de la façon suivante : var o = document.getElementsByTagName('iframe')[0]; Ensuite on peut lui envoyer un message : o.contentWindow.postMessage('Hello world', 'http://b.example.org/'); Web messaging
  • 98. Web messaging L'iframe pourra traiter le message via la callback suivante : window.addEventListener('message', receiver, false); function receiver(e) { if (e.origin == 'http://example.com') { if (e.data == 'Hello world') { e.source.postMessage('Hello', e.origin); } else { console.log(e.data); } } }
  • 99. Web messaging ● Liens : – http://www.w3.org/TR/webmessaging/ – http://en.wikipedia.org/wiki/Web_Messaging – http://dev.opera.com/articles/view/window-postmessage-messagec – http://msdn.microsoft.com/fr-fr/library/ie/hh781494(v=vs.85).aspx – http://fr.slideshare.net/miketaylr/html5-web-messaging-7970364 – http://fr.slideshare.net/miketaylr/html5-web-messaging-7970364 –
  • 100. Web sockets 100
  • 101. Web sockets ● Architecture : 101 Connexion persistante serveurclient database La connexion client/serveur : - permet une communication « temps réel » pour des applications genre chat, cours de bourse, … ; - permet aux serveurs d'envoyer des évènements ; - ouvert à l'initiative du client et reste ouvert par la suite ; - le serveur doit supporter un certain nombre de sockets (1 par client) data
  • 102. Web sockets → Exemple d'application pour un mini-chat : db users
  • 103. Web sockets http://bloga.jp/ws/jq/js/jquery.ws-0.3-noenc-pre.js <script src="./jquery-1.3.2.min.js"></script> <script src="./jquery.ws-0.3pre.js"></script> <input id="msg" type="text" value=""> <button id="send">send</button> <div id="board"></div> <script type="text/javascript"> var wsoj = $.ws.conn( { url : "ws://example.com/mytest", onopen    : function(e) { $("#board").prepend("conected"); }, onmessage : function(msg,wsoj) { $("#board").prepend(msg) }, onclose   : function(e) { $("#board").prepend("closed"); } }); $("#send").click(function() { $(wsoj).wssend($("#msg").val()) }); </script> → Exemple d'implémentation d'un client :
  • 104. Web sockets ● Langages pour le serveur : – Java (ex : jWebsocket, … ) – PHP (ex : phpwebsocket, spoutserver… ) – Ruby – Python (ex : pywebsocket, … ) – C# (ex : Nugget) – Javascript (ex : node.js, … ) 104
  • 105. Web sockets → Exemple de serveur : from mod_pywebsocket import msgutil import thread import getopt import os import sys import time _GOODBYE_MESSAGE = 'Goodbye' file = '/somewhere/test' class tail(): last_mtime = None def __init__(self, filename, delay, sock): self.filename = filename self.delay = delay self.sock = sock def run(self): while True: time.sleep(self.delay) stat = os.stat(self.filename) if stat.st_mtime != self.last_mtime: self.last_mtime = stat.st_mtime self.read() def read(self): try: length = 0 f = open(self.filename, 'r') for line in f: length += 1 f.seek(0) cnt = 0 for line in f: cnt += 1 if cnt == length: msgutil.send_message(self.sock, line[:-1])
  • 106. f.close except Exception: if(f): f.close def web_socket_do_extra_handshake(request): pass # Always accept. def web_socket_transfer_data(request): attr = () thread.start_new_thread(tail(file, 0.5, request).run, attr) while True: try: line = msgutil.receive_message(request) f = open(file, 'a') f.write(line+"") os.fsync(f.fileno()) f.flush() f.close if line == _GOODBYE_MESSAGE: Return except Exception: return Web sockets (suite) Nécessite le module python : http://code.google.com/p/pywebsocket/
  • 107. Web sockets ● Liens : – http://fr.wikipedia.org/wiki/Websocket – http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-06 – http://svn.whatwg.org/webapps/complete.html#websocket – http://www.ape-project.org/ – https://github.com/disconnect/apache-websocket – http://jwebsocket.org/ – http://code.google.com/p/pywebsocket/ – http://blog.kaazing.com/2010/02/17/html5-web-sockets-and-pipeli – http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-68 – http://archive.plugins.jquery.com/project/ws – http://martinsikora.com/nodejs-and-websocket-simple-chat-tutoria – http://dev.w3.org/html5/websockets/
  • 108. Web storage 108
  • 109. Web storage Cookies limités à quelques ko contre quelques Mo pour les storages Ajout de deux interfaces/objets de stockage : → Stockage de session sessionStorage : L'interface sessionStorage mémorise les données sur la durée d'une session de navigation, et sa portée est limitée à la fenêtre ou l'onglet actif. Lors de sa fermeture, les données sont effacées. Contrairement au cookies, il n'y a pas d'interférence. Chaque stockage de session est limité à un domaine → Stockage local localStorage : L'interface localStorage mémorise les données sans limite de durée de vie. Contrairement à sessionStorage, elles ne sont pas effacées lors de la fermeture d'un onglet ou du navigateur. La portée de localStorage est de facto plus large : il est possible de l'exploiter à travers plusieurs onglets ouverts pour le même domaine ou plusieurs fenêtres ; à partir du moment où il s'agit bien sûr du même Navigateur. Il n'y a pas de partage des données Web Storage entre les différents navigateurs qui peuvent être installés sur une même machine.
  • 110. Web storage Usages et précautions Le stockage de données dans le navigateur web se prête à différentes applications, particulièrement lorsqu'il s'agit d'exécuter des traitements sans faire intervenir le serveur, ou lorsqu'il faut mémoriser facilement de petites quantités de données pour l'utilisateur pour les faire persister durant sa navigation. Parmi ces avantages : ● stocker rapidement des données en cache sans faire intervenir le serveur (par exemple via AJAX), ● augmenter la performance ressentie et faciliter les développements, ● se passer des cookies et du trafic HTTP supplémentaire qu'ils représentent (un cookie est envoyé à chaque requête effectuée sur un domaine), ● exploiter un espace alloué plus important que la limite imposée par les cookies (fixée à 4 Ko), ● retrouver des données immédiatement à la reconnexion ou les mémoriser pour éviter la perte s'il y a déconnexion. Attention : les données ne sont pas cryptées, accessibles facilement à tout utilisateur ayant accès au navigateur, et modifiables de la même façon. Il ne faut donc pas y placer d'informations sensibles. Pour ces raisons et d'autres, certains navigateurs exigent de consulter la page appelant le stockage via un domaine, (c'est-à-dire avec une url en http://, que ce soit localhost ou bien un nom de domaine complet) et non pas en fichier local (adresse file://). Sinon, une exception de sécurité peut être déclenchée. Ceci peut sembler logique car les données sont en théorie attachées à un domaine.
  • 111. Web storage Hormis les spécificités concernant la persistance des données, les méthodes d'accès sont communes : ● setItem(clé,valeur) : stocke une paire clé/valeur ● getItem(clé) : retourne la valeur associée à une clé ● removeItem(clé) : supprime la paire clé/valeur en indiquant le nom de la clé ● key(index): retourne la clé stockée à l'index spécifié ● clear(): efface toutes les paires Pour agrémenter le tout, la propriété .length renvoie le nombre de paires stockées. La console Javascript des navigateurs est un outil essentiel pour tester et vérifier le bon fonctionnement de Web Storage. Accès aux données : Note : Les exemples suivants se basent sur sessionStorage mais fonctionneront de la même façon avec localStorage.
  • 112. Web storage Stockage : sessionStorage.setItem("couleur","vert") Le premier argument de setItem est la clé (toujours de type String). Elle précise l'endroit où sont stockées les données afin de pouvoir les y retrouver ultérieurement. Récupération : var couleur = sessionStorage.getItem("couleur"); Grâce à la clé initialement créée avec setItem il est possible de récupérer facilement les données. Ces dernières sont renvoyées sous la forme d'une chaîne de caractère. Suppression : sessionStorage.removeItem("couleur"); Nous supprimons l'élément de session "couleur". Suppression totale : sessionStorage.clear(); Suppression complète de toutes les valeurs de session. Accès direct : Dans la plupart des situations, les variables seront accessibles directement en tant que membres de l'interface. sessionStorage.couleur = "vert"; console.log(sessionStorage.couleur);
  • 113. Web storage Opera : Chrome : IE :
  • 114. Web storage Une première application peut être la mémorisation de champs de formulaire, pour stocker les données entrées par l'utilisateur. Bien que ceci soit applicable à toute variable manipulée en JavaScript. Pour ceci, l'événement change sur <textarea> est sollicité pour stocker la valeur courante de l'élément dans sessionStorage.message : <textarea id="message" name="message" onchange="sessionStorage.message=this.value"></textarea> Notez que cette façon de faire est très compacte mais n'est pas des plus esthétiques car le code JavaScript se retrouve "mélangé" au contenu HTML de la page. Ce script doit être placé en fin de document : <script> // Détection du support du storage if(typeof sessionStorage!='undefined') { // Vérifie si la variable message a été stoquée dans les sessionStorage : if('message' in sessionStorage) { $('textarea#message').text() = sessionStorage.getItem('message'); } } else { console.log("sessionStorage n'est pas supporté"); } </script> http://www.codegateway.com/2012/03/get-textarea-value-in-jquery.html Exemple n° 1 :
  • 115. Un deuxième exemple très simple à mettre en place est celui d'un compteur de visites. <p>Vous avez vu cette page <span id="visites"></span> fois</p> Le principe est : ● aller interroger la clé visites dans localStorage dès le chargement du document ● effectuer toutes les vérifications nécessaires (est-ce qu'il y a déjà quelque chose stocké à cet emplacement, peut-on convertir cette chaîne de texte en nombre entier) ● incrémenter le compteur ● le stocker à nouveau au même emplacement pour le conserver ● afficher la valeur à un emplacement dans la page <script> if(typeof localStorage!='undefined') { // Récupération de la valeur dans web storage var nbvisites = localStorage.getItem('visites'); // Vérification de la présence du compteur if(nbvisites!=null) { // Si oui, on convertit en nombre entier la chaîne de texte qui fut stockée nbvisites = parseInt(nbvisites); } else { nbvisites = 1; } // Incrémentation nbvisites++; Exemple n° 2 : Web storage
  • 116. // Stockage à nouveau en attendant la prochaine visite... localStorage.setItem('visites',nbvisites); // Affichage dans la page document.getElementById('visites').innerHTML = nbvisites; } else { alert("localStorage n'est pas supporté"); } </script> Pour l'affichage, cet exemple se sert de l'identifiant id et de la fonction getElementById() pour le cibler, afin d'accéder à sa propriété innerHTML, c'est-à-dire son contenu HTML interne, modifiable. Attention : cette information restera spécifique et locale au visiteur, ne sera pas échangée avec le serveur (hors utilisation d'Ajax par exemple), et donc ne pourra être exploitée pour établir des statistiques générales. Web storage
  • 117. Web storage Utilisation de JSON : Web Storage est bien pratique pour stocker de simples chaînes de texte. Lorsqu'il s'agit de manipuler des données plus complexes, entre autres des objets JavaScript, il faut leslinéariser au préalable en chaînes de texte puisque Web Storage n'accepte que ce type de données. Le format JSON (JavaScript Object Notation) est la solution de prédilection. Deux méthodes équipent les navigateurs modernes : JSON.stringify() qui prend en paramètre un objet et renvoie une chaîne de texte linéarisée, et son inverse JSON.parse() qui reforme un objet à partir de la chaîne linéarisée. Des frameworks populaires tels que jQuery sont équipés de fonctions similaires (parseJSON) pour les anciens navigateurs qui ne seraient pas équipés en natifs de telles méthodes de conversion. Stockage : var monobjet = { propriete1 : "valeur1", propriete2 : "valeur2" }; var monobjet_json = JSON.stringify(monobjet); sessionStorage.setItem("objet",monobjet_json); Lecture : var monobjet_json = sessionStorage.getItem("objet"); var monobjet = JSON.parse(monobjet_json); // Affichage dans la console console.log(monobjet); Dans le cadre de la lisibilité de cette démonstration, cet exemple de code ne fait appel que modestement à JSON, il serait possible de l'exploiter de façon beaucoup plus complexe et évoluée en fonction de la quantité de données à stocker et de leur provenance.
  • 118. Aller plus loin : L'API prévoit aussi des événements storage pour être notifié à chaque changement opéré dans l'espace alloué. Ceux-ci ne sont pas encore très répandus. Pour mettre en place des stockages plus évolués, pour des données binaires ou bien du point de vue de la structure et des opérations de recherche, tri et maintenance, deux approches coexistent : WebSQL dont la spécification est au point mort et qui ne sera pas maintenu à long terme ni intégré à Firefox et Internet Explorer, mais qui a été implémenté par WebKit et Opera. Cette tentative faisait entrer le langage SQL côté client, ce qui était compréhensible pour les développeurs utilisant déjà les bases côté serveur (MySQL, etc) mais n'est pas conforme à l'esprit des différents standards du web : cela nécessiterait de spécifier totalement SQL ou un sous-ensemble tel que SQLite ce qui n'est pas le rôle du W3C. IndexedDB (Indexed Database) revêt une approche totalement orientée vers JavaScript, sans SQL, avec de la manipulation d'objets. Elle est cependant encore peu répandue (IE10 avec préfixe, Chrome et Firefox avec préfixe) ; et demande une phase d'apprentissage supplémentaire même pour les développeurs déjà aguerris avec SQL. Web storage
  • 119. Prise en charge :  Pour les versions d'Internet Explorer antérieures à IE8, il existe une interface nommée userData qui alloue 1 Mo par domaine et qui fonctionne sensiblement de la même manière. Pour l'exploiter, il faudra cependant adapter les fonctions au cas par cas, ou bien passer par un framework unifiant toutes les méthodes d'appel en fonction du stockage disponible.
  • 120. Web sockets ● Liens : – http://dev.opera.com/articles/view/web-storage/ – https://developers.google.com/web-toolkit/doc/latest/DevGuideHtm – https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/Storag – http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx#_d – http://theburningmonk.com/2010/12/having-fun-with-html5-local- – http://diveintohtml5.info/detect.html
  • 121. Web sql 121
  • 122. Web sql Ouverture d'une base de données : html5rocks.webdb.db = null; html5rocks.webdb.open = function() { var dbSize = 5 * 1024 * 1024; // 5MB html5rocks.webdb.db = openDatabase("Todo", "1.0", "Todo manager", dbSize); } html5rocks.webdb.onError = function(tx, e) { console.log("There has been an error: " + e.message); } html5rocks.webdb.onSuccess = function(tx, r) { // re-render the data. // loadTodoItems is defined in Step 4a html5rocks.webdb.getAllTodoItems(loadTodoItems); }
  • 123. Web sql Creation d'une table : html5rocks.webdb.createTable = function() { // Récupération du handle de la database var db = html5rocks.webdb.db; db.transaction(function(tx) { tx.executeSql("CREATE TABLE IF NOT EXISTS " + "todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", []); }); }
  • 124. Web sql Ajout d'une donnée dans une table : html5rocks.webdb.addTodo = function(todoText) { // Récupération du handle de la database var db = html5rocks.webdb.db; db.transaction(function(tx) { var addedOn = new Date(); tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)", [todoText, addedOn], html5rocks.webdb.onSuccess, html5rocks.webdb.onError); }); }
  • 125. Web sql Sélection d'une donnée dans une table : html5rocks.webdb.getAllTodoItems = function(renderFunc) { // Récupération du handle de la database var db = html5rocks.webdb.db; db.transaction(function(tx) { tx.executeSql("SELECT * FROM todo", [], renderFunc, html5rocks.webdb.onError); }); }
  • 126. Web sql Mise en forme des données issue de la base de données : function loadTodoItems(tx, rs) { var rowOutput = ""; var todoItems = document.getElementById("todoItems"); for (var i=0; i < rs.rows.length; i++) { rowOutput += renderTodo(rs.rows.item(i)); } todoItems.innerHTML = rowOutput; } function renderTodo(row) { return "<li>" + row.todo + " [<a href='javascript:void(0);' onclick='html5rocks.webdb.deleteTodo(" + row.ID +");'>Delete</a>]</li>"; }
  • 127. Web sql Suppression d'une données dans une table : html5rocks.webdb.deleteTodo = function(id) { // Récupération du handle de la database var db = html5rocks.webdb.db; db.transaction(function(tx) { tx.executeSql("DELETE FROM todo WHERE ID=?", [id], html5rocks.webdb.onSuccess, html5rocks.webdb.onError); }); }
  • 128. Web sql Initialisation : .... function init() { html5rocks.webdb.open(); html5rocks.webdb.createTable(); html5rocks.webdb.getAllTodoItems(loadTodoItems); } </script> <body onload="init();">
  • 129. Web sql ● Liens : – http://www.w3.org/TR/webdatabase/ – http://www.w3.org/TR/IndexedDB/ – http://html5sql.com/index.html
  • 130. Web worker 130
  • 131. Web worker Vérification du support : if(typeof(Worker)!=="undefined") { // Yes! Web worker support! // Some code..... } else { // Sorry! No Web Worker support.. }
  • 132. Web worker Création d'un worker fichier « workers.js » : var i=0; function timedCount() { i=i+1; postMessage(i); setTimeout("timedCount()",500); } timedCount();
  • 133. Web worker Création d'un worker objet : if (typeof(w)=="undefined") { w = new Worker("demo_workers.js"); } Il est possible de déclarer un handle de messages associé au worker : w.onmessage=function(event) { document.getElementById("result").innerHTML = event.data; };
  • 134. Web worker Arrêt d'un worker : w.terminate();
  • 135. Exemple complet : <!DOCTYPE html> <html> <body> <p>Count numbers: <output id="result"></output></p> <button onclick="startWorker()">Start Worker</button> <button onclick="stopWorker()">Stop Worker</button> <br><br> <script> var w; function startWorker() { If (typeof(Worker) !== "undefined") { if(typeof(w)=="undefined") { w = new Worker("demo_workers.js"); } w.onmessage = function (event) { document.getElementById("result").innerHTML=event.data; }; } else { document.getElementById("result").innerHTML="Sorry, your browser does not support Web Workers..."; } } function stopWorker() { w.terminate(); } </script> </body> </html>
  • 136. Web worker ● Liens : – https://developer.mozilla.org/en-US/docs/Web/Guide/Performance – http://www.siteduzero.com/informatique/tutoriels/html5-web-work – http://blogs.msdn.com/b/davrous/archive/2011/07/08/introduction- – http://www.w3schools.com/html/html5_webworkers.asp –
  • 137. Application offline 137
  • 138. App. offline L’application cache repose principalement sur l’utilisation d’un fichier “manifest” à ajouter aux pages HTML de votre site. Tout d’abord, créons donc une structure basique de page web : <!DOCTYPE html> <html> <head> <style type="text/css"> #main{ width:900px; margin:auto; } </style> </head> <body> <div id="main"> <h1>Ceci est mon application offline</h1> <img src="earth-folder.png" /> </div> </body> </html>
  • 139. App. offline Afin d’utiliser le cache d’application, il va falloir déclarer un fichier manifest. Ce fichier se déclare dans la balise html comme ceci : <html manifest="site.manifest"> Une fois déclaré, il faut bien sûr créer le fichier manifest en question. Appelons le nôtre “site.manifest”. Dans ce fichier, qui commence obligatoirement par la ligne “CACHE MANIFEST”, nous allons déclarer les fichiers qui doivent être mis en cache : CACHE MANIFEST # Version 0.1 index.html earth-folder.png
  • 140. App. offline On peut également y ajouter des commentaires. Chaque ligne de commentaire doit commencer par #. Il est important de versionner son fichier manifest via un commentaire, afin que le navigateur détecte par la suite les changements dans le fichier. Notons qu’il est possible d’utiliser des URL absolues (http://www.mon-url.com/absolue/fichier.html). Il est possible d’ajouter différentes sections à notre fichier manifest : ● CACHE, il s’agit de la section par défaut qui liste les fichiers à mettre en cache. ● NETWORK, qui liste les fichiers qui nécessitent obligatoirement une connexion internet. ● FALLBACK, qui liste les fichiers qui, au cas où ils ne soient pas accessibles en ligne, doivent renvoyer vers d’autres fichiers. L’exemple suivant représente un site web classique dont la page d’accueil, le CSS et les images sont mises en cache. Si l’utilisateur se connecte à la page d’accueil en étant hors ligne, la page offline.html lui est présentée au lieu d’index.html. Il est donc informé qu’il est déconnecté. Par conséquent il ne pourra pas accéder aux autres pages du site, puisque la section NETWORK spécifie via une étoile “*”, que tous les autres fichiers requièrent une connexion internet. CACHE MANIFEST # v0.1 CACHE: index.html css/style.css img/logo.png FALLBACK: / /offline.html NETWORK: *
  • 141. App. offline Le .htaccess : Nous arrivons maintenant au passage (un peu) délicat. Il va falloir déclarer le MIME-type du fichier manifest. Ceci se fait par l’intermédiaire du fichier de configuration de serveur. Dans la grande majorité des cas vous utiliserez un fichier .htaccess pour les projets PHP. Créez donc un fichier .htaccess dans le répertoire de votre application et ajoutez-y simplement la ligne : AddType text/cache-manifest manifest Dans cette ligne, on déclare que tous les fichiers se terminant par “manifest” ont pour MIME-type “text/cache-manifest”.
  • 142. App. offline Test de l’application hors ligne : Afin de pouvoir tester localement notre application, nous allons devoir passer par Apache (et oui, faites chauffer vos WAMP / MAMP / LAMP !). Plaçons notre application dans le dossier de votre serveur (www pour WAMP) et rendez-vous sur l’adresse http://localhost/ Si tout se passe bien, votre page s’affiche. Maintenant stoppez les services de WAMP, puis rafraîchissez la page. Alors qu’une page classique aurait naturellement fait afficher une belle erreur 404… Votre page est toujours là ! Ouvrez maintenant la console de votre navigateur si celui-ci en possède une (pour Chrome, elle se trouve dans Outils, Outils de développement, onglet Console). On peut y voir ceci : Creating Application Cache with manifest http://localhost/le-chemin-vers-votre-manifest Application Cache Checking event Application Cache Downloading event Application Cache Progress event (0 of 3) ... (1 of 3) ... (2 of 3) ... (3 of 3) Application Cache Cached event On y voit en effet tous les événements qui ont lieu lorsque votre navigateur met à jour son AppCache. Les plus coriaces d’entre vous souhaiterons pouvoir intercepter ces événements pour pouvoir effectuer des traitements au moment du déclenchement de ces événements. Ces événements seront détaillés dans la partie “aller plus loin” de ce tutoriel.
  • 143. App. offline Mise à jour du manifest : Attention soyez bien attentif à présent ! La phrase suivante a de quoi perturber : une fois votre application dans l’AppCache grâce au fichier manifest, c’est cette version offline qui a la priorité sur la version en ligne ! Pourquoi ? Tout simplement parce que vous lui avez justement dit de le stocker dans le cache ! C’est exactement comme lorsque votre navigateur garde en mémoire une image ou un CSS sur un site, afin de ne pas avoir à le télécharger à nouveau. Seulement, c’est un peu plus perturbant lorsqu’il est question d’un fichier HTML, je le reconnais… Et donc, comment fait-on pour mettre à jour le cache avec la version en ligne ? L’Application Cache sera mis à jour si : ● L’utilisateur vide son cache manuellement. ● Le fichier manifest change. ● Le cache est mis à jour avec du code Javascript. Voilà pourquoi il était important d’insérer un numéro de version dans un commentaire ! Il suffit de changer ce numéro de version pour obliger l’AppCache du client à se mettre à jour. Si vous effectuez peu de mises à jour (dans le cas d’un site vitrine par exemple) c’est la meilleure solution. Par contre, si vous avez besoin que le client soit en permanence à jour, on préfèrera la version Javascript. Et encore une fois, c’est dans la section “Aller plus loin” que ça se passe !
  • 144. App. offline Aller plus loin avec le manifest : La solution peut être de créer un service générant le manifest en changeant, d’une part, de version à chaque nouvel article publié et, d’autre part, en listant les URLs des derniers articles dans le cache explicite. Le chargement prendra plus de temps mais le lecteur pourra consulter l’article hors-ligne sans plus d’effort. Attention, les pages implicites qui déclarent le manifest sans être listées dans ce dernier y sont ajoutées et seront téléchargées elles aussi lors de la mise à jour du cache. Soyez prudent quand vous activez le manifest et ne multipliez pas les pages. Dans le cas du blog par exemple les pages affichant les articles ne doivent pas utiliser le manifest. Le lecteur ne souhaite certainement pas télécharger l’ensemble des articles qu’il a déjà lu à chaque nouvel article. Cette solution minimaliste peut convenir à certains, mais elle n’est pas applicable pour un site dont le contenu change beaucoup ou pour un site à fort trafic tant l’utilisation du cache est mauvaise. Pour optimiser l’utilisation du cache, il faut le considérer comme la vue statique de l’application qui évoluera au gré des changements d’interface et non au gré du contenu. Le contenu dynamique devra être servi par des requêtes asynchrones. Pour la mise en cache et le fonctionnement il faudra utiliser les nouvelles API JavaSript : LocalStorage et document.onLine. De cette manière, le manifest redeviendra un fichier statique évoluant au gré des versions de l’application. Pour garantir l’indexation du contenu par les moteurs de recherche et assurer la compatibilité avec d’anciens navigateurs, prévoyez toujours un mode dégradé sans manifest ni contenu asynchrone.
  • 145. App. offline Notes de sécurité : Notez que le cache est maintenu par nom de domaine. Il n’existe qu’une seule instance du même manifest pour un serveur. Pour les serveurs hébergeant plusieurs applications, l’utilisation d’hôte virtuel est plus que conseillée. Le cache ne doit jamais contenir de données confidentielles. Les pages de login et tous services de sécurité doivent être exclus du cache. Ne les listez jamais dans le manifest sauf pour les exclure et surtout n’intégrez pas le manifest dans ces pages. Informez l’utilisateur sur les dangers de ce service et surtout laissez le choisir d’activer ou non le fonctionnement hors ligne. En effet si le navigateur lui-même n’est pas protégé, toute personne y ayant accès pourra consulter le cache. Pour limiter le problème vous pouvez activer le service en stockant un cookie sur le navigateur si l’utilisateur active le mode hors ligne. Ainsi le lecteur devra répéter l’opération pour tous les navigateurs sur lesquels il souhaite consulter le site. En dehors de ces règles de sécurité basiques, toutes les règles de sécurité inhérentes aux sites web s’appliquent.
  • 146. App. offline L’API Javascript HTML5 possède un objet window.applicationCache. Cet objet permet de : ● connaître les états du cache ● attacher des traitements aux événements ● faire une mise à jour du cache ● changer le cache actuel Voici la classe ApplicationCache telle qu’elle est donnée par le WHATWG : interface ApplicationCache { // update status const unsigned short UNCACHED = 0; const unsigned short IDLE = 1; const unsigned short CHECKING = 2; const unsigned short DOWNLOADING = 3; const unsigned short UPDATEREADY = 4; const unsigned short OBSOLETE = 5; readonly attribute unsigned short status; // updates void update(); void swapCache(); // events attribute Function onchecking; attribute Function onerror; attribute Function onnoupdate; attribute Function ondownloading; attribute Function onprogress; attribute Function onupdateready; attribute Function oncached; attribute Function onobsolete; }; ApplicationCache implements EventTarget;
  • 147. App. offline Ainsi on peut tester le statut actuel : if (webappCache.status == window.applicationCache.UPDATEREADY) Ou avec un switch : switch (appCache.status) { case appCache.UNCACHED: // UNCACHED == 0 return 'UNCACHED'; break; case appCache.IDLE: // IDLE == 1 return 'IDLE'; break; … Mais il est préférable de passer par la gestion d’événements pour détecter lorsque l’Application Cache change de statut : var webappCache = window.applicationCache; webappCache.addEventListener("updateready", updateCache, false); webappCache.update(); function updateCache() { webappCache.swapCache(); alert("Une nouvelle version est disponible.nVeuillez rafraîchir la page pour mettre à jour."); }
  • 148. App. offline ● La méthode update() force le lancement du processus de mise à jour du cache. ● addEventListener(“updateready”, updateCache, false) lancera la fonction updateCache dès que le statut de l’AppCache passera en “updateready”. ● swapCache() permet d’échanger l’ancien cache avec le nouveau cache, ce qui finalise l’opération. Si vous souhaitez trouver de plus amples informations sur le sujet, je vous invite à vous rendre sur la page Application Cache du WHATWG, où sont listés tous les status que peut prendre applicationcache.status, et tous les événements associés. Dernière petite remarque, il est possible de tester si l’utilisateur est connecté à internet ou non avec la propriété : navigator.onLine Et voilà ! Vous avez tous les outils en main pour réaliser de superbes applications web ! Il y a fort à parier que ces applications deviendront le standard sur les smartphones d’ici quelques années, puisqu’elles fonctionnent aussi bien sur iPhone qu’Android. Couplé avec une balise canvas, on pourra par exemple jouer à des jeux vidéos en 3D dans le navigateur, qui seront compatibles avec tous les mobiles ! Pas besoin de s’embêter à développer plusieurs versions pour chaque OS mobile, du HTML/CSS et Javascript suffisent !
  • 149. App. offline Voici le code source de la page en question : <!DOCTYPE html> <html manifest="site.manifest"> <head> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum- scale=1.0"/> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <link rel="apple-touch-icon" href="earth-folder.png"> <link rel="apple-touch-icon-precomposed" href="earth-folder.png"> <link rel="apple-touch-startup-image" href="earth-folder.png" /> <style type="text/css"> #main{ width:900px; margin:auto; } </style> </head> <body> <div id="main"> <h1>Cette page est accessible hors ligne</h1> <p>Elle possède une icone d'application pour les smartphones.</p> <img src="earth-folder.png" /> </div> </body> </html>
  • 150. App. offline Le fichier site.manifest : CACHE MANIFEST # Version 0.4 exemple-application-cache-manifest-html5.html earth-folder.png Le .htaccess : AddType text/cache-manifest manifest
  • 151. App. offline ● Liens : – http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5- – http://diveintohtml5.info/offline.html – http://html5demo.braincracking.org/demo/onLine.php
  • 152. Framework JS 152
  • 153. Framework JS Une famille nombreuse : JS client : ● http://prototypejs.org/ ● http://script.aculo.us/ ● http://mootools.net/ ● http://www.sencha.com/products/touch ● http://www.sencha.com/products/extjs ● http://www.sencha.com/products/gxt ● http://yuilibrary.com/ ● http://dojotoolkit.org/ ● http://www.angularjs.org/ ● http://meteor.com/ ● http://jquery.com/ ● http://jquerytools.org/ ● http://jqueryui.com/ ● http://jquerymobile.com/ ● http://jqtjs.com/ ● http://www.jqmobi.com/ ● http://www.bbc.co.uk/glow/ ● http://www.midorijs.com/ ● https://developers.google.com/web-toolkit/?hl=fr JS server : ● http://nodejs.org/ Comparatifs : ● http://en.wikipedia.org/wiki/Comparison_of_JavaScript_frameworks ● http://en.wikipedia.org/wiki/List_of_JavaScript_libraries
  • 154. jQuery 154
  • 155. jQuery ● La naissance de JavaScript : ● 1995 : Brendan Eich développe pour Netscape Communications Corporation, un langage de script, appelé Mocha, puis LiveScript et finalement JavaScript ● Javascript est intégré dans le navigateur Netscape 2. Succès immédiat. ● Javascript n'est pas java !! D'un point de vue des propriétés, Javascript est plus proche du langage python que du java. ● La guerre des navigateurs : ● Netscape et Microsoft (avec JScript dans Internet Explorer) ont développé leur propre variante de JavaScript avec des fonctionnalités supplémentaires et incompatibles, notamment dans la manipulation du DOM (modèle objet du navigateur WEB) ● 1997 : Adoption du standard ECMAScript. Les spécifications sont rédigées dans le document Standard ECMA-262.
  • 156. jQuery Définition de jQuery : ● Une bibliothèque javascript open-source et cross-browser ● Elle permet de traverser et manipuler très facilement l'arbre DOM des pages web à l'aide d'une syntaxe fortement similaire à celle d'XPath. ● JQuery permet par exemple de changer/ajouter une classe CSS, créer des animations, modifier des attributs, etc. ● Gérer les événements javascript ● Faire des requêtes AJAX simplement
  • 157. jQuery Ce que jQuery n’est pas : ● Un substitut pour apprendre JavaScript ● jQuery est très puissant et très pratique, mais vous devez néanmoins connaitre les bases de Javascript, notamment la partie “objet” du langage. ● Voir des livres comme : “Object Oriented Javascript de Stoyan Stefanov” ou “jQuery, novice to ninja” (google est votre ami) ● Une réponse à tout ● Utilisez jQuery uniquement lorsque c’est nécessaire. On commence toujours par HTML+CSS avant de chercher des plugins jQuery magiques. ● De nombreuses UI sont pures html+CSS
  • 158. jQuery Une simple bibliothèque à importer : Disponible sur le site de Jquery : http://jquery.com/ <script type="text/javascript" src="jquery.js"></script> Ou directement sur Google code : <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min .js"> </script>
  • 159. jQuery La fonction jQuery() : ● jQuery repose sur une seule fonction : jQuery() ou $() ● C’est une fonction JavaScript ● Elle accepte des paramètres ● Elle retourne un objet ● $ : Syntaxe issue de « Prototype »
  • 160. jQuery Selecteur magique : $('anything') : ● $ accepte un sélecteur CSS en argument ● $ accepte des ID : $('#nomID') retourne un élément <-> document.getElementById ● $ accepte des classes : $('.nomClasse') retourne tous les éléments qui correspondent à cette classe ● $ accepte plusieurs sélecteurs $('.article, .nouvelles, .edito')
  • 161. jQuery $(anything) : ● $ accepte des sélecteurs spécifiques : $(':radio'), $(':header'), $(':first-child') ● des sélecteurs en forme de filtres : ● $(':checked'), $(':odd'), $(':visible') ● plus fort: $(':contains(du texte)') ● des attributs : ● $('a[href]'), $('a[href^=http://'), $('img[src$=.png]'
  • 162. jQuery Rappel sur le DOM : “Le Document Object Model (DOM) est une convention cross-platform et independente du langage pour representier and interagir avec des objets dans des documents en HTML, XHTML ou XML.
  • 163. jQuery Exemple de manipulation du DOM : <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min .js"> </script> </head> <body> <div id="monDiv">Bonjour</div> <a href="#" onClick="$('#monDiv').hide();"> disparition</a> </body> </html>
  • 164. jQuery Jquery, un objet : ● les méthodes s'appliquent généralement à tous les éléments sélectionnés ● $('.classe').hide(); ● $('.classe').show(); ● de nombreuses méthodes utilitaires ● parcourir le DOM: .parent(), .next(), .children(), .parents() ● ajouter ou retirer des classes CSS: addClass, removeClass ● manipuler: append, wrap, prepend ● Intérêt fondamental: la plupart des méthodes de l'objet retournent l'objet lui- même ● on peut chaîner les appels ! ● $('anything').parent().find('still anything').show(); ● Cette propriété est extrêmement puissante !
  • 165. jQuery Nombreux exemples interactifs : ● Les selecteurs jQuery sont illustrés par de nombreux tutoriaux interactifs, par exemple : ● http://www.w3schools.com/jquery/jquery_examples.asp ● http://docs.jquery.com/Tutorials:Live_Examples_of_jQuery
  • 166. jQuery jQuery example d’utilisation 1 : <ul> <li style=“background:red;”> <span>Changed</span> First item </li> <li> Second item </li> <li style=“background:red;”> <span>Changed</span> Third item </li> </ul> <ul> <li> First item </li> <li> Second item </li> <li> Third item </li> </ul> <ul> <li> <span>Changed</span> First item </li> <li> Second item </li> <li> <span>Changed</span> Third item </li> </ul> $(“li:odd”).prepend(‘<span>Changed</span>’).css({background:“red”});
  • 167. jQuery jQuery example d’utilisation 2 : <div> <span class=“foo”> Some text </span> </div> <div style=“display:none”> <span> More text </span> <span class=“foo”> </span> </div> <div> <span class=“foo”> Some text </span> </div> <div style=“display:none”> <span> More text </span> <span class=“foo”> Goodbye cruel world. </span> </div> <div> <span class=“foo”> Some text </span> </div> <div style=“display:none”> <span> More text </span> <span class=“foo”> Goodbye cruel world. </span> </div> $(“div:hidden”).find(“.foo”).empty().text(“Changed”).end().show(); <div> <span class=“foo”> Some text </span> </div> <div style=“display:block”> <span> More text </span> <span class=“foo”> Changed </span> </div> <div> <span class=“foo”> Some text </span> </div> <div style=“display:none”> <span> More text </span> <span class=“foo”> Changed </span> </div> <div> <span class=“foo”> Some text </span> </div> <div style=“display:none”> <span> More text </span> <span class=“foo”> Changed </span> </div>
  • 168. jQuery jQuery example d’utilisation 3 : Determiner si une checkbox est cochée if ($(‘#total’).attr(‘checked’)) { //Traitement si cochée } else { //Traitement si non cochée }
  • 169. jQuery jQuery example d’utilisation 4 : Intercepter le bouton submit d’un formulaire : $(document).ready(function() { $(‘#ok’).submit(function() { if ($(‘#login’).val() == ‘’) { alert (‘Entrer un login’); return false; } }) });
  • 170. jQuery jQuery example d’utilisation 5 : Effacer le contenu d’un champs de texte lorsqu’il a le focus <input name=“nom” type=“text” id=“nom” value=“Entrez votre nom”> $(‘#nom’).focus(function() { var field = $(this); field.val(‘’); });
  • 171. jQuery jQuery example d’utilisation 6 : Tester le clic sur n’importe quel bouton radio : $(‘:radio’).click(function() { //do stuff }); Donner le focus au premier élément d’un formulaire: $(‘nom’).focus;
  • 172. jQuery jQuery example d’utilisation 7 : <div> <span class=“all”>Select All</span> <span class=“none”>Select None</span> <input name=“chk1” type=“checkbox”/> <input name=“chk2” type=“checkbox”/> <input name=“chk3” type=“checkbox”/> </div> <div> <span class=“all”>Select All</span> <span class=“none”>Select None</span> <input name=“chk4” type=“checkbox”/> <input name=“chk5” type=“checkbox”/> <input name=“chk6” type=“checkbox”/> </div> $(“span.none”).click( function(){ $(this).siblings(“:checkbox”).removeAttr(“checked”); } ); $(“span.all”).click( function(){ $(this).siblings(“:checkbox”).attr(“checked”,“checked”); } ); $(“span”).click( function(){ if($(this).text()==“Select All”)) $(this).siblings(“:checkbox”).attr(“checked”,“checked”); else if ($(this).attr(“class”)==“none”) $(this).siblings(“:checkbox”).removeAttr(“checked”); } ); OU
  • 173. jQuery Ajax : ● JQuery possède toute une panoplie de fonctions permettant de simplifier les requêtes Ajax ● La plus simple : $('#maDiv').load('page.html'); ● Plus complexe : $.get('test.html',function(data) {faire quelque chose); ● Générale : $.ajax({ url: 'document.xml', type: 'GET', dataType: 'xml', timeout: 1000, error: function(){alert('Erreur chargement'); }, success: function(xml){faire quelque chose} });
  • 174. jQuery jQuery AJAX Exemple : <html> <head> <title>AJAX Demo</title> <script type=“text/javascript” src=“jquery.js”> </script> <script type=“text/javascript”> var cnt = 0; $(function(){ $.ajaxSettings({ error:function(){alert(“Communication error!”);} }); $(“:button”).click(function(){ var input = {in:$(“:textbox”).val(),count:cnt}; $.getJSON(“ajax.php”,input,function(json){ cnt = json.cnt; $(“.cnt”).text(cnt) $(“.msg”).text(json.out); }); }); }); </script> </head> <body> <p> Input: <input type=“textbox”/> <input type=“button” value=“Send”/> Output # <span class=“cnt”></span>: <span class=“msg”></span> </p> </body> </html> <?php $output = ‘’; switch($_REQUEST[‘in’]) { case ‘hello’: $output = ‘Hello back.’; break; case ‘foo’: $output = ‘Foo you, too.’; break; case ‘bar’: $output = ‘Where Andy Capp can be found.’; break; case ‘foobar’: $output = ‘This is German, right?’; break; default: $output = ‘Unrecognized string.’; } $count = $_REQUEST[‘count’]+1; echo json_encode( array( ‘out’ => $output, ‘cnt’ => $count ) ); exit; ?>
  • 175. jQuery jQuery AJAX Fonctions : ● $.func(url[,params][,callback]) ● $.get ● $.getJSON ● $.getIfModified ● $.getScript ● $.post ● $(selector), inject HTML ● load ● loadIfModified ● $(selector), ajaxSetup alts ● ajaxComplete ● ajaxError ● ajaxSend ● ajaxStart ● ajaxStop ● ajaxSuccess ● $.ajax, $.ajaxSetup ● async ● beforeSend ● complete ● contentType ● data ● dataType ● error ● global ● ifModified ● processData ● success ● timeout ● type ● url
  • 176. jQuery Inconvénients d’AJAX / XML : ● XML est délicat à parser en Javascript/jQuery : $.ajax({ type: "GET", url: "courses.xml", dataType: "xml", complete : function(data, status) { var products = data.responseXML; var html = ""; $ (products).find('product').each(function(){ var id = $(this).attr('id'); var name = $(this).find('name').text(); var price =$(this).find('price').text(); html += "<li>#"+id +" - <strong>"+name+"</strong> : " +price+"</li>"; }); $ ("#cousesList").html(html); }});
  • 177. jQuery Inconvénients d’AJAX / Sécurité : ● pour des raisons de sécurité, les navigateurs interdisent de faire du « cross-domain » avec XMLHttpRequest dont le résultat serait du XML (et donc du HTML) ….mais pas pour des scripts Javascript ! ● D’où l’idée de définir un modèle de données sous la forme d’objet Javascript ● JSON ● Voir : http://www.jsonpexamples.com/
  • 178. jQuery JSON (JavaScript Object Notation) : ● format de données textuel, générique, dérivé de la notation des objets de JavaScript ● Permet de représenter de l'information structurée. ● décrit par la RFC 4627 de l’IETF. ● Exemple : { "Image": { "Width": 800, "Height": 600, "Title": "Vue du 15ème étage", "Thumbnail": { "Url": "http://www.example.com/481989943", "Height": 125, "Width": "100" }, "IDs": [116, 943, 234, 38793] } }
  • 179. jQuery Les avantages de JSON : ● Type de données générique et abstrait pouvant ● être représenté dans n'importe quel langage de programmation ● représenter n'importe quelle donnée concrète. ● simple à mettre œuvre tout en étant complet. ● peu verbeux, lisible aussi bien par un humain que par une machine ● facile à apprendre, syntaxe réduite ● types de données sont connus et simples à décrire ● indépendant du langage de programmation (bien qu'utilisant une notation JavaScript) ● Le type MIME application/json est utilisé pour le transmettre par le protocole HTTP (notamment en Ajax) ● Standard dans les web services .Net, Java EE, etc.
  • 180. jQuery Les avantages de JSON : ● Vis-à-vis de JavaScript, un document JSON représente un objet, d'où son nom. Il est donc plus facile à interpréter qu'un XML. var donnees = eval('('+donnees_json+')'); ● Le site json.org fournit une liste de parseurs pour d'autres langages ● Il peut aussi être utilisé pour : ● la sérialisation et déserialisation d'objets ; ● l’encodage de documents ;
  • 181. jQuery jQuery et JSON : jQuery.getJSON( url, [ data ], [ callback(data, textStatus) ] ) Exemple : <html> <head> <script src="jquery.min.js"></script> </head> <body> <div id="images" style="height: 300px"></div> <script> $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne? tags=besancon&tagmode=any&format=json&jsoncallback=?", function(data){ $.each(data.items, function(i,item){ $("<img/>").attr("src", item.media.m).appendTo("#images"); if ( i == 3 ) return false; }); }); </script> </body> </html>
  • 182. jQuery jQuery UI : ● http://jqueryui.com/ ● Un ensemble de composants graphiques téléchargeable à l'adresse http://jqueryui.com/download ● un noyau (Core) ● des « comportements » (interactions) : ● draggable : pour glisser-déplacer un élément http://jqueryui.com/demos/draggable/ ● droppable : pour « déposer » un élément http://jqueryui.com/demos/droppable/ ● resizable : pour redimensionner un élément http://jqueryui.com/demos/resizable/ ● selectable : pour sélectionner des éléments à la souris http://jqueryui.com/demos/selectable/ ● sortable : pour trier des éléments http://jqueryui.com/demos/selectable/
  • 183. jQuery jQuery UI : ● des « widgets » : ● « accordéon » http://jqueryui.com/demos/accordion/ ● « calendrier » http://jqueryui.com/demos/datepicker/ ● boîte de dialogue http://jqueryui.com/demos/dialog/ ● barre de progression http://jqueryui.com/demos/progressbar/ ● curseur http://jqueryui.com/demos/slider/ ● onglets http://jqueryui.com/demos/tabs/ ● des « effets » ● http://jqueryui.com/demos/effect/ ● Clignotement, disparition, apparition, éclatement, transition… ● Une collection de thèmes ● http://jqueryui.com/themeroller/
  • 184. jQuery jQuery Plugins : ● On peut étendre facilement jQuery en utilisant des « plugins » ● Les méthodes ajoutées sont au même niveau que les méthodes natives ● Ils conservent les mêmes sémantiques que les méthodes natives: retourner l'objet jQuery, appliquer la méthode à tous les éléments représentés ● Des centaines plugins existent d'ores et déjà, de qualité variable; certains mis en avant par l'équipe de développement ● http://plugins.jquery.com/ ● des menus : http://apycom.com/ http://www.wizzud.com/jqDock/ ● Galerie photo : VisualLightbox http://visuallightbox.com
  • 185. jQuery Conclusion : ● jQuery est un framework complet et facile à utiliser ● Bibliothèque légère à charger ● Simplifier et unifie la syntaxe d’accès au DOM ● Permet de faire des requètes AJAX simplement ● UI et nombreux plugins complémentaires ● D’autres frameworks sont disponibles et ne sont pas à oublier : il est possible de combiner les frameworks ● Dojo recommandé pour application riche en widgets et nécessitant une forte cohérence (widgets MVC notamment)
  • 186. Outils
  • 187. Outils
  • 188. Ressources 189
  • 189. Liens ● http://www.w3schools.com/html/html5_intro.asp ● http://fr.wikipedia.org/wiki/HTML5 ● http://html5test.com/ ● http://www.html5rocks.com/fr/ ● http://html5boilerplate.com/ ● http://html5gallery.com/ ● http://www.alsacreations.com/article/lire/750-HTML5-nouveautes.html ● http://html5demos.com/ ● http://www.apple.com/html5/ ● http://diveintohtml5.info/ ● http://www.w3.org/html/wg/drafts/html/master/ ● http://html5doctor.com/ ● http://www.whatwg.org/specs/web-apps/current-work/ ● http://html5demo.braincracking.org/
  • 190. Liens ● http://www.html5-css3.fr/ ● https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5 ● http://html5please.com/ ● http://html5.fr/ ● http://html5.org/ ● http://miageprojet2.unice.fr/Intranet_de_Michel_Buffa/Option_web_2.0_Master_1_informatique_2011/Ressources_JQuery ● http://www.jsfiddle.net/ ● http://jsbin.com/ ● stateofhtml5.appspot.com ● http://www.w3.org/TR/html5-diff/ ● http://dev.w3.org/html5/spec/Overview.html ● http://www.w3.org/TR/#tr_Javascript_APIs ● http://www.w3.org/TR/css3-selectors/ ● http://www.w3.org/TR/css3-roadmap/ ● http://www.20thingsilearned.com/ ● http://www.evolutionoftheweb.com/
  • 191. Liens ● http://modernizr.com/ ● http://code.google.com/p/webforms2/ ● http://www.w3.org/TR/html5/forms.html ● http://www.useragentman.com/blog/2010/07/27/creating-cross-browser-html5-forms-now-using-modernizr-webforms2-and-html5widgets ● www.uize.com ● http://viralpatel.net/blogs/2009/04/jquery-ajax-tutorial-example-ajax-jquery-development.html
  • 192. Outils ● http://html5.validator.nu/ ● http://www.w3schools.com/tags/ref_colorpicker.asp ● validator.w3.org/
  • 193. Outils
  • 194. Outils
  • 195. Outils
  • 196. Outils
  • 197. HTML 4/5 (livre)
  • 198. CSS 2/3 (livre)
  • 199. JS (livre)
  • 200. JS (livre)
  • 201. Jquery
  • 202. DES QUESTIONS ? 203