Your SlideShare is downloading. ×
0
Formation web
html5 / css3
Thierry GAYET - Thierry.Gayet@gmail.fr
TIMING DE LA FORMATION
Timing journalier :
●
Matin :
09h00-10h30 : première partie
10h30-10h45 : pause
10h45-13h00 : secon...
PLAN DE LA FORMATION

Historique du web & standards

Nouveaux éléments & attributs

Le formulaires web forms

Les micr...
Historique
4
Historique
5
Pour mieux comprendre la transition que le Web vit en ce moment, voici un bref historique de ce changement de...
Historique
Quelques dates à retenir :
– 1991 HTML
– 1994 HTML 2
– 1996 CSS 1 + JavaScript
– 1997 HTML 4
– 1998 CSS 2
– 199...
HISTORIQUE
●
Liens :
– http://www.zdnet.fr/actualites/html5-petite-histoire-et-promesses-d
– http://www.weblife.fr/wp-cont...
NOUVEAUX ELEMENTS
& ATTRIBUTS
8
HTML 5
● <!DOCTYPE html>
& <meta charset="UTF-8">
● Nouvelles balises
● Balises vidéos et audio
● Nouveaux champs de
formu...
CSS 3
● Multi-colonnes
● Bordures
● Gradients
● Webfonts
● Manipulation de texte
● Animations & transitions
● Flexible box...
JavaScript
● Geolocation
● WebWorkers
● WebSockets
● Orientation
● Notification
● sessionStorage & localStorage
● Web SQL ...
HTML 5 + JavaScript
● Canvas 2D
● Intégration audio et vidéo
● Mode offline
● Gestion de l'historique
● Edition de contenu...
CSS 3 + JavaScript
● Selectors
● Classlist
LES NOUVEAUX ELEMENTS
WebGL
● Avant Chrome 9, lancer chrome avec --enable-webgl
● Sous Firefox 4, about:config puis enable for all sites
● Exemp...
A Venir
● Contacts API
● Webcam (Capture API)
● Device Orientation API
● Calendar API
● Speech input
● ...
LES NOUVEAUX EL...
LES FORMULAIRES
WEB FORMS
16
Nouveaux types d'entrées dans HTML5
Ce que nous connaissons aujourd'hui comme étant HTML5 Forms ou HTML5 Web Forms a démar...
La balise <input> en HTML4 possède les propriétés suivante :
Type Description
text A free-form text field, nominally free ...
La balise <input> en HTML5 a évolué en incluant de nouvelles propriétés :
Type Description
datetime A date and time (year,...
Quelques exemples de formulaires :
<form>
<p><label>Customer name: <input></label></p>
<fieldset>
<legend> Pizza Size </le...
<form>
<p><label>Customer name: <input></label></p>
<p><label>Telephone: <input type=tel></label></p>
<p><label>E-mail add...
<form method="post"
enctype="application/x-www-form-urlencoded"
action="https://pizza.example.com/order.cgi">
<p><label>Cu...
<fieldset>
<legend>Display</legend>
<p><label><input type=radio name=c value=0 checked> Black on White</label>
<p><label><...
<fieldset name="clubfields" disabled>
<legend> <label>
<input type=checkbox name=club onchange="form.clubfields.disabled =...
LES WEBFORMS
●
Liens :
– http://diveintohtml5.info/forms.html
– http://msdn.microsoft.com/fr-fr/magazine/hh547102.aspx
– h...
LES MICROFORMATS
& MICRODATA
26
Le microformat propose une syntaxe qui s’apparente à du HTML classique et s’applique bien en
dehors de la norme HTML5 puis...
Les microdonnées :
Les microdonnées sont représentées par l’arrivée de nouveaux attributs en HTML5.
Il est alors possible ...
Nouveaux attributs :
Il n’en existe pas énormément :
● itemscope : il permet de créer un item dont le type peut-être préci...
Exemple d’une notation imbriquée dans une revue :
Aussi appelée Embedded Items, l’imbrication de différents types de schém...
Création d’une fiche « film » :
Je prends volontairement ce dernier exemple pour vous présenter une technique qui permet d...
Cet attribut permet de présenter un même item découpé en plusieur éléments à travers la page. Si les
informations de notre...
Le code HTML correspondant à cette mise en page pourrait ressembler à cela :
<section role="main">
<article itemscope item...
<dd itemprop="actors">Christine Citti</dd>
<dd itemprop="actors">Nathalie Boutefeu</dd>
<dt>Distributeur</dt>
<dd itemprop...
LES MICROFORMATS
●
Liens :
– http://microformats.org/wiki/html5
– http://html5doctor.com/microformats/
– http://speckyboy....
AUDIO & VIDEO
36
L'élément <video>, cousin de <audio> offre en HTML5 une solution simple, native pour les
navigateurs pour l'intégration d'...
On peut également proposer plusieurs sources dans plusieurs formats différents en indiquant les
types MIME grâce à l'attri...
● Attributs :
L'attribut controls donne accès aux contrôles de lecture (boutons de navigation, volume, etc, selon les
poss...
● Formats :
Plusieurs formats tiennent le devant de la scène : WebM, MP4 et Ogg Theora. Même si le but de ce
tutoriel est ...
→ OGG/Theora :
Theora est un format de compression vidéo open-source, sans brevets. Ceci donne le droit à tous
d'utiliser ...
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...
AUDIO & VIDEO
●
Liens :
– http://diveintohtml5.info/video.html
– http://fr.wikipedia.org/wiki/Theora
– http://www.videojs....
CANVAS
44
Introduit à l'origine par Apple pour être utilisé dans WebKit pour des logiciels comme Dashboard et le
navigateur Safari, ...
Tous les exemples suivants dans ce tutoriel feront appel à cette structure (élément Canvas +
élément script + appel à getE...
Pour commencer, voici un exemple simple qui dessine deux rectangles ayant une intersection, l'un
d'entre-eux possédant une...
La fonction beginPath commence un nouveau chemin, et moveTo, lineTo, arcTo, arc et des méthodes
similaires sont utilisées ...
Canvas
Canvas
●
Liens :
– http://www.html5canvastutorials.com/
– http://www.lafermeduweb.net/tutorial/l-element-html-5-canvas-p2
...
Géolocalisation
51
Une des nouveautés introduites par HTML5 est la géolocalisation utilisable via une
API d'un navigateur.
Cela permet aux pa...
Détail de la méthode getCurrentPosition() :
PropertyProperty DescriptionDescription
coords.latitude The latitude as a deci...
Exemple de code pour un client :
<script>
var x = document.getElementById("demoLoc");
function getLocation()
{
if (navigat...
Gestion des erreurs :
function showError(error)
{
switch(error.code)
{
case error.PERMISSION_DENIED:
x.innerHTML="User den...
Example d'affichage de la position sur une carte :
function showPosition(position)
{
var latlon = position.coords.latitude...
Autre méthodes :
● watchPosition() : retourne la position courante ainsi que le mouvement via une icône
(voiture).
● clear...
Géolocalisation
●
Liens :
– http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geo
– http://dev.w3.org/geo/api/spec...
Gérer les fichiers
59
L'API offerte aux navigateur web pour gérer les fichiers permet:
● De gérer une liste de fichiers (1:n) sélectionnable dep...
Vérifier le support disponible :
if (window.File && window.FileReader && window.FileList && window.Blob)
{
// Accès possib...
Soit le code HTML suivant :
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
Voici un ...
Soit le code HTML suivant :
<div id="drop_zone">Drop files here</div>
<output id="list"></output>
Voici un exemple de code...
(...)
function handleDragOver(evt)
{
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; //...
A aprtir du code html & css suivant :
<style>
.thumb
{
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
</sty...
(...)
reader.onload = (function(theFile)
{
return function(e)
{
var span = document.createElement('span');
span.innerHTML ...
A partir du code html suivant :
<style>
#byte_content
{
margin: 5px 0;
max-height: 100px;
overflow-y: auto;
overflow-x: hi...
Le code Javascript permettant de télécharger un fichier binaire est le suivant :
<script>
function readBlob(opt_startByte,...
(...)
document.querySelector('.readBytesButtons').addEventListener('click', function(evt)
{
if (evt.target.tagName.toLower...
A partir du code html suivant :
<style>
#progress_bar
{
margin: 10px 0;
padding: 3px;
border: 1px solid #000;
font-size: 1...
<input type="file" id="files" name="file" />
<button onclick="abortRead();">Cancel read</button>
<div id="progress_bar"><d...
(...)
function updateProgress(evt)
{
// evt is an ProgressEvent.
if (evt.lengthComputable)
{
var percentLoaded = Math.roun...
(...)
reader.onload = function(e)
{
// Ensure that the progress bar displays 100% at the end.
progress.style.width = '100%...
Autre exemple :
var file = document.getElementById('file').files[0];
if (file)
{
// create an identical copy of file
// th...
Création d'un objet blob (Binary Large Object) :
var a = new Blob();
// Creation d'un tableau de 10.24 octets
var buffer =...
Gérer les fichiers
●
Liens :
– http://www.html5rocks.com/en/tutorials/file/dndfiles/
– http://en.wikipedia.org/wiki/File_s...
Drag & drop
77
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 ...
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 ...
Exemple d'implémentation des callbacks de gestion des évenements ondrop et
ondragover :
<script>
function allowDrop(ev)
{
...
Drag & drop
●
Liens :
– http://html5demos.com/drag
– http://html5demo.braincracking.org/demo/dragNDrop.php
– http://www.st...
Push de données
82
Une des raisons pour lesquels les SSE ont été maintenus dans l'ombre, c'est que
des API comme les Web Sockets fournissaien...
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 mi...
Exemple d'enregistrement sur un flux d'évènements serveur :
Cela revient à instancier un objet EventSource avec l'url du f...
Ensuite, il faut déclarer un handle de message pour chaque événement :
source.addEventListener('message', function(e)
{
co...
Il est possible que le serveur envoie des données complexes sous format json :
data: {n
data: "msg": "hello world",n
data:...
Pour des messages plus complexes :
data: {"msg": "First message"}nn
event: userlogonn
data: {"username": "John123"}nn
even...
Coté serveur une implémentation en PHP est la suivante :
<?php
header('Content-Type: text/event-stream');
header('Cache-Co...
Autre implémentation en Node.js :
var http = require('http');
var sys = require('sys');
var fs = require('fs');
http.creat...
function sendSSE(req, res)
{
res.writeHead(200,
{
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Conne...
Le fichier sse-node.html aura le contenu suivant :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<...
Web socket (WS) vs évènements (SSE pour Server-Sent Events) envoyé depuis le serveur :
Advantages de SSE opposé aux Web so...
Push server
●
Liens :
– http://fr.wikipedia.org/wiki/Server_push
– http://html5hacks.com/blog/2013/04/21/push-notification...
Web messaging
95
96
Web messaging
Architecture :
Html5 page
Iframe XXX
(message)
Soit une page web contenant une iframe, on récupère son handle de la façon
suivante :
var o = document.getElementsByTagNam...
Web messaging
L'iframe pourra traiter le message via la callback suivante :
window.addEventListener('message', receiver, f...
Web messaging
●
Liens :
– http://www.w3.org/TR/webmessaging/
– http://en.wikipedia.org/wiki/Web_Messaging
– http://dev.ope...
Web sockets
100
Web sockets
●
Architecture :
101
Connexion persistante
serveurclient database
La connexion client/serveur :
- permet une c...
Web sockets
→ Exemple d'application pour un mini-chat :
db users
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=...
Web sockets
●
Langages pour le serveur :
– Java (ex : jWebsocket, … )
– PHP (ex : phpwebsocket, spoutserver… )
– Ruby
– Py...
Web sockets
→ Exemple de serveur :
from mod_pywebsocket import msgutil
import thread
import getopt
import os
import sys
im...
f.close
except Exception:
if(f):
f.close
def web_socket_do_extra_handshake(request):
pass # Always accept.
def web_socket_...
Web sockets
●
Liens :
– http://fr.wikipedia.org/wiki/Websocket
– http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketpr...
Web storage
108
Web storage
Cookies limités à quelques ko contre quelques Mo pour les storages
Ajout de deux interfaces/objets de stockage...
Web storage
Usages et précautions
Le stockage de données dans le navigateur web se prête à différentes applications,
parti...
Web storage
Hormis les spécificités concernant la persistance des données, les méthodes d'accès sont communes :
● setItem(...
Web storage
Stockage :
sessionStorage.setItem("couleur","vert")
Le premier argument de setItem est la clé (toujours de typ...
Web storage
Opera :
Chrome :
IE :
Web storage
Une première application peut être la mémorisation de champs de formulaire, pour stocker les données
entrées p...
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=...
// Stockage à nouveau en attendant la prochaine visite...
localStorage.setItem('visites',nbvisites);
// Affichage dans la ...
Web storage
Utilisation de JSON :
Web Storage est bien pratique pour stocker de simples chaînes de texte. Lorsqu'il s'agit...
Aller plus loin :
L'API prévoit aussi des événements storage pour être notifié à chaque changement opéré dans l'espace
all...
Prise en charge : 
Pour les versions d'Internet Explorer antérieures à IE8, il existe une interface nommée userData qui al...
Web sockets
●
Liens :
– http://dev.opera.com/articles/view/web-storage/
– https://developers.google.com/web-toolkit/doc/la...
Web sql
121
Web sql
Ouverture d'une base de données :
html5rocks.webdb.db = null;
html5rocks.webdb.open = function()
{
var dbSize = 5 ...
Web sql
Creation d'une table :
html5rocks.webdb.createTable = function()
{
// Récupération du handle de la database
var db...
Web sql
Ajout d'une donnée dans une table :
html5rocks.webdb.addTodo = function(todoText)
{
// Récupération du handle de l...
Web sql
Sélection d'une donnée dans une table :
html5rocks.webdb.getAllTodoItems = function(renderFunc)
{
// Récupération ...
Web sql
Mise en forme des données issue de la base de données :
function loadTodoItems(tx, rs)
{
var rowOutput = "";
var t...
Web sql
Suppression d'une données dans une table :
html5rocks.webdb.deleteTodo = function(id)
{
// Récupération du handle ...
Web sql
Initialisation :
....
function init()
{
html5rocks.webdb.open();
html5rocks.webdb.createTable();
html5rocks.webdb....
Web sql
●
Liens :
– http://www.w3.org/TR/webdatabase/
– http://www.w3.org/TR/IndexedDB/
– http://html5sql.com/index.html
Web worker
130
Web worker
Vérification du support :
if(typeof(Worker)!=="undefined")
{
// Yes! Web worker support!
// Some code.....
}
el...
Web worker
Création d'un worker fichier « workers.js » :
var i=0;
function timedCount()
{
i=i+1;
postMessage(i);
setTimeou...
Web worker
Création d'un worker objet :
if (typeof(w)=="undefined")
{
w = new Worker("demo_workers.js");
}
Il est possible...
Web worker
Arrêt d'un worker :
w.terminate();
Exemple complet :
<!DOCTYPE html>
<html>
<body>
<p>Count numbers: <output id="result"></output></p>
<button onclick="start...
Web worker
●
Liens :
– https://developer.mozilla.org/en-US/docs/Web/Guide/Performance
– http://www.siteduzero.com/informat...
Application offline
137
App. offline
L’application cache repose principalement sur l’utilisation d’un fichier “manifest” à
ajouter aux pages HTML ...
App. offline
Afin d’utiliser le cache d’application, il va falloir déclarer un fichier manifest.
Ce fichier se déclare dan...
App. offline
On peut également y ajouter des commentaires. Chaque ligne de commentaire doit commencer par #. Il est import...
App. offline
Le .htaccess :
Nous arrivons maintenant au passage (un peu) délicat. Il va falloir déclarer le MIME-type du f...
App. offline
Test de l’application hors ligne :
Afin de pouvoir tester localement notre application, nous allons devoir pa...
App. offline
Mise à jour du manifest :
Attention soyez bien attentif à présent ! La phrase suivante a de quoi perturber : ...
App. offline
Aller plus loin avec le manifest :
La solution peut être de créer un service générant le manifest en changean...
App. offline
Notes de sécurité :
Notez que le cache est maintenu par nom de domaine. Il n’existe qu’une seule instance du ...
App. offline
L’API Javascript HTML5 possède un objet window.applicationCache. Cet objet permet de :
● connaître les états ...
App. offline
Ainsi on peut tester le statut actuel :
if (webappCache.status == window.applicationCache.UPDATEREADY)
Ou ave...
App. offline
● La méthode update() force le lancement du processus de mise à jour du cache.
● addEventListener(“updateread...
App. offline
Voici le code source de la page en question :
<!DOCTYPE html>
<html manifest="site.manifest">
<head>
<meta na...
App. offline
Le fichier site.manifest :
CACHE MANIFEST
# Version 0.4
exemple-application-cache-manifest-html5.html
earth-f...
App. offline
●
Liens :
– http://blog.xebia.fr/2010/12/02/application-hors-ligne-avec-html5-
– http://diveintohtml5.info/of...
Framework JS
152
Framework JS
Une famille nombreuse :
JS client :
● http://prototypejs.org/
● http://script.aculo.us/
● http://mootools.net...
jQuery
154
jQuery
● La naissance de JavaScript :
● 1995 : Brendan Eich développe pour Netscape Communications
Corporation, un langage...
jQuery
Définition de jQuery :
● Une bibliothèque javascript open-source et cross-browser
● Elle permet de traverser et man...
jQuery
Ce que jQuery n’est pas :
● Un substitut pour apprendre JavaScript
● jQuery est très puissant et très pratique, mai...
jQuery
Une simple bibliothèque à importer :
Disponible sur le site de Jquery : http://jquery.com/
<script type="text/javas...
jQuery
La fonction jQuery() :
● jQuery repose sur une seule fonction : jQuery() ou $()
● C’est une fonction JavaScript
● E...
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Formation html3 css3
Upcoming SlideShare
Loading in...5
×

Formation html3 css3

1,261

Published on

Formation html5 / css3 / js (jquery / jqmobi)

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,261
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
181
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Formation html3 css3"

  1. 1. Formation web html5 / css3 Thierry GAYET - Thierry.Gayet@gmail.fr
  2. 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. 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. 4. Historique 4
  5. 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. 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. 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. 8. NOUVEAUX ELEMENTS & ATTRIBUTS 8
  9. 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. 10. CSS 3 ● Multi-colonnes ● Bordures ● Gradients ● Webfonts ● Manipulation de texte ● Animations & transitions ● Flexible box model ● Nouveaux selecteurs ● Media Queries ● ... LES NOUVEAUX ELEMENTS
  11. 11. JavaScript ● Geolocation ● WebWorkers ● WebSockets ● Orientation ● Notification ● sessionStorage & localStorage ● Web SQL database & IndexedDB ● ... LES NOUVEAUX ELEMENTS
  12. 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. 13. CSS 3 + JavaScript ● Selectors ● Classlist LES NOUVEAUX ELEMENTS
  14. 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. 15. A Venir ● Contacts API ● Webcam (Capture API) ● Device Orientation API ● Calendar API ● Speech input ● ... LES NOUVEAUX ELEMENTS
  16. 16. LES FORMULAIRES WEB FORMS 16
  17. 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. 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. 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. 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. 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. 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. 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. 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. 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. 26. LES MICROFORMATS & MICRODATA 26
  27. 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. 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. 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. 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. 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. 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. 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. 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. 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. 36. AUDIO & VIDEO 36
  37. 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. 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. 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. 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. 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. 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. 43. AUDIO & VIDEO ● Liens : – http://diveintohtml5.info/video.html – http://fr.wikipedia.org/wiki/Theora – http://www.videojs.com/ –
  44. 44. CANVAS 44
  45. 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. 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. 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. 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. 49. Canvas
  50. 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. 51. Géolocalisation 51
  52. 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. 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. 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. 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. 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. 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. 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. 59. Gérer les fichiers 59
  60. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 77. Drag & drop 77
  78. 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. 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. 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. 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. 82. Push de données 82
  83. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 95. Web messaging 95
  96. 96. 96 Web messaging Architecture : Html5 page Iframe XXX (message)
  97. 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. 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. 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. 100. Web sockets 100
  101. 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. 102. Web sockets → Exemple d'application pour un mini-chat : db users
  103. 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. 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. 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. 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. 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. 108. Web storage 108
  109. 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. 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. 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. 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. 113. Web storage Opera : Chrome : IE :
  114. 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. 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. 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. 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. 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. 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. 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. 121. Web sql 121
  122. 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. 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. 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. 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. 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. 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. 128. Web sql Initialisation : .... function init() { html5rocks.webdb.open(); html5rocks.webdb.createTable(); html5rocks.webdb.getAllTodoItems(loadTodoItems); } </script> <body onload="init();">
  129. 129. Web sql ● Liens : – http://www.w3.org/TR/webdatabase/ – http://www.w3.org/TR/IndexedDB/ – http://html5sql.com/index.html
  130. 130. Web worker 130
  131. 131. Web worker Vérification du support : if(typeof(Worker)!=="undefined") { // Yes! Web worker support! // Some code..... } else { // Sorry! No Web Worker support.. }
  132. 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. 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. 134. Web worker Arrêt d'un worker : w.terminate();
  135. 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. 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. 137. Application offline 137
  138. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 152. Framework JS 152
  153. 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. 154. jQuery 154
  155. 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. 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. 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. 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. 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 »
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×