Sei sulla pagina 1di 93

Guida HTML5

di: Sandro Paganotti, Gianluca Guarini, Simone Bonati


Le basi di HTML5
1.
1. Introduzione
Introduzione alla guida e presentazione del metodo operativo
2.
2. Da HTML 4 ad HTML5
Il percorso che ha portato allo sviluppo di HTML5, con una breve presentazione delle caratteristiche salienti del linguaggio e della specifica
3.
3. La sintassi di HTML5
Le regole di base per scrivere codice HTML5; le differenze rispetto a XHTML
4.
4. Elementi disegnati per un web moderno
Cosa cambia in HTML5 rispetto alla versione 4 del linguaggio: elementi e attributi non pi presenti nella specifica
5.
5. Attributi globali
Analisi dei nuovi attributi globali introdotti nella specifica ed elenco degli attributi applicabili a tutti gli elementi
6.
6. Un nuovo content model
Un nuovo approccio alla strutturazione semantica dei contenuti in un documento HTML
7.
7. Panoramica sui content model e presentazione del primo progetto guida
Esaminiamo da vicino gli altri content model previsti nella specifica HTML5
Nuovi elementi strutturali e semantici
1.
8. Header
Raggruppare elementi ausiliari e introduttivi
2.
9. Footer
Un tag per raggruppare informazioni sulle sezioni che compongono la pagina
3.
10. Section
Creare sezioni generiche all'interno di una pagina
4.
11. Article
Definire sezioni di contenuto autonome e ripubblicabili
5.
12. Nav
Un tag studiato per definire e raggruppare gli elementi di navigazione presenti nella pagina
6.
13. Aside
Raggruppare informazioni correlate ai contenuti principali
7.
14. Hgroup
Raggruppare correttamente i titoli
8.
15. Mark
Evidenziare parti o parole importanti della pagina
9.
16. Time e gli attributi pubdate e datetime
Definire sementicamente le date e gli orari
10.
17. Meter
Rappresentare e definire misure scalari
11.
18. Progress
Un tag per rappresentare lo stato di completamento di un compito
12.
19. Altri tag
Un elenco dei tag meno importanti definiti nella specifica
I form: nuovi attributi e tipi di input
1.
20. I formin HTML5: una panoramica
Cosa cambia nella gestione dei moduli in HTML5
2.
21. Nuovi attributi per i form: autofocus, placeholder e form
Iniziamo la panoramica sui nuovi attributi definiti nella specifica per i campi di input di un form
3.
22. Nuovi attributi dei formper la validazione
Analisi degli attributi required, autocomplete, multiple, pattern, min, max, step, novalidate
4.
23. Input type: tel
Inserire numeri di telefono in un form
5.
24. Input type: search
Un campo specifico per le ricerche
6.
25. Input type: url
Inserimento di URL in un form
7.
26. Input type: email
Un campo destinato all'inserimento di indirizzi e-mail
8.
27. Nuovi tipi di input per la gestione delle date
Una panoramica dei tipi di input datetime, date, month, week, time, datetime-local
9.
28. Input type: number
Inserire valori numerici in un form
10.
29. Input type: range
Inserimento di un numero attraverso uno slider
11.
30. Input type: color
Un campo per la selezione di colori da una palette
12.
31. Cosa sono le datalist?
Collegare un campo di testo ad una lista di opzioni
I microdati
1.
32. La potenza dei microdati
Definire contenuti semantici in HTML5
Primo progetto guida
1.
33. Un template per blog in HTML5
Struttura, compatibilit cross-browser, stili
API per Web Applications
1.
34. Nuova linfa alle applicazioni web
Una panoramica sulle nuove API legate alla specifica HTML5
2.
35. Applicazioni web offline (file .manifest)
Conservare una copia locale di risorse presenti in un'applicazione
3.
36. Indexed Database API
Creare e manipolare un database di ispirazione NoSQL memorizzato allinterno del browser dellutente
4.
37. WebStorage API
Superare i limiti dei cookie con sessionStorage e localStorage
5.
38. Web Workers API
Eseguire codice J avascript in modo asincrono, senza intaccare le performance della pagina web
6.
39. WebSocket API
Stabilire e mantenere una connessione dati tra browser e server remoto sulla quale far transitare messaggi in entrambe le direzioni
7.
40. Drag and Drop
L'implementazione in HTML del meccanismo di trascinamento e rilascio di oggetti in una pagina web
8.
41. Geolocation API
Gestire dati geografici e geospaziali
Canvas e Multimedia
1.
42. Canvas
Disegnare e tracciare immagini in HTML5
2.
43. Canvas: un esempio pratico
Implementiamo l'elemento canvas nel nostro progetto guida
3.
44. Video
Incorporare, riprodurre e gestire filmati in modo nativo
4.
45. Video e Canvas: un esempio pratico
Manipolare flussi video in tempo reale con l'ausilio di un canvas
5.
46. Audio
Incorporare, riprodurre e gestire file audio in modo nativo
6.
47. SVG e MathML
Novit nel supporto in HTML5 per Scalable Vector Graphic e Mathematical Markup Language
Secondo progetto guida
1.
48. Una 'lavagna virtuale'
Evoluzione dell'applicazione attraverso lutilizzo delle API HTML5
HTML5 e compatibilit cross-browser
1.
49. Feature detection e strategie di fallback
Tecniche, strumenti e alternative per iniziare a implementare HTML5 mantenendo la compatibilit su tutti i principali browser
2.
50. Appendice: Tabelle del supporto sui browser di HTML5
Una sintesi visuale e aggiornata del supporto cross-browser delle funzionalit HTML5
Introduzione
Una guida operativa
Affrontare un tema vasto come quello dell'HTML5 spaventa sempre un po', soprattutto quando l'obiettivo quello di abbracciare l'intera tecnologia sottostante le
specifiche proponendo al contempo un'opera che sia fruibile e divertente da leggere. Il primo passo che abbiamo deciso di compiere nella stesura di questo progetto stato
individuare il target di lettori ai quali la guida vorrebbe rivolgersi. Abbiamo allora identificato da un lato un gruppo di sviluppatori interessati alla consultazione di
specifiche referenze del linguaggio, dall'altro un insieme di lettori desiderosi di informarsi a tutto tondo sulle novit offerte dall'HTML5. A questa commistione di
interessi si aggiunge una naturale segmentazione della guida secondo i due temi che maggiormente permeano le specifiche: il nuovo approccio semantico nella creazione
di pagine web e il ricco set di API reso disponibile.
Il percorso si snoda in modo organico tra le due macro-sezioni alternando lezioni di stampo divulgativo, ottime per avere una visione di insieme della tematica trattata, a
percorsi verticali costruiti attorno a funzionalit specifiche. Non sono previsti articoli introduttivi alla sintassi del linguaggio HTML e nemmeno approfondimenti su
elementi o API gi presenti nelle versioni precedenti, a meno che questi non abbiano subito un cambio radicale; se fosse necessario recuperare informazioni su tali aspetti
rimandiamo alla lettura della guida HTML 4 (http://xhtml.html.it/guide/leggi/51/guida-html/) redatta da Wolfgang Cecchin.
I progetti guida
Per questa guida abbiamo deciso di combinare i tanti piccoli esempi dedicati ad ogni lezione in un vero e proprio progetto che sappia anche mostrare come le singole
funzionalit HTML5 lavorano insieme.
In realt i progetti sono due, come due gli aspetti principali di questa specifica: al termine delle lezioni legate al nuovo supporto semantico dell'HTML5 la combinazione
dei vari esempi mostrati dar vita ad un template per blog studiato per trarre vantaggio da elementi come <sect i on>e <ar t i cl e>, dai nuovi content model e dalle novit
in materia di form. La parte incentrata sulle API dedicate allo sviluppo di applicazioni web invece includer tutti gli elementi necessari alla stesura di una lavagna virtuale
sulla quale si potranno tracciare linee utilizzando il mouse e che dar la possibilit di salvare in locale le opere create.
Chiaramente tale scelta stata implementata in modo da non pregiudicare l'indipendenza delle singole lezioni ma con l'idea di suggellare un ulteriore filo conduttore
all'interno dell'opera.
Figura 1 - Anteprima del template per blog in HTML5 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_1/blog_preview.png)
Alcuni prerequisiti
Nella prossima lezione ci interesseremo con maggior attenzione alla timeline ufficiale HTML5, per ora basti sapere che la data di accettazione delle specifiche come
standard W3C ancora sufficientemente lontana. Nonostante questo, buona parte di quanto verr trattato in questa guida gi disponibile sulla grande maggioranza dei
browser e, come vedremo, alcuni aspetti del linguaggio sono da tempo in produzione su portali di notevoli dimensioni, come youtube.com
(http://www.youtube.com/html5) o vimeo.com(http://vimeo.com/blog:268).
Esistono tuttavia ampie porzioni delle specifiche che, perch meno strategiche, di pi difficile implementazione o meno mature, sono ad oggi supportate in modo
superficiale e disomogeneo; per poter beneficiare al massimo delle demo e degli esempi anche per elementi o API che ricadono in questa categoria si consiglia quindi di
dotarsi di un browser che utilizzi WebKit come layout engine in quanto dotato del pi ampio supporto HTML5 ad oggi disponibile sia per le parti della specifica ormai
consolidate sia per quelle al momento pi 'sperimentali'.
In particolare, tutto il codice di questa guida stato sviluppato e testato usando la Nightly Build' di Chromium, cio la versione speciale per fini di sviluppo che contiene
ogni feature ad oggi implementata, per quanto sperimentale esso sia. La pagina per il download, disponibile per i principali sistemi operativi, raggiungibile all'indirizzo
http://build.chromium.org/f/chromium/snapshots/ (http://build.chromium.org/f/chromium/snapshots/) seguendo il link nominato come il proprio sistema operativo e
successivamente la cartella recante il numero pi alto tra i presenti.
Tabella della compatibilit sui browser
Se Chromium, lo accennavamo, garantisce ad oggi il supporto pi ampio alle funzionalit previste nella specifica e in via di definizione presso il W3C e il WHATWG, la
maggior parte dei browser commerciali pi diffusi, con ritmi e tempi diversi, si sta adeguando. Internet Explorer 9 e Firefox 5, rilasciati nella primavera di questanno,
condividono infatti un ottimo supporto a queste specifiche.
Lo stato dell'arte relativamente al supporto HTML5 lo abbiamo tracciato in questa tabella di compatibilit
(http://www.html.it/guide/esempi/html5/tabella_supporto/tabella.html) che sar via via aggiornata con l'estendersi del supporto alle feature che attualmente non sono
supportate. Estratti della tabella sono inseriti anche a corredo delle lezioni dedicate a ciascun elemento.
Mappa della guida
Nell'immagine seguenti riassunta l'intera struttura dell'opera mettendo in evidenza la posizione delle singole lezioni rispetto al contenuto globale con l'obiettivo di fornire
una panoramica esauriente sui temi che verranno trattati.
Ai nastri di partenza!
Figura 2 - Mappa della guida (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_1/2.jpg)
Bene, con questo pu definirsi conclusa questa necessaria sezione introduttiva, la prossima lezione affronter la travagliata storia che ha caratterizzato la definizione di
queste specifiche, con un piccolo ma sentito cameo anche da parte dell'XHTML2.
Da HTML 4 ad HTML5
Un po' di storia
Siete curiosi di sapere come tutto nato? Venerd 4 giugno 2004, in una notte buia e tempestosa, Ian Hickson annuncia la creazione del gruppo di ricerca WHAT
(http://www.whatwg.org/), acronimo di Web Hypertext Application Technology in un sintetico ma ricco messaggio (http://lists.whatwg.org/htdig.cgi/whatwg-
whatwg.org/2004-J une/000005.html).
L'obiettivo del gruppo quello di elaborare specifiche per aiutare lo sviluppo di un web pi orientato alle applicazioni che ai documenti; tra i sottoscrittori di questa
iniziativa si annoverano aziende del calibro di Apple, Mozilla e Opera. Questa piccolo scisma dal W3C determinato dal disaccordo in merito alla rotta decisa dal
consorzio durante un famoso convegno del 2004 dove, per un pugno di voti, prevalse la linea orientata ai documenti di XHTML2.
"XHTML 2.0 considered harmful (http://lists.w3.org/Archives/Public/www-html/2003J an/0123.html)" il titolo di un messaggio inviato alla mailing list ufficiale del
W3C datato 14 gennaio 2003 che ben riassume i sentimenti contrastanti che all'epoca si respiravano in merito a queste specifiche. La principale causa di perplessit da
ricercarsi nella decisione azzardata di non mantenere la retro-compatibilit con la versione 1.1 eliminando alcuni tag e imponendo agli sviluppatori web un controllo
rigoroso nella creazione delle pagine, pena lo stop del processo di parsing e la visualizzazione a schermo degli errori di interpretazione. Nei due anni successivi i gruppi
XHTML2 e WHAT proseguono i lavori sulle proprie specifiche in modo indipendente e parallelo, sollevando dubbi e confusione sia da parte dei produttori di browser che
degli sviluppatori web. Emblematico in tal senso un articolo firmato da Edd Dumbill nel dicembre 2005 intitolato The future of HTML
(http://www.ibm.com/developerworks/xml/library/x-futhtml1/). Il 27 ottobre 2006 in un post sul proprio blog intitolato Reinventing HTML
(http://dig.csail.mit.edu/breadcrumbs/archive/2006/10/27), TimBerners-Lee annuncia la volont di creare un nuovo gruppo di ricerca che strizzi l'occhio al WHAT e
ammette alcuni sbagli commessi seguendo la filosofia XHTML2:
Some things are clearer with hindsight of several years. It is necessary to evolve HTML incrementally. The attempt to get the world to switch to XML,
including quotes around attribute values and slashes in empty tags and namespaces all at once didn't work. The large HTML-generating public did not move,
largely because the browsers didn't complain. Some large communities did shift and are enjoying the fruits of well-formed systems, but not all. It is important
to maintain HTML incrementally, as well as continuing a transition to well- formed world, and developing more power in that world. TimBerners-Lee.
Dovranno passare quasi altri due anni di competizione tra le due specifiche, questa volta entrambe interne al W3C, prima che nel luglio del 2009 lo stesso Timsancisca di
non voler riconfermare il gruppo XHTML2 per l'anno successivo preferendo di fatto la direzione intrapresa dall'HTML5. Frattanto il gruppo di ricerca, formato da una
commistione di elementi del W3C e del WHAT, sotto la guida di Ian Hickson, giunto alla 4 versione delle specifiche (http://www.whatwg.org/specs/web-apps/current-
work/multipage/).
Nonostante il continuo e solerte lavoro e il grande intervallo di tempo speso nella stesura di questo documento, i passi residui necessari ad eleggere questa tecnologia al
rango di 'W3C Reccomandation', relegandola cos tra gli standard riconosciuti, sono ancora molti, al punto che si prevede di raggiungere l'agognato traguardo soltanto
attorno al 2020.
Ricordiamo per che il consorzio si riferisce sempre all'intero universo inscritto nelle specifiche mentre alcune feature ritenute peculiari ed importanti, ad esempio il tag
<vi deo>, sono gi implementate da tempo dalla totalit (o quasi) dei browser in commercio.
Che cos' l'HTML5?
Domanda semplice solo all'apparenza; siamo sicuramente di fronte alla quinta revisione delle specifiche HTML ma anche di un vastissimo elenco di funzionalit che si
sviluppano attorno al tema del linguaggio di markup: cerchiamo quindi di fare un po' di ordine.
Per prima cosa importante ricordare che, anche in virt della storia della sua nascita, all'interno dell'HTML5 convivono in armonia due anime: la prima, che raccoglie
l'eredit semantica dell'XHTML2, e la seconda che invece deriva dallo sforzo di aiutare lo sviluppo di applicazioni Web. Il risultato di questo mix di intenti pi articolato
di quanto si immagini; in prima istanza si assiste ad una evoluzione del modello di markup, che non solo si amplia per accogliere nuovi elementi, ma modifica in modo
sensibile anche le basi della propria sintassi e le regole per la disposizione dei contenuti sulla pagina. A questo segue un rinvigorimento delle API JavaScript che
vengono estese per supportare tutte le funzionalit di cui una applicazione moderna potrebbe aver bisogno:
z salvare informazioni sul device dell'utente;
z accedere all'applicazione anche in assenza di una connessione Web;
z comunicare in modo bidirezionale sia con il server sia con altre applicazioni;
z eseguire operazioni in background;
z pilotare flussi multimediali (video, audio);
z editare contenuti anche complessi, come documenti di testo;
z pilotare lo storico della navigazione;
z usare metafore di interazione tipiche di applicazioni desktop, come il drag and drop;
z generare grafica 2D in tempo reale;
z generare grafica 3D in tempo reale;
z accedere e manipolare informazioni generate in tempo reale dallutente attraverso sensori multimediali quali microfono e webcam.
Anche l'aspetto semantico a contorno del markup non dimenticato; ecco quindi nascere le specifiche per la nuova generazione di microformati e per l'integrazione tra
HTML5 e RDFa. Ma non tutto, attorno a quello che pu essere definito il nucleo autentico delle specifiche gravitano tutta una serie di altre iniziative, alcune delle quali
in avanzato stato di definizione, studiate per:
z accedere alle informazioni geografiche del device dell'utente (posizione, orientamento,...);
z mantenere un database sul device dell'utente;
z generare grafica 3D in tempo reale;
E non dimentichiamo che l'evoluzione dell'HTML viaggia di pari passo con quella dei CSS, che si avvicinano alla terza versione, e di altri importanti standard come SVG
e MathML, e che ognuno di questi componenti progettato nella sua versione pi recente per recare e ricevere beneficio dagli altri.
Perch dovremmo passare all'HTML5?
Il panorama di Internet cambiato molto dall'assunzione a 'W3C Reccomandation' della versione precedente delle specifiche, avvenuta verso la fine del 1999. In quel
tempo il Web era strettamente legato al concetto di ipertesto e l'azione pi comune per l'utente era la fruizionedi contenuti, tipicamente in forma testuale. La
mediamente bassa velocit di connessione e il limitato investimento sul media contribuivano ad una scarsa presenza di applicazioni web, pi care da sviluppare ed esigenti
in termini di banda.
Tutto questo era ben rappresentato da un linguaggio, HTML, principalmente orientato ad agevolare la stesura di semplici documenti testuali collegati fra loro. Negli
anni successivi l'interesse intorno alla rete ha subito una brusca accelerazione e questo ha condizionato positivamente sia la diffusione che la velocit di connessione della
stessa, attirando di conseguenza maggiori investimenti e ricerca. Al modello di fruizione dei contenuti si aggiunta la possibilit per l'utente finale di divenire esso stesso
creatore attraverso applicazioni web sempre pi elaborate ed interessanti.
Questo nuovo livello di complessit, in termini di sviluppo, ha per dovuto scontrarsi con un set di specifiche poco inclini ad essere utilizzate per tali fini e che quindi si
sono prestate al compito solo a scapito di infiniti hack e workaround. Esempi di questi 'utilizzi non premeditati' dell'HTML si possono trovare un po' ovunque, famoso il
caso degli attributi r el e r ef che hanno assunto nel tempo valori non previsti, (eg: nof ol l ow) anche esterni alla loro funzione naturale (eg: l'utilizzo di questi due attributi
in librerie come Lightbox).
Parallelamente il percorso di crescita del web ha fatto emergere alcune strutture di contenuto ricorrenti, ben caratterizzate dal fenomeno dei blog: informazioni di
testata, menu di navigazione, elenchi di articoli, testo a pie' di pagina, ed altri. La parte dedicata al singolo articolo presenta anch'essa solitamente lo stesso set di
informazioni quali autore, data di pubblicazione, titolo e corpo del messaggio. Anche in questo caso l'HTML4 non ha saputo fornire gli strumenti adatti a consentire una
corretta gestione e classificazione del contenuto obbligando gli sviluppatori web a ripiegare su strutture anonime, quali <di v>e <p>, arricchite di valore semantico con
l'utilizzo di attributi quali cl ass e i d.
L'HTML5 nasce per risolvere questi problemi offrendo agli sviluppatori web un linguaggio pronto ad essere plasmato secondo le pi recenti necessit, sia dal lato
della strutturazione del contenuto che da quello dello sviluppo di vere e proprie applicazioni.
Grandi cambiamenti nell'ombra
La differenza principale tra le versioni correnti di HTML e XHTML risiede nella sintassi. Il linguaggio di markup creato da TimBerners-Lee, e che ancora oggi popola i
nostri browser, stato studiato come applicazione del pi generico SGML, Standard Generalized Markup Language; ne la prova la dichiarazione di Document
Definition Type che dovrebbe essere posta nella prima riga di una pagina Web ad indicare la grammatica, HTML per l'appunto, usata nel documento:
<! DOCTYPE HTML PUBLI C " - / / W3C/ / DTD HTML 4. 01/ / EN" " ht t p: / / www. w3. or g/ TR/ ht ml 4/ st r i ct . dt d" >
In realt la quasi totalit dei browser ignora la definizione e interpreta il documento secondo logiche pi permissive, frutto di anni di eccezioni e di esperienza accumulata
su pagine malformate. L'XHTML, invece, una versione della sintassi HTML costretta all'interno delle regole XML, a sua volta grammatica SGML: questo approccio
dovrebbe implicare un maggior rigore nella pagina e l'aderenza a regole quali l'obbligo di chiusura di tutti i tag. Il parser XML inoltre dovrebbe sospendere
l'interpretazione della pagina al primo errore rilevato.
L'arrivo dell'HTML5 introduce una importante novit in questo scenario, per la prima volta l'obiettivo delle specifiche quello di definire un linguaggio ubiquo, che
possa poi essere implementato su entrambe le sintassi. L'occasione buona anche per fare un po' di pulizia e rompere definitivamente il legame tra HTML e SGML
formalizzando e traducendo in standard le regole adottate da tempo nei browser. Per indicare un documento HTML5 nata quindi la seguente semplice istruzione:
<! DOCTYPE ht ml >
Che si affianca a quella da utilizzare in caso si intenda scrivere una pagina XHTML5:
<ht ml xml ns=" ht t p: / / www. w3. or g/ 1999/ xht ml " xml : l ang=" en" >
E adesso?
Questa lezione aveva l'obiettivo di fornire un contesto storico e operativo ai temi dei quali questa guida tratter in modo approfondito. Nelle prossime lezioni affronteremo
in sequenza prima la parte legata al markup ed alla gestione della disposizione del contenuto e successivamente le principali API introdotte da queste specifiche. Il viaggio
all'interno dell'universo dell'HTML5 appena iniziato!
La sintassi di HTML5
Prima di scendere nei dettagli presentando i nuovi elementi e le nuove API definite nella specifica, necessario spendere qualche momento per parlare delle regole
sintattiche introdotte dallHTML5, per larga misura ereditate e razionalizzate dalla precedente versione delle specifiche. In primo luogo familiarizziamo con il concetto
noto di tag. Esistono tre distinte versioni di questa particella, ognuna di esse si applica selettivamente solo ad alcuni elementi:
Tag cl assi co
<p> bl a bl a bl a bl a . . . </ p>
Tag vuot o
<i mg sr c=" i mmagi ne_i nt er essant e. j pg" al t =" Una i mmagi ne i nt er essant e" >
Tag aut ochi udent e
<r ect x=" 150" y=" 40" wi dt h=" 60" hei ght =" 30" f i l l =" bl ack" st r oke=" bl ack" / >
Gli elementi HTML5 si possono dividere in tre categorie sulla base della tipologia di tag da usare per implementarli.
1. Elementi normali: sono quelli che possono racchiudere dei contenuti sotto forma di testo, commenti HTML, altri elementi HTML, etc. Sono elementi normali, dunque,
i paragrafi (<p>), le liste (<ul >), i titoli (<h1>), etc. Salvo specifici casi, cui accenneremo nel seguito della lezione, gli elementi normali vengono definiti attraverso un tag
di apertura (<p>) e un tag di chiusura (</ p>).
2. Elementi vuoti: gli elementi vuoti sono quelli che non possono avere alcun contenuto. Per questi elementi si utilizza un tag vuoto. Essi sono: ar ea, base, br , col ,
command, embed, hr , i mg, i nput , keygen, l i nk, met a, par am, sour ce, t r ack, wbr .
Per gli elementi vuoti, la chiusura del tag, obbligatoria in XHTML, invece opzionale. Possiamo dunque definire un tag <i mg>secondo le regole XHTML:
<i mg sr c=" i mmagi ne. png" al t =" t est o" / >
O seguendo la vecchie regole di HTML 4:
<i mg sr c=" i mmagi ne. png" al t =" t est o" >
3. Elementi provenienti da altri namespace: per questi elementi sono richiesti i tag autochiudenti. Si tratta degli elementi adottati da specifiche esterne, come SVG e
MathML.
Maiuscolo, minuscolo
Una delle differenze principali rispetto alle regole XHTML riguarda l'uso del maiuscolo e del minuscolo per definire un tag. In XHTML obbligatorio usare il minuscolo.
In HTML5 consentito scrivere un tag usando anche il maiuscolo:
<I MG sr c=" i mmagi ne. png" al t =" t est o" >
Casi particolari
Esistono alcune casistiche per le quali un tag classico pu mancare della sua particella di apertura o di chiusura; questo succede quando il browser comunque in grado di
determinare i limiti di operativit dellelemento. Gli esempi pi eclatanti riguardano i tag contenitori, come head, body e ht ml , che possono essere omessi in toto a meno
che non contengano un commento o del testo come istruzione successiva. quindi sintatticamente corretto scrivere un documento come segue:
<met a char set =" ut f - 8" >
<t i t l e>Pagi na HTML5 Val i da</ t i t l e>
<p>Un par agr af o pu non aver e l a par t i cel l a di chi usur a
<ol >
<l i >e anche un el ement o di l i st a
</ ol >
Notiamo che, come mostrato nellesempio, anche i tag p e l i possono essere scritti omettendo la particella di chiusura, a patto che lelemento successivo sia allinterno di
una cerchia di elementi definita dalle specifiche. A fronte di queste opzioni di semplificazione per errato pensare che la pagina generata dal codice di cui sopra manchi,
ad esempio, dellelemento ht ml ; esso infatti dichiarato implicitamente ed inserito a runtime dallo user-agent.
Per un quadro dettagliato rimandiamo a questa sezione (http://www.w3.org/TR/html5/syntax.html#optional-tags) delle specifiche.
Attributi
Anche rispetto alle definizione degli attributi HTML5 consente una libert maggiore rispetto a XHTML, segnando di fatto un ritorno alla filosofia di HTML 4. In sintesi:
non pi obbligatorio racchiudere i valori degli attributi tra virgolette.
I casi previsti nella specifica sono 4.
Attributi 'vuoti': non necessario definire un valore per l'attributo, basta il nome, il valore si ricava implicitamente dalla stringa vuota. Un caso da manuale:
Secondo l e r egol e XHTML:
<i nput checked=" checked" / >
I n HTML5:
<i nput checked>
Attributi senza virgolette: perfettamente lecito in HTML5 definire un attributo senza racchiudere il valore tra virgolette. Esempio:
<di v cl ass=t est at a>
Attributi con apostrofo: il valore di un attributo pu essere racchiuso tra due apostrofi (termine pi corretto rispetto a 'virgoletta singola'). Esempio:
<di v cl ass=' t est at a' >
Attributi con virgolette: per concludere, possibile usare la sintassi che prevede l'uso delle virgolette per racchiudere il valore di un attributo. Il codice:
<di v cl ass=" t est at a" >
Semplificazioni
In direzione della semplificazione vanno anche altre indicazioni. Ci soffermiamo su quelle riguardanti due elementi fondamentali come st yl e e scr i pt . La sintassi tipica
di XHTML prevede la specificazione di attributi accessori come t ype:
<st yl e t ype=" t ext / css" > r egol e CSS. . . </ st yl e>
<scr i pt t ype=" t ext / j avascr i pt " sr c=" scr i pt . j s" > </ scr i pt >
In HTML5 possiamo farne a meno, scrivendo dunque:
<st yl e> r egol e CSS. . . </ st yl e>
<scr i pt sr c=" scr i pt . j s" > </ scr i pt >
Conclusioni
Come abbiamo sperimentato, la sintassi HTML5 si caratterizza per una spiccata flessibilit e semplicit di implementazione. Le osservazioni che abbiamo snocciolato in
questa lezione sono chiaramente valide a patto di implementare la serializzazione HTML; ricordiamo infatti che le specifiche prevedono anche lutilizzo di una sintassi
XML attraverso luso delle istruzioni:
<! doct ype ht ml >
<ht ml xml ns=" ht t p: / / www. w3. or g/ 1999/ xht ml " xml : l ang=" en" >
Infine, per una migliore leggibilit del codice sorgente, consigliamo di ricorrere il meno possibile allutilizzo di elementi impliciti, scrivendo sempre tutti i tag necessari
nella loro forma completa.
Elementi disegnati per un web moderno
Allinizio erano tabelle; ricordiamo tutti bene il tedio provocato dal dover costruire strutture complesse spezzandole allinterno di una griglia fatta da infiniti <t r >e <t d>:
un attivit noiosa, resa ancora peggiore dalla scarsa qualit e flessibilit del risultato. Poi arrivarono i <di v>e fu una vera e propria rivelazione; finalmente un modello di
costruzione del documento pensato per separare in modo chiaro i contenuti tipici di una pagina web. Grazie alla commistione tra questo elemento e i CSS nacquero pagine
con codici HTML eleganti e leggibili come:
<ht ml >
<head>
</ head>
<body>
<di v i d=" header " >
- - - Ti t ol o e Test at a - - -
</ di v>
<di v i d=" body" >
<di v i d=" menu" >
- - - Voci di Menu - - -
</ di v>
<di v i d=" mai n_cont ent " >
<di v cl ass=" post " >
- - - Un Post - - -
</ di v>
<di v cl ass=" post " >
- - - Un al t r o Post - - -
</ di v>
</ di v>
</ di v>
</ body>
</ ht ml >
Allinterno di un costrutto come questo tutto molto semplice da interpretare: basta seguire il flusso dei rientri di pagina facendosi guidare dai valori semantici attribuiti a
i d e cl ass.
Passarono anni e il modello cominci a mostrare le sue prime debolezze; in primo luogo ci si accorse che da un lato non vi era una regola collettiva e quello che per uno
sviluppatore era body per laltro poteva benissimo essere corpo; inoltre si realizz che n il browser n tantomeno i motori di ricerca avrebbero mai potuto beneficiare
di questa divisione semantica, proprio per colpa di quellarbitrariet che permetteva a milioni di siti web di essere organizzati in strutture simili ma sempre leggermente
diverse tra loro e per questo non raggruppabili secondo schemi automatici. Emerse in questo modo uno dei pi grandi problemi dellHTML4: lincapacit di descrivere il
significato delle informazioni di una pagina web in un formato interpretabile da altri software. In un mondo sempre pi caratterizzato dallinterconnessione e
dallaggregazione su base semantica dei contenuti ci si adatt inventando e condividendo convenzioni studiate per rappresentare eventi di calendario, persone e
quantaltro; nacquero cos diversi microformati, come ad esempio hRecipe (http://microformats.org/wiki/hrecipe) per le ricette:
<span cl ass=" hr eci pe" >
<span cl ass=" f n" >Ti sana al l a l i qui r i zi a</ span>
<span cl ass=" i ngr edi ent " >2 cucchi ai di Zuccher o</ span>
<span cl ass=" i ngr edi ent " >20g Radi ce di l i qui r i zi a</ span>
<span cl ass=" yi el d" >2</ span>
<span cl ass=" i nst r uct i ons" >
Scal dar e un pent ol i no con 200cl d acqua f i no a 95C;
ver sar e l a r adi ce di l i qui r i zi a;
l asci ar macer ar e per 7 mi nut i ;
zuccher ar e e ser vi r e.
</ span>
<span cl ass=" dur at i on" >
<span cl ass=" val ue- t i t l e" t i t l e=" PT90M" ></ span> 90 mi n
</ span>
</ span>
LHTML5 nasce per gestire ed incanalare tutte queste problematiche; nelle prossime lezioni scopriremo come beneficiare di nuovi tag disegnati appositamente per le pi
comuni strutture di contenuto e di attributi utilizzabili per definire ulteriore contenuto semantico alle pagine. Ma per arrivare a questo prima serve fare un po di pulizia...
Elementi e attributi non pi previsti nelle specifiche
Le specifiche HTML5 (http://dev.w3.org/html5/spec/Overview.html) sanciscono definitivamente la fine di tutta una serie di elementi e attributi che mantengono
validit formale solo per preservare la retrocompatibilit di pagine datate ma sono espressamente vietati nella creazione di nuovi documenti.
I primi a subire questo esilio sono tutti quei costrutti funzionali alla parte di presentazione e caduti ampiamente in disuso con lintroduzione dei fogli di stile. Stiamo
parlando di elementi come: basef ont , bi g, cent er , f ont , s, st r i ke, t t e u.
Ad essi si aggiunge una moltitudine di attributi pi o meno noti, tra i quali ricordiamo: al i gn e val i gn, backgr ound, bgcol or , cel l paddi ng, bor der , cel l spaci ng e
molti altri. In realt alcuni tra i citati perdurano solamente su specifici elementi, per una lista completa ed esaustiva consigliamo di visionare questa pagina del W3C
(http://www.w3.org/TR/html5-diff/#absent-attributes) dedicata al tema.
Interessante notare come si sia deciso invece di mantenere elementi come i e b; trasformandoli, per, da modificatori tipografici a semplici indicatori di porzioni di testo
particolari e consentendone luso solo come ultima risorsa.
La falce della semplificazione si successivamente abbattuta su un piccolo elenco di elementi obsoleti: acr onym(sostituibile dal pi comune abbr ), appl et (rimpiazzato
da obj ect ), i si ndex (gi arcaico in HTML4) e infine di r , sfavorito nel confronto con ul .
Cadono, infine, anche tutti i tag che gravitano intorno al concetto dei frame, ritenuti dannosi per usabilit e accessibilit: f r ame, f r ameset e nof r ames.
E con questi ultimi si chiude la lista degli elementi soppressi; in loro onore terminiamo la lezione con un piccolo snippet che li omaggi:
<cent er >
<f ont col or =" bl ue" si ze=" 2" >
<bi g>Addi o</ bi g>,
<s>mont i sor gent i dal l ' acque, ed el evat i al ci el o;
ci me</ s> el ement i di mar kup i nugual i ,
not i a chi cr esci ut o t r a voi ,
e i mpr essi nel l a sua ment e,
non meno che l o si a l ' aspet t o de' suoi pi f ami l i ar i .
</ f ont >
Li ber ament e adat t at o da: <acr onymt i t l e=" I Pr omessi Sposi " >I PS</ acr onym>
</ cent er >
Attributi globali
Di attributi globali (quelli cio che si possono applicare a tutti gli elementi HTML) ce ne sono sempre stati: basti pensare al classico i d , disponibile da sempre sulla
totalit degli elementi. HTML5 formalizza questa definizione e arricchisce lo sparuto gruppo con nuovi membri che, come intuibile, possono essere applicati a un qualsiasi
tag di queste specifiche. In questo capitolo dedicheremo qualche paragrafo ad ognuno dei nuovi arrivati, alcuni dei quali, vedrete, sono decisamente interessanti.
Modificare il contenuto di una pagina: contenteditable
TinyMCE, CKEditor e WYMeditor sono solo tre di una lunga lista di librerie studiate per offrire uno strumento di editing testuale su web che superi le classiche textarea. I
risultati sono gi ad oggi eccellenti, vicini a prodotti desktop come Microsoft Word, ma le soluzioni implementate fanno tutte uso di escamotage pi o meno furbi per
ottenere questo livello di interazione in quanto lHTML 4 non prevede alcun modo esplicito di generare controlli del genere.
Durante la stesura delle specifiche HTML5 questo problema stato affrontato e si deciso di sviluppare un approccio comune al rich-editing di un documento re-
introducendo un set di specifiche implementate in sordina da Microsoft (http://msdn.microsoft.com/en-us/library/ms537837(VS.85).aspx) nella versione 5.5 di Internet
Explorer. Questo lavoro ha portato alla creazione di un nuovo attributo globale: contenteditable, che impostato a t r ue su di un qualsiasi elemento lo rende modificabile
da browser; lo stesso destino subiscono tutti gli elementi in esso contenuti a meno che non espongano un esplicito cont ent edi t abl e=f al se.
document . execCommand( ' bol d' )
Prima di passare oltre sappiate che lattributo contenteditable stato applicato con valore t r ue a allintera sezione precedente con lesclusione di questo paragrafo,
permettendovi cos di editarla e sperimentare linterazione di questa nuova interessante caratteristica! (e se selezionate del testo e cliccate qui
(javascript:document.execCommand('bold');), potrete renderlo grassetto!).
Menu contestuali associati ad un elemento: contextmenu
Lattributo globale contextmenu serve ad associare a un elemento un menu contestuale; questa forma di interazione poco comune sul web ma molto praticata sul
desktop dove, ad esempio, su di una cartella di sistema ci si aspetta di poter operare azioni quali copia, elimina e rinomina. Vediamo un esempio:
<i mg sr c=" ht t p: / / f ar m4. st at i c. f l i ckr . com/ 3623/ 3527155504_6a47f b4988_d. j pg"
cont ext menu=" i mage_menu" >
<menu t ype=" cont ext " i d=" i mage_menu" >
<command l abel =" Modi f i ca i l cont r ast o" oncl i ck=" cont r ast Di al og( ) ; " >
<command l abel =" Negat i vo" oncl i ck=" negat i vo( ) ; " >
</ menu>
Cliccando con il tasto destro del mouse sullimmagine il browser dovrebbe mostrare un menu contenente le due azioni disponibili. Purtroppo ad oggi non esiste ancora
nessuna implementazione funzionante di questa feature, che resta al momento relegata a semplice specifica.
Lattributo data-*
LHTML5 predispone la possibilit di associare ad ogni elemento che compone la pagina un numero arbitrario di attributi il cui nome pu essere definito dallutente sulla
base di esigenze personali, a patto che venga mantenuto il prefisso 'dat a- '; ad esempio:
<i mg i d=" ombr a"
cl ass=" cane"
dat a- cane- r azza=" mast i no cor so
dat a- cane- et a=" 5"
dat a- cane- col or e=" ner o"
sr c=" l a_f ot o_del _mi o_cane. j pg" >
inoltre interessante notare come queste informazioni, che arricchiscono e danno valore semantico allelemento, siano accessibili anche attraverso un comodo metodo
J avascript:
al er t ( " Ombr a ha : " + document . get El ement ByI d( " ombr a" ) . dat aset . caneEt a + " anni " ) ;
La fine del display:none in linea: hidden
Lattributo globale hidden stato introdotto per offrire unalternativa allutilizzo del predicato st yl e=" di spl ay: none" che ha subito una proliferazione incontrollata
soprattutto a seguito della diffusione di librerie Javascript come jQuery o Prototype. Un elemento marcato come hi dden deve essere considerato dallo user agent come non
rilevante e quindi non visualizzato a schermo.
Spellcheck
La quasi totalit dei browser oggi in commercio contiene un motore di verifica della sintassi grammaticale. Le specifiche HTML5 introducono un meccanismo per
abilitare o disabilitare il controllo della sintassi su porzioni della pagina modificabili dallutente. Lattributo in questione si chiama spellcheck e, quando impostato a
t r ue, ordina al browser di attivare il proprio correttore sullelemento corrente e su tutti i suoi figli.
Laddove invece non venga impostata nessuna preferenza, le specifiche prevedono che il browser utilizzi un proprio comportamento di default.
Altri attributi globali
Ci sono un paio di altri attributi globali introdotti dalle specifiche e non trattati in questa sede, dr aggabl e e ar i a- *; entrambi sottendono un discorso che si estende ben al
di l della semplice implementazione di markup e verranno trattati pi avanti nella guida.
Ma... cosa significa esattamente modificabile da browser? Che tipo di feedback visivo ci si dovrebbe aspettare? E come si comporterebbe il markup a fronte delle
modifiche? Sfortunatamente qui le specifiche non sono troppo chiare e sanciscono semplicemente che qualsiasi cosa venga concessa allutente il risultato deve comunque
restare conforme allHTML5: questa libert operativa ha prodotto comportamenti diversi da browser a browser; ad esempio c chi traduce il tasto invio comun <br >e chi
invece crea un nuovo paragrafo con <p>. Parallelamente disponibile anche un set di API utilissime (http://dev.w3.org/html5/spec/dnd.html%23execCommand) per
insistere sulla zona modificabile con comandi attivati dallesterno, come ad esempio da una toolbar. Un pulsante che volesse attivare/disattivare il grassetto sulla selezione
corrente dovrebbe invocare la seguente funzione:
Ecco comunque la lista di tutti gli attributi globali previsti dalla specifica:
accesskey, cl ass, cont ent edi t abl e, cont ext menu, di r , dr aggabl e
hi dden, i d, l ang, spel l check, st yl e, t abi ndex, t i t l e
Tabella del supporto sui browser
Conclusioni
In questa lezione abbiamo appreso che la nuova configurazione di markup dellHTML5 stata studiata per ovviare a tutti i problemi emersi in anni sviluppo di siti web e
applicazioni con la precedente versione delle specifiche. Nelle prossime lezione introdurremo il nuovo content model, pensato non pi nella forma binaria block e
inline ma articolato in una serie di modelli di comportamento complessi ed interessanti.
Attributi globali
contenteditable 5.5+3.0+3.1+ 2.0+ 9.0+
contextmenu No No No No No
data-* No No 5.0+ 6.0+ No
draggable No 3.5+5.0+ 5.0+ No
hidden No 4.0+Nightly buildNightly buildNightly build
spellcheck No 2.0+No No No
Un nuovo content model
Non pi solo div
Ecco come si potrebbe codificare lesempio della lezione precedente utilizzando i nuovi elementi messi a disposizione dallHTML5:
<! doct ype ht ml >
<ht ml l ang=" i t " >
<head>
</ head>
<body>
<header >
- - - Ti t ol o e Test at a - - -
</ header >
<nav>
- - - Voci di Menu - - -
</ nav>
<ar t i cl e>
- - - Un Post - - -
</ ar t i cl e>
<ar t i cl e>
- - - Un al t r o Post - - -
</ ar t i cl e>
</ body>
</ ht ml >
Come si pu notare, i tag introdotti hanno un nome in strettissima attinenza con il proprio contenuto; questo approccio risolve in modo elegante sia il problema
dellutilizzo dellattributo cl ass con valore semantico, sia la riconoscibilit delle singole aree del documento da parte di un browser. Ma non tutto; lintroduzione di
ar t i cl e, nav, header e altri tag che vedremo, impone anche sostanziose novit al modo in cui lo user-agent deve comportarsi nellinterpretare questi elementi.
Contenuti in una bolla di sapone
Partiamo dal seguente esempio HTML4:
<ht ml >
<body>
<h1>I di ar i di vi aggi o: </ h1>
<h2>A spasso per i l mondo al l a scoper t a di nuove cul t ur e: </ h2>
<h3>Gi r o t ur i st i co del l a Br et agna</ h3>
<p>l or emi psum. . </ p>
<h3>Al l a scoper t a del Kenya</ h3>
<p>l or emi psum. . </ p>
<h3>Cr acovi a e l a Pol oni a mi st er i osa</ h3>
<p>l or emi psum. . </ p>
<p>t ut t i i vi aggi sono compl et i di i nf or mazi oni su al ber ghi e pr ezzi </ p>
</ body>
</ ht ml >
Se lo visualizziamo avremo un risultato assolutamente strutturato come questo:
Figura 3 (click per ingrandire) - Struttura del documento
(http://www.html.it/guide/esempi/html5/imgs/lezione_5/immagine_1.png)
Supponiamo ora di voler dividere i viaggi per continente. Con il modello attuale saremmo obbligati a cambiare lelemento h3 in h4 in modo da fare spazio alla nuova
suddivisione:
<ht ml >
<body>
<h1>I di ar i di vi aggi o: </ h1>
<h2>A spasso per i l mondo al l a scoper t a di nuove cul t ur e: </ h2>
<h3>Eur opa</ h3>
<h4>Gi r o t ur i st i co del l a Br et agna</ h4>
<p>l or emi psum. . </ p>
<h4>Cr acovi a e l a Pol oni a mi st er i osa</ h4>
<p>l or emi psum. . </ p>
<h3>Af r i ca</ h3>
<h4>Al l a scoper t a del Kenya</ h4>
<p>l or emi psum. . </ p>
<p>t ut t i i vi aggi sono compl et i di i nf or mazi oni su al ber ghi e pr ezzi </ p>
</ body>
</ ht ml >
Questo accade perch la gerarchia delle intestazioni assoluta rispetto allintero documento e ogni tag <h*> tenuto a rispettarla. Nella maggior parte dei casi per questo
comportamento fastidioso in quanto molto comune avere a che fare con contenuti che, come articoli o commenti, vorremmo avessero una struttura indipendente dalla
loro posizione nella pagina. In HTML5 questo stato reso possibile definendo una nuova tipologia di content model, chiamato sectioning content, al quale
appartengono elementi come ar t i cl e e sect i on. Allinterno di tag come quelli appena citati la vita scorrecome in una bolla di sapone, quindi lutilizzo di un <h1>
considerato relativo alla sezione in cui si trova.
Riprendiamo lesempio precedente ed interpretiamolo in salsa HTML5:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>I di ar i di vi aggi o</ t i t l e>
</ head>
<body>
<header >
<hgr oup>
<h1>I di ar i di vi aggi o: </ h1>
<h2>A spasso per i l mondo al l a scoper t a di nuove cul t ur e: </ h2>
</ hgr oup>
</ header >
<sect i on>
<h1>Eur opa</ h1>
<ar t i cl e>
<h1>Gi r o t ur i st i co del l a Br et agna</ h1>
<p>l or emi psum. . </ p>
</ ar t i cl e>
<ar t i cl e>
<h1>Cr acovi a e l a Pol oni a mi st er i osa</ h1>
<p>l or emi psum. . </ p>
</ ar t i cl e>
</ sect i on>
<sect i on>
<h1>Af r i ca</ h1>
<ar t i cl e>
<h1>Al l a scoper t a del Kenya</ h1>
<p>l or emi psum. . </ p>
</ ar t i cl e>
</ sect i on>
<p>t ut t i i vi aggi sono compl et i di i nf or mazi oni su al ber ghi e pr ezzi </ p>
</ body>
</ ht ml >
Molto meglio! Ora i singoli componenti di questo documento sono atomici e possono essere spostati allinterno della pagina senza dover cambiare la loro struttura interna.
Inoltre, grazie a queste divisioni, il browser riesce a discernere perfettamente il fatto che lultimo paragrafo non appartenga al testo del viaggio in Kenia.
Diamo prova dellatomicit creando un blocco dedicato allultimo articolo inserito: Un week-end a Barcellona:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>I di ar i di vi aggi o</ t i t l e>
</ head>
<body>
<header >
<hgr oup>
<h1>I di ar i di vi aggi o: </ h1>
<h2>A spasso per i l mondo al l a scoper t a di nuove cul t ur e: </ h2>
</ hgr oup>
</ header >
<ar t i cl e>
<h1>Un week- end a Bar cel l ona</ h1>
<p>l or emi psum. . </ p>
</ ar t i cl e>
<! - - r est o del l a pagi na - - >
Anche grazie a questo content model lHTML5 introduce un nuovo e preciso algoritmo per il calcolo delloutline del documento. La vista ad outline, tipica nei software di
word processing e ancora non presente nei browser, utilissima nella navigazione dei contenuti di una pagina. Sperimentiamo questa feature installando unapposita
estensione per Chromium(https://chrome.google.com/extensions/detail/afoibpobokebhgfnknfndkgemglggomo):
Figura 4 (click per ingrandire) - Vista ad outline del documento
(http://www.html.it/guide/esempi/html5/imgs/lezione_5/immagine_2.png)
interessante notare come lalgoritmo non solo identifichi correttamente i vari livelli di profondit, ma per ognuno di essi sappia anche recuperare il titolo adeguato.
NellHTML5 vitale che il design della pagina si rispecchi in una outline ordinata e coerente, questa infatti la miglior cartina tornasole possibile in merito al corretto
utilizzo delle specifiche: ad esempio, in una prima revisione della lezione, il codice HTML precedente mancava dellelemento hgr oup, utile a raggruppare elementi che
concorrono a formare un titolo. Lerrore stato individuato e corretto proprio grazie alla visualizzazione di una outline errata:
Figura 5 (click per ingrandire) - Strutturazione corretta del documento
(http://www.html.it/guide/esempi/html5/imgs/lezione_5/immagine_3.png)
Concludiamo la trattazione di questo content model citando la presenza di alcuni elementi che, pur seguendo le linee interpretative del 'sectioning content', devono essere
ignorati dall'algoritmo di outline. Tali tag sono definiti 'sectioning roots' ed il motivo della loro esclusione legato al fatto che essi non concorrono tanto alla struttura dei
contenuti della pagina quanto all'arricchimento della stessa. Fanno parte di questo elenco elementi come: bl ockquot e, det ai l s, f i el dset , f i gur e e t d. Seppur esclusi
dall'outline del documento, nulla vieta agli appartenenti di questo gruppo di avere una propria outline interna.
Panoramica sui content model e presentazione del primo progetto guida
Lo scopo di questa lezione duplice: da un lato riallacciarsi al tema del sectioning content per offrire una visione di ampio respiro in merito alle differenti tipologie di
disposizione di contenuto offerte dall'HTML5, dall'altro iniziare la stesura del primo progetto guida.
Una panoramica completa
Esistono altri content model oltre a quelli trattati nella lezione precedente, alcuni implicitamente presenti anche nelle vecchie specifiche, altri nuovi di zecca, per una
rappresentazione grafica rimando all'ottima infografica (http://www.whatwg.org/specs/web-apps/current-work/multipage/content-models.html#kinds-of-content) dello
stesso W3C, fra l'altro realizzata usando la sintassi SVG (provate a scorrere il mouse sopra le varie aree dell'insieme).
Metadata content
Fanno parte di questa categoria tutti gli elementi utili alla definizione del documento nel suo insieme: a livello di presentazione o di funzionamento.
Tag: base, command, l i nk, met a, noscr i pt , scr i pt , st yl e, t i t l e.
Sectioning content
Ne abbiamo appena parlato: il gruppo contiene tutti quegli elementi studiati per ospitare contenuti atomici e semanticamente ordinati. importante utilizzare almeno
un appartenente alla categoria heading content allinterno di ognuno di questi tag, questo anche per non avere un outline popolato da voci senza titolo (vedi immagine).
Tag: ar t i cl e, asi de, nav, sect i on.
Figura 6 (click per ingrandire) - Visualizzazione della struttura del documento
(http://www.html.it/guide/esempi/html5/imgs/lezione_6/immagine_4.png)
Heading content
Tutti gli appartenenti a questo gruppo servono per definire titoli. Interessante notare come se la presenza di uno di questi elementi non sia associata ad un sectioning
content questo venga definito implicitamente.
Tag: h1, h2, h3, h4, h5, h6, hgr oup
Phrasing content
Incorpora il testo del documento cos come tutti i modificatori tipografici e visuali dello stesso.
Tag: a (solo se contiene phrasing content a sua volta), abbr , ar ea (se figlio di un elemento map), audi o, b, bdi , bdo, br , but t on, canvas, ci t e, code, command,
dat al i st , del (solo se contiene phrasing content a sua volta), df n, em, embed, i , i f r ame, i mg, i nput , i ns (solo se contiene phrasing content a sua volta), kbd, keygen,
l abel , map (solo se contiene phrasing content a sua volta), mar k, mat h, met er , noscr i pt , obj ect , out put , pr ogr ess, q, r uby, s, samp, scr i pt , sel ect , smal l , span,
st r ong, sub, sup, svg, t ext ar ea, t i me, var , vi deo, wbr .
Embedded content
Ne fanno parte tutti quegli elementi che, come il nome del gruppo suggerisce, incorporano nella pagina oggetti esterni.
Tag: audi o, canvas, embed, i f r ame, i mg, mat h, obj ect , svg, vi deo.
Interactive content
Questa categoria comprende tutto ci specificatamente studiato per interagire con lutente.
Tag: a, audi o (con lattributo cont r ol s presente), but t on, det ai l s, embed, i f r ame, i mg (con lattributo usemap presente), i nput (con lattributo t ype diverso da
hi dden), keygen, l abel , menu (con lattributo t ype=" t ool bar " ), obj ect (con lattributo usemap presente), sel ect , t ext ar ea, vi deo (i con lattributo cont r ol s
presente).
Come avrete notato ogni elemento pu appartenere ad uno o pi content models, anche a seconda della sua configurazione degli attributi. Oltre ai gruppi citati, che sono i
principali, va ricordato flow, che raggruppa la quasi totalit degli elementi e alcuni gruppi creati specificatamente per i controlli dei form, che vedremo pi avanti.
Progetto guida - nel tag HEAD
Cogliamo loccasione di questa panoramica alla struttura dellHTML5 per gettare le prime fondamenta del progetto guida: in questo capitolo vedremo come impostare e
strutturare il contenitore della pagina ed il tag head. Creiamo un file index.html ed iniziamo ad inserire i primi elementi:
<! doct ype ht ml >
<ht ml l ang=" i t " >
<head>
<t i t l e>We5! I l bl og del l a gui da HTML5</ t i t l e>
</ head>
</ ht ml >
Fin qui, eccezion fatta per il doct ype, nessuna differenza rispetto alla versione 4 delle specifiche; andiamo avanti aggiungendo alcuni tag met a e l i nk:
. . .
<head>
<t i t l e>We5! I l bl og del l a gui da HTML5</ t i t l e>
<l i nk r el =" st yl esheet " hr ef =" moni t or . css" medi a=" scr een" >
<l i nk r el =" st yl esheet " hr ef =" pr i nt er . css" medi a=" pr i nt " >
<l i nk r el =" st yl esheet " hr ef =" phone_l andscape. css" medi a=" scr een and ( max- devi ce- wi dt h: 480px) and ( or i ent at i on: l andscape) " >
<l i nk r el =" st yl esheet " hr ef =" phone_por t r ai t . css"
medi a=" scr een and ( max- devi ce- wi dt h: 480px) and ( or i ent at i on: por t r ai t ) " >
</ head>
. . .
Incuriositi dalla strana sintassi degli attributi medi a degli ultimi due <l i nk>? State osservando una tipica media query: il CSS viene interpretato solamente se le condizioni
dellespressione sono valutate come vere dallo user agent. Le media query, profetizzate gi nel 1999, consentono di identificare il corretto CSS per un dato device con un
incredibile livello di dettaglio, alcuni esempi:
<! - - TV con scan del l i mmagi ne pr ogr essi va - - >
<l i nk r el =" st yl esheet " hr ef =" pr ogr essi ve. css" medi a=" t v and ( scan: pr ogr essi ve) " >
<! - - St ampant i con al meno 1000dpi - - - >
<l i nk r el =" st yl esheet " hr ef =" pr i nt er . css" medi a=" pr i nt and ( mi n- r esol ut i on: 1000dpi ) " >
<! - - Ret i na di spl ay - - >
<l i nk r el =" st yl esheet " hr ef =" r et i na. css" medi a=" scr een and ( - webki t - mi n- devi ce- pi xel - r at i o: 2) " >
<! - - Devi ce monocr omat i ci ( Ki ndl e, et c. . ) - - >
<l i nk r el =" st yl esheet " hr ef =" mono. css" medi a=" scr een and ( monochr ome) " >
Bene, completiamo questo capitolo aggiungendo icone e charset:
<head>
<met a char set =" ut f - 8" >
<! - - . . gl i al t r i t ag. . - - >
<l i nk r el =" i con" hr ef =" st andar d. gi f " si zes=" 16x16" t ype=" i mage/ gi f " >
<l i nk r el =" i con" hr ef =" i phone. png" si zes=" 57x57" t ype=" i mage/ png" >
<l i nk r el =" i con" hr ef =" vect or . svg" si zes=" any" t ype=" i mage/ svg+xml " >
</ head>
Come potete notare ora possibile specificare un attributo si zes per ogni icona, in questo modo lo user agent pu liberamente scegliere quale icona abbia le dimensioni
pi adatte. Ci sono due motivi che giustificano linserimento della direttiva char set in questo progetto: in primo luogo la nuova sintassi molto pi succinta della
passata, seppur ancora valida:
<met a ht t p- equi v=" Cont ent - Type" cont ent =" t ext / ht ml ; char set =UTF- 8" >
In seconda istanza intenzione dellautore sottolineare come sussistano reali rischi di sicurezza legati allassenza di questa direttiva.
Dalla prossima lezione analizzeremo nel dettaglio i singoli elementi che concorrono alla costituzione della nuova impalcatura semantica del linguaggio.
Header
Funzioni e dati tecnici
Il tag header serve a rappresentare "un gruppo di ausili introduttivi o di navigazione". Tale definizione, seppure apparentemente vaga, contiene in s i concetti chiave per
comprendere appieno la funzione di questo tag:
1. L'elemento <header > un contenitore per altri elementi.
2. L'elemento <header >non va confuso con quella che la testata/intestazione principale di un documento (quella che oggi si definisce in genere con il tag <h1>).
3. La natura e gli scopi dell'elemento <header >non dipendono dalla sua posizione nel documento, ma dai suoi contenuti (ausili alla navigazione o elementi
introduttivi).
4. Il suo uso non obbligatorio e in alcuni casi pu risultare superfluo se non utilizzato in maniera appropriata.
<header >
<h1>Quest o un t i t ol o</ h1>
<h2>Quest o un sot t o- t i t ol o</ h2>
[ . . . ]
</ header >
Header: esempi concreti
Riprendendo il nostro progetto guida, dove nella lezione precedente (http://xhtml.html.it/guide/lezione/4966/panoramica-sui-content-model-e-presentazione-del-primo-
progetto-guida/) abbiamo definito il contenuto dell'<head>:
<head>
<met a char set =" ut f - 8" >
<t i t l e> We5! I l bl og del l a gui da HTML5 </ t i t l e>
<l i nk r el =" st yl esheet " hr ef =" moni t or . css" medi a=" scr een" >
<l i nk r el =" st yl esheet " hr ef =" pr i nt er . css" medi a=" pr i nt " >
<l i nk r el =" st yl esheet " hr ef =" phone_l andscape. css"
medi a=" scr een and ( max- devi ce- wi dt h: 480px) and ( or i ent at i on: l andscape) " >
<l i nk r el =" st yl esheet " hr ef =" phone_por t r ai t . css"
medi a=" scr een and ( max- devi ce- wi dt h: 480px) and ( or i ent at i on: por t r ai t ) " >
<l i nk r el =" i con" hr ef =" st andar d. gi f " si zes=" 16x16" t ype=" i mage/ gi f " >
<l i nk r el =" appl e- t ouch- i con" hr ef =" i phone. png" si zes=" 57x57" t ype=" i mage/ png" >
<l i nk r el =" i con" hr ef =" vect or . svg" si zes=" any" t ype=" i mage/ svg+xml " >
</ head>
A questo punto possiamo iniziare a comporre il <body>del nostro documento partendo proprio con il tag <header>, che con l'elemento <hgr oup>
(http://xhtml.html.it/guide/lezione/4973/hgroup/) definisce il titolo principale del documento (del sito) e la cosiddetta tagline:
<header >
<hgr oup>
<h1>We5! I l bl og del l a gui da HTML5</ h1>
<h2>Appr of i t t i amo f i n da oggi dei vant aggi del l e speci f i che HTML5! </ h2>
</ hgr oup>
</ header >
Ma header non deve contenere necessariamente solo titoli <hn>! Se titolo e sottotitolo principali sono certamente elementi introduttivi ai contenuti successivi,
naturalmente un ausilio di navigazione una lista di link che andr a formare la barra di navigazione principale del sito. Ecco come possiamo completare la struttura del
nostro primo <header >:
<header >
<hgr oup>
<h1>We5! I l bl og del l a gui da HTML5</ h1>
<h2>Appr of i t t i amo f i n da oggi dei vant aggi del l e speci f i che HTML5! </ h2>
</ hgr oup>
<nav>
<h1>Navi gazi one: </ h1>
<ul >
<l i ><a hr ef =" / home" >Home</ a></ l i >
<l i ><a hr ef =" / about " >Gl i aut or i </ a></ l i >
<l i ><a hr ef =" / r ef act or i ng" >I l pr oget t o f our 2f i ve</ a></ l i >
<l i ><a hr ef =" / ar chi ves" >Ar chi vi o</ a></ l i >
</ ul >
</ nav>
</ header >
Nel seguente schema abbiamo realizzato graficamente ci che il codice semanticamente rappresenta nel nostro progetto:
Figura 8 - Struttura del documento: primo header
Abbiamo inserito una sezione di navigazione (http://xhtml.html.it/guide/lezione/4971/nav/) (<nav> </ nav>) introdotta da un elemento <h1>e strutturata con una lista non
ordinata.
In realt, il menu di navigazione non deve essere necessariamente inserito nell'<header >, nel nostro esempio non poteva essere fatto altrimenti ma esistono numerosi tipi
di layout in cui il menu di navigazione pu essere facilmente slegato dagli elementi introduttivi di intestazione del documento.
Il template del nostro progetto guida, lo accennavamo nelle precedenti lezioni, relativo ad un blog. Nel corpo del documento, ad un certo punto, trova posto una sezione
che ospita i contenuti principali della pagina, i post. Per definire semanticamente la sezione useremo il tag <sect i on>
(http://xhtml.html.it/guide_preview/lezione/4969/section/); ciascun post sar definito a livello strutturale da un tag <ar t i cl e>
(http://xhtml.html.it/guide_preview/lezione/4970/article/):
<sect i on>
<h1>L' ul t i mo post </ h1>
<ar t i cl e>
[ . . . ]
</ ar t i cl e>
</ sect i on>
Si noti, innanzitutto, come il tag <h1>che fa da titolo principale alla sezione non sia racchiuso in un elemento <header>. Ribadiamo: non obbligatorio inserire i titoli
<hn>all'interno di un contenitore <header >.
A questo punto, dobbiamo definire due elementi fondamentali per la struttura di un post di blog: il titolo e la data. Sono certamente ausili introduttivi, secondo la
definizione da cui siamo partiti. pi che legittimo e sensato, pertanto, racchiuderli in un tag <header>:
<sect i on>
<h1>L' ul t i mo post </ h1>
<ar t i cl e>
<header>
<time datetime="2010-11-22" pubdate>Luned 22 Novembre</time>
<h2>Nuove scoperte sul tag video!</h2>
</header>
<p>
[ . . . ]
</ p>
</ f oot er >
[ . . . ]
</ f oot er >
</ ar t i cl e>
</ sect i on>
Ecco quindi come il nostro articolo potrebbe essere rappresentato graficamente:
Figura 9 - Struttura del documento: header degli articoli
I due scenari mostrati rendono bene l'idea rispetto agli utilizzi tipici dell'elemento <header >. La specifica suggerisce come altri contesti d'uso la tavola dei contenuti di una
sezione, un formdi ricerca o i loghi pi rilevanti presenti nel documento.
Nella prossima lezione capiremo come utilizzare l'elemento <f oot er >e quale la sua rilevanza semantica all'interno di un template.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<header> 9.0+3.0+3.1+5.0+10.0+
Footer
Funzioni e dati tecnici
L'elemento <footer> deve contenere in genere informazioni sulla sezione che lo contiene come:
z i dati di chi ha scritto i contenuti;
z collegamenti ai documenti correlati;
z i dati di copyright;
z e cos via...
Riguardo il suo apporto semantico ad una pagina web sembra essere tutto chiaro, ma pi complesso il suo utilizzo a livello pratico:
z Non necessariamente deve essere inserito solo alla fine di un documento.
z Quando contiene intere sezioni, esse rappresentano: appendici, indici, note, accordi di licenza e altri contenuti del genere.
z Non introduce una nuova sezione e quindi non rilevante per l'outliner (http://it.wikipedia.org/wiki/Outliner).
z All'interno di una pagina web possono essere presenti diversi <f oot er >anche pi di uno per lo stesso elemento.
<f oot er >
<smal l >2011 Aut or e cont enut o. Desi gn by Desi gner si t o </ smal l >
</ f oot er >
Footer: esempi concreti
Riprendendo il nostro progetto guida, dopo aver definito definito il contenuto dell'<header >(http://xhtml.html.it/guide/lezione/4967/header/), possiamo vedere come il
<footer> chiuda il blog distaccandosi dalle altre sezioni in modo molto naturale, racchiudendo al proprio interno una lista che aggiunge informazioni riguardo l'autore
della pagina e la data del suo ultimo aggiornamento; infine il tag <smal l >ridefinito nella specifica dell'HTML 5 (http://www.whatwg.org/specs/web-apps/current-
work/multipage/text-level-semantics.html#the-small-element) racchiude il copyright della pagina:
<f oot er >
<dl >
<dt >Cr eat o da</ dt >
<dd><addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess></ dd>
<dt >Ul t i mo aggi or nament o</ dt >
<dd><t i me dat et i me=" 2010- 11- 23" pubdat e>Mar t ed&i gr ave; 23 Novembr e</ t i me></ dd>
<dd>
</ dl >
<smal l >Tut t i i cont enut i sono pr ot t et t i dal l a l i cenza cr eat i ve commons</ smal l >
</ f oot er >
Nel seguente schema abbiamo realizzato graficamente ci che il codice semanticamente rappresenta nel nostro progetto (figura 1):
Figura 10 - Struttura del documento: il footer principale
Cos come l'intero documento, ogni articolo del nostro blog avr un <f oot er >contenente il nome dell'autore ed altre eventuali informazioni aggiuntive:
<sect i on>
<h1>L' ul t i mo post </ h1>
<ar t i cl e>
<header >
[ . . . ]
</ header >
<p>
[ . . . ]
</ p>
<f oot er >
<dl >
<dt >aut or e: </ dt >
<dd><addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess></ dd>
<dt >cat egor i a: </ dt >
<dd><a hr ef =" cat egor i a/ mul t i medi a" >mul t i medi a</ a>, </ dd>
<dt >t ags: </ dt >
<dd><a hr ef =" t ags/ vi deo" >vi deo</ a>, </ dd>
<dd><a hr ef =" t ags/ canvas" >canvas</ a>, </ dd>
<dt >per mal i nk: </ dt >
<dd><a hr ef =" 2010/ 22/ 11/ nuove- scoper t e- sul - t ag- vi deo" >per mal i nk</ a>, </ dd>
<dt >r ank: </ dt >
<dd><met er val ue=" 3. 0" mi n=" 0. 0" max=" 5. 0" opt i mum=" 5. 0" >r anked 3/ 5</ met er ></ dd>
</ dl >
</ f oot er >
</ ar t i cl e>
</ sect i on>
da notare la scelta di inserire le informazioni riguardanti l'autore dell'articolo all'interno del tag <dl >; infatti nella specifica HTML5 questo elemento viene ridefinito
come contenitore di metadati e quindi semanticamente corretto all'interno del nostro <footer>.
Ecco quindi come il nostro articolo potrebbe essere rappresentato graficamente, tutte le informazioni contenute nel <f oot er >per comodit abbiamo deciso di chiamarle
metadati:
Figura 11 - Struttura del documento: footer degli articoli
L'elemento <f oot er >potrebbe essere inserito anche all'inizio di un documento subito dopo il <body>oppure all'apertura di un tag <ar t i cl e>
(http://xhtml.html.it/guide_preview/lezione/4970/article/) ma in questi casi non dovrebbe contenere elementi introduttivi riguardo il contenuto della sezione che lo
contiene; il suo uso in questa posizione potrebbe essere dovuto solamente a ragioni pratiche come ad esempio la duplicazione del <f oot er >in fondo alla pagina quando i
contenuti della stessa sono molto lunghi:
<body>
<f oot er >
<a hr ef =" #i ndi ce" >Tor na al l ' i ndi ce</ a>
</ f oot er >
<sect i on>
[ Cont enut i mol t o l unghi . . . ]
<sect i on>
<sect i on>
[ Cont enut i mol t o l unghi . . . ]
<sect i on>
<sect i on>
[ Cont enut i mol t o l unghi . . . ]
<sect i on>
<f oot er >
<a hr ef =" #i ndi ce" >Tor na al l ' i ndi ce</ a>
</ f oot er >
</ body>
Nella prossima lezione parleremo del tag <sect i on>e della sua importanza nel sezionare la pagina in blocchi semanticamente distinti.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<footer> 9.0+3.0+3.1+5.0+10.0+
Section
Funzioni e dati tecnici
Il tag <section>, secondo la definizione presente nella specifica HTML5, rappresenta una sezione generica di un documento o applicazione. L'elemento <sect i on>, in
questo contesto, individua un raggruppamento tematico di contenuti,ed in genere contiene un titolo introduttivo.
Vediamo quindi quali sono i punti fondamentali da ricordare riguardo il suo utilizzo:
1. l'elemento <sect i on>non deve essere utilizzato in sostituzione del <di v>per impostare graficamente la pagina; inoltre fortemente consigliato utilizzare i <di v>
anche quando risultano pi convenienti per gli script;
2. l'elemento <sect i on>non deve essere preferito all'elemento <ar t i cl e>quando i contenuti possono essere ripubblicati anche su altri siti;
3. l'elemento <sect i on>e l'elemento <ar t i cl e>non sono indipendenti ed esclusivi: possiamo avere sia un <ar t i cl e>all interno di un <sect i on>che viceversa.
<ar t i cl e>
<sect i on>
<h1>Ti t ol o 1</ h1>
<p>Test o cor r el at o al t i t ol o 1. </ p>
</ sect i on>
<sect i on>
<h1>Ti t ol o 2</ h1>
<p>Test o cor r el at o al t i t ol o 2. </ p>
</ sect i on>
</ ar t i cl e>
L'elemento <section> pu essere utilizzato in combinazione con l'attributo ci t e attraverso il quale possibile specificare l'url dalla quale si stanno riportando i contenuti.
Section: esempi concreti
Come abbiamo visto nei capitoli precedenti, il codice del nostro progetto inizia a prendere una forma pi chiara e definita: infatti, dopo aver compreso l'utilit semantica
dell'<header >(http://xhtml.html.it/guide_preview/lezione/4967/header/) e del <f oot er >(http://xhtml.html.it/guide_preview/lezione/4968/footer/), capiamo come
utilizzare l'elemento <section> all'interno del nostro blog.
Per strutturare la pagina raggruppando i contenuti correlati, in ordine decrescente incontriamo le prime due grandi macrosezioni del blog: "l'ultimo post" e "i post meno
recenti" contenuti quindi in due <sect i on>:
<sect i on>
<h1>L' ul t i mo post </ h1>
<ar t i cl e>
[ cont enut o del post . . . ]
<sect i on>
[ comment i . . . ]
</ sect i on>
</ ar t i cl e>
</ sect i on>
<sect i on>
<h1>Post meno r ecent i </ h1>
<ar t i cl e>
[ cont enut o del post . . . ]
</ ar t i cl e>
<ar t i cl e>
[ cont enut o del post . . . ]
</ ar t i cl e>
<ar t i cl e>
[ cont enut o del post . . . ]
</ ar t i cl e>
</ sect i on>
Nel seguente schema abbiamo realizzato graficamente ci che il codice semanticamente rappresenta nel nostro progetto:
Figura 12 - Struttura del documento: sezioni principali
Nel nostro progetto le <sect i on>, oltre a poter raggruppare i vari <ar t i cl e>(http://xhtml.html.it/guide_preview/lezione/4970/article/), sono presenti anche all'interno del
primo <ar t i cl e>per suddividere i commenti dal contenuto del post. La sezione dei commenti a sua volta contiene un'altra sezione contenente il formper l'inserimento di
un nuovo commento:
<ar t i cl e>
[ cont enut o del post . . . ]
<sect i on>
<ar t i cl e>
[ comment o1. . . ]
</ ar t i cl e>
<ar t i cl e>
[ comment o2. . . ]
</ ar t i cl e>
<ar t i cl e>
[ comment o3. . . ]
</ ar t i cl e>
<sect i on>
[ I nser i sci un nuovo comment o. . . ]
</ sect i on>
</ sect i on>
</ sect i on>
</ ar t i cl e>
In questo modo il post diviso in maniera molto netta rispetto ai propri contenuti solo con l'ausilio dei tag HTML5, separando quindi i commenti che sono una sezione
aggiuntiva eventualmente anche eliminabile dall'argomento principale trattato all'interno dell'articolo.
Lo schema dell'articolo analizzato quindi il seguente:
Figura 13 - Struttura del documento: suddivisione semantica del post
Il tag <section> rappresenta un elemento che viene considerato una sezione a sstante dall'outliner (http://it.wikipedia.org/wiki/Outliner) e quindi un blocco con dei
contenuti univoci che necessitano di un titolo (<hN>) che li riassuma. Come vedremo nelle prossime lezioni esistono anche altri elementi nelle specifiche HTML5 che sono
considerati "contenitori di sezionamento dei contenuti" (http://xhtml.html.it/guide_preview/lezione/4965/un-nuovo-content-model/).
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<section> 9.0+3.0+3.1+5.0+10.0+
Article
Funzioni e dati tecnici
Il tag <article> rappresenta una sezione autonoma in un documento, pagina, applicazione o sito; infatti potenzialmente ridistribuibile o riutilizzabile, e quindi
ripubblicabile in parte o interamente in diverse pagine.
Esso pu identificare il post di un forum, un articolo di una rivista o di un giornale, l'articolo di un blog, un commento, un widget interattivo, o qualsiasi cosa che abbia un
contenuto indipendente.
Prima di vedere un esempio concreto bisogna chiarire alcuni concetti riguardo il suo utilizzo:
1. quando gli elementi <ar t i cl e>sono nidificati, gli <ar t i cl e>interni rappresentano gli articoli che sono in linea di principio relativi al contenuto dell'<ar t i cl e>
esterno. Ad esempio, un blog che accetta commenti dagli utenti potrebbe rappresentarli come <ar t i cl e>figli annidati all'interno dell'elemento padre <ar t i cl e>;
2. le informazioni relative all'autore dell'<ar t i cl e>non devono essere replicate all'interno degli elementi nidificati all'interno dello stesso;
3. l'elemento <t i me>con l'attributo pubdat e pu essere utilizzato per definire la data di pubblicazione dell'<ar t i cl e>;
4. l'elemento <sect i on>e l'elemento <ar t i cl e>non sono indipendenti ed esclusivi: possiamo avere sia un <ar t i cl e>all interno di un <sect i on>che viceversa.
<ar t i cl e>
<header >
<h1>Ti t ol o ar t i col o</ h1>
<t i me pubdat e dat et i me=" 2011- 10- 09T14: 28- 08: 00" ></ t i me></ p>
</ header >
<p>Cont enut o del l ' ar t i col o</ p>
<f oot er >
<p>I nf or mazi oni r i guar do l ' aut or e</ p>
</ f oot er >
</ ar t i cl e>
In sostanza, anche se nelle specifiche non espresso, l'elemento <ar t i cl e>rappresenta una forma particolare di <sect i on>
(http://xhtml.html.it/guide_preview/lezione/4969/section/).
Article: esempi concreti
Nella lezione precedente abbiamo diviso i contenuti centrali del blog che stiamo costruendo in due <sect i on>. All'interno della prima <sect i on>possiamo trovare diversi
tag <article>: il primo che incontriamo l'articolo vero e proprio con tanto di <header >(http://xhtml.html.it/guide_preview/lezione/4967/header/) contenente il titolo
dell'articolo e la data di pubblicazione e <f oot er >che all'interno di un <dl >raccoglie i metadati riguardanti l'autore.
All'interno dell'<ar t i cl e>padre sono annidati ulteriori <ar t i cl e>contenenti i commenti all'articolo racchiusi in una <sect i on>che li rende semanticamente separati dal
contenuto principale. Cos come i commenti, anche il formche permette di inserire un'ulteriore commento inserito all'interno di una <sect i on>. Possiamo quindi
facilmente immaginare come il contenuto del nostro <ar t i cl e>possa essere citato o ripubblicato in altri blog indipendentemente dai commenti che ha ricevuto.
Ecco quindi il codice dell'<ar t i cl e>sopra descritto:
<sect i on>
<h1>L' ul t i mo post </ h1><ar t i cl e>
<header >
<t i me dat et i me=" 2010- 11- 22" pubdat e>Luned 22 Novembr e</ t i me>
<h2>Nuove scoper t e sul t ag vi deo! </ h2>
</ header >
<p>
At t r aver so un ut i l i zzo sapi ent e del t ag canvas possi bi l e l egger e uno st r eam
di dat i pr oveni ent e da un t ag vi deo e <mar k>mani pol ar l o i n t empo r eal e</ mar k>.
</ p>
<f oot er >
<dl >
<dt >aut or e: </ dt >
<dd><addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess></ dd>
<dt >cat egor i a: </ dt >
<dd><a hr ef =" cat egor i a/ mul t i medi a" >mul t i medi a</ a>, </ dd>
<dt >t ags: </ dt >
<dd><a hr ef =" t ags/ vi deo" >vi deo</ a>, </ dd>
<dd><a hr ef =" t ags/ canvas" >canvas</ a>, </ dd>
<dt >per mal i nk: </ dt >
<dd><a hr ef =" 2010/ 22/ 11/ nuove- scoper t e- sul - t ag- vi deo">per mal i nk</ a>, </ dd>
<dt >r ank: </ dt >
<dd><met er val ue=" 3. 0" mi n=" 0. 0" max=" 5. 0" opt i mum=" 5. 0" >r anked 3/ 5</ met er ></ dd>
</ dl >
</ f oot er >
<sect i on>
<h3>Comment i </ h3>
<ar t i cl e>
<h4>
<t i me dat et i me=" 2010- 11- 22" pubdat e>Luned 22 Novembr e</ t i me>
Angel o I mbel l i ha scr i t t o:
</ h4>
<p>C' un bel l ' esempi o sul l a r et e: ef f et t o ambi - l i ght ! </ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: ambel l i @mbel l . i t " >Angel o I mbel l i </ a></ addr ess>
</ f oot er >
</ ar t i cl e>
<ar t i cl e>
<h4>
<t i me dat et i me=" 2010- 11- 23" pubdat e>Mar t ed 23 Novembr e</ t i me>
Sandr o Paganot t i ha scr i t t o:
</ h4>
<p>Bel l i ssi mo! Gr azi e per l a segnal azi one! </ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess>
</ f oot er >
</ ar t i cl e>
<sect i on>
<h4>I nser i sci un nuovo comment o: </ h4>
<f or m>
[ campi f or mper i nser i r e un nuovo comment o]
</ f or m>
</ sect i on>
</ sect i on>
</ ar t i cl e>
</ sect i on>
Nel seguente schema abbiamo realizzato graficamente come si presenta il nostro articolo morfologicamente:
Figura 14 - Struttura del documento: suddivisione semantica degli articoli
C' da notare che anche se il tag <article> rappresenta un elemento che viene considerato una sezione a s stante dall'outliner (http://it.wikipedia.org/wiki/Outliner) e
quindi un blocco con dei contenuti unici e un titolo univoco (quindi per ogni blocco avremmo potuto utilizzare un titolo racchiuso in un <h1>), abbiamo preferito rispettare
comunque l'ordine decrescente per i titoli in modo da rendere i contenuti accessibili anche agli screen reader che al momento non hanno ancora implementato l'algoritmo
outliner.
Nella prossima lezione parleremo del tag <nav>e della sua fondamentale importanza all'interno di una pagina in HTML5.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<article> 9.0+3.0+3.1+5.0+10.0+
Nav
Funzioni e dati tecnici
Il tag <nav> uno degli elementi introdotti nelle specifiche HTML5 di pi facile comprensione. Infatti, rappresenta una sezione di una pagina che contiene link
(collegamenti) ad altre pagine o a parti interne dello stesso documento; quindi, in breve, una sezione contenente link di navigazione.
A questo punto potremmo potremmo porci una domanda: come mai un elemento cos scontatamente fondamentale stato introdotto solamente adesso? La risposta
potrebbe essere che, cos come per i tag visti nelle precedenti lezioni, finalmente si cercato di incentivare l'uso di standard condivisi proponendo elementi che possano
aiutare gli sviluppatori proprio perch molto vicini ai modelli mentali oramai assimilati dagli esperti e di semplice comprensione per i novizi del mestiere.
Per poter utilizzare correttamente l'elemento <nav>dobbiamo ricordare i seguenti punti:
1. solo sezioni che sono costituite da grandi blocchi di navigazione sono appropriati per l'elemento <nav>;
2. i link a pie' di pagina e le breadcumb non devono essere inseriti in una sezione <nav>;
3. l'elemento <nav>non sostituisce i link inseriti in elementi come gli <ul >o gli <ol >ma deve racchiuderli.
<nav>
<ul >
<l i >Quest o un l i nk</ l i >
<l i >Quest o un l i nk</ l i >
<l i >Quest o un l i nk</ l i >
<l i >Quest o un l i nk</ l i >
[ . . . ]
</ ul >
</ nav>
Nav: esempi concreti
Prima di spiegare in che modo l'elemento <nav> pu essere inserito nel progetto che abbiamo preso come base, riassumiamo brevemente i tag spiegati nelle lezioni
precedenti:
z Con l'elemento <header >(http://xhtml.html.it/guide_preview/lezione/4967/header/) abbiamo indicato il titolo introduttivo del blog pi i titoli dei singoli articoli.
z Con il <f oot er >(http://xhtml.html.it/guide_preview/lezione/4968/footer/) abbiamo racchiuso le informazioni relative agli autori dei contenuti, i metadati e il
copyright.
z Con l'elemento <sect i on>(http://xhtml.html.it/guide_preview/lezione/4969/section/) abbiamo strutturato la parte centrale della pagina dividendola in due sezioni
semanticamente distinte.
z Infine abbiamo utilizzato <ar t i cl e>(http://xhtml.html.it/guide_preview/lezione/4970/article/) per racchiudere i contenuti degli articoli.
A questo punto non possiamo che inserire i link presenti nell'<header >all'interno del tag <nav>:
<header >
<hgr oup>
<h1>We5! I l bl og del l a gui da HTML5</ h1>
<h2>Appr of i t t i amo f i n da oggi dei vant aggi del l e speci f i che HTML5! </ h2>
</ hgr oup>
<nav>
<h1>Navigazione:</h1>
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/about">Gli autori</a></li>
<li><a href="/refactoring">Il progetto four2five</a></li>
<li><a href="/archives">Archivio</a></li>
</ul>
</nav>
</ header >
Da notare la presenza del titolo <h1>che serve a specificare pi dettagliatamente la funzione del nostro blocco di link e a conferirgli un titolo valido anche per l'outliner. Il
tag <nav>, infatti, rappresenta un elemento che viene considerato una sezione a s stante dall'outliner (http://it.wikipedia.org/wiki/Outliner) e quindi un blocco con dei
contenuti univoci che necessitano di un titolo che li riassuma.
Nel seguente schema abbiamo realizzato graficamente ci che il codice semanticamente rappresenta nel nostro progetto:
Figira 15 - Struttura del documento: visualizzazione grafica del tag nav
In realt (come gi specificato nel paragrafo <header >) il menu di navigazione non deve essere necessariamente inserito nel <header>, nel nostro esempio non poteva
essere fatto altrimenti ma esistono numerosi tipi di layout in cui il menu di navigazione pu essere facilmente slegato dagli elementi introduttivi di intestazione del
documento.
Nel nostro esempio l'elemento <nav> presente anche nella colonna laterale del blog (<asi de>) e racchiude un menu che ha come link le categorie nelle quali sono inseriti
i vari articoli:
<asi de>
<h1>Si debar </ h1>
<sect i on>
<h2>Ri cer ca nel f or m: </ h2>
<f or m>
[ f or mdi r i cer ca dei cont enut i . . . ]
</ f or m>
</ sect i on>
<nav>
<h2>Categorie</h2>
<ul>
<li><a href="/categoria/multimedia">multimedia</a></li>
<li><a href="/categoria/text">marcatori testuali</a></li>
<li><a href="/categoria/form">forms</a></li>
</ul>
</nav>
</ asi de>
Per comprendere quale la funzione dell'elemento <asi de>che contiene il menu laterale non ci resta quindi che leggere la prossima lezione.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<nav> 9.0+3.0+3.1+5.0+10.0+
Aside
Funzioni e dati tecnici
L'elemento <aside> rappresenta una sezione di una pagina costituita da informazioni che sono marginalmente correlate al contenuto dell'elemento padre che la contiene,
quest'ultimo. Questo ci che viene indicato nelle specifiche HTML5, ma facile immaginare l'utilit del tag <asi de>semplicemente pensandolo come un contenitore di app
link, pubblicit, bookmark e cos via.
<asi de>
<h1>Quest i sono dei cont enut i di appr of ondi ment o mar gi nal i r i spet t o al cont enut o pr i nci pal e</ h1>
<nav>
<h2>Li nk a pagi ne cor r el at e al cont enut o</ h2>
<ul >
<l i >I nf or mazi one cor r el at a al cont enut o</ l i >
<l i >I nf or mazi one cor r el at a al cont enut o</ l i >
<l i >I nf or mazi one cor r el at a al cont enut o</ l i >
</ ul >
</ nav>
<sect i on>
<h2>Pubbl i ci t </ h2>
[ i mmagi ni pubbl i ci t ar i e]
<sect i on>
</ asi de>
Aside: esempi concreti
Ritornando al nostro progetto guida, dopo aver definito il contenuto dell'elemento <nav>, possiamo analizzare la parte di codice in cui abbiamo utilizzato il tag <aside>:
<asi de>
<h1>Si debar </ h1>
<sect i on>
<h2>Ri cer ca nel f or m: </ h2>
<f or mname=" r i cer ca" met hod=" post " act i on=" / sear ch" >
<l abel > Par ol a chi ave:
<i nput t ype=" sear ch" aut ocompl et e=" on" pl acehol der =" ar t i cl e, sect i on, . . . " name=" keywor d" r equi r ed
</ l abel >
<i nput t ype=" submi t " val ue=" r i cer ca" >
</ f or m>
</ sect i on>
<nav>
<h2>Cat egor i e</ h2>
<ul >
<l i ><a hr ef =" / cat egor i a/ mul t i medi a" >mul t i medi a</ a></ l i >
<l i ><a hr ef =" / cat egor i a/ t ext " >mar cat or i t est ual i </ a></ l i >
<l i ><a hr ef =" / cat egor i a/ f or m" >f or ms</ a></ l i >
</ ul >
</ nav>
</ asi de>
Nel seguente schema abbiamo realizzato graficamente ci che il codice semanticamente rappresenta nel nostro progetto:
Figura 16 - Struttura del documento: visualizzazione grafica del tag aside
Come possiamo notare, il formper la ricerca di parole chiavee i link alle categorie presenti nel nostro blog non sono informazioni particolarmente rilevanti per il contenuto cen
facilmente separarli con l'elemento <asi de>che li qualifica come contenuti marginali.
Nel nostro caso abbiamo utilizzato un <asi de>per contenere la colonna sinistra del blog, ma in realt, visto che in diversi siti va di moda la presenza di footer molto grossi con
<aside> in combinazione con il tag <nav>che potrebbe essere la soluzione migliore per questa tipologia di contenuti dato che, come abbiamo potuto constatare nella lezione de
del tag <f oot er >.
Cos come gli elementi <ar t i cl e>(http://xhtml.html.it/guide_preview/lezione/4970/article/), <sect i on>(http://xhtml.html.it/guide_preview/lezione/4969/section/) e <nav>(h
anche l'<asi de>appartiene alla categoria dei "contenitori di sezionamento dei contenuti" (http://xhtml.html.it/guide_preview/lezione/4965/un-nuovo-content-model/) in quanto
propri contenuti.
Ricordiamo per che non obbligatorio inserire un titolo per gli elementi che vengono considerati delle sezioni a s stanti dall'outliner, infatti in questo caso queste sezioni rim
errore di validazione.
Vediamo quindi ora che abbiamo completato la struttura del blog come l'outline del nostro documento Outline (esempi/outline_progetto/outline.html).
Nella prossima lezione comprenderemo come usare l'elemento <hgr oup>e la sua importanza per l'outline di un documento in HTML5.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<aside> 9.0+3.0+3.1+5.0+10.0+
Hgroup
Funzioni e dati tecnici
L'elemento <hgroup> rappresenta l'intestazione di una sezione. L'elemento viene utilizzato per raggruppare un insieme di elementi h1- h6, quando il titolo ha pi livelli, com
sottotitoli, titoli alternativi o slogan.
<hgr oup>
<h1>Quest o i l t i t ol o</ h1>
<h2>Quest o un sot t ot i t ol o</ h2>
</ hgr oup>
La vera importanza del tag <hgr oup> che maschera l'outline dell'elemento padre che lo contiene; infatti, l'algoritmo dell'outliner riconosce come un titolo solamente l'heading
il valore pi alto e considera tutti gli altri elementi sottotitoli.
Esempio:
<ar t i cl e dat et i me=" 2010- 11- 22" pubdat e >
<header >
<hgroup>
<h2>Le prospettive per il futuro del web</h2>
<h1>L'HTML 5 rivoluzioner il mondo del web</h1>
</hgroup>
</ header >
<p>Pr est o i l web sar pi eno di si t i e appl i cazi oni che sar anno i n gr ado di met t er e i n cr i si l e pi gr andi case di deskt op appl i cat i on. . . <
<f oot er >
<p>Pi nco pal l i no</ p>
</ f oot er >
</ ar t i cl e>
Se facessimo l'outline della pagina HTML contenente questo <ar t i cl e>(http://xhtml.html.it/guide_preview/lezione/4970/article/) ci restituirebbe come titolo della sezione
solamente l'<h1>contenuto nell'<hgroup> (non considerando l'<h2>anche se posto prima nel codice) poich il tag con il valore pi alto all'interno della sezione. Senza
l'elemento <hgr oup>i due titoli verrebbero considerati entrambi sullo stesso livello d'importanza come titoli dell' <ar t i cl e>.
Nella prossima lezione parleremo del tag <mar k>e della sua utilit nell'evidenziare parti particolarmente importanti del testo.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<hgroup> 9.0+3.0+3.1+5.0+10.0+
Mark
Funzioni e dati tecnici
L'elemento <mark> rappresenta una parte di un testo segnato o evidenziato all'utente a causa della sua rilevanza anche in un altri contesti. Esso, in un testo in prosa,
indica un punto culminante che non era originariamente presente, ma che stato aggiunto per attirare l'attenzione del lettore su una parte del testo che potrebbe non essere
stata considerata rilevante dall'autore originale quando il contenuto stato scritto.
Questa definizione abbastanza complessa in realt pu essere semplificata di molto chiarendoci le idee con un esempio: immaginiamo di cercare una determinata parola
chiave in diverse pagine web e che la parola che abbiamo cercato nel motore di ricerca, ci venga evidenziata all'interno della pagina che andiamo a visualizzare; ci che
abbiamo appena descritto la situazione ideale per l'utilizzo del tag <mark> poich con quest'ultimo dobbiamo racchiudere la parola ricercata segnalandola graficamente
all'utente.
<p>Senza <mar k>pl ug i n</ mar k> di t er ze par t i i l web pot r ebbe di vent ar e
per noi svi l uppat or i pi democr at i co; con l e nuove API HTML5 non abbi amo pi bi sogno
di di ver si <mar k>pl ug i n</ mar k> di t er ze par t i che si no ad or a er ano i ndi spensabi l i
per i cont enut i mul t i medi al i </ p>
Allo stato attuale non esiste un tag HTML standard utilizzato per evidenziare le parole chiave agli utenti che utilizzano i motori di ricerca per navigare: Google utilizza il
tag <em>, Bing il tag <st r ong>, Yahoo il tag <b>e cos via. Si spera che con l'introduzione dell'elemento <mar k>le cose possano cambiare.
Nella prossima lezione parleremo del tag <t i me>, un'altra delle novit dell'HTML5.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<mark> 9.0+4.0+5.0+5.0+11.0+
Time e gli attributi pubdate e datetime
Funzioni e dati tecnici
L'elemento <time> rappresenta il tempo su un orologio di 24 ore, o una data precisa nel calendario Gregoriano accompagnata opzionalmente con un orario e una
differenza di fuso orario.
Questo elemento inteso come un modo moderno per codificare le date e gli orari in maniera leggibile anche per i computer. Ad esempio, i browser saranno in grado di
offrire la possibilit di aggiungere promemoria per i compleanni o gli eventi in programma in una web application che funziona da calendario.
<p>Oggi pomer i ggi o penso che sar l per l e <t i me>15: 00</ t i me></ p>
Prima di inserire l'elemento <time> nelle nostre pagine in HTML5 dobbiamo comprendere quali sono i contesti in cui sconsigliato utilizzarlo:
z non bisogna inserire nel tag <t i me>le date che non possono essere determinate con precisione; ad esempio: "un giorno nel lontano inverno del '68","da quando
nato il primo uomo"...;
z non bisogna inserire nel tag <t i me>le date prima dell'introduzione del calendario Gregoriano.
L'elemento <time> pu possedere l'attributo pubdate che di tipo booleano; la sua presenza indica che la data presente nel tag <t i me> anche la data nella quale stato
scritto l'<ar t i cl e>(http://xhtml.html.it/guide_preview/lezione/4970/article/) padre pi vicino, e nel caso non esistesse un <ar t i cl e>padre allora essa riferita alla
creazione dei contenuti dell'intero documento.
Ovviamente un elemento che possiede l'attributo pubdat e necessita di una data. Per ciascun <ar t i cl e>pu esserci solo un singolo tag <t i me>con pubdat e e la stessa
cosa vale per l'intero documento.
Possiamo specificare in maniera pi dettagliata una data aggiungendo l'attributo datetime:
z il valore dell'attributo deve essere una "stringa valida" (http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-global-
date-and-time-string) del tipo (ANNO-MESE-GIORNO-ORE:MINUTI:SECONDI.MILLISECONDI-FUSO ORARIO).
z se l'attributo dat et i me non presente allora il contenuto testuale del'tag <t i me>deve essere una "stringa valida" (http://www.whatwg.org/specs/web-apps/current-
work/multipage/common-microsyntaxes.html#valid-global-date-and-time-string).
<t i me pubdat e dat et i me=" 2011- 01- 20" >20 Gennai o</ t i me>
Dobbiamo specificare che l'attributo pubdat e in quanto di tipo booleano pu essere inserito anche nel seguente modo:
<t i me pubdat e=" pubdat e" dat et i me=" 2011- 01- 20" >20 Gennai o</ t i me>
Nella prossima lezione vedremo in quali occorrenze utilizzare il tag <met er >.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<time> No No No No No
Meter
Funzioni e dati tecnici
L'elemento <meter> rappresenta una misura scalare all'interno di un intervallo noto, o un valore frazionario.
Il tag <met er > anche utilizzato come un indicatore di livello.
<met er val ue=" 6" max=" 8" >6 bl occhi ut i l i zzat i ( su un t ot al e di 8) </ met er >
Vediamo alcuni contesti in cui non deve essere utilizzato:
z quando indica lo stato di una barra di progresso;
z quando i valori rappresentati sono di tipo arbitrario a scalare; ad esempio non deve segnalare un peso o un'altezza a meno che non vi sia un valore massimo
riconosciuto.
Esistono 6 attributi per determinare il valore semantico dell'elemento <meter>:
1. mi n: indica il valore limite minimo disponibile;
2. max: indica il valore limite massimo disponibile;
3. val ue: indica il valore dell'elemento;
4. l ow: indica un valore che viene considerato basso;
5. hi gh: indica un valore che viene considerato alto;
6. opt i mum: indica un valore che viene considerato "ottimale"; se pi alto del valore specificato nell'attributo hi gh indica che il valore pi alto il migliore,viceversa
pi basso del valore specificato nell'attributo l owindica che il valore pi basso il migliore.
Se non specificato un valore minimo e un valore massimo questi sono di default rispettivamente 0 e 1.
Ad oggi l'unico browser che renderizza il tag <meter> Google Chrome presentandolo graficamente come una barra di progresso, quindi gli sviluppatori sono fortemente
incoraggiati a specificare il suo valore in formato testuale al suo interno.
Nella prossima lezione illustreremo come utilizzare l'elemento <pr ogr ess>e la sua utilit nel caricare i contenuti dei documenti web.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<meter> No No No 8.0+11.0+
Progress
Funzioni e dati tecnici
L'elemento <progress> rappresenta lo stato di completamento di un compito e pu essere di due tipi:
z indeterminato: indica che il compito (task) in fase di completamento, ma che non chiaro quanto ancora resta da fare prima che l'operazione sia completata (ad
esempio perch l'operazione in attesa della risposta di un host remoto);
z determinato quando possibile ricavare un numero quantificabile nel range da zero a un massimo, in modo da ottenere la percentuale di lavoro completato rispetto
al totale(ad esempio un preloader di un'immagine).
Esistono due attributi che determinano lo stato di completamento dell'attivita del tag <pr ogr ess>. L'attributo val ue, che specifica la quantit di lavoro completata, e
l'attributo max, che specifica la quantit di lavoro richiesta in totale. Le unit sono arbitrarie e non specificate.
Tuttavia, i valori passati come attributi del tag <progress> non sono renderizzati e quindi dovrebbero comunque essere inseriti in forma testuale nell'HTML in modo da
poter fornire un feedback pi preciso agli utenti; inoltre questo elemento attualmente non viene renderizzato dalla maggior parte dei browser ed quindi ancora
sconsigliato il suo utilizzo.
<sect i on>
<p>Car i cament o: <pr ogr ess i d=" mi oLoader " max=" 100" val ue=" 30" ><span>30</ span>%</ pr ogr ess></ p>
</ sect i on>
Vediamone adesso un esempio concreto in questa demo (http://www.html.it/guide/esempi/html5/esempi/lezione_progress/progress.html) (funziona nelle pi recenti
versioni di Opera e Google Chrome).
Gli attributi val ue e max, se presenti, devono essere valori validi (http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-
floating-point-number). L'attributo val ue, se presente, deve avere un valore uguale o maggiore di zero e minore o uguale al valore dell'attributo max, se presente, o 1.0, in
caso contrario. L'attributo max, se presente, deve avere un valore maggiore di zero.
Ovviamente, l'elemento <progress> deve essere utilizzato solamente per indicare lo stato in fasedi progressione di un compito; per indicare quantitativamente la misura di
un'oggetto o di uno stato non in progressione bisogna utilizzare l'elemento <met er >(http://xhtml.html.it/guide_preview/lezione/4976/meter/).
Data la complessit dell'argomento e la costante variazione delle specifiche a riguardo consigliamo di consultare il sito del WHATWG
(http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-progress-element) per un maggiore approfondimento.
Nella prossima lezione descriveremo brevemente gli altri tag semantici introdotti nella specifica HTML5.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<progress> No No No 8.0+11.0+
Altri tag
Abbiamo scelto di riassumere brevemente in un'unica lezione diversi tag in quanto il costante aggiornamento delle specifiche non ci consente di poterli descrivere
dettagliatamente, almeno sino a quando queste ultime non saranno rilasciate ufficialmente; inoltre, ne sconsigliamo l'utilizzo almeno sino a quando i browser non
inizieranno a supportarli in maniera standard.
I tag <figure> e <figcaption>
Nell'elemento <figure> possiamo racchiudere dei contenuti, opzionalmente con una didascalia (<figcaption>), che rappresentano delle singole unit indipendenti rispetto
al contenuto principale; ad esempio possiamo utilizzare l'elemento <f i gur e>per annotare le illustrazioni, schemi, foto, elenchi di codice, etc... ovvero tutto ci che fa
parte del contenuto principale ma che potrebbe essere anche allontanato dallo stesso senza intaccarne il senso.
L'elemento <f i gcapt i on>quindi rappresenta una didascalia o una leggenda per l'elemento <f i gur e>padre.
Esempio:
<f i gur e>
<i mg sr c=" benevenut i . j pg" al t =" " >
<f i gcapt i on>
Fot o di benvenut o
<smal l >Di r i t t i r i ser vat i </ smal l >
</ f i gcapt i on>
</ f i gur e>
importante notare che l'attributo al t vuoto poich l'immagine descritta nel tag <f i gcapt i on>ed stato usato il tag <smal l >per il copyright.
Il tag <embed>
L'elemento <embed> gi utilizzato da anni per inserire nel codice HTML contenuti interattivi o multimediali (tipicamente Flash, Quicktime, etc.). Questo elemento,
per, era stato deprecato nelle specifiche HTML 4 in favore del tag <obj ect >. Ora stato reintrodotto perch, nonostante la potenza delle nuove API HTML5, si pensa
che al momento non tutto ci che si riesce ad ottenere con plug-in di terze parti possa essere realizzato in HTML5. Inoltre, si cercato di mantenere la retrocompatibilit
con applicazioni basate sull'utilizzo di questo elemento.
Il tag <ruby>
Il tag <ruby> usato per specificare le annotazioni Ruby, che vengono utilizzate nella tipografia orientale in combinazione con il testo principale.
Il tag <wbr>
Il tag <wbr> definisce dove, in una parola, sarebbe opportuno aggiungere un a capo. Infatti, quando una parola lunga, utilizzando l'elemento <wbr >il browser
comprender dove eventualmente sar possibile inserire un a capo.
I tag <command> e <menu>
Entrambi sono elementi molto interessanti: permettono di definire barre degli strumenti o menu di scelta rapida per le nostre applicazioni, con le icone e i relativi comandi
che possono essere eseguiti da script.
Il tag <command> rappresenta un'azione che l'utente pu richiamare in qualche modo. Esso visibile solo se inserito all'interno di un elemento <menu>. In caso
contrario, non verr visualizzato, ma pu essere utilizzato per specificare un tasto di scelta rapida.
Al momento nessun browser supporta questi tag.
I tag <details> e <summary>
I tag <details> e <summary> rappresentano un widget informativo da cui l'utente pu ottenere informazioni supplementari o controlli aggiuntivi. Nel tag <summar y>,che
contenuto all interno del tag <det ai l s>, deve essere inserita una sintesi del contenuto del widget o anche una legenda. I contenuti dell'elemento <det ai l s>possono
essere mostrati o meno dal browser grazie all'attributo open, di tipo booleano. Anche questi tag non sono supportati ancora da nessun browser.
Il tag <keygen>
L'elemento <keygen> rappresenta un generatore di chiavi numeriche all'interno di un form. Quando si effettua l'invio di un formcontenente il tag <keygen>, la chiave
privata viene memorizzata nel keystore locale e la chiave pubblica viene confezionato e inviata al server.
L'elemento gi supportato da diversi browser ma manca il suo supporto in IE.
Il tag <output>
L'elemento <output> ci restituisce il risultato di un calcolo.
Tabella del supporto sui browser
Nuovi tag semantici e strutturali
<figure> 9.0+4.0+Nightly buildNightly build11.0+
<figcaption> 9.0+4.0+Nightly buildNightly build11.0+
<ruby> 5.5+No 5.0+ 5.0+ No
<wbr> No No No No No
<command> No No No No No
<menu> No No No No No
<details> No No No No No
<summary> No No No No No
<keygen> No 1.0+2.0+ 2.0+ 7.0+
<output> No 4.0+Nightly buildNightly build9.0+
I form in HTML5: una panoramica
Quando J avascript fu introdotto nelle pagine web, fu subito implementato per assolvere a due compiti: il rollover delle immagini e la validazione dei form.
Mentre il primo era un mero problema visuale (e in parte anche di usabilit), il secondo utlizzo comune di J avascript era necessario perch permetteva di eliminare (o per
meglio dire arginare) l'invio di formmal compilati o con errori, evitando all'utente l'attesa non necessaria tra il l'invio, l'eventuale fallita validazione dei dati inviati e il
conseguente reload della pagina.
Ovviamente nessun programmatore esperto si fida di quello che "arriva" dai form. Si rende necessario, quindi, il controllo lato server dei dati inviati. Nonostante questo,
l'implementazione di controlli client side una prassi comune.
Con HTML5 avviene per la validazione e in generale per l'interazione tramite i moduli, quello che accaduto con elementi come vi deo e audi o. La specifica introduce
funzionalit e tecniche che permettono allo sviluppatore da affidarsi unicamente al linguaggio di markup, senza dove ricorrere a J avascript o a plugin esterni.
Quello che andremo a descrivere nelle prossime lezioni era originariamente parte della specifica del WHATWG chiamata Web Form2.0
(http://www.whatwg.org/specs/web-forms/current-work/), aggiornamento della specifica del W3C denominata Web Form1.0
(http://www.w3.org/TR/html4/interact/forms.html).
Attualmente Web Form2.0 un progetto chiuso in quanto ora si lavora sulla parte dedicata ai form(http://www.whatwg.org/specs/web-apps/current-
work/multipage/forms.html) della specifica HTML5.
Lavorare con i form stato finora molto semplice: si inizia tutto con il tag <f or m>, si prosegue con gli <i nput t ype=" t ext " >, a volte con gli <i nput t ype=" passwor d" >
e magari con una <t ext ar ea>o una <sel ect >o <i nput t ype=" r adi o" >, e si finisce sempre con <i nput t ype=" submi t ">.
Questi tipi di input, per, non si adattano alla variet di dati possibilmente richiesti. Spesso ci troviamo a richiedere indirizzi e-mail, numeri di telefono, date e molti altri
tipi di dati ancora.
Non solo, ci sono anche le validazioni di consistenza derivate da questi dati, per esempio il fatto che l'indirizzo e-mail deve contenere la @ o che le date devono essere in
un formato preciso, oltre a validazioni di presenza e obbligatoriet. soprattutto a questo livello, come si accennava, che entravano in gioco J avascript e le validazioni
client side.
Tutto questo con HTML5 finisce grazie all'inserimento nella specifica di nuovi t ype come emai l , number , r ange, sear ch e di diversi nuovi attributi come pl acehol der ,
aut of ocus, r equi r e, mi n, max, etc.
Questi nuovi tipi di i nput e attributi sono molto apprezzati dalla comunit dei programmatori perch oltre a fornire un aumento dell'accessibilit dei form(anche in ambito
mobile) sono pronti per l'uso.
Non tutti funzionano perfettamente su tutti i browser, ma senza nessun hack, senza Javascript che ne controlla il funzionamento, degradano bene, anche in preistorici
browser.
Possiamo allora iniziare.
Nuovi attributi per i form: autofocus, placeholder e form
I tipi di attributi
Prima di iniziare cominciamo con il dire che esistono diversi tipi di attributi per i tag HTML. Nel particolare:
z Attributi booleani: questi tipi di attributi hanno due stati, lo stato vero e lo stato falso. Il primo rappresentato dalla presenza dell'attributo mentre il secondo, lo
stato falso, rappresentato dalla sua assenza. Il valore dell'attributo, quindi, non necessario (es. di sabl ed) anche se sono accettati comunque alcuni valori. Nello
specifico possiamo valorizzarlo con una stringa vuota (es. di sabl ed=" " ) oppure con il nome dell'attributo senza spazi iniziali o finali (es. di sabl ed=di sabl ed o
di sabl ed=" di sabl ed" ).
z Attributi enumerati: questi tipi di attributi possono prendere come valore un insieme finito di parole chiavi (es. l'attributo t ype per il tag ul pu assumere i valori
di sc, squar e e ci r cl e). A volte le parole chiave possono avere sinonimi. Una parola chiave potrebbe essere anche " " , cio il valore nullo.
z Attributi generici: questo tipo di attributo, invece, pu prendere qualsiasi valore. Esempi di questi attributi sono cl ass, i d e pl acehol der .
Dopo questa premessa vediamo subito all'opera i primi tre dei nuovi attributi per i formdefiniti in HTML5: aut of ocus, pl acehol der e f or m.
autofocus
L'attributo autofocus un attributo booleano e serve a impostare il focus su uno specifico elemento del f or mappena la pagina caricata. Un esempio canonico quello
della home page di Google: appena viene caricata il focus automaticamente impostato sul campo per la ricerca.
Ovviamente solo un elemento per pagina pu avere l'attributo aut of ocus.
Questo attributo deve essere usato con parsimonia in quanto alcuni utenti, come quelli che usano la barra spaziatrice per scorrere la pagina, potrebbero trovare questa
costrizione fastidiosa, preferendo un atteggiamento pi soft.
per questo motivo che aut of ocus dovrebbe essere usato solo nelle pagine che contengono solamente (o principalmente) f or m(come per esempio pagine di login o di
ricerca).
Esempi d'uso dell'attributo autofocus
Ecco comunque un esempio pratico:
<f or mact i on=" / " met hod=" get " >
<i nput t ype=" t ext " name=" myname" i d=" myi d" aut of ocus>
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Alternative per l'implementazione dell'attributo autofocus
Per far s che l'attributo autofocus funzioni su tutti i browser sufficiente modificare il codice in questo modo:
<f or mact i on=" / " met hod=" get " >
<i nput t ype=" t ext " name=" myname" i d=" myi d" aut of ocus >
<scr i pt >
i f ( ! ( " aut of ocus" i n document . cr eat eEl ement ( " i nput " ) ) )
{
document . get El ement ByI d( " myi d" ) . f ocus( ) ;
}
</ scr i pt >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
placeholder
Il valore dell'attributo placeholder visualizzato all'interno di un i nput , o di una t ext ar ea, fin quando il campo vuoto e non guadagna il focus (tramite il click o
spostandosi su di esso il tasto Tab).
Semanticamente l'attributo placeholder dovrebbe essere valorizzato con valori accettabili dal form, dovrebbe, in altre parole, contenere un esempio di ci che l'utente
andr a scrivere nel campo.
Spesso il pl acehol der viene utilizzato erroneamente al posto della l abel descrivendo quindi cosa dovrebbero inserire.
Esempi d'uso dell'attributo placeholder
All'interno del nostro progetto guida si fa molto uso dell'attributo pl acehol der . Per esempio:
<f or mname=" r i cer ca" met hod=" post " act i on=" / sear ch" >
<l abel > Par ol a chi ave:
<i nput t ype=" sear ch" aut ocompl et e=" on" pl acehol der =" ar t i cl e, sect i on, . . . " name=" keywor d" r equi r ed maxl engt h=" 50" >
</ l abel >
<i nput t ype=" submi t " val ue=" r i cer ca" >
</ f or m>
Creando un risultato come nella seguente immagine:
Figura 17 - Resa visiva di un input con l'attributo placeholder
Alternative per l'implementazione dell'attributo placeholder
Non sar semplice scrivere una funzione che faccia funzionare il placeholder su tutti i browser e per tutti gli input, ma data la natura dell'attributo non dovrebbe essere
nemmeno necessario.
Ad ogni modo, se volessimo farlo funzionare su tutti i browser, avremmo diverse soluzioni, alcune pi semplici altre pi complesse.
Proponiamo qui l'alternativa proposta da Andrew J anuary sul suo blog (http://www.morethannothing.co.uk/2010/01/placeholder-text-in-html5-a-js-fallback/).
Nello script placeholder.js (http://www.html.it/guide/esempi/html5/esempi/lezione_placeholder/placeholder.js) abbiamo modificato i commenti mettendoli in italiano di
modo che sia di pi facile comprensione. Per farlo funzionare si ricordi di includere la libreria jQuery nella pagina.
form
Un nuovo attributo che si pu inserire in tutti gli i nput appunto f or m, anche se sfortunatamente non molto supportato e non esiste una vera e propria alternativa.
Questo nuovo attributo serve per specificare a quale form, o a quali form, l'input fa riferimento. Richiede come valore l'i d del forma cui vogliamo che faccia
riferimento, o nel caso di pi form, gli i d separati da uno spazio, " ".
Esempi d'uso dell'attributo form
Ecco comunque un esempio pratico:
<f or mact i on=" / " met hod=" get " i d=" myFor mI d" >
<i nput t ype=" t ext " name=" myname" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
<i nput t ype=" t ext " name=" mysur name" f or m=" myFor mI d" >
Nonostante l'input con i d mysur name sia fuori dal form, inviando il forminviamo anche il suo valore grazie al suo attributo f or m.
L'uso di questo attributo sconsigliato a meno di non conoscere con certezza il browser dell'utente che utilizzar la nostra applicazione.
Alternative per l'implementazione dell'attributo form
Come detto nella descrizione dell'attributo, non c' una vera e propria alternativa. Siamo di fronte a due soluzioni:
z La prima quella di agire sul DOM e spostare gli elementi interessati all'interno del form.
z La seconda quella di assegnare una funzione al submit del formche cerchi i valori degli input interessati e per ognuno di questi inserire nel DOM degli <i nput
t ype=" hi dden" >e quindi procedere con l'invio.
Tabella del supporto sui browser
Form: nuovi attributi
autofocus No 4.0+4.0+ 2.0+ 9.0+
placeholder No 4.0+4.0+ 2.0+ 11.0+
form No 4.0+Nightly buildNightly build9.0+
Nuovi attributi dei form per la validazione
La validazione dei form forse l'argomento relativo ai formpi importante. Vediamo subito in dettaglio che cosa ci propone la nuova specifica HTML5.
required
required un attributo booleano e serve a rendere obbligatoria la compilazione dell'elemento a cui applicato. La condizione viene valutata al submit del form.
Ecco un esempio di utilizzo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Messaggi o:
<t ext ar ea name=" messaggi o" pl acehol der =" Scr i vi qui i l t uo messaggi o ( max 300 car at t er i ) " maxl engt h=" 300" r equi r ed></ t ext ar ea>
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
autocomplete
Anche se questo attributo non esattamente un attributo per le validazioni, abbiamo deciso di inserirlo in questa lezione in quanto previene un comportamento dei browser
non sempre voluto: spesso i browser riempiono i campi da inserire in maniera automatica.
Questo comportamento nella maggior parte dei casi un comportamento comodo, per in alcuni casi fastidioso. Si pensi per esempio ai campi password o ai campi del
codice della banca: probabilmente non vogliamo che il browser li completi in automatico.
Ecco che arriva in nostro soccorso l'attributo autocomplete che un attributo enumerato. In particolare i valori che accetta sono:
z on: indica che il valore non particolarmente sensibile e che il browser pu compilarlo in maniera automatica;
z off: indica che il valore particolarmente sensibile o con un tempo di scadenza (il codice di attivazione di un servizio, per esempio) e che quindi l'utente deve
inserirlo manualmente ogni volta che lo compila;
z nessun valore: indica in questo caso di usare il valore di default scelto dal browser (normalmente on).
Ecco un esempio di utilizzo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Ni ck:
<i nput t ype=" t ext " name=" ni ckname" aut ocompl et e=" on"
r equi r ed pat t er n=" [ a- z] {1}[ a- z_] {2, 19}"
t i t l e=" Un ni ckname compost o da l et t er e mi nuscol e e ' _' ; Sono consent i t i da 3 a 20 car at t er i . "
pl acehol der =" your _ni ckname" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
multiple
In molti casi abbiamo bisogno che l'utente possa inserire pi valori per lo stesso input (per esempio se gli stiamo chiedendo gli indirizzi e-mail di amici a cui inviare un
invito).
Ecco che arriva in nostro soccorso l'attributo multiple che un attributo booleano.
Un esempio di utilizzo:
<f or m>
<l abel >eMai l a cui i nvi ar e l ' i nvi t o:
<i nput t ype=" emai l " mul t i pl e name=" f r i endEmai l "
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
pattern
In molti casi abbiamo bisogno di validare un determinato input verificando che il valore inserito sottostia a determinate regole di creazione (per esempio potremmo volere
che il campo password non contenga spazi).
Possiamo contare in questi casi sull'attributo pattern.
Il valore di pat t er n, se specificato, deve essere una espressione regolare valida (http://www.ecma-international.org/publications/standards/Ecma-262.htm).
Se viene indicato l'attributo pat t er n bisognerebbe indicare anche il t i t l e per dare una descrizione del formato richiesto, altrimenti il messaggio di errore sar generico e
probabilmente di poco aiuto.
Ecco un esempio di utilizzo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Ni ck:
<i nput t ype=" t ext " name=" ni ckname" aut ocompl et e=" on"
r equi r ed pat t er n=" [ a- z] {1}[ a- z_] {2, 19}"
t i t l e=" Un ni ckname compost o da l et t er e mi nuscol e e ' _' ; Sono consent i t i da 3 a 20 car at t er i . "
pl acehol der =" your _ni ckname" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
In questo esempio si sta richiedendo che lo username sia una parola in minuscolo composta solo da lettere e da "_", di una lunghezza minima di 3 caratteri e massima di 20
e che non cominci con "_"
min e max
I valori mi n e max descrivono rispettivamente il valore minimo e massimo consentito.
Il valore di max deve essere maggiore del valore di mi n se indicato.
Questi attributi si applicano sia alle date (come det et i me (http://xhtml.html.it/guide_preview/lezione/4986/nuovi-tipi-di-input-per-la-gestione-delle-date/), dat e
(http://xhtml.html.it/guide_preview/lezione/4986/nuovi-tipi-di-input-per-la-gestione-delle-date/), mont h (http://xhtml.html.it/guide_preview/lezione/4986/nuovi-tipi-di-
input-per-la-gestione-delle-date/)) sia ai numeri (number (http://xhtml.html.it/guide_preview/lezione/4987/input-type-number/) e r ange
(http://xhtml.html.it/guide_preview/lezione/4988/input-type-range/)). Per maggiore dettagli rimandiamo alle lezioni che trattano in maniera specifica questi nuovi tipi di
input.
Ecco un esempio di utilizzo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Et :
<i nput t ype=" number " name=" age" mi n=" 13" max=" 130" st ep=" 1" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
In questo caso stiamo chiedendo un'et compresa tra i 13 e i 130 anni (estremi compresi).
step
Il valore step definisce la distanza che intercorre tra un valore e il successivo. Definisce, in altre parole, la granularit dei valori permessi.
Il valore di st ep deve essere un valore positivo non nullo.
Questo attributo si applica sia alle date (come det et i me, dat e, mont h) sia ai numeri (number e r ange).
Ecco un esempio di utilizzo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Et :
<i nput t ype=" number " name=" age" mi n=" 13" max=" 130" st ep=" 1" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
In questo caso stiamo chiedendo solo valori interi.
novalidate
Questo attributo si applica al tag f or me permette di saltare tutte le validazioni dei tag che da esso discendono.
novalidate un attributo booleano.
Ecco un esempio di utilizzo:
<f or mnoval i dat e>
<l abel >Et :
<i nput t ype=" emai l " name=" myEmai l " r equi r ed>
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
In questo caso non verr controllato che il campo emai l sia in un formato valido n che sia presente.
Tabella del supporto sui browser
Form: nuovi attributi
autocomplete No No No No 10.6+
min, max No No Nightly buildNightly build9.0+
multiple No 3.6+4.0+ 2.0+ 11.0+
pattern No 4.0+4.0+ 2.0+ 9.0+
required No 4.0+4.0+ 2.0+ 9.0+
step No No 4.0+ 2.0+ 9.0+
Input type: tel
possibile utilizzare l'elemento i nput con type=tel per creare un campo adatto all'inserimento di numeri di telefono.
A differenza degli input di tipo emai l (http://xhtml.html.it/guide_preview/lezione/4985/input-type-email/) e ur l (http://xhtml.html.it/guide_preview/lezione/4984/input-
type-url/), questo tipo non impone un particolare formato. Ci intenzionale. In pratica, i campi di numero di telefono sono campi liberi, perch, a livello intenzionale, i
numeri possono essere scritti in diversi modi. comunque possibile usare l'attributo pat t er n (http://xhtml.html.it/guide_preview/lezione/4981/nuovi-attributi-dei-form-
per-la-validazione/) per forzare un determinato formato.
I dispositivi mobili e il type tel
I dispositivi mobili possono presentare tastiere personalizzate per facilitare l'inserimento come mostrato nelle immagini che seguono (la prima relativa a iPhone/iOS,
mentre la seconda a un sistema Android).
Figura 18 - Tastiera iPhone
Figura 19 - Tastiera Android
Esempi d'uso
L'esempio molto semplice, eccolo:
<f or m>
<l abel >I nser i sci i l t uo numer o di t el ef ono:
<i nput t ype=" t el " name=" myTel ephone" >
</ l abel >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Questo codice produce visivamente un normale <i nput t ype=" t ext " >.
Tabella del supporto sui browser
Form: nuovi tipi di input
tel No 4.0+4.0+2.0+11.0+
Input type: search
possibile utilizzare l'elemento input con type=search per creare un campo di ricerca. Questo campo , ovviamente, un campo libero nel senso che non impone nessun
pattern.
Safari su Mac OS X e il type search
Nella maggior parte dei browser non c' alcuna differenza tra un campo di tipo text e un campo sear ch, ma in Safari su Mac OS X abbiamo un comportamento
particolare:
1. Visivamente l'input ha i bordi arrotondati.
2. Se scriviamo qualcosa nel campo compare una piccola X sulla destra che, se cliccata, svuota il campo.
Figura 1
Esempi d'uso
Ecco un semplice esempio per implementare questo tipo di input:
<f or mname=" r i cer ca" met hod=" post " act i on=" / sear ch" >
<l abel > Par ol a chi ave:
<i nput t ype=" sear ch" aut ocompl et e=" on" pl acehol der =" ar t i cl e, sect i on, . . . " name=" keywor d" r equi r ed maxl engt h=" 50" >
</ l abel >
<i nput t ype=" submi t " val ue=" Ri cer ca" >
</ f or m>
Come detto precedentemente, questo codice nella maggior parte dei browser produce visivamente un normale <i nput t ype=" t ext " >.
Tabella del supporto sui browser
Form: nuovi tipi di input
search No 4.0+2.0+2.0+11.0+
Input type: url
Si usa l'elemento i nput con t ype=ur l per creare un campo destinato all'inserimento di un indirizzo web.
Il tipo ur l , se specificato, dovrebbe rappresentare l'inserimento di un URL assoluto, ovvero nel formato ht t p: / / www. si t o. com/ et c. . . . Nel caso in cui il valore inserito
non sia valido, viene sollevata, nei browser che supportano il tipo ur l , un'eccezione che non riconosce il pattern.
I dispositivi mobili e il type url
I dispositivi mobili possono presentare tastiere personalizzate per facilitare l'inserimento. iPhone modifica la sua tastiera eliminando la barra spaziatrice e mettendo il
punto, la slash e l'estensione ".com" come visualizzato nella figura sottostante. Android, invece, visualizza attualmente la tastiera standard.
Figura 21 - Tastiera iPhone con un campo di tipo url
Esempi d'uso
L'esempio molto semplice, eccolo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel > Www:
<i nput t ype=" ur l " name=" ur l " aut ocompl et e=" on" pl acehol der =" ht t p: / / mywebsi t e. com" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
Produce visivamente un normale <i nput t ype=" t ext " >.
Tabella del supporto sui browser
Form: nuovi tipi di input
url No 4.0+4.0+2.0+9.0+
Input type: email
L'elemento input con type=email viene usato per creare un campo per inserire un indirizzo e-mail.
L'input con tipo emai l , se specificato, dovrebbe rappresentare l'inserimento di indirizzi e-mail. Una fondamentale condizione di validit, dunque, sar rappresentata dalla
presenza del simbolo @. Nel caso in cui il valore inserito non sia valido viene sollevata un'eccezione.
I dispositivi mobili e il type email
I dispositivi mobili possono presentare, anche in questo caso, tastiere ad hoc. iPhone modifica la sua tastiera mostrando la chiocciola e il punto come visualizzato in figura
22. Android attualmente visualizza la tastiera standard.
Figura 22 - Tastiera iPhone con un campo di tipo email
Esempi d'uso
Anche per questo tipo di input presentiamo un piccolo snippet di codice:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel > Emai l :
<i nput t ype=" emai l " name=" emai l " aut ocompl et e=" on" pl acehol der =" emai l @domai n. ext " >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
Il codice visto produce visivamente un normale <i nput t ype=" t ext " >.
Tabella del supporto sui browser
Form: nuovi tipi di input
email No 4.0+4.0+2.0+9.0+
Nuovi tipi di input per la gestione delle date
Tutti i programmatori prima o poi hanno avuto a che fare con la gestione delle date, con tutti i problemi che ne conseguono. HTML5 mette a disposizione nuovi tipi di
input concepiti per facilitare il compito dei programmatori nell'inserimento di date da parte degli utenti.
Dal momento che ci sono diversi tipi di date di cui potremmo aver bisogno, ecco che sono stati implementati nella specifica diversi tipologie. In particolare:
z datetime: gestisce sia la data che l'ora (con fuso orario);
z datetime-local: gestisce sia la data che l'ora (senza fuso orario);
z date: gestisce le date;
z month: gestisce i mesi;
z week: gestisce le settimane;
z time: gestisce l'ora.
Per tutti questi input abbiamo degli attributi specifici che sono:
z mi n: che rappresenta il minimo valore accettato;
z max: che rappresenta il massimo valore accettato;
z st ep: che rappresenta la granulosit dei valori accettati.
Vediamoli nel dettaglio.
datetime
Come detto, serve per permettere l'inserimento di date e ore in un solo colpo. Visivamente nei browser che lo supportano (pochi per ora) abbiamo la generazione di un
datepicker in cui abbiamo la possibilit di selezionare un giorno e con l'opzione di mettere anche l'ora, come nell'immagine qui sotto. Ecco cosa avviene quando
clicchiamo su quella che sembra essere una sel ect (lo screenshot di Opera 11):
Figura 23 - Input datetime su Opera
Nei sistemi che non supportato il tipo dat et i me, viene generato un normale input di testo.
Vediamo un esempio di codice
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" dat et i me" name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere una data e ora con il fuso orario valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-global-date-
and-time-string).
z max: il valore di questo attributo deve essere una data e ora con il fuso orario valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-global-date-
and-time-string) e deve essere maggiore del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere un intero e rappresenta i secondi. Il valore di default di 60 secondi.
datetime-local
del tutto simile a datetime, con l'unica differenza che non vengono passate informazioni sul fuso orario.
Ecco come appare su Opera 11:
Figura 24 - Input datetime-local su Opera
Nei sistemi che non supportato il dat et i me- l ocal viene generato un normale i nput t ype=" t ext " .
Esempio:
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" dat et i me- l ocal " name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere una data e ora valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-local-date-and-time-string).
z max: il valore di questo attributo deve essere una data e ora valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-local-date-and-time-string) e
deve essere maggiore del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere espresso in secondi. Il valore di default di 60 secondi.
date
Serve per inserire una data. Nei browser che lo supportano si ottiene un datepicker in cui abbiamo la possibilit di selezionare un giorno:
Figura 25 - Input date su Opera
Nei sistemi che non supportato il tipo dat e viene generato un normale campo di testo.
Esempio:
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" dat e" name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere una data valida(http://developers.whatwg.org/common-microsyntaxes.html#valid-date-string).
z max: il valore di questo attributo deve essere una data valida(http://developers.whatwg.org/common-microsyntaxes.html#valid-date-string) e deve essere maggiore
del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere espresso in giorni. Il valore di default di 1 giorno.
month
Serve per permettere di selezionare un mesedell'anno. In figura 4 il datepicker per selezionare un mese generato su Opera 11:
Figura 26 - Input month su Opera
Nei sistemi che non supportato mont h viene generato un normale campo di testo.
Esempio
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" mont h" name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere un mese valido (http://developers.whatwg.org/common-microsyntaxes.html#valid-month-string).
z max: il valore di questo attributo deve essere una mese valido (http://developers.whatwg.org/common-microsyntaxes.html#valid-month-string) e deve essere
maggiore del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere espresso in mesi. Il valore di default di 1 mese.
week
Viene usato per la selezione di una determinata settimana dell'anno (composta da anno - numero di settimana). In figura 5 il widget prodotto dall'inserimento di questo tipo
di input su Opera 11:
Figura 27 - Input week su Opera
Nei sistemi che non supportato week viene creato un normale campo di testo.
Esempio:
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" week" name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere una settimana valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-week-string).
z max: il valore di questo attributo deve essere una settimana valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-week-string) e deve essere
maggiore del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere espressa in settimane. Il valore di default di 1 settimana.
time
Serve per selezionare e inserire una determinata ora del giorno. Ancora una schermata da Opera 11:
Figura 28 - Input time su Opera
Nei sistemi che non supportato il t i me genera un normale i nput t ype=" t ext " .
Vediamo un esempio di codice
<f or m>
<l abel >Quando sei di sponi bi l e per un i ncont r o?
<i nput t ype=" t i me" name=" mydat et i me" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a l a f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Gli attributi specifici
z mi n: il valore di questo attributo deve essere una ora valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-time-string).
z max: il valore di questo attributo deve essere una ora valida (http://developers.whatwg.org/common-microsyntaxes.html#valid-time-string) e deve essere maggiore
del valore dell'attributo mi n se specificato.
z st ep: il valore di questo attributo deve essere espresso in secondi. Il valore di default di 60 secondi.
Tabella del supporto sui browser
Form: nuovi tipi di input
datetime No No ParzialeParziale9.0+
date No No ParzialeParziale9.0+
month No No ParzialeParziale9.0+
week No No ParzialeParziale9.0+
time No No ParzialeParziale9.0+
datetime-local No No ParzialeParziale9.0+
Input type: number
possibile utilizzare l'elemento input con type=number per creare un campo destinato all'inserimento di un numero.
I dispositivi mobili e il type number
I dispositivi mobili possono presentare tastiere personalizzate per facilitare l'inserimento come mostrato nelle immagini che seguono (fanno riferimento, rispettivamente, a
iPhone/iOS e Android).
Figura 29 - Tastiera iPhone con un input di tipo number
Figura 30 - Tastiera Android con un input di tipo number
Attributi specifici per il type number
HTML5 mette a disposizione un set di attributi specifici per i campi di tipo number . Servono a specificare delle limitazioni per il valore di questo attributo. Questi attributi
sono mi n, max e st ep.
Attributo min
Specifica il minimo valore permesso. La sintassi semplice: mi n=" 1" permette solo l'inserimento di numeri positivi. I valori permessi sono, ovviamente, numeri.
Attributo max
Specifica il massimo valore permesso. max=" 10" permette solo l'inserimento di numeri inferiori o uguali a 10. Il valore di questo attributo deve essere maggiore del valore
dell'attributo mi n (se specificato).
Attributo step
L'attributo st ep indica la granulosit che deve avere il valore, limitando i valori permessi. Il valore di st ep se specificato deve essere un numero (anche non intero)
maggiore di zero oppure la stringa "any" (che equivale a non inserire l'attributo).
La sintassi anche in questo caso molto semplice: st ep=3 influenza i valori permettendo valori come -3, 0, 3, 6 ma non -1 o 2.
Esempi d'uso
Un esempio potrebbe avere questa forma:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Et :
<i nput t ype=" number " name=" age" mi n=" 13" max=" 130" st ep=" 1" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
In questo caso stiamo chiedendo di inserire un'et compresa tra i 13 e i 130 anni (estremi compresi) e i valori accettati sono interi.
Nella maggior parte dei browser si produce attualmente un normale <i nput t ype=" t ext " >, ma nei browser che supportano number abbiamo:
Figura 31 - Un input di tipo number
Tabella del supporto sui browser
Form: nuovi tipi di input
number No No 4.0+2.0+9.0+
Input type: range
Molto simile semanticamente all'i nput t ype=number (http://xhtml.html.it/guide_preview/lezione/4987/input-type-number/), questo nuovo tipo di i nput permette agli
utenti di inserire un numero tramite uno slider.
Attributi specifici
HTML5 mette a disposizione un set di attributi specifici per il tipo range (che sono gli stessi del t ype=number ): servono a specificare delle limitazioni per il valore di
questo attributo. Questi attributi sono mi n, max e st ep.
z mi n: specifica il minimo valore permesso. Esempio: mi n=" 1" , che permette solo di passare numeri da 1 in su.
z max: specifica il massimo valore permesso. Esempio: max=" 10" , che permette solo di inviare numeri inferiori o uguali a 10. Il valore di questo attributo deve essere
maggiore del valore dell'attributo mi n (se specificato).
z st ep: indica la granulosit che deve avere il val ue limitando i possibili valori passati. Il valore di st ep se specificato deve essere un numero (anche non intero)
maggiore di zero oppure la stringa "any" (che equivale a non inserire l'attributo). Esempio: st ep=3, che influenza i valori inseriti passando valori come -3, 0, 3, 6.
Esempi d'uso
L'esempio molto semplice, eccolo:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >Vot o:
<i nput t ype=" r ange" name=" vot o" mi n=" 0" max=" 5" st ep=" 1" >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
Ecco come appare un input di tipo r ange sui browser che lo supportano:
Figura 32 - Un input di tipo range
Tabella del supporto sui browser
Form: nuovi tipi di input
range No No 4.0+2.0+9.0+
Input type: color
L'elemento input con type=color dovrebbe creare un color picker, quel tipo particolare di widget utile per la selezione di un colore a partire da una palette di colori.
Una volta selezionato il colore, il campo passa alla nostra pagina di ricezione un colore RGB esadecimale composto da 6 cifre.
Questo tipo input ad oggi non molto supportato. Per la sua implementazione sui nostri siti si pu per ricorrere ad una qualsiasi delle tante soluzioni Javascript
disponibili.
Opera e il type color
Nella maggior parte dei browser non c' alcuna differenza tra un campo di tipo text e un campo col or , ma su Opera abbiamo un comportamento particolare:
1. Visivamente abbiamo una select particolare con i colori (esempio in figura 33).
2. Se clicchiamo abbiamo una scelta dei colori base (esempio in figura 34).
3. Se clicchiamo su "Altro" richiamiamo il color picker di sistema (esempio su Opera su Mac OS X in figura 35).
Figura 33 - Input color su Opera: stato iniziale
Figura 34 - Input color su Opera: selezione del colore
Figura 35 - Input color su Opera: color-picker di sistema
Esempi d'uso
Un input di tipo col or si crea cos:
<f or m>
<l abel >Sel ezi ona i l col or e di sf ondo:
<i nput t ype=" col or " name=" mybackgr ound" >
</ l abel >
<i nput t ype=" r eset " val ue=" Reset t a l a f or m" >
<i nput t ype=" submi t " val ue=" I nvi a" >
</ f or m>
Tabella del supporto sui browser
Form: nuovi tipi di input
color No No ParzialeParziale11.0+
Cosa sono le datalist?
L'elemento HTML5 <datalist> utilizzato per fornire una funzione di "completamento automatico" ad un elemento del form. Permette, in altre parole, di fornire all'utente
un elenco di opzioni predefinite da cui scegliere, offrendo al contempo la possibilit di inserire un valore non presente inizialmente nella lista.
Mette insieme i vantaggi di una sel ect e di un i nput di testo. Sfortunatamente questo tag molto utile al momento poco supportato dai browser (solo Opera lo supporta).
Datalist su Opera
Nella maggior parte dei browser il codice relativo all'elemento datalist viene completamente ignorato ma su Opera abbiamo il seguente comportamento:
1. Visivamente abbiamo solo il nostro input e la dat al i st non renderizzata in nessun modo (figura 36).
2. Se clicchiamo sull'input a cui la dat al i st collegata, vengono presentate le opzioni della dat al i st (figura 37).
3. Se clicchiamo su un'opzione, l'input a cui la dat al i st collegato assume il valore dell'opzione (figura 38).
Figura 36 - Datalist su Opera: stato iniziale
Figura 37 - Datalist su Opera: opzioni della datalist
Figura 38 - Datalist su Opera: valorizzazione dell'opzione
Esempi d'uso
Per utilizzare datalist prima di tutto dobbiamo scrivere un input a cui collegare la nostra dat al i st . Per collegare l'input alla dat al i st basta impostare l'attributo l i st
dell'input con l'i d della dat al i st .
Per ogni suggerimento che vogliamo dare all'utente facciamo discendere da dat al i st un tag opt i on, mettendo il suggerimento nell'attributo val ue. Il value dell'opt i on
non deve essere vuoto e l'opt i on non deve essere settata su di sabl ed per essere visualizzata.
Vediamo il codice:
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
[ . . . ]
<l abel >St at o d' ani mo:
<i nput t ype=" t ext " name=" mood" pl acehol der =" f el i ce, t r i st e, i ncur i osi t o, . . . " l i st =" st at o- dani mo" >
<dat al i st i d=" st at o- dani mo" >
<opt i on val ue=" t r i st e" >
<opt i on val ue=" annoi at o" >
<opt i on val ue=" cur i oso" >
<opt i on val ue=" f el i ce" >
<opt i on val ue=" ent usi ast a! " >
</ dat al i st >
</ l abel >
[ . . . ]
<i nput t ype=" r eset " val ue=" Reset t a i l f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
Tabella del supporto sui browser
Form: nuovi tipi di input
datalist No 4.0+No No 9.0+
La potenza dei microdati
Introduzione: semantica e rich snippet
Leggendo questa guida dovrebbe essere chiaro che un punto focale di HTML5 la semantica.
HTML5 ha introdotto infatti diversi tag semantici (come header , ar t i cl e o nav) che permettono di strutturare il contenuto secondo una logica, appunto, semantica. Ma
questa suddivisione non assolve a tutte le necessit semantiche di cui il web ha bisogno.
L'obbiettivo quello di dare la possibilit a programmi come crawler dei motori di ricerca o screen reader di comprendere il significato del testo. Queste informazioni sono
accessibili da questi programmi e rimangono (attualmente) invisibili per l'utente. Entrano qui in gioco i cosiddetti microdati.
Ecco come Google li descrive, all'interno della Guida di Strumenti per i Webmaster:
"La specifica dei microdati HTML5 un modo per assegnare etichette ai contenuti al fine di descrivere un tipo specifico di informazioni (ad esempio
recensioni, informazioni su persone o eventi). Ogni tipo di informazione descrive uno specifico tipo di elemento, come una persona, un evento o una
recensione. Ad esempio, un evento ha propriet quali il luogo, l'ora di inizio, il nome e la categoria."
Attualmente, la cosa forse pi interessante relativa ai microdati in effetti uscita fuori dai laboratori di Google: si tratta dei cosiddetti rich snippet. I rich snippet sono
risultati della ricerca di Google in cui, oltre alle comuni informazioni, compaiono altri dati allegati, come nelle immagini qui sotto:
Figura 39 - Rich snippet relativo a un hotel
Figura 40 - Rich snippet con informazioni personali
I microdata in pratica
Applicare i microdati semplice: per ogni tag HTML possiamo specificare degli attributi che ci permettono di definire gli oggetti semantici.
Prima di tutto dobbiamo applicare a un elemento radice (cio un elemento che contiene tutte le informazioni che vogliamo specificare) i t emscope e i t emt ype.
i t emscope definisce l'elemento a cui applicato un contenitore dell'oggetto che andremo a descrivere.
i t emt ype definisce il vocabolario che specifica il tipo di oggetto che andremo a descrivere.
Per finire, sugli elementi che discendono dall'elemento radice specifichiamo l'attributo i t empr op che definisce la propriet che verr valorizzata con il testo contenuto nel
tag.
Ecco un esempio semplice:
<di v i t emscope i t emt ype=" ht t p: / / dat a- vocabul ar y. or g/ Per son" >My name i s
<span i t empr op=" name" >Si mone Bonat i </ span> and my ni ckname i s
<span i t empr op=" ni ckname" >svar i one</ span> on sever al si t e ( l i ke t wi t t er ) .
Her e i s my t wi t t er account :
<a hr ef =" ht t p: / / www. exampl e. com" i t empr op=" ur l " >ht t p: / / t wi t t er . com/ svar i one</ a> I l i ve i n
Mi l ano, I t al y and wor k as
<span i t empr op=" r ol e" >web devel oper </ span>.
</ di v>
Possiamo anche nidificare gli oggetti. Ecco un esempio:
<di v i t emscope i t emt ype=" ht t p: / / dat a- vocabul ar y. or g/ Per son" >My name i s
<span i t empr op=" name" >Si mone Bonat i </ span> and my ni ckname i s
<span i t empr op=" ni ckname" >svar i one</ span> on sever al si t e ( l i ke t wi t t er ) .
Her e i s my t wi t t er account :
<a hr ef =" ht t p: / / www. exampl e. com" i t empr op=" ur l " >ht t p: / / t wi t t er . com/ svar i one</ a> I l i ve i n
<span i t empr op=" addr ess" i t emscope i t emt ype=" ht t p: / / dat a- vocabul ar y. or g/ Addr ess" >
<span i t empr op=" l ocal i t y" >Mi l ano</ span>,
<span i t empr op=" count r y- name" >I t al y</ span>
</ span> and wor k as
<span i t empr op=" r ol e" >web devel oper </ span>.
</ di v>
I vocabolari
Per sfruttare al massimo la potenza dei microdati e per ottenere i rich snippet dobbiamo usare i vocabolari (che specifichiamo, come abbiamo visto, con i t emt ype)
supportati da Google.
I vocabolari descrivono l'insieme di propriet che possono essere definite per un determinato oggetto.
I vocabolari pi popolari supportati da Google sono:
z Breadcrumbs: questo vocabolario serve a rappresentare un insieme di link che pu aiutare un utente a comprendere e navigare all'interno del sito.
z Businesses and organizations: questo vocabolario definisce una societ, un negozio e pi in generale un luogo.
z People: questo vocabolario definisce una persona.
z Address: questo vocabolario definisce un indirizzo.
z Events: questo vocabolario definisce un evento (con informazioni come il titolo, la data e il luogo).
z Product: questo vocabolario definisce un prodotto.
z Offer: questo vocabolario definisce un'offerta.
z Offer-aggregate: questo vocabolario definisce un aggregato di offerte (con prezzo minimo, prezzo massimo, etc).
z Recipes: questo vocabolario definisce una ricetta.
z Review: questo vocabolario definisce una singola recensione.
z Review-aggregate: questo vocabolario definisce una recensione aggregata.
z Rating: questo vocabolario definisce una valutazione.
Link utili
Google: informazioni sui microdati (http://www.google.com/support/webmasters/bin/answer.py?hlrm=en&answer=176035)
Vocabolario Breadcumbs (http://data-vocabulary.org/Breadcrumb)
Vocabolario Businesses and Organizations (http://data-vocabulary.org/Organization)
Vocabolario People (http://data-vocabulary.org/People)
Vocabolario Address (http://data-vocabulary.org/Address)
Vocabolario Events (http://data-vocabulary.org/Event)
Vocabolario Products (http://data-vocabulary.org/Product)
Vocabolario Offer (http://data-vocabulary.org/Offer)
Vocabolario Aggregate (http://data-vocabulary.org/Offer-aggregate)
Vocabolario Recipes (http://data-vocabulary.org/Recipes)
Vocabolario Reviews (http://data-vocabulary.org/Review)
Vocabolario Review-aggregate (http://data-vocabulary.org/Review-aggregate)
Vocabolario Rating (http://data-vocabulary.org/Rating)
Un template per blog in HTML5
Terminata la disamina dei nuovi elementi semantici e strutturali introdotti con HTML5, conclusa l'analisi delle novit relative ai form, possiamo fare il punto sul nostro primo p
Quello che abbiamo preparato un template concepito per un blog che fa un uso estensivo delle nuove funzionalit. Essendoci soffermati sui dettagli essenziali nel corso dell
rapida verifica sul codice usato nella sezione comprendente il <body> sufficiente per farci apprezzare l'utilizzo dei nuovi elementi per la strutturazione dei contenuti. Ecco il l
<header >
<hgr oup>
<h1>We5! I l bl og del l a gui da HTML5</ h1>
<h2>Appr of i t t i amo f i n da oggi dei vant aggi del l e speci f i che HTML5! </ h2>
</ hgr oup>
<nav>
<h1>Navi gazi one: </ h1>
<ul >
<l i ><a hr ef =" / home" >Home</ a></ l i >
<l i ><a hr ef =" / about " >Gl i aut or i </ a></ l i >
<l i ><a hr ef =" / r ef act or i ng" >I l pr oget t o f our 2f i ve</ a></ l i >
<l i ><a hr ef =" / ar chi ves" >Ar chi vi o</ a></ l i >
</ ul >
</ nav>
</ header >
<sect i on>
<h1>L' ul t i mo post </ h1>
<ar t i cl e>
<header >
<t i me dat et i me=" 2010- 11- 22" pubdat e>Luned 22 Novembr e</ t i me>
<h2>Nuove scoper t e sul t ag vi deo! </ h2>
</ header >
<p>
At t r aver so un ut i l i zzo sapi ent e del t ag canvas possi bi l e l egger e uno st r eam
di dat i pr oveni ent e da un t ag vi deo e <mar k>mani pol ar l o i n t empo r eal e</ mar k>.
</ p>
<f oot er >
<dl >
<dt >aut or e: </ dt >
<dd><addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess></ dd>
<dt >cat egor i a: </ dt >
<dd><a hr ef =" cat egor i a/ mul t i medi a" >mul t i medi a</ a>, </ dd>
<dt >t ags: </ dt >
<dd><a hr ef =" t ags/ vi deo" >vi deo</ a>, </ dd>
<dd><a hr ef =" t ags/ canvas" >canvas</ a>, </ dd>
<dt >per mal i nk: </ dt >
<dd><a hr ef =" 2010/ 22/ 11/ nuove- scoper t e- sul - t ag- vi deo" >per mal i nk</ a>, </ dd>
<dt >r ank: </ dt >
<dd><met er val ue=" 3. 0" mi n=" 0. 0" max=" 5. 0" opt i mum=" 5. 0" >r anked 3/ 5</ met er ></ dd>
</ dl >
</ f oot er >
<sect i on>
<h3>Comment i </ h3>
<ar t i cl e>
<h4>
<t i me dat et i me=" 2010- 11- 22" pubdat e>Luned 22 Novembr e</ t i me>
Angel o I mbel l i ha scr i t t o:
</ h4>
<p>C' un bel l ' esempi o sul l a r et e: ef f et t o ambi - l i ght ! </ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: ambel l i @mbel l . i t " >Angel o I mbel l i </ a></ addr ess>
</ f oot er >
</ ar t i cl e>
<ar t i cl e>
<h4>
<t i me dat et i me=" 2010- 11- 23" pubdat e>Mar t ed 23 Novembr e</ t i me>
Sandr o Paganot t i ha scr i t t o:
</ h4>
<p>Bel l i ssi mo! Gr azi e per l a segnal azi one! </ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess>
</ f oot er >
</ ar t i cl e>
<sect i on>
<h4>I nser i sci un nuovo comment o: </ h4>
<f or mname=" comment i " met hod=" post " act i on=" / 141/ comment s" >
<f i el dset name=" dat i - ut ent e" >
<l egend>Dat i del l ' ut ent e</ l egend>
<l abel >
Ni ck:
<i nput t ype=" t ext " name=" ni ckname" aut ocompl et e=" on"
r equi r ed pat t er n=" [ a- z] {1}[ a- z_] {2, 19}"
t i t l e=" A ni ckname i s composed by l ower case l et t er s and ' _' ; 3 t o 20 char s ar e al l owed. "
pl acehol der =" your _ni ckname" >
</ l abel >
<l abel >
Emai l :
<i nput t ype=" emai l " name=" emai l " aut ocompl et e=" on" pl acehol der =" emai l @domai n. ext " >
</ l abel >
<l abel >
WWW:
<i nput t ype=" ur l " name=" ur l " aut ocompl et e=" on" pl acehol der =" ht t p: / / mywebsi t e. com" >
</ l abel >
<l abel >
Et :
<i nput t ype=" number " name=" age" mi n=" 13" max=" 130" st ep=" 1" >
</ l abel >
<l abel >
St at o d' ani mo:
<i nput t ype=" t ext " name=" mood" pl acehol der =" f el i ce, t r i st e, i ncur i osi t o, . . . " l i st =" st at o- dani mo" >
<dat al i st i d=" st at o- dani mo" >
<opt i on val ue=" t r i st e" >
<opt i on val ue=" annoi at o" >
<opt i on val ue=" cur i oso" >
<opt i on val ue=" f el i ce" >
<opt i on val ue=" ent usi ast a! " >
</ dat al i st >
</ l abel >
</ f i el dset >
<f i el dset name=" dat i - comment o" >
<l egend>Messaggi o e vot o</ l egend>
<l abel >
Messaggi o:
<t ext ar ea name=" messaggi o" pl acehol der =" scr i vi qui i l t uo messaggi o ( max 300 car at t er i ) " maxl engt h=" 300" r equi r ed></ t ext ar ea>
</ l abel >
<l abel >
Vot o:
<i nput t ype=" r ange" name=" vot o" mi n=" 0" max=" 5" st ep=" 1" >
</ l abel >
</ f i el dset >
<i nput t ype=" r eset " val ue=" Reset t a l a f or m" >
<i nput t ype=" submi t " val ue=" I nvi a i l comment o" >
</ f or m>
</ sect i on>
</ sect i on>
</ ar t i cl e>
</ sect i on>
<sect i on>
<h1>Post meno r ecent i </ h1>
<ar t i cl e>
<header >
<t i me dat et i me=" 2010- 11- 10" pubdat e>10/ 11/ 2010</ t i me>
<h2>Sect i on e ar t i cl e: i mpar i amo a conoscer l i </ h2>
</ header >
<p>
Cor r e mol t a di f f er enza t r a quest i due t ag HTML5, se non dal punt o di
vi st a del l a pr esent azi one, quant omeno da quel l o semant i co. . .
<a hr ef =" 2010/ 11/ 10/ sect i on- ar t i cl e" >cont i nua a l egger e</ a>
</ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: nonesi st e@non. st " >Fr ancesca Rest a</ a></ addr ess>
</ f oot er >
</ ar t i cl e>
<ar t i cl e>
<header >
<t i me dat et i me=" 2010- 11- 01" pubdat e>01/ 11/ 2010</ t i me>
<h1>Chi ha paur a del t ag menu?</ h1>
</ header >
<p>
Cadut o i n di sgr azi a dur ant e i l r egno HTML4 st at o r i abi l i t at o
a pi eni vot i da quest e speci f i che, scopr i amone i nsi eme l ' ut i l i zzo. . .
<a hr ef =" 2010/ 11/ 01/ menu- t ag" >cont i nua a l egger e</ a>
</ p>
<f oot er >
<addr ess><a hr ef =" mai l t o: nonesi st e@non. st " >Cesar e Lamanna</ a></ addr ess>
</ f oot er >
</ ar t i cl e>
</ sect i on>
<asi de>
<h1>Si debar </ h1>
<sect i on>
<h2>Ri cer ca nel f or m: </ h2>
<f or mname=" r i cer ca" met hod=" post " act i on=" / sear ch" >
<l abel > Par ol a chi ave:
<i nput t ype=" sear ch" aut ocompl et e=" on" pl acehol der =" ar t i cl e, sect i on, . . . "
name=" keywor d" r equi r ed maxl engt h=" 50" >
</ l abel >
<i nput t ype=" submi t " val ue=" r i cer ca" >
</ f or m>
</ sect i on>
<nav>
<h2>Cat egor i e</ h2>
<ul >
<l i ><a hr ef =" / cat egor i a/ mul t i medi a" >mul t i medi a</ a></ l i >
<l i ><a hr ef =" / cat egor i a/ t ext " >mar cat or i t est ual i </ a></ l i >
<l i ><a hr ef =" / cat egor i a/ f or m" >f or ms</ a></ l i >
</ ul >
</ nav>
</ asi de>
<f oot er >
<dl >
<dt >Cr eat o da</ dt >
<dd><addr ess><a hr ef =" mai l t o: sandr o. paganot t i @gmai l . com" >Sandr o Paganot t i </ a></ addr ess></ dd>
<dt >Ul t i mo aggi or nament o</ dt >
<dd><t i me dat et i me=" 2010- 11- 23" pubdat e>Mar t ed 23 Novembr e</ t i me></ dd>
<dd>
</ dl >
<smal l >Tut t i i cont enut i sono pr ot t et t i dal l a l i cenza Cr eat i ve Commons</ smal l >
</ f oot er >
Un'attenzione particolare meritano anche i campi dei form. Anche per questi ultimi si fatto ricorso ai nuovi attributi e ai nuovi tipi di input HTML5. Si osservi, per esempio, i
<f or mname=" r i cer ca" met hod=" post " act i on=" / sear ch" >
<l abel > Par ol a chi ave:
<i nput t ype=" sear ch" aut ocompl et e=" on" pl acehol der =" ar t i cl e, sect i on, . . . "
name=" keywor d" r equi r ed maxl engt h=" 50" >
</ l abel >
<i nput t ype=" submi t " val ue=" r i cer ca" >
</ f or m>
Viene settata l'opzione per far s che il browser proceda con l'autocompletamento del testo inserito (aut ocompl et e=" on" ), si imposta attraverso l'attributo pl acehol der il testo
pagina viene caricata, attraverso r equi r ed si definisce come obbligatoria la compilazione del campo.
E ancora, nella sezione dei commenti, per i campi destinati all'inserimento dell'indirizzo e-mail e del sito web personale, sono stati usati i tipi di input emai l e ur l :
<l abel >
Emai l :
<i nput t ype=" emai l " name=" emai l " aut ocompl et e=" on" pl acehol der =" emai l @domai n. ext " >
</ l abel >
<l abel >
WWW:
<i nput t ype=" ur l " name=" ur l " aut ocompl et e=" on" pl acehol der =" ht t p: / / mywebsi t e. com" >
</ l abel >
Stili e presentazione
Terminato il lavoro sulla struttura, si pu passare all'applicazionedegli stili. Nel preparare i CSS, abbiamo pensato di fare affidamento il pi possibile su alcune delle nuove fun
risultato sono due varianti del template, create da Filippo Buratti, che differiscono solo per alcuni dettagli relativi alla presentazione. I link: versione 1
(http://www.html.it/guide/esempi/html5/esempi/progetto_blog/stili/progetto1.html) e versione 2 (http://www.html.it/guide/esempi/html5/esempi/progetto_blog/stili/progetto2.h
Le differenze nella resa visuale sono eventualmente dovute al mancato supporto da parte nei singoli browser delle funzionalit e propriet CSS3.
Una nota fondamentale da aggiungere a proposito di Internet Explorer. Il browser di Microsoft supporta nativamente i nuovi elementi strutturali solo a partire dalla versione 9
versioni precedenti e far s che gli stili vengano applicati correttamente anche a tag che Internet Explorer non interpreta, abbiamo inserito nella <head>della pagina il riferimen
(http://code.google.com/p/html5shim/), uno script creato per lo scopo da Remy Sharp. L'inserimento semplice, basta copiare e incollare nei vostri progetti queste righe di cod
<! - - [ i f l t I E 9] >
<scr i pt sr c=" ht t p: / / ht ml 5shi m. googl ecode. com/ svn/ t r unk/ ht ml 5. j s" ></ scr i pt >
<! [ endi f ] - - >
Dal momento che si usano i commenti condizionali, lo script sar applicato solo alle versioni di IE inferiori alla 9.
Per completezza e per garantire al massimo livello la compatibilit cross-browser rispetto agli elementi HTML5 combinati agli stili, stato incorporato anche un CSS di reset (
reset-stylesheet/) disponibile su HTML5 Doctor:
<l i nk r el =" st yl esheet " hr ef =" r eset . css" medi a=" scr een" >
possibile scaricare il pacchetto zip (http://www.html.it/guide/esempi/html5/esempi/progetto_blog/progetto_blog.zip) contenente tutti i file usati nel progetto.
Nuova linfa alle applicazioni web
Lacronimo alla base di HTML chiaro, HyperText Markup Language; ipertesto: un insieme di documenti messi in relazione tra loro da parole chiave. La tecnologia in
questione dovrebbe essere quindi utile per strutturare collezioni di contenuti legati fra di loro in modo pi o meno oggettivo; Wikipedia ne il classico e pi calzante
esempio. Lascia invece un po pi perplessi realizzare che lHTML sempre pi la base di vere e proprie applicazioni web: google docs, Google Maps, Meebo, solo
per citarne alcune, dove la forma ipertestuale decisamente marginale quando non completamente assente. Come gi abbiamo avuto modo di anticipare, lHTML5 nasce
anche per meglio indirizzare questo crescente filone di realtweb, mettendo a disposizione dello sviluppatore una nutrita serie di nuovissime API studiate per dare adito
alle pi ardite applicazioni allinterno di un browser. un po come se il prematuro sogno di Marc Andressen
(http://www.forbes.com/forbes/1997/1201/6012308a_print.html) stesse per avverarsi.
La risposta ad un bisogno molto sentito
Lo sforzo profuso prima dal gruppo WHAT e poi dal W3C stato parzialmente accentuato dalla necessit di porre un freno al dilagare di tecnologie, parallele allHTML,
sorte per rispondere ai nuovi bisogni delle applicazioni web. Il motivo principale di questo comportamento da ricercarsi nella necessit di mantenere unito il controllo
sullo standard e, conseguentemente, di evitare che linsediamento in pianta stabile di soluzioni non interne al consorzio possacomplicare di fatto la gestione dellintero
sistema.
Flash ed il cugino Flex sono due ottimi esempi della tendenza intrapresa dal web in tal senso, seguono Google Gears, Google O3D e uninfinita di altre estensioni, ognuna
delle quali cerca di riempire un vuoto pi o meno piccolo percepito dagli utenti della rete.
I punti chiave dellofferta
Ecco un elenco esaustivo delle API trattate nelle prossime lezioni della guida. E&grave; possibile suddividere tale insieme sommariamente in due categorie: nella prima,
multimedialit, trovano spazio le API studiate per gestire ed incanalare nuovi strumenti di comunicazione, come video, audio e grafica bi/tridimensionale; nella seconda,
che invece potremmo chiamare arricchimento, si posizionano le nuove funzionalit studiate per avvicinare lesperienza di fruizione di una web application a quella di un
normale programma eseguito in una finestra del desktop.
Multimedialit
z Gestione di flussi video (il tag <vi deo>e le relative API);
z Gestione di flussi audio (il tag <audi o>e le relative API);
z Gestione di grafica libera bi/tridimensionale (il tag <canvas>e le relative API);
z Grafica vettoriale e notazioni matematiche (i tag <svg>, <mat h>e le relative API).
Arricchimento
z Applicazioni web offline (file .manifest e API di sincronizzazione);
z Memorizzazione di informazioni sul browser (WebSQL e LocalStorage API);
z J avascript asincrono e parallelo (Web Workers API);
z Comunicazioni bidirezionali tra client e server (Web Socket API);
z Drag and Drop;
z Utilizzo di informazioni georeferenziate (GeoLocation API).
Oltre a questo elenco, meritano di essere citate e brevemente esplorate alcune funzionalit che, seppur non rivoluzionarie, promettono di semplificare alcuni aspetti dello
sviluppo odierno di applicazioni web.
Manipolare la cronologia: le History API
Tutti conosciamo il meccanismo per navigare allinterno della cronologia del browser:
al er t ( " La cr onol ogi a cont i ene " + hi st or y. l engt h + " document i . " ) ;
/ / t or na al document o pr ecedent e
hi st or y. back( ) ;
Meno invece sanno che di questo oggetto hi st or y, seppur supportato dalla totalit degli user-agent, non esiste traccia nelle attuali specifiche HTML. Con lavvento della
versione 5 il W3C ha deciso di includere le API per la navigazione della cronologia allinterno del futuro standard; loccasione si rivelata ghiotta anche per un
interessante arricchimento delle funzionalit. In particolare ora possibile creare nuovi elementi della cronologia associando loro un payoff di dati, come ad esempio un
hash chiave-valore, che poi potr essere recuperato attraverso lutilizzo del tasti di navigazione del browser. Vediamone un esempio:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>Messaggi dal l a st or i a: </ t i t l e>
<scr i pt >
hi st or yI nj ect = f unct i on( ) {
message = pr ompt ( ' Che messaggi o vuoi sal var e i n hi st or y?' ) ;
hi st or y. pushSt at e( message, document . t i t l e + " ' " + message + " ' " ) ;
};
onpopst at e = f unct i on( event ) {
document . get El ement ByI d( " messagel i st " ) .
i nser t Adj acent HTML( ' bef or eend' , " <l i >" +event . st at e+" </ l i >" ) ;
}
</ scr i pt >
</ head>
<body>
<h1>Li st a dei messaggi pr esent i nel l a cr onol ogi a: </ h1>
Pr emi i l t ast o back del br owser o <a hr ef =" j avascr i pt : hi st or yI nj ect ( ) ; r et ur n f al se; " >
car i ca un nuovo messaggi o. </ a>
<ul i d=" messagel i st " ></ ul >
</ body>
</ ht ml >
La funzione hi st or yI nj ect crea, attraverso il metodo pushSt at e, un nuovo elemento nella cronologia che contiene il messaggio generato dallutente. Successivamente,
la pressione del tasto back del browser viene intercettata dallhandler onpopst at e che recupera il messaggio e lo aggiunge allelenco a fondo pagina. Con questo
meccanismo diviene possibile simulare una normale navigazione con i pulsanti back e forward anche allinterno di applicazioni web che fanno uso intensivo di J avascript,
come ad esempio la maggior parte delle realizzazioni sviluppatecon il framework Ext.J S (http://dev.sencha.com/deploy/dev/examples/).
Associare protocolli e MIME type alla propria web application
Supponiamo di aver sviluppato una web application per inviare e ricevere sms. Le specifiche HTML5 introducono la possibilit di registrare la propria applicazione come
gestore preposto ad uno specifico protocollo; nel nostro caso sarebbe quindi auspicabile che qualunque link nel formato:
<a hr ef =" sms: / / +39396819577" >Manda un SMS a Sandr o Paganot t i </ a>
convogli lutente alla nostra applicazione a prescindere dal sito in cui si trova il link, un po come succede con il client di posta al click di link col protocollo mailto.
Registrare un protocollo molto semplice:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>Tut t i SMS: I l ser vi zi o per i nvi ar e e r i cever e SMS</ t i t l e>
<scr i pt >
r egi st r aPr ot ocol l o = f unct i on( ) {
navi gat or . r egi st er Pr ot ocol Handl er (
' sms' , ' ht t p: / / l ocal host / i nvi a_sms?dest =%s' , ' Tut t i SMS' ) ;
};
</ scr i pt >
</ head>
<body onl oad=" r egi st r aPr ot ocol l o( ) ; " >
</ body>
</ ht ml >
Caricando la pagina in un browser che supporta questa funzionalit, noi abbiamo usato Firefox 3.5, verremo notificati della volont da parte dellapplicazione web di
registrare il protocollo sms e potremo decidere se consentire o meno loperazione:
Figura 41 (click per ingrandire) - Associazione del protocollo su Firefox
(http://www.html.it/guide/esempi/html5/imgs/lezione_api/1.jpg)
Una volta accettata questa associazione, ad ogni link nel formato: sms: / / qual si asi _cosa seguir un redirect automatico allindirizzo specificato come parametro nella
funzione r egi st er Pr ot ocol Handl er , nel nostro caso: ht t p: / / l ocal host / i nvi a_sms?dest =%s , con la particella %s sostituita con lintero link in questione. Ecco un
esempio di risultato:
ht t p: / / l ocal host / i nvi a_sms?dest =sms%3A%2F%2F%2B39396819577
E possibile seguire esattamente la stessa procedura anche per registrare uno specifico MIME type utilizzando la funzione gemella: r egi st er Cont ent Handl er .
Un progetto ambizioso
Chiudiamo la lezione gettando le basi per lo sviluppo del progetto guida associato al prossimo gruppo di lezioni: FiveBoard, una lavagna interattiva basata su canvas.
Chiaramente lobiettivo del progetto quello di fornire un pretesto per poter esplorare le novit introdotte dallHTML5 in un contesto un po pi ampio rispetto a quello
solitamente offerto. Proprio per questo alcune scelte potranno essere opinabili in un ottica di efficenza o di strutturazione dellarchitettura.
Bene, cominciamo creando una cartella di progetto, fiveboard, contenente un file index.html e una cartella js con un ulteriore file application.js:
Figura 42 - Vista delle cartelle
Ora impostiamo la pagina html perch richiami il file J avascript:
<! doct ype ht ml >
<ht ml l ang=' i t ' >
<head>
<met a char set =" ut f - 8" >
<t i t l e>Fi veBoar d: uno spazi o per gl i appunt i . </ t i t l e>
<scr i pt sr c=" j s/ appl i cat i on. j s" def er ></ scr i pt >
</ head>
</ ht ml >
Lattributo def er , poco supportato perch definito in modo poco chiaro nelle specifiche HTML4 (http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.1), assume
nella versione 5 un significato pi delineato:
(se) [..] l'attributo def er presente, allora lo script viene eseguito quando la pagina ha finito di essere processata.
In questo nuovo contesto interessante lutilizzo di def er per velocizzare il caricamento della pagina posticipando in seconda battuta il load del file J avascript. Da notare,
prima di proseguire, anche laggiunta nelle specifiche dellattributo async che causa il caricamento dello script in parallelo, o asincrono, da qui il nome, rispetto a quello
della pagina.
Prima di concludere sinceriamoci del funzionamento del nostro impianto aggiungendo al file Javascript:
al er t ( " pr ont i per comi nci ar e! " ) ;
e caricando il tutto allinterno di un browser:
Figura 43 (click per ingrandire) - Risultato dell'operazione
(http://www.html.it/guide/esempi/html5/imgs/lezione_api/3.jpg)
Codice degli esempi
Prima di proseguire, potete scaricare per una migliore consultazione il pacchetto zip (http://www.html.it/guide/esempi/html5/esempi/esempi_html5_api.zip) che contiene il
codice di tutti gli esempi che vedremo nelle lezioni che seguono.
Applicazioni web offline (file .manifest)
Con le Offline API possibile specificare in un apposito file, detto manifest, un elenco di asset (pagine web, filmati Flash, immagini, fogli di stile CSS, J avascript e
quantaltro pu finire in una pagina web) dei quali vogliamo che il browser conservi copia locale. Tali oggetti, dopo la prima sessione di navigazione online, resteranno
quindi accessibili anche in assenza di una connessione di rete. In questo modo possibile creare applicazioni web perfettamente funzionanti anche offline. Il primo
passo per ottenere questo risultato aggiungere lattributo manifest allelemento html segnalando cos allo user agent lesistenza di un file preposto alla memorizzazione
offline:
<! doct ype ht ml >
<ht ml l ang=' i t ' mani f est =' f i veboar d. mani f est ' >
. . .
A questo punto deve essere creato un file con MIME type t ext / cache- mani f est , dal nome specificato nel valore dellattributo, contenente lelenco dei documenti per i
quali si richiede la memorizzazione offline. Ad esempio, considerando il nostro progetto guida, il file potrebbe risultare:
CACHE MANI FEST
i ndex. ht ml
j s/ appl i cat i on. j s
Per fare in modo che il file venga servito con il corretto MIME type ci sono molte soluzioni, tutte, purtroppo, molto legate al tipo di webserver che sostiene la pagina. Nel
caso si tratti del popolare Apache la soluzione pi veloce consiste nel creare un file .htaccess nella cartella principale del progetto contenente la seguente istruzione:
AddType t ext / cache- mani f est mani f est
Una volta soddisfatte queste condizioni possibile verificare il buon funzionamento delle API utilizzando un browser come Chromiume caricando la pagina assicurandosi
di avere i Developer Tools attivati (CTRL + SHIFT + J) e posizionati sulla sezione Console (figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_offline/1.jpg)
Aggiornando nuovamente il contenuto della pagina riceveremo conferma della corretta memorizzazione in locale dei documenti specificati nel file manifest, ora
disponibili anche per consultazioni in assenza di rete (figura 2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_offline/2.jpg)
Andare in profondit
Il file .manifest di cui abbiamo accennato nella sezione precedente, offre una serie di interessanti funzionalit aggiuntive; in primo luogo possibile indicare al browser
percorsi di fallback, da utilizzare nel caso in cui durante la navigazione offline si necessiti di risorse non disponibili:
CACHE MANI FEST
i ndex. ht ml
FALLBACK:
news. ht ml of f l i ne. ht ml
In questo esempio, il tentativo di navigazione verso la pagina news.html verr risolto, in caso di browser in stato offline, servendo la pagina offline.html. In caso fosse
necessario convogliare risorse multiple si pu anche far ricorso a wildcard, ad esempio:
CACHE MANI FEST
i ndex. ht ml
FALLBACK:
news. ht ml of f l i ne. ht ml
news/ * of f l i ne. ht ml
Cos facendo anche la navigazione verso una pagina di dettaglio news, come ad esempio news/ 10/12/2010/nuovi-progressi-al-cern verr servita in assenza di rete con il
contenuto di offline.html. Usando la sezione NETWORK invece possibile notificare risorse che devono sempre essere recuperate online:
CACHE MANI FEST
i ndex. ht ml
NETWORK:
sal do_cont o_cor r ent e. php
Le API associate
La gestione della cache introduce tutta una serie di eventi e propriet che consentono di acquistare controllo su ogni passo della procedura, vediamoli in questo esempio
(offline.html), che stampa a video un nuovo elemento di un elenco puntato per ogni evento intercettato:
<! doct ype ht ml >
<ht ml l ang=' i t ' mani f est =' of f l i ne. mani f est ' >
<head>
<t i t l e>Tut t i i passi del l a cache</ t i t l e>
<scr i pt >
/ / Funzi one di ser vi zi o:
say = f unct i on( message) {
document . get El ement ByI d( " cache- st eps" ) .
i nser t Adj acent HTML( ' bef or eend' , " <l i >" +message+" ; </ l i >" ) ;
}
cl ear = f unct i on( message) {
document . get El ement ByI d( " cache- st eps" ) . i nner HTML = " " ;
}
/ / L' ogget t o che cont r ol l a l a cache
var appCache = wi ndow. appl i cat i onCache;
/ / Nuovi event i di sponbi l i con l e Of f l i ne API
appCache. addEvent Li st ener ( ' checki ng' , f unct i on( ev) {
say( " Cont r ol l o, se posso, che i l . mani f est onl i ne non si a cambi at o" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' noupdat e' , f unct i on( ev) {
say( " I l . mani f est non cambi at o" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' downl oadi ng' , f unct i on( ev) {
say( " I ni zi o a scar i car e i f i l e l i st at i dal mani f est che non ho gi i n cache" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' pr ogr ess' , f unct i on( ev) {
say( " Scar i co una r i sor sa" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' cached' , f unct i on( ev) {
say( " Tut t e l e r i sor se sono st at e scar i cat e" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' updat er eady' , f unct i on( ev) {
say( " Ho scar i cat o una nuova ver si one del l a cache e sono pr ont o " +
" a sost i t ui r l a al l a pr ecedent e" ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' obsol et e' , f unct i on( ev) {
say( " Ho cer cat o i l . mani f est onl i ne ot t enendo un 404 o 410 come r i spost a " +
" pr obabi l ment e i l si t o non suppor t a pi f unzi onal i t di " +
" cachi ng, cancel l o l a cache i n l ocal e. " ) ;
}, f al se) ;
appCache. addEvent Li st ener ( ' er r or ' , f unct i on( ev) {
say( " Ops, si ver i f i cat o un er r or e" ) ;
}, f al se) ;
</ scr i pt >
</ head>
<body>
<but t on oncl i ck=" cl ear ( ) ; appCache. updat e( ) ; " >For za i l cont r ol l o del l a cache</ but t on>
<ul i d=" cache- st eps" >
</ ul >
</ body>
</ ht ml >
Proviamo ad eseguire questa pagina in Chromiumsenza aver preventivamente creato il file offline.manifest (figura 3):
Figura 3
Creiamo ora un semplice offline.manifest come segue,
CACHE MANI FEST
of f l i ne. ht ml
e ricarichiamo la pagina (figura 4):
Figura 4
Ricarichiamo nuovamente la pagina per certificare lavvenuto cache delle risorse (figura 5):
Figura 5
Bene, da qui si dipanano tutta una serie di comportamenti interessanti come ad esempio: modificare il file .manifest e forzare il controllo della cache, oppure rimuovere il
file .manifest e ricaricare la pagina. Provando ognuno di essi con lo script che abbiamo appena steso sar facile identificare i vari eventi coinvolti. Ecco la demo
(http://www.html.it/guide/esempi/html5/esempi/lezione_offline/offline.html).
Conclusioni
Come avete potuto notare le attivit per far in modo che il nostro progetto guida benefici delle Offline API sono state semplici e di pochissimo impatto sullarchitettura
della pagina. E&grave; importante per ricordare che man mano andremo ad aggiungere risorse al progetto (immagini, librerie, etc...) sar necessario includerle nel
file .manifest pena il malfunzionamento dello stesso in assenza di connessione.
Tabella del supporto sui browser
API e Web Applications
Applicazioni web offline (.manifest) No 3.5+4.0+2.0+10.6+
Indexed Database API
Queste API nascono per dare la possibilit di creare e manipolare un database di ispirazione NoSQL memorizzato all'interno del browser dell'utente. Ogni database,
identificato da un nome, pu contenere un numero arbitrario di Obj ect St or e, letteralmente contenitori di oggetti: ad esempio un ipotetico databaselibreria' potrebbe
ospitare i seguenti Obj ect St or e: Libri, Clienti. Sia Libri' che Clienti' non sono altro che strutture paragonabili ad array associativi ordinati, dove ogni coppia chiave-
valore rappresenta un oggetto, quindi in questo caso o un libro o un cliente.
All'interno di un Obj ect St or e possibile eseguire le normali operazioni di inserimento, modifica, eliminazione e ricerca; le API sono state pensate per ragionare con
record in un formato J SON-like ma nulla vieta di memorizzare oggetti J avascript di fattura diversa, purch serializzabili.
Come funzionano le API
Utilizziamo Chromiumper un tour operativo di questo interessante set di API; iniziamo preparando un documento HTML5 e creando il database:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e> WebLi br er i a: gest i onal e per l i br er i e </ t i t l e>
<scr i pt >
set up = f unct i on( ) {
i f ( ' webki t I ndexedDB' i n wi ndow) {
i ndexedDB = webki t I ndexedDB;
I DBCur sor = webki t I DBCur sor ;
I DBKeyRange = webki t I DBKeyRange;
I DBTr ansact i on = webki t I DBTr ansact i on;
}el se i f ( ' moz_i ndexedDB' i n wi ndow) {
i ndexedDB = moz_i ndexedDB;
}
}
i ni t = f unct i on( ) {
set up( ) ;
var r equest = i ndexedDB. open( " WebLi br er i a" , " I l gest i onal e per l i br er i e" ) ;
}
</ scr i pt >
</ head>
<body onl oad=" i ni t ( ) ; " >
</ body>
</ ht ml >
Essendo, ad oggi, queste features ancora sperimentali Chromium(e Firefox) prefissano le classi di riferimento con la particella webkit': la funzione set up' serve
solamente per creare degli alias che abbiano nomi pi aderenti alle specifiche. Mano a mano che queste API si avvicineranno allo status di standard assisteremo alla
rimozione di questi prefissi e potremo commentare la funzione setup. La creazione del database avviene attraverso l'istruzione i ndexedDB. open', che accetta come
parametro il nome e la descrizione dell'oggetto che stiamo creando; in caso un database con lo stesso nome e lo stesso dominio di origine sia gi presente nel browser
allora verr utilizzato quest'ultimo.
A questo punto possiamo intercettare gli eventi di avvenuta creazionedella connessione e di errore durante la procedura gestendoli nel modo che meglio ci aggrada:
i ni t = f unct i on( ) {
set up( ) ;
var r equest = i ndexedDB. open( " WebLi br er i a" , " I l gest i onal e per l i br er i e" ) ;
r equest . onsuccess = f unct i on( ) {consol e. l og( " Connessi one Ok! " ) ; }
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}
Eseguiamo la pagina all'interno di Chromiumprestando attenzione alla linguetta 'console' all'interno dei Developer Tools (CTRL + SHI FT + J ) e avremo conferma
dell'avvenuta connessione/creazione al database (figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_database/1.jpg)
Ora che abbiamo stabilito una connessione essenziale determinare se l'utente sia alla sua prima visita, perch in questo caso necessario procedere con la creazione degli
object store e della struttura necessari. Per gestire questo meccanismo le API mettono a disposizione il concetto di versione, impostata a null per un database appena
creato, che pu essere utilizzata proprio capire quando sia necessario apportare modifiche alla struttura. Ad esempio:
. . .
i ni t = f unct i on( ) {
set up( ) ;
var r equest = i ndexedDB. open( " WebLi br er i a" , " I l gest i onal e per l i br er i e" ) ;
r equest . onsuccess = cont r ol l aVer si one;
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}
cont r ol l aVer si one = f unct i on( event ) {
wi ndow. dat abase = event . r esul t ;
i f ( dat abase. ver si on ! = " 1. 0" ) {
var r equest = dat abase. set Ver si on( " 1. 0" ) ;
r equest . onsuccess = aggi or naLoSchema;
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}el se{
/ / i l dat abase gi aggi or nat o al l a ver si one pi r ecent e
}
}
aggi or naLoSchema = f unct i on( ) {
consol e. l og( " Qui posso aggi or nar e l o schema" ) ;
}
. . .
La funzione aggi or naLoSchema viene invocata solamente nel caso in cui la versione del database sul browser dell'utente sia diversa da quella attesa dal javascript (in
questo caso la 1.0'); in particolare registrare una funzione sul callback onsuccess' del metodo set Ver si on l'unico modo in cui sia consentito dalle specifiche
modificare la struttura del database.
Se ora provate questo codice all'interno del browser, nella linguetta console vedrete comparire la scritta Qui posso aggiornare lo schema', se poi ricaricate nuovamente la
pagina invece noterete che tale messaggio scompare: il database infatti gi nella versione 1.0, quindi il flusso del programma transita attraverso il blocco else, che al
momento vuoto. Per cancellare il database creato e poter cos ripetere la procedura necessario svuotare completamente la cache, chiudere Chromiume riaprirlo (figura
2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_database/2.jpg)
A questo punto creiamo la struttura del database: per prima cosa dobbiamo aprire una transazione, successivamente istruiamo il database alla creazione dell'obj ect st or e
libri', con chiave sul campo isbn', e di due indici, rispettivamente per i campi titolo' e autore'. Approfittiamone anche per creare la funzione r ecuper aLi br i , che verr
invocata sia al completamento della struttura sia nel caso il database sia gi alla versione desiderata:
. . .
cont r ol l aVer si one = f unct i on( event ) {
wi ndow. dat abase = event . r esul t ;
i f ( dat abase. ver si on ! = " 1. 0" ) {
var r equest = dat abase. set Ver si on( " 1. 0" ) ;
r equest . onsuccess = aggi or naLoSchema;
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}el se{
r ecuper aLi br i ( ) ;
}
}
aggi or naLoSchema = f unct i on( ) {
wi ndow. t r ansazi one = event . r esul t ;
t r ansazi one. oncompl et e = r ecuper aLi br i ;
t r ansazi one. onabor t = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
var l i br i = dat abase. cr eat eObj ect St or e( " l i br i " , " i sbn" , f al se) ;
var t i t ol o = l i br i . cr eat eI ndex( " t i t ol o" , " t i t ol o" , f al se) ;
var aut or e = l i br i . cr eat eI ndex( " aut or e" , " aut or e" , f al se) ;
}
r ecuper aLi br i = f unct i on( ) {
/ / r ecuper a l ' el enco dei l i br i e st ampal i a vi deo
}
. . .
La funzione cr eat eObj ect St or e richiede 3 parametri, di cui solamente il primo, il nome, obbligatorio; il secondo parametro rappresenta il nome della propriet del
record che vogliamo funga da chiave all'interno dell'obj ect st or e. Il terzo parametro imposta invece la propriet aut oi ncr ement ; nel caso non sia presente una chiave
nel record in inserimento e aut oi ncr ement = t r ue, una chiave verr generata in automatico. Le due chiamate alla funzione cr eat eI ndex provvedono alla creazione di
due indici, utili per ricerche e query, sui campi titolo' e autore'; il terzo parametro impostato a f al se consente la presenza di valori duplicati. Ora che abbiamo creato la
struttura del database stampiamo a video l'elenco, per ora vuoto, dei libri registrati e creiamo un piccola formper l'inserimento di un nuovo volume:
. . .
r ecuper aLi br i = f unct i on( ) {
wi ndow. t r ansazi one = dat abase. t r ansact i on( [ " l i br i " ] ,
I DBTr ansact i on. READ_WRI TE, 0) ;
var r equest = t r ansazi one. obj ect St or e( " l i br i " ) . openCur sor ( ) ;
r equest . onsuccess = st ampaLi br i ;
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}
st ampaLi br i = f unct i on( ) {
var cur sor = event . r esul t ;
i f ( cur sor ! = nul l ) {
document . get El ement ByI d( " cat al ogo_l i br i " ) . i nser t Adj acent HTML( ' bef or eend' ,
" <l i >" + cur sor . val ue. aut or e + " : " + cur sor . val ue. t i t ol o +
" ( I SBN: " + cur sor . val ue. i sbn +" ) ; </ l i >" ) ;
cur sor . cont i nue( ) ;
}
}
aggi ungi Li br o = f unct i on( ) {
/ / aggi ungi amo un nuovo l i br o al l ' obj ect st or e
}
</ scr i pt >
</ head>
<body onl oad=" i ni t ( ) ; " >
<h1> WebLi br er i a: gest i onal e per l i br er i e</ h1>
<sect i on>
<h1>El enco dei l i br i </ h1>
<ul i d=" cat al ogo_l i br i " >
</ ul >
</ sect i on>
<asi de>
<h1>Aggi ungi un nuovo l i br o</ h1>
<f or mname=" aggi ungi _l i br o" onsubmi t =" aggi ungi Li br o( t hi s) ; r et ur n f al se; " >
<f i el dset name=" i nf o_l i br o" >
<l egend>Dat i r i chi est i : </ l egend>
<l abel >Ti t ol o:
<i nput name=" t i t ol o" t ype=" t ext " r equi r ed pl acehol der =" es: Dal l a t er r a al l a l una" >
</ l abel >
<l abel >Aut or e:
<i nput name=" aut or e" t ype=" t ext " r equi r ed pl acehol der =" es: J ul es Ver ne" >
</ l abel >
<l abel >I SBN:
<i nput name=" i sbn" t ype=" t ext " r equi r ed pl acehol der =" es: 8862221320" >
</ l abel >
<i nput t ype=" submi t " val ue=" Aggi ungi " >
</ f i el dset >
</ f or m>
</ asi de>
</ body>
</ ht ml >
Possiamo tranquillamente tralasciare la spiegazione della nuova porzione di codice HTML aggiunto: trattasi semplicemente di un formche all'invio chiama una funzione,
ancora da sviluppare, per l'aggiunta di un nuovo libro. Molto pi interessanti sono invece r ecuper aLi br i e st ampaLi br i . In r ecuper aLi br i viene creata una nuova
transazione che coinvolge l'obj ect st or e libri'; il secondo parametro indica il tipo di transazione: purtroppo lettura/scrittura (I DBTr ansact i on. READ_WRI TE) l'unica
opzione supportata ad oggi; il terzo valore rappresenta invece il timeout della transazione: lo 0 utilizzato significa mai. Vediamo l'istruzione successiva:
var r equest = t r ansazi one. obj ect St or e( " l i br i " ) . openCur sor ( ) ;
La funzione openCur sor inizializza un puntatore, detto anche cursore, al primo record dell'obj ect st or e libri'. La funzione st ampaLi br i , che viene chiamata appena il
cursore stato creato e popola una lista con i libri in catalogo, agisce come una specie di ciclo, infatti il metodo continue non fa nient'altro che richiamare nuovamente
stampaLibri, posizionando per il cursore al record successivo; questo fino a quando non si giunge alla fine dei risultati di ricerca, a quel punto il valore del cursore
diviene nul l e un apposito i f si preoccupa dell'abbandono della funzione.
Completiamo il nostro progetto con la funzione aggi ungi Li br o:
. . .
aggi ungi Li br o = f unct i on( dat a) {
var el ement s = dat a. el ement s
wi ndow. t r ansazi one = dat abase. t r ansact i on( [ " l i br i " ] ,
I DBTr ansact i on. READ_WRI TE, 0) ;
var r equest = t r ansazi one. obj ect St or e( " l i br i " ) . put ( {
t i t ol o: el ement s[ ' t i t ol o' ] . val ue,
aut or e: el ement s[ ' aut or e' ] . val ue,
i sbn: el ement s[ ' i sbn' ] . val ue
}, el ement s[ ' i sbn' ] . val ue) ) ;
r equest . onsuccess = f unct i on( ) {pul i sci Li st a( ) ; r ecuper aLi br i ( ) ; }
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}
pul i sci Li st a = f unct i on( ) {
document . get El ement ByI d( " cat al ogo_l i br i " ) . i nner HTML =" " ;
}
</ scr i pt >
Il metodo interessante in questo caso il put , che si preoccupa di aggiungere al database, previa apertura di una transazione appropriata, un nuovo record con gli elementi
ricevuti dal form(da notare il secondo parametro, corrispondente alla chiave del record). Da notare che esiste anche un metodo add che differisce nell'impedire la
creazione di un record la cui chiave sia gi presente nel database.
Eseguiamo un ultima volta l'applicazione, proviamo ad inserire un paio di libri ed ammiriamone il risultato (figura 3):
Figura 3 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_database/3.jpg)
Una funzione di ricerca
Aggiungiamo questa funzione al progetto:
. . .
r i cer caLi br o = f unct i on( aut or e) {
pul i sci Li st a( ) ;
wi ndow. t r ansazi one = dat abase. t r ansact i on( [ " l i br i " ] ,
I DBTr ansact i on. READ_WRI TE, 0) ;
var r equest = t r ansazi one. obj ect St or e( " l i br i " ) . i ndex( ' aut or e' ) . openCur sor (
I DBKeyRange. bound( aut or e, aut or e+" z" , t r ue, t r ue) , I DBCur sor . NEXT) ;
r equest . onsuccess = st ampaLi br i ;
r equest . oner r or = f unct i on( ) {consol e. l og( " Ops, er r or e" ) ; }
}
</ scr i pt >
L'unica differenza rispetto alla gi analizzata r ecuper aLi br i sta nel fatto che, in questo caso, con il metodo i ndex( aut or e' ) ' indichiamo al database che la selezione
dovr essere fatta utilizzando come discriminante l'indice autore' creato sull'omonimo campo. In particolare tale selezione dovr recuperare tutti i record il cui autore
inizia con una stringa passata al metodo. Per provare questa funzione di ricerca creiamo un nuovo frammento HTML in coda alla formdi inserimento:
. . .
</ f or m>
<h1>Cer ca un l i br o per aut or e</ h1>
<f or mname=" cer ca_per _aut or e"
onsubmi t =" r i cer caLi br o( t hi s. el ement s[ ' keywor d' ] . val ue) ; r et ur n f al se; " >
<f i el dset name=" campi _r i cer ca" >
<l egend>Ri cer ca per aut or e: </ l egend>
<l abel >I ni zi o del nome:
<i nput name=" keywor d" t ype=" sear ch" r equi r ed pl acehol der =" es: Fr anc" >
</ l abel >
<i nput t ype=" submi t " val ue=" Ri cer ca" >
</ f i el dset >
</ f or m>
</ asi de>
. . .
Ricarichiamo l'applicazione e proviamo ad inserire una valida stringa di ricerca (figura 4):
Figura 4 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_database/4.jpg)
Conclusione
Le Indexed Database API sono uno strumento estremamente potente che consentono di beneficiare di un vero e proprio database all'interno del browser dell'utente. Le
stesse funzionalit, anche se in una sintassi pi orientata a SQL, venivano offerte anche dalle promettenti Web SQL Database API (http://www.w3.org/TR/webdatabase/),
abbandonate dal 4 dicembre 2010 per motivi di sicurezza e di, ironia della sorte, troppa uniformit di implementazione da parte degli user-agent (avevano tutti scelto
SQLlite come back-end per questo tipo di specifiche).
Prima di passare alla prossima lezione ricordo che le stesse API che abbiamo usato in forma asincrona all'interno di questo progetto sono disponibili anche nel formato
sincrono; per maggiori informazioni in questo senso rimando alla documentazione ufficiale (http://www.w3.org/TR/IndexedDB/).
Per testare il tutto potete partire dalla demo (http://www.html.it/guide/esempi/html5/esempi/lezione_indexeddb/indexeddb.html).
Tabella del supporto sui browser
API e Web Applications
Indexed Database API 9.0+(parziale) 4.0+(parziale) 5.0+(parziale) 8.0+(parziale) No
WebStorage API
Le WebStorage API nascono per risolvere due problematiche tipiche dei cookies; la loro limitata dimensione massima (tipicamente 4K) e limpossibilit di avere
cookies differenziati tra due diverse sessioni di navigazione sullo stesso dominio dallo stesso browser. Il secondo punto si esplicita molto bene cercando di mantenere
aperti contemporaneamente due account Gmail sullo stesso browser, ogni navigazione sul primo comporter il logout del secondo e viceversa.
I problemi in questione sono stati risolti creando due nuovi oggetti. sessionStorage consente di avere un meccanismo di persistenza dei dati distinto per ogni sessione di
navigazione in ogni finestra, o tab, del browser. Usando sessi onSt or age sarebbe quindi possibile coordinare lapertura contemporanea di due distinti account GMail
sullo stesso browser. localStorage mantiene il comportamento del cookie essendo comune a tutte finestre del browser che condividono lo stesso dominio. Entrambi sono
inoltre stati studiati per ospitare molti pi dati, almeno 5Mb, ed essere persistenti anche alla chiusura ed alla riapertura del browser.
Le specifiche
Le API si compongono di una singola interfaccia St or age. l ocal St or age e sessi onSt or age implementano entrambi questa interfaccia e quindi dispongono dello stesso
set di metodi anche se chiaramente restano due oggetti distinti. Le principali operazioni possono essere eseguite come su di un normale array associativo:
l ocal St or age. nome = ' Sandr o' ;
l ocal St or age. cognome = ' Paganot t i ' ;
o con lausilio di metodi dedicati:
l ocal St or age. set I t em( ' nome' , ' Sandr o' ) ;
l ocal St or age. get I t em( ' nome' ) ; / / r i t or na ' Sandr o'
Se per ci accingiamo ad inserire valori diversi da stringhe il comportamento diverge: in un oggetto come l ocal St or age o sessi onSt or age consentita la
memorizzazione di soli contenuti testuali:
l ocal St or age. or di ni = Ar r ay( " 1" , " 2" , " 3" ) ;
l ocal St or age. or di ni ; / / r i t or na " 1, 2, 3"
quindi necessario ricorrere a stratagemmi, come la serializzazione su JSON, per ottenere leffetto desiderato:
l ocal St or age. or di ni = J SON. st r i ngi f y( Ar r ay( 1, 2, 3) ) ;
J SON. par se( l ocal St or age. or di ni ) ; / / r i t or na un ar r ay di 3 el ement i : [ 1, 2, 3]
Chromiummette a disposizione degli sviluppatori web che intendono utilizzare queste API la linguetta Storage dei Developer Tools (raggiungibili da menu o con la
combinazione di tasti Control - Shift - J e visibile in figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_webstorage/1.jpg)
Un esempio
Utilizziamo il progetto guida per implementare una meccanica di salvataggio dei dati basata su l ocal St or age. Non avendo ancora sviluppato la gestione della lavagna ci
concentreremo sul memorizzare e visualizzare stringhe inserite dallutente attraverso una textarea, iniziamo con il markup completando il file index.html:
<! doct ype ht ml >
<ht ml l ang=' i t ' mani f est =' f i veboar d. mani f est ' >
<head>
<met a char set =" ut f - 8" >
<t i t l e>Fi veBoar d: uno spazi o per gl i appunt i . </ t i t l e>
<scr i pt sr c=" j s/ appl i cat i on. j s" def er ></ scr i pt >
</ head>
<body>
<hgr oup>
<h1>D qual cosa </ h1>
<h2>Fi veBoar d r i cor da t ut t o</ h2>
</ hgr oup>
<f or mname=" f or m_da_r i cor dar e" >
<menu t ype=" t ool bar " >
<but t on t ype=" but t on" oncl i ck=" sal vaI l Dat o( t hi s. f or m. el ement s[ ' t est o_da_r i cor dar e' ] . val ue) ; " >
Memor i zza quant o scr i t t o
</ but t on>
<but t on t ype=" but t on" oncl i ck=" r ecuper aI l Dat o( t hi s. f or m. el ement s[ ' t est o_da_r i cor dar e' ] ) ; " >
Recuper a l ' ul t i mo t est o memor i zzat o
</ but t on>
</ menu>
<l abel >Cosa hai i n ment e?
<t ext ar ea name=" t est o_da_r i cor dar e" r equi r ed aut of ocus
pl acehol der =" La l i st a del l a spesa, i l t eat r o di quest a ser a . . . " ></ t ext ar ea>
</ l abel >
</ f or m>
</ body>
</ ht ml >
Dato che questo progetto si configura pi come una web application che come un sito web, implementiamo una classica struttura di controllo desktop-oriented: la toolbar.
Allinterno di questa, due semplici pulsanti gestiscono le azioni di memorizzazione e recupero del testo salvato attraverso una t ext ar ea; lattributo aut of ocus indica
allo user-agent di portare il cursore in posizione di inserimento testo nellistante di completo caricamento della pagina.
Ora, nel file application.js completiamo lesempio introducendo le funzioni di salvataggio e di recupero informazioni basate su l ocal St or age:
sal vaI l Dat o = f unct i on( i nf o_da_sal var e) {
l ocal St or age. ul t i mo_pensi er o = i nf o_da_sal var e;
al er t ( " Memor i zzazi one ef f et t uat a" ) ;
};
r ecuper aI l Dat o = f unct i on( el ement o) {
i f ( conf i r m( " Sost i t ui r e i l cont enut o at t ual e con l ' ul t i mo pensi er o memor i zzat o?" ) ) {
el ement o. val ue = l ocal St or age. ul t i mo_pensi er o;
}
};
Bene, non ci resta che provare lesempio (http://www.html.it/guide/esempi/html5/esempi/lezione_webstorage/fiveboard/index.html) allinterno di Chromiume constatare
il suo semplice ma efficace funzionamento, capace di persistere linformazione anche a seguito di un riavvio del browser.
Tabella del supporto sui browser
API e Web Applications
WebStorage 8.0+3.6+3.1+2.0+10.5+
Web Workers API
I Web Workers nascono per consentire lesecuzione di porzioni di codice Javascript in modo asincrono, senza intaccare le performance della pagina web in
visualizzazione. I Web Workers, nientaltro che file J avascript, possono essere comparati a dei thread che la pagina web pu lanciare e con i quali pu dialogare attraverso
semplici metodi. Ogni WebWorker pu eseguire a sua volta altri WebWorkers ed ognuno di essi pu effettuare operazioni di I/O, calcoli complessi e quantaltro.
Le API in questione prevedono che un WebWorker possa essere generato come oggetto della classe Wor ker o Shar edWor ker : nel primo caso la sua esecuzione sar
limitata alla specifica sessione di navigazione allinterno della finestra (o tab) del browser che lha invocato; nel secondo invece ogni sessione di navigazione che
condivide la stessa origine (lo stesso dominio) potr connettersi e scambiare messaggi con il medesimo worker. In questo modo lo Shar edWor ker assume il ruolo di
coordinatore, ottimo per, ad esempio, propagare su tutte le finestre del browser puntate su di un particolare dominio un messaggio ricevuto dal server.
Le specifiche
Per creare un Wor ker listruzione da eseguire decisamente semplice:
/ / pagi na pr i nci pal e
bot _noi oso = new Wor ker ( ' bot _noi oso. j s' ) ;
Lo script invocato, bot_noioso.js, verr eseguito in asincrono e potr inviare messaggi verso la pagina principale attraverso la funzione post Message:
/ / bot _noi oso. j s
post Message( ' Per ch l a t er r a t onda?' ) ;
Per ricevere questi messaggi necessario registrare una funzione allhandler onmessage del worker contenuto nella variabile bot _noi oso: chiaramente utilizzando la
stessa variabile possibile inviare, sempre tramite post Message messaggi al worker.
/ / pagi na pr i nci pal e
bot _noi oso = new Wor ker ( ' bot _noi oso. j s' ) ;
bot _noi oso. onmessage = f unct i on( event ) {
bot _noi oso. post Message( pr ompt ( event . dat a) ) ;
}
Allo stesso modo possibile registrare lhandler onmessage anche allinterno del file del worker:
/ / bot _noi oso. j s
post Message( ' Per ch l a t er r a t onda?' ) ;
onmessage = f unct i on( event ) {
i f ( event . dat a ! = nul l ) {
post Message( ' Per ch: ' + event . dat a + ' ?' ) ;
}
}
Ora, se lanciamo Chromiumpotremo sincerarci del buon funzionamento dello script (figura 1):
Figura 1 - Testo
Le API dello Shar edWor ker differiscono in modo sensibile rispetto a queste, anche se ovviamente mantengono immutato il funzionamento di base; per poterle trattare con
la dovuta cura costruiamo un piccolo esempio che le utilizzi.
Ecco la demo (http://www.html.it/guide/esempi/html5/esempi/lezione_webworkers/webworker.html).
Un esempio
Continuiamo con il progetto guida; lobiettivo di questo capitolo beneficiare delle feature di uno Shar edWor ker per implementare una dashboard di controllo, che
amministri le sessioni di Fiveboard aperte contemporaneamente in un browser. Per raggiungere questo (ambizioso) bersaglio creeremo un file js/hub.js, presso il quale
tutte le finestre attive del progetto dovranno registrarsi, che convoglier le informazioni da e verso una console dashboard.html. Ecco uno schema dellarchitettura (figura
2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_webworkers/2.jpg)
Le comunicazioni da e verso lo Shar edWor ker transitano attraverso oggetti chiamati MessagePor t , nellimmagine qui sopra sono esplicitate 4 MessagePor t . Una
MessagePor t utilizzata implicitamente anche dalloggetto Wor ker del capitolo precedente e quindi non ci si deve sorprendere nellapprendere che il meccanismo di
funzionamento di uno Shar edWor ker esattamente lo stesso, fatto salvo che in questo caso necessario specificare la porta attraverso la quale si vuole inviareo ricevere il
messaggio.
/ / I nvi o di un messaggi o ad uno Shar edWor ker
wor ker . por t . post Message( ' . . . ' ) ;
/ / Ri cezi one di un messaggi o da uno Shar edWor ker
wor ker . por t . onmessage = f unct i on( event o) { . . . }
/ / Dal l i nt er no di uno Shar edWor ker : i nvi o di un messaggi o
messagepor t _del _dest i nat ar i o. post Message( ' . . . ' ) ;
/ / Dal l i nt er no di uno Shar edWor ker : r i cezi one di un messaggi o
messagepor t _del _mi t t ent e. onmessage = f unct i on( event ) { . . . }
Bene, ecco in breve come dovranno comportarsi i 3 componenti che andremo a definire:
z Index.html
{ Connettersi allo SharedWorker;
{ Presentarsi come Client e specificare il proprio nome (il titolo del documento);
z Dashboard.html
{ Connettersi allo SharedWorker;
{ Presentarsi come dashboard e ricevere informazioni su tutti i Client gi registrati;
{ Essere notificata ad ogni nuova registrazione di un Client;
{ Mantenere a video un elenco dei Client registrati;
z Hub.js (SharedWorker)
{ Registrare ogni Client e notificare, se presente, la dashboard;
{ Registrare la dashboard ed inviarle tutti i Client registrati fino a quel momento.
Lo scambio di messaggi tra le varie parti avverr tramite stringhe di testo nel formato chi ave: val or e, come ad esempio r egi st r a_cl i ent : Document o di pr ova;
questa scelta non dettata dalle specifiche, che sono abbastanza lasche in tal senso, ma da una semplice convenzione adottata anche da alcuni esempi del W3C
(http://www.whatwg.org/specs/web-apps/current-work/complete/workers.html#shared-state-using-a-shared-worker).
Bene, possiamo partire; iniziamo dal file application.js che dovr assumere questo aspetto:
sal vaI l Dat o = f unct i on( i nf o_da_sal var e) {
l ocal St or age. set I t em( " f b_" + t i t ol o_f i veboar d, i nf o_da_sal var e) ;
al er t ( " Memor i zzazi one ef f et t uat a" ) ;
};
r ecuper aI l Dat o = f unct i on( el ement o) {
i f ( conf i r m( " Sost i t ui r e i l cont enut o at t ual e con l ' ul t i mo pensi er o memor i zzat o?" ) ) {
el ement o. val ue = l ocal St or age. get I t em( " f b_" + t i t ol o_f i veboar d) ;
}
};
var t i t ol o_f i veboar d = nul l ;
wi ndow. onl oad = f unct i on( ) {
var wor ker = new Shar edWor ker ( ' j s/ hub. j s' ) ;
wor ker . por t . onmessage = f unct i on( event o) {
nome_comando= event o. dat a. spl i t ( " : " ) [ 0]
val or e_comando = event o. dat a. subst r ( nome_comando. l engt h + 1) ;
consol e. l og( " Ri cevut o comando: " + nome_comando) ;
swi t ch ( nome_comando) {
case ' pr ont o' :
t i t ol o_f i veboar d = pr ompt ( " Sel ezi ona i l t i t ol o per quest a Fi veBoar d" ) ;
document . t i t l e = " FB: " + t i t ol o_f i veboar d;
wor ker . por t . post Message( " r egi st r a_cl i ent : " + t i t ol o_f i veboar d) ;
br eak;
}
}
}
Al caricamento della pagina viene attivata la funzione collegata a wi ndow. onl oad: questa crea il collegamento con lo Shar edWor ker (se il worker non gi presente verr
caricato in memoria e lanciato) e definisce una funzione di ascol t o nella quale, per ogni messaggio ricevuto, esegue particolari azioni a seconda della chiave estratta. In
questo momento la funzione reagisce alla sola chiave pronto chiedendo allutente un titolo del documento ed inviando il risultato al worker con la chiave
r egi st r a_cl i ent .
Il titolo del documento viene anche utilizzato nelle funzioni di salvataggio e di recupero del dato, per differenziare fra di loro le variabili memorizzate su Local St or age in
modo da evitare collisioni durante lapertura contemporanea di pi index.html.
Ora definiamo hub.js:
var f i veboar ds_r egi st r at e = new Ar r ay( ) ;
var dashboar d = nul l ;
pr ocessa_i l _messaggi o = f unct i on( event o) {
nome_comando = event o. dat a. spl i t ( " : " ) [ 0]
val or e_comando = event o. dat a. subst r ( nome_comando. l engt h + 1) ;
swi t ch ( nome_comando) {
case ' r egi st r a_cl i ent ' :
f i veboar ds_r egi st r at e[ val or e_comando] =event o. t ar get ;
i f ( dashboar d ! = nul l ) {
dashboar d. post Message( " nuova_f i veboar d: " + val or e_comando) ;
}
br eak;
case ' r egi st r a_dashboar d' :
dashboar d = event o. t ar get ;
f or ( f i veboar d i n f i veboar ds_r egi st r at e) {
event o. t ar get . post Message( " nuova_f i veboar d: " + f i veboar d) ;
}
br eak;
}
}
onconnect = f unct i on( nuova_f i nest r a) {
var por t = nuova_f i nest r a. por t s[ 0] ;
por t . onmessage = pr ocessa_i l _messaggi o;
por t . post Message( " pr ont o" ) ;
}
Lhandler onconnect viene invocato ogni qualvolta una pagina tenta di aprire una connessione verso il worker; nella funzione si delega al metodo
pr ocessa_i l _messaggi o la gestione dei futuri scambi tra in worker e la pagina; a questultima inoltre segnalato il concludersi delle operazioni con un messaggio
pr ont o.
La funzione pr ocessa_i l _messaggi o interpreta e gestisce le due chiavi r egi st r a_cl i ent e r egi st r a_dashboar d: nel primo caso aggiunge la MessagePor t di
comunicazione con il client ad una collezione fi veboar ds_r egi st r at e e comunica alla dashboard, se presente, la nuova aggiunta tramite un messaggio con chiave
nuova_fiveboard. Nel secondo caso registra la MessagePort della dashboard (attraverso event o. t ar get , che corrisponde ad event o. por t s[ 0] ) e comunica alla stessa
tutti client finora memorizzati attraverso un ciclo sulla collezione f i veboar ds_r egi st r at e e ad un messaggio con la gi nota chiave nuova_f i veboar d.
Perfetto, ora non ci resta che definire markup e Javascript di dashboard.html:
<ht ml l ang=' i t ' >
<head>
<met a char set =" ut f - 8" >
<t i t l e>Fi ve( Dash) Boar d: t ut t o sot t o cont r ol l o! . </ t i t l e>
<scr i pt >
var wor ker = nul l ;
get I nf o = f unct i on( t i t l e) {
/ / t o be def i ned. . .
}
i ni t = f unct i on( ) {
wor ker = new Shar edWor ker ( ' j s/ hub. j s' ) ;
wor ker . por t . onmessage = f unct i on( event o) {
nome_comando = event o. dat a. spl i t ( " : " ) [ 0]
val or e_comando = event o. dat a. subst r ( nome_comando. l engt h + 1) ;
consol e. l og( " Ri cevut o comando: " + nome_comando) ;
swi t ch ( nome_comando) {
case ' pr ont o' :
wor ker . por t . post Message( " r egi st r a_dashboar d" )
br eak;
case ' nuova_f i veboar d' :
document . get El ement ByI d( " el enco_f i veboar d" ) . i nser t Adj acent HTML( ' bef or eend' ,
" <l i >" +
" Ti t ol o: " + val or e_comando + " " +
" ( <a hr ef =' j avascr i pt : get I nf o( " " + val or e_comando +" " ) ; ' >" +
" pi i nf or mazi oni " + " </ a>) " +
" </ l i >" ) ;
br eak;
}
}
}
</ scr i pt >
</ head>
<body onl oad=" i ni t ( ) ; " >
<h1>Fi veBoar d: </ h1>
<ol i d=" el enco_f i veboar d" >
</ ol >
</ body>
</ ht ml >
Il listato largamente autoesplicativo sulla base di quanto gi enunciato: in questo caso le chiavi gestite sono pr ont o e nuova_f i veboar d: mentre la prima attiva il
meccanismo di registrazione (r egi st r a_dashboar d) appena visto in hub.js, la seconda si incarica di popolare unalista ordinata ogniqualvolta la pagina riceve una notifica
di registrazione di una nuova fiveboard.
Eseguiamo il tutto in Chromiume godiamoci il risultato dei nostri sforzi (figura 3):
Figura 3 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_webworkers/3.jpg)
possibile verificare il tutto in questa demo (http://www.html.it/guide/esempi/html5/esempi/lezione_webworkers/fiveboard/index.html).
Pi informazioni per i pi ardimentosi
Vi siete chiesti a cosa debba servire il link pi informazioni e la funzione get I nf o ad esso collegata? Lidea questa: al click sul comando il sistema deve mostrare
allutente il testo inserito ed il testo memorizzato per listanza selezionata. Per raggiungere lobiettivo ecco come interverremo:
1. La dashboard chiede allo Shar edWor ker maggiori_informazioni per una data finestra;
2. Lo Shar edWor ker mette in diretta comunicazione la finestra in oggetto e la dashboard;
3. La finestra in oggetto comunica alla dashboard testo inserito e testo memorizzato.
Ecco uno schema delle comunicazioni (figura 4):
Figura 4 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_webworkers/4.jpg)
Il punto 2 decisamente il pi interessante e si avvale di MessageChannel : trattasi di un semplicissimo oggetto, nato allinterno delle API di comunicazione HTML5
(http://www.w3.org/TR/html5/comms.html), contenente due MessagePor t ed istruito per fare in modo che ogni messaggio in ingresso alla porta1 venga recapitato alla
porta2 e viceversa.
Tutto quello che hub.js deve fare quindi creare un MessageChannel e dare i due capi del filo (le due MessagePor t ) rispettivamente alla dashboard ed al client
interessato; per fare questo risulta molto comodo il secondo argomento del metodo post Message, che consente appunto di specificare un array di porte da allegare ad un
messaggio.
Tutto chiaro? No? Vediamo le modifiche apportate al progetto:
/ / f i l e dashboar d. ht ml
/ / i nvi o del l a r i chi est a al l o Shar edWor ker ( punt o 1)
get I nf o = f unct i on( t i t l e) {
wor ker . por t . post Message( " maggi or i _i nf or mazi oni : " + t i t l e) ;
}
/ / una nuova chi ave da gest i r e.
case ' at t endi _t est o' :
event o. por t s[ 0] . onmessage = f unct i on( e) {
al er t ( e. dat a) ;
}
br eak;
/ / f i l e hub. j s
/ / una nuova chi ave da gest i r e, cr eazi one del canal e ed i nvi o del l e por t e di
/ / comuni cazi one al l a dashboar d ed al cl i ent i nt er essat o ( punt o 2)
case ' maggi or i _i nf or mazi oni ' :
var channel = new MessageChannel ( ) ;
dashboar d. post Message( " at t endi _t est o" , [ channel . por t 1] ) ;
f i veboar ds_r egi st r at e[ val or e_comando] . post Message( " r i chi edi _t est o" ,
[ channel . por t 2] ) ;
br eak;
/ / f i l e appl i cat i on. j s
/ / una nuova chi ave da gest i r e, i nvi o del l e i nf or mazi oni r i chi est e at t r aver so l a
/ / MessagePor t r i cevut a dal l event o ( non l a MessagePor t di comuni cazi one col wor ker )
/ / ( punt o 3)
case ' r i chi edi _t est o' :
event o. por t s[ 0] . post Message(
" t est o cor r ent e: " + document . f or ms[ ' f or m_da_r i cor dar e' ] . el ement s
[ ' t est o_da_r i cor dar e' ] . val ue + " n" +
" t est o memor i zzat o: " + l ocal St or age. get I t em( " f b_" + t i t ol o_f i veboar d)
) ;
br eak;
Eseguiamo il tutto in Chromiumed ammiriamone il risultato (figura 5):
Figura 5 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_webworkers/5.jpg)
Conclusioni
I Web Worker sono il classico esempio di API semplici solo in apparenza; pi ci si addentra in utilizzi concreti pi si scoprono possibilit e nuove metodologie di
sviluppo. importante ricordare infatti che sono previsti meccanismi di interazione tra i Web Workers, lApplicationCache, e i WebSocket, e che ogni WebWorker pu
invocarne altri.
Sono diretta conseguenza di questa intrinseca flessibilit delle API gli innumerevoli scenari di utilizzo ipotizzabili oltre a quello gi mostrato, come ad esempio svolgere
calcoli complessi (ogni Worker pu girare su di un core differente) quali rendering o image detection in tempo reale, centralizzare le comunicazioni con il server attraverso
uno SharedWorker e un WebSocket oppure monitorare processi browser-side.
Tabella del supporto sui browser
API e Web Applications
WebWorkers No 3.6+4.0+2.0+10.6+
WebSockets API
Le WebSockets API introducono, nella loro estrema semplicit, una funzionalit tra le pi attese ed emulate: la possibilit di stabilire e mantenere una connessione dati
tra browser e server remoto sulla quale far transitare messaggi in entrambe le direzioni. Le attuali specifiche, che lasciano ben poco spazio per implementazioni del
genere, hanno, nel corso degli anni, dato luogo a workaround pi o meno esotici tra i quali l'utilizzo di socket in Flash pilotati via J avascript e della famosa tecnica di long
polling (l'utilizzo continuo di chiamate AJ AX mantenute aperte fino alla ricezione del dato o al tempo di timeout). Le nuove API offrono invece un meccanismo ben pi
semplice grazie all'oggetto WebSocket , al metodo send e all'evento onmessage.
Prima di passare alla visione delle specifiche e al dovuto esempio di implementazione importante ricordare che questa tecnologia non consente di creare connessioni
verso altri, ben conosciuti protocolli, come ad esempio telnet, SMTP, IRC, etc., per due distinti motivi: in primo luogo lo user agent implementa una policy che blocca
l'accesso verso porte riservate a servizi conosciuti (fanno eccezione solo la 80 e la 443). In seconda istanza le comunicazioni viaggiano all'interno di un nuovo e specifico
protocollo, chiamato con molta fantasia 'The WebSocket Protocol (http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-03)' che richiama per certi aspetti,
soprattutto durante l'handshake (http://en.wikipedia.org/wiki/WebSockets#WebSocket_Protocol_Handshake), una conversazione HTTP.
Le specifche
L'utilizzo di queste API assolutamente didascalico, ci troviamo di fronte infatti a poco pi di tre metodi; vediamoli insieme:
var echo_ser vi ce = new WebSocket ( ' ws: / / echo. websocket . or g' ) ;
La creazione di un nuovo WebSocket richiede come unico parametro obbligatorio l'url verso la quale si vuole stabilire la connessione. Il protocollo pu essere ws o wss,
dove il secondo indica la richiesta di una connessione sicura. Opzionalmente possibile passare al costruttore anche una stringa o un array di sub-protocolli: valori
arbitrari utili per comunicare al server un elenco di servizi che l'oggetto in costruzione pu supportare. Ad esempio un server di chat potrebbe rispondere solo a richieste
con protocollo 'server_di_chat', e via dicendo...
echo_ser vi ce. onmessage = f unct i on( event ) {
al er t ( event . dat a) ;
}
Una volta creato un nuovo WebSocket , il funzionamento dello stesso diventa praticamente identico, nella forma, a quello gi esposto per la comunicazione tra Worker: la
funzione associata all'handler onmessage viene invocata ogniqualvolta dal server proviene un messaggio,
echo_ser vi ce. onopen = f unct i on( ) {
echo_ser vi ce. send( " hel l o! " ) ;
}
mentre la funzione send provvede all'invio, verso il server remoto, del testo passato come argomento. Da notare che l'invio deve essere necessariamente subordinato alla
condizione di avvenuta connessione, notificata tramite l'evento onopen. Esistono altri eventi all'interno del ciclo vita di un WebSocket: oncl ose e oner r or ; vediamoli
insieme completando l'esempio:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e> WebSocket : Echo Ser ver </ t i t l e>
<scr i pt >
append = f unct i on( t ext ) {
document . get El ement ByI d( " event i _websocket " ) . i nser t Adj acent HTML( ' bef or eend' ,
" <l i >" + t ext + " ; </ l i >"
) ;
}
wi ndow. onl oad = f unct i on( ) {
var echo_ser vi ce = new WebSocket ( ' ws: / / echo. websocket . or g' ) ;
echo_ser vi ce. onmessage = f unct i on( event ) {
append( " messaggi o r i cevut o" )
al er t ( event . dat a) ;
echo_ser vi ce. cl ose( ) ;
}
echo_ser vi ce. onopen = f unct i on( ) {
append( " connessi one ef f et t uat a" )
echo_ser vi ce. send( " hel l o! " ) ;
}
echo_ser vi ce. oncl ose = f unct i on( ) {
append( " connessi one chi usa" ) ;
}
echo_ser vi ce. oner r or = f unct i on( ) {
append( " er r or e nel l a connessi one" ) ;
}
}
</ scr i pt >
</ head>
<body>
<ul i d=" event i _websocket " >
</ ul >
</ body>
</ ht ml >
In questo esempio stato introdotto anche il metodo cl ose, utile per terminare una connessione. Eseguiamo l'esempio all'interno di Chromium(figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_websocket/1.jpg)
Prima di proseguire bene ricordare che il server utilizzato per questo esempio (demo (esempi/lezione_websockets/websocket.html)): echo. websocket . or g ha la
peculiarit, come il nome stesso suggerisce, di rispondere ad ogni messaggio con lo stesso testo ricevuto.
Un esempio
Nel prossimo capitolo estenderemo il progetto guida in modo che ogni FiveBoard sia connessa ad un server centrale; creeremo quindi un viewer: una pagina html
capace di connettersi ad una FiveBoard registrata presso il server e leggerne il testo mano mano esso viene digitato. Ecco lo schema (figura 2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_websocket/2.jpg)
Per poter raggiungere questo obiettivo necessario scrivere anche del codice in un linguaggio server-side. Tale codice servir per creare e istruire il WebSocket Server, al
quale le varie pagine dovranno connettersi; ai fini di questo esempio non necessario cercare un servizio di hosting sul quale installare il codice del WebSocket Server: la
nostra macchina di sviluppo andr benissimo. Per questa implementazione utilizzeremo Ruby (http://ruby.html.it), un linguaggio di programmazione elegante e conciso.
L'installazione dell'interprete Ruby veramente facile ed il codice che utilizzeremo molto leggibile. Per prima cosa colleghiamoci al portale ufficiale: http://www.ruby-
lang.org/it/downloads/ (http://www.ruby-lang.org/it/downloads/) e selezioniamo la procedura di installazione dedicata al nostro sistema operativo, quindi apriamo una
console di comando (a volte chiamata anche terminale) e digitiamo:
gemi nst al l em- websocket
Per installare la libreria necessaria allo sviluppo del WebSocket Server (per alcuni sistemi operativi necessario anteporre sudo all'istruzione).
Creiamo ora un file 'websocket_server.rb' e modifichiamone il contenuto come segue:
r equi r e ' r ubygems'
r equi r e ' em- websocket '
Event Machi ne. r un {
@channel s = Hash. new {| h, k| h[ k] = EM: : Channel . new }
Event Machi ne: : WebSocket . st ar t ( : host => " 0. 0. 0. 0" , : por t => 8080, : debug => t r ue) do |
ws|
ws. onopen do
si d = ni l
f i veboar d_channel = ni l
ws. onmessage do | msg|
command, val ue = msg. spl i t ( " : " , 2) ;
case command
when ' r egi st r a'
f i veboar d_channel = @channel s[ val ue]
si d = f i veboar d_channel . subscr i be { | t xt | ws. send( t xt ) }
when ' aggi or na'
f i veboar d_channel . push( ' t est o: ' + val ue)
end
end
ws. oncl ose do
f i veboar d_channel . unsubscr i be( si d)
end
end
end
put s " I l ser ver cor r et t ament e par t i t o"
}
Seppur possiate essere non abituati a questo linguaggio il codice tutto sommato comprensibile e succinto, ecco la spiegazionedell'algoritmo:
z Con l'istruzione WebSocket . st ar t (.. l'applicazione si mette in attesa di connessioni websocket sulla porta 8080; ogni connessione in ingresso viene memorizzata
nella variabile ws e causa l'esecuzione delle successive istruzioni (quelle comprese nell'attiguo blocco do. . end).
z Alla ricezione di un messaggio attraverso una connessione ws (ws. onmessage) il server si comporta dividendo il testo ricevuto secondo la solita convenzione
'comando: val or e' ed agendo in modo diverso a seconda che il comando sia 'registra' o 'aggiorna'.
z Nel caso il messaggio sia 'r egi st r a: t i t ol o_del _document o' il server aggiunger la connessione attuale ad un canale che porta il nome del valore del messaggio
(in questo caso 't i t ol o_del _document o'). In questo modo tutte le pagine che vorranno 'osservare' il documento 'A' non dovranno far altro che inviare al WebSocket
Server il messaggio 'r egi st r a: A'.
z Nel caso il messaggio sia 'aggi or na: t est o_del _document o' il server si comporter semplicemente inviando lungo il canale associato alla connessione corrente il
valore del messaggio (in questo caso 't est o_del _document o'), propagandolo in questo modo a tutte le connessioni registrate al canale.
z Infine con l'istruzione ws. oncl ose do. . . si gestisce, in caso di disconnessione del client, la rimozione di ws dal canale presso il quale si era registrata.
Eseguiamo il server portandoci con il terminale nella posizione dello script e digitando:
r uby websocket _ser ver . r b
Un messaggio, 'Il server correttamente partito', dovrebbe confermare la bont del nostro operato. Dedichiamoci ora alle API Javascript ed alla loro implementazione, per
prima cosa editiamo il file 'js/application.js' per fare in modo che ogni FiveBoard si registri presso il server ed invii segnali di aggiornamento ad ogni modifica del testo,
ecco il codice da inserire all'interno della funzione wi ndow. onl oad:
/ / al l ' i nt er no di wi ndow. onl oad, j s/ appl i cat i on. j s
/ / quest e due i st r uzi oni sono st at e spost at e dal l a l or o pr ecedent e posi zi one
t i t ol o_f i veboar d = pr ompt ( " Sel ezi ona i l t i t ol o per quest a Fi veBoar d" ) ;
document . t i t l e = " FB: " + t i t ol o_f i veboar d;
/ / cr eazi one di un nuovo socket ver so i l ser ver Ruby
websocket = new WebSocket ( ' ws: / / 0. 0. 0. 0: 8080' ) ;
websocket . onopen = f unct i on( ) {
/ / i nvi o del comando ' r egi st r a'
websocket . send( " r egi st r a: " + t i t ol o_f i veboar d) ;
}
/ / ad ogni var i azi one di i nput segue l ' i nvi o del comando ' aggi or na' /
/ ver so i l ser ver Ruby
document . f or ms[ ' f or m_da_r i cor dar e' ] . el ement s[ ' t est o_da_r i cor dar e' ] . oni nput = f unct i on
( event ) {
websocket . send( " aggi or na: " + event . t ar get . val ue) ;
}
Anche in questo caso l'implementazione risulta abbastanza leggibile; unico appunto da fare sull'evento oni nput , anch'esso novit introdotta dalle specifiche HTML5, che
viene invocato ad ogni attivit di input (pressione di un tasto, copia ed incolla, drag and drop,...) sull'elemento in oggetto.
Completiamo l'esempio con la creazione della semplicissima pagina 'viewer.html':
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>Fi veBoar d Vi ewer </ t i t l e>
<scr i pt >
wi ndow. onl oad = f unct i on( ) {
var document o_da_vi si onar e = pr ompt ( " I nser i sci i l nome del document o che vuoi
osser var e" ) ;
var websocket = new WebSocket ( ' ws: / / 0. 0. 0. 0: 8080' ) ;
websocket . onopen = f unct i on( ) {
document . t i t l e = " VB: " + document o_da_vi si onar e;
websocket . send( " r egi st r a: " + document o_da_vi si onar e) ;
}
websocket . onmessage = f unct i on( event o) {
nome_comando = event o. dat a. spl i t ( " : " ) [ 0]
val or e_comando = event o. dat a. subst r ( nome_comando. l engt h + 1) ;
swi t ch ( nome_comando) {
case ' t est o' :
document . get El ement ByI d( ' document o_i n_vi si one' ) . val ue = val or e_comando;
br eak;
}
}
}
</ scr i pt >
</ head>
<body>
<t ext ar ea i d=" document o_i n_vi si one" r eadonl y>Aspet t ando i l pr i mo aggi or nament o. . . </ t ext ar ea>
</ body>
</ ht ml >
In questo caso la pagina istruita nel reagire alla ricezione di un messaggio da parte del WebSocket Server; il valore ricevuto viene infatti gestito con la solita convenzione
'comando: val or e' e, nel caso il comando sia 't est o', il valore viene inserito all'interno di una textarea preposta.
Bene, eseguiamo una prova di funzionamento (http://www.html.it/guide/esempi/html5/esempi/lezione_websockets/fiveboard/index.html): sincerandoci di aver lanciato il
WebSocket Server navighiamo prima sulla pagina 'index.html' e creiamo un nuovo documento 'esempi o1', quindi apriamo una nuova finestra e puntiamola all'indirizzo di
'viewer.html': alla richiesta del nome del documento inseriamo anche qui 'esempi o1' in modo da legare il viewer alla fiveboard.
Ora proviamo a digitare alcuni caratteri sulla prima finestra e noteremo che, attraverso il server, questi sono propagati in tempo reale alla seconda! Ovviamente il tutto
funzionerebbe anche se la conversazione avvenisse tra due macchine distinte attraverso un server remoto; nell'immagine seguentesi pu notare una fiveboard aperta
sull'iPad ed il suo corrispondente viewer visibile su di un portatile; in alto i messaggi di log del WebSocket Server (figura 3).
Figura 3 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_websocket/3.jpg)
Conclusioni
I WebSocket, sono nella loro estrema semplicit, degli strumenti incredibilmente potenti; a riprova di questo fatto la rete ha gi incominciato ad offrire interessanti
prospettive di utilizzo nonostante l'innegabile giovinezza di queste API. Tra le soluzioni degne di nota merita sicuramente una citazione Pusher (http://pusherapp.com/), un
servizio che offre la possibilit di gestire eventi real-time attraverso l'utilizzo di WebSocket. Un po' pi artigianale, ma altrettanto valido http://jsterm.com/
(http://jsterm.com/), un'applicazione che consente di collegarsi a server remoti utilizzando un proxy, scritto in node.js, tra il protocollo WebSocket e Telnet.
Recentemente lo sviluppo delle API stato frenato dalla scoperta di una seria vulnerabilit [documento PDF] (http://www.adambarth.com/experimental/websocket.pdf)
legata al potenziale comportamento di un caching proxy che pu essere indotto, attraverso l'utilizzo di WebSocket ad-hoc, a modificare il contenuto delle informazioni
consegnate ad altri client. La vulnerabilit stata correttamente risolta dalla versione 0.7 del protocollo ma sfortunatamente le versioni 4 e 5 di Firefox, rilasciate prima del
fix, hanno i websocket disabilitati per default; la versione 6 del browser dovrebbe per ripristinare il funzionamento out-of-the-box di questa interessantissima feature.
Tabella del supporto sui browser
API e Web Applications
WebSockets No 4.0+(parziale) 5.0+7.0+11.0+(parziale)
Drag and Drop
La soluzione al Drag and Drop proposta dalle specifiche HTML5 (http://dev.w3.org/html5/spec/editing.html#dnd) va ben oltre la metafora classica emulata in modo
eccelso (http://jqueryui.com/demos/draggable/) da librerie come JQurey e similari. Certo, anche quel tipo di comportamento possibile, ma stiamo solo raschiando la
superficie di una feature ben pi complessa, articolata e potente. Un assaggio pi consistente delle reali capacit del Drag and Drop offerto dalla versione HTML5 del
famoso client di posta Gmail: trascinando un file al di sopra della pagina per la composizione di un nuovo messaggio si evidenza una zona verde, rilasciando il documento
al di sopra di tale zona possiamo assistere allupload dello stesso; ed il tutto funziona anche con pi file contemporaneamente! Prima di passare ad una analisi delle
specifiche bene quindi capire che questo meccanismo non stato studiato solo per riordinare liste o spostare oggetti in un carrello ma deve essere inteso come vero e
proprio sistema di input sia per informazioni interne alla pagina sia esterne.
Le specifiche
Gli attori coinvolti in queste API sono essenzialmente tre, e non necessario che siano tutti presenti ad ogni implementazione. Stiamo parlando delloggetto che subisce il
drag, della struttura che contiene i dati che intendiamo trasferire attraverso il drop, e delloggetto che accetta il drop. Ecco come funziona una sessione completa di
Drag and Drop:
<ul i d=" el ement i _da_t r asci nar e" ondr agst ar t =" i ni zi aTr asci nament o( event ) " >
<l i dr aggabl e=" t r ue" dat a- i cona=" ht t p: / / bi t . l y/ h5Khyt " dat a- val or e=" 0. 5" >50 Cent s</ l i >
<l i dr aggabl e=" t r ue" dat a- i cona=" ht t p: / / bi t . l y/ gnyFf h" dat a- val or e=" 1" > 1 Eur o </ l i >
<l i dr aggabl e=" t r ue" dat a- i cona=" ht t p: / / bi t . l y/ eXq6y5" dat a- val or e=" 2" > 2 Eur o </ l i >
<l i dr aggabl e=" t r ue" dat a- i cona=" ht t p: / / bi t . l y/ hi f t Bg" dat a- val or e=" 10" > 10 Eur o </ l i >
</ ul >
In primo luogo necessario lutilizzo dellattributo globale dr aggabl e=" t r ue" per specificare gli elementi che vogliamo rendere trascinabili; utilizziamo inoltre i campi
dat a- * per salvare informazioni che potranno tornare utili pi tardi, come lurl dellicona della moneta e il suo valore numerico. Il passo successivo consiste nel definire la
funzione associata allevento che notifica linizio di un trascinamento (ondr agst ar t ), nel nostro caso levento stato associato allul , in quanto sottende lintero elenco
degli elementi con il comportamento drag abilitato.
<scr i pt >
i ni zi aTr asci nament o = f unct i on( event o) {
event o. dat aTr ansf er . set Dat a( " t ext " , event . t ar get . dat aset . val or e) ;
event o. dat aTr ansf er . ef f ect Al l owed = ' copy' ;
i cona = document . cr eat eEl ement ( ' i mg' ) ;
i cona. sr c = event o. t ar get . dat aset . i cona;
event o. dat aTr ansf er . set Dr agI mage( i cona, - 10, - 10) ;
}
</ scr i pt >
Nellargomento evento lo user-agent si premura di fornirci tutto il necessario per gestire il trascinamento dellelemento. Nellaprima riga della funzione viene invocata la
struttura dat aTr ansf er , atta a contenere i dati che vogliamo siano disponibili alloggetto incaricato del drop; con il metodo set Dat a richiediamo poi linserimento di un
nuovo valore allinterno di tale struttura. Stando alle specifiche potremmo identificare questo valore con unetichetta (usando il primo argomento, ad esempio val ut a),
in questo modo saremmo poi in grado di istruire larea di drop ad accettare solo il rilascio di elementi con tale etichetta; nella realt questa funzionalit non ancora
supportata in modo sufficiente (http://code.google.com/p/chromium/issues/detail?id=31037) e funziona solo con etichette text o url. Come secondo argomento alla
chiamata specifichiamo invece il contenuto del campo dat a- val or e dellelemento che sta subendo il trascinamento.
Nella riga successiva, con listruzione event o. ef f ect Al l owed = ' copy' segnaliamo allo user-agent che lazione di drag da intendersi come copia e non, ad esempio,
come spostamento (in quel caso sarebbe stato 'move'). importante notare che tale segnalazione non implica di per s nessun cambiamento alla dinamica dello user-agent
nei confronti di questo drag and drop (se non qualche accortezza grafica, come vedremo poi) ma ci da ancora una volta la possibilit di filtrare in fase di drop gli elementi
che rilasciamo accettando, ad esempio, solamente azioni di tipo 'copy'.
Le due righe di codice seguenti servono invece per creare una immagine avente come sr c il campo dat a- i cona dellelemento che stiamo trascinando; infine con lultima
istruzione, event o. dat aTr ansf er . set Dr agI mage( i cona, - 10, - 10) , comunichiamo al dat aTr ansf er di usare limmagine appena generata come oggetto da
visualizzare durante il trascinamento.
Se proviamo ad includere i due frammenti di codice in una classicastruttura HTML5 e ad eseguirli con Chromiumavremo questo effetto (figura 1):
Figura 1
Bene, ora creiamo loggetto di drop e gestiamo lazione di rilascio:
. . .
</ ul >
<i mg i d=" por t amonet e"
dr opzone=" copy s: t ext "
dr aggabl e=" f al se"
sr c=" ht t p: / / bi t . l y/ gZH4H5"
ondr agent er =" i ngr essoI nZonaDi Dr op( event ) "
ondr agl eave=" usci t aZonaDi Dr op( event ) "
ondr agover =" t r asci nament oI nZonaDi Dr op( event ) "
ondr op=" r i l asci oDel l Ogget t oTr asci nat o( event ) "
>
<p> I l por t amonet e cont i ene: <out put i d=" sommat or i a" >0</ out put > eur o</ p>
Cos come ogni elemento HTML pu essere impostato come trascinabile grazie allattributo dr aggabl e=t r ue, anche il ruolo di area di drop pu essere delegato a
qualsiasi tag. In questo caso abbiamo scelto di utilizzare unimmagine di un portamonete nel quale riporremo i nostri risparmi. Diamo una scorsa agli attributi che abbiamo
impostato:
z dr opzone: con questo attributo, purtroppo ancora poco supportato, possibile specificare in modo sintetico ed efficace le varie tipologie di dati per i quali larea
di drop abilitata. I primi comandi, separati da uno spazio, indicano le tipologie di ef f ect Al l owed supportate (in questo caso solamente copy) mentre le restanti
istruzioni, nel formato s: t est o o f : t est o rappresentano in caso di s: t est o le etichette supportate, o i mime-type supportati nel caso di f : t est o. La particella s
indica che il contenuto del dat aTr ansf er deve essere di natura testuale (come nellesempio che stiamo studiando), mentre la particella f implica che larea di drop
accetti solamente file, come ad esempio succede nel caso dellaggiunta di allegati alla Gmail. Validi esempi di valorizzazione di questo attributo sono i seguenti:
- - Accet t a copy per f i l e di t i po png e j peg
dr opzone=" copy f : i mage/ png f : i mage/ j peg"
- - Accet t a move e copy per et i chet t e " val ut a"
dr opzone=" move copy s: val ut a"
z dr aggabl e: conosciamo gi questo attributo; in ogni caso importante segnalare che qui stato utilizzato per informare lo user-agent di non rendere trascinabile
questa immagine. Infatti nella maggioranza dei browser le immagini lo sono di default;
z ondr agent er , ondr agmove e ondr agl eave: questi tre eventi vengono invocati quando lelemento viene trascinato allinterno di unarea di drop (ondr agent er ),
mosso allinterno della stessa (ondr agmove) e infine spostato nuovamente allesterno dellarea (ondr agl eave);
z ondr op: levento chiave dellintero processo, viene invocato al rilascio di un elemento al di sopra di un area di drop.
Ottimo! Non ci resta che completare questa panoramica delle specifiche osservando una possibile implementazione degli eventi appena descritti:
. . .
i ngr essoI nZonaDi Dr op = f unct i on( event o) {
event o. t ar get . sr c = " ht t p: / / bi t . l y/ gRo6cc" ;
event o. pr event Def aul t ( ) ;
}
usci t aZonaDi Dr op = f unct i on( event o) {
event o. t ar get . sr c = " ht t p: / / bi t . l y/ gZH4H5" ;
}
t r asci nament oI nZonaDi Dr op = f unct i on( event o) {
event o. dat aTr ansf er . dr opEf f ect = ' copy' ;
event o. pr event Def aul t ( ) ;
}
r i l asci oDel l Ogget t oTr asci nat o = f unct i on( event o) {
sommat or i a = document . get El ement ByI d( " sommat or i a" ) ;
sommat or i a. i nner HTML = par seFl oat ( sommat or i a. i nner HTML) + par seFl oat
( event o. dat aTr ansf er . get Dat a( " t ext " ) ) ;
event o. t ar get . sr c = " ht t p: / / bi t . l y/ gZH4H5" ;
}
. . .
Listruzione che merita maggiore attenzione sicuramente pr event Def aul t ( ) che, se posizionata allinterno di un evento, impedisce al browser di attivare il proprio
comportamento di default. In questo caso la funzione in questione stata utilizzata in i ngr essoI nZonaDi Dr op per impedire che il browser negasse laccesso al drop
(comportamento di default) ed in t r asci nament oI nZonaDi Dr op per evitare lanimazione di ritorno degli elementi draggati al loro rilascio.
Per il resto le due funzioni associate a ondr agent er e ondr agl eave si preoccupano solamente di alternare, tra chiusa e aperta, limmagine del portamonete allingresso (o
uscita) di un elemento trascinato al di sopra di esso. t r asci nament oI nZonaDi Dr op deve invece preoccuparsi nuovamente di segnalare il supporto al solo effetto copy;
questo accorgimento non sarebbe necessario con un pieno supporto dellattributo dr opzone.
Infine la funzione legata allevento ondr op contiene limportante metodo get Dat a( et i chet t a) , indispensabile per recuperare dal dat aTr ansf er lultimo oggetto inserito
con letichetta richiesta. Eseguiamo il tutto in Chromiumnotando anche come licona del mouse si modifichi durante lazione di drag and drop ad indicare la copia (figura
2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_drag/2.jpg)
Ecco la demo (http://www.html.it/guide/esempi/html5/esempi/lezione_drag/demo.html).
Un esempio
Visto che non abbiamo ancora sperimento il drag and drop di file, utilizziamo il progetto guida per fare alcune prove; in particolare implementiamo la possibilit di
rilasciare un file di testo al di sopra di una textarea per fare in modo che in questa vi si riversi il contenuto. Questo esempio ci dar anche loccasione di toccare con
mano la potenza delle nuove File API (http://www.w3.org/TR/FileAPI/), in particolare approfondiremo gli oggetti J avascript Fi l e, Fi l eLi st e Fi l eReader : ottimi
compagni nel caso sia necessario accedere agli attributi o al contenuto di un file selezionato (o trascinato) per lupload.
Incominciamo modificando il markup del file index.html per attivare una drop area sulla textarea:
<l abel >Cosa hai i n ment e?
<t ext ar ea name=" t est o_da_r i cor dar e" r equi r ed aut of ocus
pl acehol der =" La l i st a del l a spesa, i l t eat r o di quest a ser a . . . "
dr opzone=" copy f : t ext / pl ai n"
ondr agover =" consent i I l Dr op( event ) "
ondr op=" car i caI l Cont enut oTest ual e( event , t hi s) " >
</ t ext ar ea>
</ l abel >
Fin qui niente di strano, la parte divertente tutta racchiusa nella definizione delle due funzioni. Vediamole insieme nel file 'application.js':
consent i I l Dr op = f unct i on( event o) {
event o. dat aTr ansf er . dr opEf f ect = ' copy' ;
event o. pr event Def aul t ( ) ;
}
car i caI l Cont enut oTest ual e = f unct i on( event o, el ement ) {
var f i l es = event o. dat aTr ansf er . f i l es;
var r eader = new Fi l eReader ( ) ;
r eader . onl oad = f unct i on( event o) {
el ement . val ue = el ement . val ue + event o. t ar get . r esul t ;
}
f or ( f i l e i n f i l es) {
r eader . r eadAsBi nar ySt r i ng( f i l es[ f i l e] ) ;
}
}
La funzione car i caI l Cont enut oTest ual e merita un approfondimento: il metodo f i l es chiamato su dat aTr ansf er ritorna un elenco di Fi l e racchiusi in un oggetto di
tipo Fi l eLi st , che per i nostri scopi assimilabile ad un array.
Successivamente, nella variabile r eader , viene caricata un istanza di Fi l eReader , una classe predisposta esclusivamente alla lettura del contenuto degli oggetti di tipo
Fi l e. Nelle righe successive viene impostata lazione associata allevento onl oad di r eader , che viene invocato al completamento dellazione di lettura di un file;
allinterno di questa azione il contenuto testuale del file (event o. t ar get . r esul t ) concatenato al testo gi presente nella textarea. Lultimo frammento di questa
funzione cicla su tutti i file presenti in f i l es; successivamente su ognuno di essi viene richiesta la lettura al reader attraverso il metodo r eadAsBi nar ySt r i ng.
Anche per questo esempio abbiamo preparato una demo (http://www.html.it/guide/esempi/html5/esempi/lezione_drag/fiveboard/index.html). Funziona al momento solo su
Chromium. Per il test basta creare un file di testo, salvarlo (magari sul desktop) e trascinarlo nella textarea.
Tabella del supporto sui browser
API e Web Applications
Drag and Drop No 3.5+3.2+2.0+No
Geolocation API
Le Geolocation Api non sono contenute allinterno dellHTML5 ma fanno parte di quellinsieme di documenti (http://dev.w3.org/geo/api/spec-source.html) che gravitano
attorno alle specifiche; la loro funzionalit abbastanza semplice, definire una struttura dati atta a contenere vari dati geospaziali e impostare alcune funzioni di
accesso a tali dati. Nessuna menzione viene fatta in merito ai meccanismi che il browser deve utilizzare per recuperare questi dati, ogni piattaforma infatti tenuta ad
utilizzare al meglio le informazioni provenienti dal device. Su di un dispositivo mobile di ultima generazione avremo quindi un set di coordinate provenienti dal sensore
GPS, mentre su di un portatile potremo avvalerci del posizionamento legato allip della connessione internet.
Per proteggere la privacy dellutente inoltre fatto divieto di utilizzo delle suddette informazioni senza preventivo consenso esplicito.
Le specifiche
Esistono praticamente solo due metodi a disposizione, fra laltro entrambi utili allo stesso scopo: ottenere la posizione corrente. La differenza tra i due,
get Cur r ent Posi t i on e wat chPosi t i on, va ricercata nella loro periodicit, mentre il primo metodo fornisce il dato una sola volta, il secondo si attiva automaticamente
ogniqualvolta la posizione cambi, ad esempio perch lutente sta passeggiando.
La sintassi per invocare questi metodi la seguente:
navi gat or . geol ocat i on. get Cur r ent Posi t i on( i nCasoDi Successo, opzI nCasoDi Er r or e, opzi oni ) ;
navi gat or . geol ocat i on. wat chPosi t i on( i nCasoDi Successo, opzI nCasoDi Er r or e, opzi oni ) ;
Il primo argomento contiene i riferimenti ad una funzione da eseguire al corretto recupero delle informazioni geospaziali, il secondo argomento, opzionale, punta invece ad
una funzione che verr invocata in caso di errore. Lultimo parametro, anchesso facoltativo, pu essere utilizzato per specificare alcune opzioni utilizzando una struttura
{opzione1: valore1, ...}. Le opzioni disponibili sono 3:
z enabl eHi ghAccur acy ( t r ue/ f al se) : questo flag pu essere utilizzato per notificare allo user-agent la necessit o meno di ottenere dati il pi accurati possibile.
Lopzione stata introdotta in quanto il recupero di informazioni pi dettagliate richiede di solito maggiore dispendio di tempo ed energia e, in particolare su device
mobile, potrebbe risultare fastidiosa per lutente;
z t i meout ( mi l l i secondi ) : lopzione rappresenta il tempo massimo concesso al browser per recuperare la posizione dellutente. In caso di fallimento verr invocata
la funzione associata al secondo argomento;
z maxi muAge ( mi l l i secondi ) : indica al browser di effettuare una ricerca preventiva nella cache di un dato geospaziale non pi vecchio dei millisecondi specificati.
Se disponibile tale dato verr restituito come posizione corrente, altrimenti verr eseguita la procedura classica.
La funzione invocata in caso di successo deve accettare un singolo argomento, un oggetto di tipo Posi t i on che contiene tutte le informazioni recuperate cos come un
timestamp delle data e ora di recupero.
i nCasoDi Successo = f unct i on( posi t i on) {
al er t ( " Posi zi one del l e: " + posi t i on. t i mest amp. get Hour s( ) + " : " +
posi t i on. t i mest amp. get Mi nut es( ) + " n" +
" Accur at ezza del l e coor di nat e: " + posi t i on. coor ds. accur acy + " mt ; n" +
" Lat i t udi ne: " + posi t i on. coor ds. l at i t ude + " gr adi ; n" +
" Longi t udi ne: " + posi t i on. coor ds. l ongi t ude + " gr adi ; n" +
" Accur at ezza del l ' al t ezza: " + posi t i on. coor ds. al t i t udeAccur acy + " mt ; n" +
" Al t ezza: " + posi t i on. coor ds. al t i t ude + " mt ; n" +
" Di r ezi one: " + posi t i on. coor ds. headi ng + " gr adi n " +
" ( 0 = Nor d, 90 = Ovest , 180 = Sud, 270 = Est ) ; n" +
" Vel oci t a: " + posi t i on. coor ds. speed + " m/ s; "
) ;
}
Nel frammento di codice appena illustrato possiamo vedere tutte le informazioni estraibili dalla struttura Posi t i on; chiaramente, a seconda del device sul quale viene
effettuata linterrogazione, non tutte saranno sempre disponibili; in tal caso il loro valore sar impostato a nul l . Nellimmagine seguente il risultato dellinterrogazione
eseguita dal mio portatile domestico (notate laccuratezza!):
Figura 1 - (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_geolocation/ishot-437.png)
In caso invece si verifichi un errore la funzione preposta deve accettare anchessa un parametro, un oggetto di tipo Posi t i onEr r or contenente un codice di errore ed un
messaggio ad uso di debug, rispettivamente nei metodi code e message.
opzI nCasoDi Er r or e = f unct i on( er r or ) {
al er t ( " Er r or e " + er r or . code + " : " + er r or . message) ;
}
In ultimo ricordiamo che un invocazione del metodo wat chPosi t i on pu essere successivamente interrotta utilizzando la funzione cl ear Wat ch, come nellesempio
seguente:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e> Un esempi o di wat chPosi t i on</ t i t l e>
<scr i pt >
var i d_wat ch = nul l ;
i nCasoDi Successo = f unct i on( posi t i on) {
document . get El ement ByI d( " posi zi one_cor r ent e" ) . i nser t Adj acent HTML( ' bef or eend' ,
" <l i > Lat : " + posi t i on. coor ds. l at i t ude + " , Lon: " + posi t i on. coor ds. l ongi t ude + ) ;
" </ l i >"
) ;
}
sospendi LaRi cezi one = f unct i on( ) {
navi gat or . geol ocat i on. cl ear Wat ch( i d_wat ch) ;
}
wi ndow. onl oad = f unct i on( ) {
i d_wat ch = navi gat or . geol ocat i on. wat chPosi t i on( i nCasoDi Successo) ;
}
</ scr i pt >
</ head>
<body>
<h1>La t ua posi zi one at t ual e</ h1>
<menu t ype=" t ool bar " >
<but t on t ype=" but t on" oncl i ck=" sospendi LaRi cezi one( ) " >
sospendi l a r i cezi one di dat i geospazi al i
</ but t on>
</ menu>
<ul i d=" posi zi one_cor r ent e" >
</ ul >
</ body>
</ ht ml >
Sono disponibili le demo per il primo (http://www.html.it/guide/esempi/html5/esempi/lezione_geolocation/geolocation.html) e per il secondo esempio
(http://www.html.it/guide/esempi/html5/esempi/lezione_geolocation/geolocation_watchposition.html).
Conclusioni
Come avete potuto notare questo set di API contemporaneamente facilissimo da utilizzare ed estremamente potente. Le possibilit offerte si dilatano enormemente se ci
si concentra sul mercato mobile dove la stragrande maggioranza dei device di ultima generazione equipaggiata con ottimi sensori GPS e bussole.
Tabella del supporto sui browser
API e Web Applications
Geolocation No 3.6+5.0+5.0+10.6+
Canvas
Una tela trasparente
Il canvas di HTML5 un elemento rappresentato dal tag <canvas>. Pu essere inteso come il corrispettivo digitale di una tela trasparente: uno spazio all'interno di una
pagina web sul quale insistere con specifiche API (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#the-canvas-element) adatte a
tracciare linee, cerchi, rettangoli, immagini e altro ancora.
Il canvas , in estrema sintesi, una grande matrice di pixel, ognuno dei quali modificabile singolarmente nelle sue quattro componenti RGBA, rosso, verde, blu e alpha, la
trasparenza. Tutti siamo a conoscenza di questo elemento HTML5 per una sua semplice attitudine: la possibilit di replicare i comportamenti fino ad oggi appannaggio
della tecnologia Flash. In questo articolo esploreremo le numerose API disponibili e ne sperimenteremo una buona parte per poi concentrarci successivamente su di una
interessante evoluzione del progetto guida.
Le specifiche
Prima di addentrarci nella giungla dei vari metodi a disposizione per disegnare sul canvas vediamo brevemente l'architettura che contraddistingue il markup
dell'elemento:
<canvas wi dt h=" 200px" hei ght =" 200px" i d=" demo_canvas" >
Cont enut o da most r ar e i n caso i l canvas non si a suppor t at o.
( qui ndi anche i nf or mazi oni per i mot or i di r i cer ca) .
</ canvas>
Gli unici due attributi disponibili, oltre ai canonici globali, sono wi dt h e hei ght , rispettivamente larghezza e altezza dell'elemento.
Sotto il profilo J avaScript i metodi disponibili direttamente attraverso questo elemento sono due: t oDat aUr l e get Cont ext . Il primo, t oDat aUr l , fantastico nella sua
semplicit: ritorna infatti il contenuto del canvas secondo il protocollo 'data URL' (http://tools.ietf.org/html/rfc2397). Questo schema memorizza file di ogni tipo in
lunghissime sequenze di caratteri, che poi possono essere salvati su disco o, se come nel caso del canvas siano immagini, essere utilizzate come attributo sr c di tag i mg.
Nei prossimi esempi vedremo un utilizzo tangibile di questo metodo, per ora invece concentriamoci su get Cont ext , vera e propria 'porta' verso le API di disegno.
get Cont ext , quando invocato, ritorna un oggetto detto contesto del disegno:
var canvas = document . get El ement ByI d( " demo_canvas" ) ;
var cont est o = canvas. get Cont ext ( " 2d" ) ;
In questa lezione esploreremo solamente i metodi legati al contesto di disegno '2d', come specificato dall'argomento utilizzato nello snippet, ma sappiate che esiste gi una
versione sperimentale di contesto '3d' che sottende un set di API completamente diverso, basato sulle OpenGL ES 2.0 e detto WebGL.
Ma torniamo al contesto '2d': possiamo dividere le funzionalit in esso racchiuse in categorie: path, modificatori, immagine, testo e pixel per pixel; nelle prossime
sezioni affronteremo in dettaglio ognuno di questi aspetti. Prima di proseguire per importante evidenziare che il contesto un oggetto stateful, che mantiene cio al suo
interno dei valori che influiscono sulle operazioni successive; aspettiamoci quindi delle direttive di questo tipo:
z imposta colore di linea verde;
z imposta percorso della linea da (0,0) a (10,10);
z traccia tutti i percorsi di linea.
In questo caso, se avessimo usato le corrette API, avremmo ottenuto una linea verde tra i punti (0,0) e (10,10). L'insieme dei valori memorizzati in un contesto viene detto
drawing state.
Path
I metodi di questa categoria sono tutti funzionali al disegno di frammenti geometrici come linee, archi e quant'altro: ecco un esempio omnicomprensivo:
di segnaBar chet t a = f unct i on( cont est o) {
cont est o. begi nPat h( ) ;
/ / spost a i l cur sor e del pat h nel l a posi zi one 40, 170
cont est o. moveTo( 40, 170) ;
/ / cr ea un subpat h l i nea f i no al l a posi zi one 260, 170
cont est o. l i neTo( 260, 170) ;
/ / cr ea un subpat h ar co che si a t angent e al l e due l i nee ( 260, 170 - 150, 250)
/ / ( 150, 250 - 40, 170) con di amet r o 150
cont est o. ar cTo( 150, 250, 40, 170, 150) ;
cont est o. l i neTo( 40, 170) ;
cont est o. moveTo( 150, 170) ;
cont est o. l i neTo( 150, 40) ;
cont est o. r ect ( 150, 40, 60, 30) ;
/ / di segna t ut t i i subpat h del pat h cor r ent e sul canvas usando l a
/ / conf i gur azi one del dr awi ng st at e
cont est o. st r oke( ) ;
/ / r i empi t ut t i l e ar ee i nscr i t t e dal pat h cor r ent e usant o l a conf i gur azi one
/ / del deawi ng st at e
cont est o. f i l l ( ) ;
}
Il concetto principe il path, ovverosia un insieme di punti uniti fra loro da definite primitive geometriche (arco, linea,...), dette subpath. Ogni contesto possiede
solamente un path attivo per volta. Per aggiungere un subpath al path attivo si possono utilizzare metodi come l i neTo, ar cTo, r ect e altri. Metodi come st r oke e f i l l
vengono applicati a tutti i subpath del path attivo. Per resettare il path attivo, rimuovendo quindi tutti i subpath non ancora disegnati, si utilizza l'istruzione begi nPat h( ) .
Eseguiamo l'esempio appena mostrato per ottenere il risultato seguente (figura 1):
Figura 1
Oltre ai subpath mostrati ce ne sono altri, ma il meccanismo di generazione resta sempre lo stesso, la lista completa disponibile nel documento ufficiale delle specifiche
(http://dev.w3.org/html5/2dcontext/#complex-shapes-paths).
Modificatori
Le funzioni all'interno di questo gruppo insistono sul drawing state di un canvas, modificando il modo in cui i path, le immagini ed i testi vengono disegnati. Nella
categoria si annoverano matrici di trasformazione (scal e, r ot at e, t r ansl at e), gestione della trasparenza globale e delle funzioni di composizione nonch
impostazioni di colore, di linea e di gradiente. Suona complicato ? Facciamo un po' di prove:
cont est o. scal e( 0. 5, 0. 5) ;
cont est o. r ot at e( 0. 5) ;
cont est o. t r ansl at e( 300, - 100) ;
di segnaBar chet t a( cont est o) ;
Ecco il risultato, i modificatori impostati vengono applicati alla barchetta (figura 2):
Figura 2
Utilizziamo ora trasparenza e composizione:
cont est o. gl obal Al pha = 0. 5;
di segnaBar chet t a( cont est o) ;
cont est o. t r ansl at e( 40, - 0) ;
cont est o. gl obal Composi t eOper at i on = " sour ce- out " ;
di segnaBar chet t a( cont est o) ;
L'attributo gl obal Al pha definisce (da 0.0 a 1.0) il livello di trasparenza che dovr essere applicato a quanto verr disegnato sul canvas. gl obal Composi t eOper at i on ci
permette invece di specificare in che modo vogliamo che le immagini vengano sovrapposte: possibile utilizzare un set di parole chiave per indicare un ben preciso
comportamento; in questo caso con sour ce- out chiediamo allo user agent di effettuare una somma tra le trasparenze ottenendo un risultato come questo (figura 3):
Figura 3
Attenzione, al momento non tutti i browser reagiscono allo stesso modo alle definizioni legate a Gl obal Composi t eOper at i on. Infine esaminiamo anche le operazioni
legate ai modificatori di colore:
cont est o. st r okeSt yl e = " #FF0000" ;
cont est o. l i neWi dt h = " 5" ;
var gr adi ent e = cont est o. cr eat eRadi al Gr adi ent ( 150, 150, 30, 150, 160, 100) ;
gr adi ent e. addCol or St op( 0. 5, ' #0000FF' ) ;
gr adi ent e. addCol or St op( 0. 1, ' #000000' ) ;
cont est o. f i l l St yl e = gr adi ent e;
di segnaBar chet t a( cont est o) ;
Con st r okeSt yl e e f i l l St yl e possiamo impostare le nostre preferenze su come intendiamo debba essere disegnata la linea di contorno degli oggetti (stroke) ed il loro
riempimento (fill). Entrambi gli attributi possono essere valorizzati con stringhe, oggetti di tipo gr adi ent ed oggetti di tipo pat t er n. In questo caso mostrato l'utilizzo di
una semplice stringa di colore rosso per lo stroke e di un gradient radiale con una variazione di colore dal nero al blu per il fill. L'utilizzo dell'oggetto pat t er n simile, il
metodo da utilizzare cont est o. cr eat ePat t er n( i mmagi ne, opzi onal eRi pet i zi one) dove il secondo argomento riprende le scelte effettuabili via CSS (no- r epeat ,
r epeat - x, ecc..) mentre il primo pu essere valorizzato con con un elemento i mg, un altro canvas o perfino un elemento video. Ecco il risultato che si ottiene utilizzando il
codice visto (figura 4):
Figura 4
Prima di passare al prossimo gruppo di funzioni citiamo brevemente anche la possibilit di implementare un ombreggiatura, ecco le istruzioni:
cont est o. shadowCol or = ' #003300'
cont est o. shadowOf f set X = 10;
cont est o. shadowOf f set Y = 10;
cont est o. shadowBl ur = 30;
di segnaBar chet t a( cont est o) ;
Ed il risultato (figura 5):
Figura 5
Immagini nel Canvas HTML5
L'unico metodo appartenente a questo gruppo si chiama dr awI mage ed disponibile in un certo numero di varianti; il primo argomento pu infatti essere sia un elemento
immagine, sia un altro canvas, sia un elemento di tipo video. Il risultato dell'operazione sempre quello di disegnare sul contesto invocante l'immagine prescelta,
rispettando alcuni parametri dimensionali opzionali. Ecco un esempio:
var i mmagi ne = new I mage( ) ;
i mmagi ne. sr c = " ht t p: / / i mg227. i mageshack. us/ i mg227/ 7092/ mar ei . j pg" ;
cont est o. dr awI mage( i mmagi ne, 0, 0) ;
di segnaBar chet t a( cont est o) ;
E il risultato (figura 6):
Figura 6
In questo caso chiediamo che l'immagine sia disegnata a partire dall'angolo in alto a sinistra del canvas (coordinate 0,0); possiamo per anche specificare una dimensione
di destinazione e perfino un rettangolo di partenza in modo da prelevare solo una porzione di immagine utilizzando i numerosi argomenti opzionali messi a disposizione
dalle specifiche.
Testo nel Canvas HTML5
Come il nome del gruppo suggerisce, questi metodi permettono di scrivere porzioni di testo all'interno di un canvas, eccone un esempio:
di segnaBar chet t a( cont est o) ;
cont est o. gl obal Composi t eOper at i on = " sour ce- out " ;
cont est o. f ont = " 34px Geor gi a"
cont est o. st r okeText ( " Va va va bar chet t a" , 20, 100) ;
cont est o. f i l l Text ( " va, navi ga navi ga navi ga" , 20, 140) ;
cont est o. f i l l Text ( " navi ga e mai si " , 20, 180) ;
cont est o. f i l l Text ( " f er mer a' . . . " , 20, 220) ;
L'attributo f ont pu essere valorizzato allo stesso modo del suo omonimo su CSS, per il resto f i l l Text provvede a scrivere il testo desiderato partendo dalla posizione x,
y specificata come secondo e terzo argomento; anche st r okeText si comporta in modo simile ma con una piccola variante che si pu facilmente evincere dal risultato
dell'esecuzione dell'esempio. Da notare inoltre il comportamento interessante dell'applicazione di un particolare tipo di composizione (figura 7):
Figura 7
Pixel per Pixel
Come gi anticipato in precedenza, il canvas non nient'altro che una matrice di valori in formato RGBA: non stupisce che sia quindi possibile insistere su ogni singolo e
specifico pixel della stessa; ecco un esempio:
di segnaBar chet t a( cont est o) ;
var dat i _i mmagi ne = cont est o. get I mageDat a( 0, 0,
cont est o. canvas. wi dt h, cont est o. canvas. hei ght ) ;
var ar r ay_dat i _i mmagi ne = dat i _i mmagi ne. dat a;
f or ( var i = 0; i < ar r ay_dat i _i mmagi ne. l engt h; i +=4 ) {
ar r ay_dat i _i mmagi ne[ i ] = Mat h. r ound( Mat h. r andom( ) * 255) ;
ar r ay_dat i _i mmagi ne[ i +1] = Mat h. r ound( Mat h. r andom( ) * 255) ;
ar r ay_dat i _i mmagi ne[ i +2] = Mat h. r ound( Mat h. r andom( ) * 255) ;
}
dat i _i mmagi ne. dat a = ar r ay_dat i _i mmagi ne;
cont est o. canvas. wi dt h = cont est o. canvas. wi dt h;
cont est o. put I mageDat a( dat i _i mmagi ne, 0, 0) ;
Il fulcro dello snippet da ricercarsi nelle due funzioni get I mageDat a e put I mageDat a che rispettivamente prelevano e 'stampano' sul canvas una porzione di immagine
delineata dagli argomenti passati. Tale porzione, un oggetto di classe I mageDat a, possiede in una sua propriet, data, un lunghissimo array contenente le componenti
RGBA di ogni pixel. Il ciclo for presentato nel codice precedente insiste proprio su questo array assegnando ad ognuna delle tre componenti RGB un valore randomico.
Ecco il risultato (figura 8):
Figura 8
Per una verifica diretta di quanto visto nel corso della lezione disponibile questa demo (http://www.html.it/guide/esempi/html5/esempi/lezione_canvas/index.html).
Ora che abbiamo almeno un'idea delle potenzialit dello strumento che stiamo analizzando, accingiamoci ad una sperimentazione pratica attraverso il progetto guida. Lo
vedremo nella prossima lezione.
Supporto sui browser del Canvas HTML5
Grafica e Multimedia
<canvas> 9.0+2.0+3.1+2.0+10.0+
Canvas: un esempio pratico
Un esempio
Ora che abbiamo almeno un'idea delle potenzialit dello strumento che stiamo analizzando, accingiamoci ad una sperimentazione pratica attraverso il progetto guida.
Quello che faremo sar dare la possibilit agli utenti della fiveboard di disegnare utilizzando un canvas, lo stesso verr poi memorizzato insieme al testo sul gi noto
l ocal St or age. Introduciamo anche in questo contesto il concetto di Event oCust om, la possibilit cio di lanciare arbitrariamente eventi in tutto e per tutto simili a quelli
utilizzati dal DOM. Questa feature ci sar utilissima per mantenere un codice elegante e contemporaneamente sincronizzare salvataggio e recupero di testo e canvas dal
l ocal St or age; aggiungiamo ad application.js il seguente metodo:
l anci aEvent o = f unct i on( nome_event o) {
var event o = document . cr eat eEvent ( " Cust omEvent " ) ;
event o. i ni t Cust omEvent ( nome_event o, t r ue, t r ue, t i t ol o_f i veboar d) ;
document . di spat chEvent ( event o) ;
}
Eliminiamo successivamente dallo stesso file le funzioni sal vaI l Dat o e r ecuper aI l Dat o sostituendole con le seguenti:
sal vaAppunt i = f unct i on( event o) {
l ocal St or age. set I t em( " f b_" + event o. det ai l ,
document . f or ms[ ' f or m_da_r i cor dar e' ] . el ement s[ ' t est o_da_r i cor dar e' ] . val ue
) ;
al er t ( " Appunt i sal vat i " ) ;
}
r ecuper aAppunt i = f unct i on( event o) {
document . f or ms[ ' f or m_da_r i cor dar e' ] . el ement s[ ' t est o_da_r i cor dar e' ] . val ue =
l ocal St or age. get I t em( " f b_" + event o. det ai l ) ;
al er t ( " Appunt i r ecuper at i " ) ;
}
document . addEvent Li st ener ( ' sal vadat o' , sal vaAppunt i ) ;
document . addEvent Li st ener ( ' r ecuper adat o' , r ecuper aAppunt i ) ;
Bene, ora abbiamo creato le due funzioni e le abbiamo registrate rispettivamente agli eventi customsal vadat o e r ecuper adat o; ora non ci resta che scatenare questi
eventi al click dei bottoni del file index.html, modifichiamo quindi come segue:
. . .
<menu t ype=" t ool bar " >
<but t on t ype=" but t on" oncl i ck=" l anci aEvent o( ' sal vadat o' ) ; " >
Memor i zza quant o scr i t t o
</ but t on>
<but t on t ype=" but t on" oncl i ck=" l anci aEvent o( ' r ecuper adat o' ) ; " >
Recuper a l ' ul t i mo t est o memor i zzat o
</ but t on>
</ menu>
. . .
Ottimo! Ora possiamo aggiungere un canvas poco prima della fine della pagina e procedere con il nostro esperimento:
. . .
<canvas i d=" dr awboar d" ></ canvas>
</ f or m>
. . .
In un file chiamato canvas.js, sempre nella cartella js, scriviamo:
var ct x = nul l ;
var st ar t ed = f al se;
i ni zi aDi segno = f unct i on( event o) {
ct x. begi nPat h( ) ;
ct x. moveTo( event o. of f set X, event o. of f set Y) ;
st ar t ed = t r ue;
}
di segna = f unct i on( event o) {
i f ( st ar t ed) {
ct x. l i neTo( event o. of f set X, event o. of f set Y) ;
ct x. st r oke( ) ;
}
}
f er maDi segno = f unct i on( event o) {
ct x. cl osePat h( ) ;
st ar t ed = f al se;
}
sal vaCanvas = f unct i on( event o) {
l ocal St or age. set I t em( " canvas_f b_" + event o. det ai l , ct x. canvas. t oDat aURL( ' i mage/ png' ) ) ;
al er t ( " Canvas sal vat o" ) ;
}
r ecuper aCanvas = f unct i on( event o) {
var i mmagi ne_sal vat a = l ocal St or age. get I t em( " canvas_f b_" + event o. det ai l ) ;
i f ( i mmagi ne_sal vat a == nul l ) r et ur n;
var i mg = new I mage( ) ;
i mg. sr c = i mmagi ne_sal vat a;
ct x. canvas. wi dt h = ct x. canvas. wi dt h;
ct x. dr awI mage( i mg, 0, 0) ;
al er t ( " Canvas r ecuper at o" ) ;
}
at t i vaI l Canvas = f unct i on( event o) {
ct x = document . quer ySel ect or ( ' canvas' ) . get Cont ext ( ' 2d' ) ;
ct x. canvas. addEvent Li st ener ( ' mousedown' , i ni zi aDi segno, f al se ) ;
ct x. canvas. addEvent Li st ener ( ' mousemove' , di segna , f al se ) ;
ct x. canvas. addEvent Li st ener ( ' mouseup' , f er maDi segno , f al se ) ;
ct x. canvas. addEvent Li st ener ( ' mousel eave' , f er maDi segno , f al se ) ;
document . addEvent Li st ener ( ' sal vadat o' , sal vaCanvas ) ;
document . addEvent Li st ener ( ' r ecuper adat o' , r ecuper aCanvas ) ;
}
wi ndow. addEvent Li st ener ( ' l oad' , at t i vaI l Canvas, f al se) ;
Approfondiamo un po quanto scritto: la funzione appena qui sopra at t i vaI l Canvas viene eseguita al load della pagina e si preoccupa di registrare tutti gli handler
necessari alla gestione delle funzioni di disegno e di registrazione. In particolare i ni zi aDi segno, disegna e f er maDi segno utilizzano alcune funzioni che abbiamo
esplorato nelle specifiche per disegnare delle spezzate che seguono la posizione del mouse. sal vaCanvas e r ecuper aCanvas sono invece funzioni che vengono attivate
dai nostri eventi custom; in questo caso la parte interessante da ricercarsi nellutilizzo del metodo t oDat aUr l che trasforma il contenuto del canvas in una stringa,
rendendolo quindi memorizzabile allinterno dellhash l ocal St or age. In r ecuper aCanvas poi, la stessa stringa contenente limmagine viene utilizzata come attributo sr c
di un oggetto I mage e successivamente ridipinta sul canvas.
Ricordiamoci di richiedere il file canvas.js allinterno della pagina index.html e proviamo la nostra creazione
(http://www.html.it/guide/esempi/html5/esempi/lezione_canvas/fiveboard/index.html) (figura 1):
Figura 1
Conclusioni
Il canvas uno strumento incredibilmente vasto, potente ed articolato. La panoramica offerta da questa lezione introduce in modo abbastanza esauriente linsieme delle
tematiche anche se per non dilungarsi troppo non ne approfondisce nessuna. Nonostante questa evidente ricchezza il canvas resta comunque uno strumento di basso livello
e permane in uno stato di difficile utilizzo a meno che non sia supportato dai dovuti framework, come ad esempio processing.js (http://processingjs.org/), canto.js
(http://www.davidflanagan.com/2010/07/cantojs-an-impr.html) e lottimo Easel.js (http://easeljs.com/). In questa lezione si inoltre volutamente ignorato il tema
dellinterazione tra canvas e video, che verr affrontato nel dovuto dettaglio nella prossima lezione di questa guida.
Video
L'introduzione della possibilit di riprodurre filmati in un browser senza l'ausilio di plug-in di terze parti rappresenta di per s una grossa novit: vanno ad esaurirsi
infatti tutte le tematiche legate alla proliferazione del plug-in utilizzato ed alla portabilit dello stesso (basti pensare ai mille grattacapi generati dal connubio Flash - iOs).
Ma c' molto di pi! Portando il player video all'interno del DOM si sono rese disponibili tutta una serie di interessantissime possibilit di interazione: ad esempio il tag
video pu essere modificato utilizzando i CSS; lo stesso effetto pu essere poi ovviamente applicato anche ai pulsanti di controllo. Inoltre l'elemento espone una ricca
interfaccia Javascript che ci consente di effettuare senza alcunefatica moltissime efficaci manipolazioni. Infine ricordiamo che il canvas, trattato nella lezione precedente,
ha la facolt di recuperare fotogrammi da un elemento video e di manipolarli; pi avanti mostreremo questa potente tecnica in azione.
Le specifiche
Prima di iniziare la sperimentazione necessario procurarsi dei video da utilizzare: per queste demo abbiamo scelto il trailer del cartone 'Big Buck Bunny', distribuito in
licenza Creative Commons e disponibile per il download all'indirizzo http://www.webmfiles.org/demo-files/ (http://www.webmfiles.org/demo-files/) e dal sito ufficiale
(http://www.bigbuckbunny.org/index.php/trailer-page/); l'intero esempio e tutti i file necessari sono allegati al pacchetto zip
(http://www.html.it/guide/esempi/html5/esempi/esempi_html5_api.zip) che contiene tutti gli esempi della guida.
Incominciamo dal markup, ecco un esempio di implementazione:
<vi deo post er =" bi g_buck_bunny/ post er . j pg" cont r ol s>
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . webm" t ype=" vi deo/ webm" >
</ vi deo>
L'attributo post er ci consente di specificare una immagine che verr utilizzataall'interno dell'area di riproduzione prima che il video venga eseguito; cont r ol s invece
indica che richiediamo la presenza dei classici controlli, come play, pausa, volume, barra di avanzamento e quant'altro. Ci sono altri attributi utilizzabili a livello di video,
vediamoli:
z aut opl ay: se presente questa stringa di testo indica allo user agent di provvedere alla riproduzione del video appena si raggiungono le condizioni minime di buffer
necessarie;
z l oop: se il browser rileva questa stringa inizier nuovamente la riproduzione del filmato una volta che questo giunto al termine;
z pr el oad: per questo attributo sono previste tre opzioni: none, met adat a e aut o. Con none si indica allo user-agent di non effettuare nessun download preventivo
del contenuto del file video, il buffer inizier quindi ad essere riempito alla prima pressione del tasto play; con met adat a invece si richiede che vengano
recuperate almeno le informazioni essenziali, come la durata del filmato e le sue dimensioni. Infine con aut o, che anche la valorizzazione di default, si lascia al
browser totale libert di scelta;
z audi o: possiamo valorizzare questo attributo a 'mut ed' ottenendo in questo modo che il player video non riproduca nessun suono. Nell'ultima versione delle
specfiche la propriet stata sostituita da un pi consono muted che deve essere valorizzato a t r ue
Passiamo a sour ce e al grande dilemma che questi elementi sottendono: i codec. Ogni elemento di questo tipo infatti indicaal browser la disponibilit dello stesso
contenuto video in formati di codifica diversi. Ad oggi non esiste un singolo codec che sia supportato dai maggiori browser in commercio: la scelta pi compatibile in
assoluto il nuovissimo, e open-source, formato .webm/ vp8, che per non ben accetto da Safari (e quindi da iPhone et-simila), per il quale la scelta obbligata invece il
classico .mp4 con codifica h264. Per ogni sour ce necessario quindi specificare un attributo sr c, un t ype ed opzionalmente anche un codec, da valorizzare con una lista
di stringhe contenente il dettaglio della codifica audio e video, separati dalla virgola.
Eseguendo il primo esempio otterremo questo risultato (figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_video/1.png)
Ecco la demo (http://www.html.it/guide/esempi/html5/esempi/lezione_video/video.html).
Ma non finita. Insieme agli elementi di tipo sour ce possiamo anche specificare tag t r ack che rappresentano vari elementi testuali che si possono combinare con il
video in modi diversi. Sono un esempio di track sottotitoli, tracce, che contengono testo ed onomatopee di effetti speciali, e sono di solito utilizzate dai non udenti,
descrizioni, che sono invece composte da testo predisposto per la sintesi audio da parte di sintetizzatori vocali, di solito utilizzati da persone non vedenti, capitoli ed altri
dati:
<vi deo post er =" bi g_buck_bunny/ post er . j pg" cont r ol s>
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . webm" t ype=" vi deo/ webm" >
<t r ack ki nd=" subt i t l es" sr c=" bi g_buck_bunny/ bunny. i t . vt t "
sr cl ang=" i t " l abel =" Sot t ot i t ol i i n I t al i ano" >
</ vi deo>
Le specifiche legate all'elemento in questione non sono per, ad oggi, supportate da nessuno dei principali browser in commercio; la stessa estensione di file (.vtt) proposta
dal W3C come standard per i sottotitoli praticamente sconosciuta e priva di documentazione.
Le API
Parallelamente al markup sono state introdotte tutta una serie di API utilissime per interfacciarsi con oggetti video. Iniziamo dai pi semplici, intuitivi ed utili:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>Bi g Buck Bunny, i l t r ai l er </ t i t l e>
<scr i pt >
var vi deo;
esegui I l Pl ay = f unct i on( ) {
vi deo. pl ay( ) ;
}
esegui I l Pause = f unct i on( ) {
vi deo. pause( ) ;
}
cambi aVol ume = f unct i on( event o) {
vi deo. vol ume = event o. t ar get . val ue;
}
wi ndow. addEvent Li st ener ( ' l oad' , f unct i on( e) {
vi deo = document . quer ySel ect or ( ' vi deo' ) ;
})
</ scr i pt >
</ head>
<body>
<menu t ype=" t ool bar " >
<but t on t ype=" but t on" oncl i ck=" esegui I l Pl ay( ) " > Pl ay </ but t on>
<but t on t ype=" but t on" oncl i ck=" esegui I l Pause( ) " > Pause </ but t on>
<l abel > Vol ume: </ l abel >
<i nput t ype=" r ange" mi n=" 0. 0" max=" 1. 0"
st ep=" 0. 1" val ue=" 0. 5" oni nput =" cambi aVol ume( event ) " >
</ menu>
<vi deo post er =" bi g_buck_bunny/ post er . j pg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . webm" t ype=" vi deo/ webm" >
</ vi deo>
</ body>
</ ht ml >
Come potete notare, il controllo base del flusso e del volume alquanto semplice, esistono per alcune funzioni pi particolari; ad esempio la propriet pl aybackRat e di
un oggetto video pu essere valorizzata con cifre che indicano quale vogliamo che sia la velocit di riproduzione.
Interessanti sono anche i metodi che gravitano attorno alle tematiche temporali: dur at i on, cur r ent Ti me e i ni t i al Ti me ritornano rispettivamente la durata in secondi del
filmato, la posizione corrente e la posizione dalla quale partita la riproduzione (tipicamente 0). Il metodo cur r ent Ti me pu essere inoltre valorizzato causando uno
spostamento della posizione del video al secondo richiesto. Ecco due funzioni che mostrano rispettivamente come raddoppiare la velocit di riproduzione e modificare la
posizione corrente esattamente a met della lunghezza del video:
doppi aVel oci t a = f unct i on( ) {
vi deo. pl aybackRat e = 2. 0;
}
posi zi onat i Al Cent r o = f unct i on( ) {
vi deo. cur r ent Ti me = Mat h. r ound( vi deo. dur at i on / 2) ;
}
Per attivarle aggiungiamo due pulsanti nella toolbar:
<menu t ype=" t ool bar " >
. . .
<but t on t ype=" but t on" oncl i ck=" doppi aVel oci t a( ) " > x2 </ but t on>
<but t on t ype=" but t on" oncl i ck=" posi zi onat i Al Cent r o( ) " > Cent r o </ but t on>
. . .
</ menu>
Eseguiamo il codice finora prodotto per testare la bont di quanto sviluppato (figura 2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_video/2.png)
L'ultima parte del capitolo riguardante le API di questo elemento dedicata ad una classe interessante denominata Ti meRanges e composta da un attributo: l engt h e due
metodi st ar t ( n) e end( n) . Alcuni metodi dell'elemento video ritornano oggetti di questo tipo che contengono informazioni in merito a collezioni di intervalli temporali;
ecco un esempio (aggiungiamolo alla demo precedente):
gener aTest o = f unct i on( i nt er val l i ) {
var t est o = " Ci sono: " + i nt er val l i . l engt h + " i nt er val l i " ;
f or ( var i =0; i < i nt er val l i . l engt h; i ++) {
t est o +=" nt da: " + i nt er val l i . st ar t ( i ) +
" a: " + i nt er val l i . end( i ) + " secondi "
}
r et ur n t est o;
}
ot t i eni I nf or mazi oni = f unct i on( ) {
var car i cat o = vi deo. buf f er ed;
var r i pr odot t o= vi deo. pl ayed;
var r i cer cabi l e = vi deo. seekabl e;
al er t ( " Al cune i nf or mazi oni sul vi deo n" +
" = Car i cat o =n" + gener aTest o( car i cat o) + " n" +
" = Ri pr odot t o =n" + gener aTest o( r i pr odot t o) + " n" +
" = Ri cer cabi l e =n" + gener aTest o( r i cer cabi l e)
) ;
}
Creiamo il bottone corrispondente, lanciamo la demo e sinceriamoci dell'effettivo funzionamento:
<but t on t ype=" but t on" oncl i ck=" ot t i eni I nf or mazi oni ( ) " > I nf o </ but t on>
Nello screenshot in figura 3 possiamo verificare il risultato:
Figura 3 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_video/3.png)
Anche in questo caso disponibile una demo (http://www.html.it/guide/esempi/html5/esempi/lezione_video/video_api_1.html).
Gli eventi
L'elemento vi deo comunica attraverso un elenco lunghissimo di eventi, i principali sono facili e facilmente comprensibili, come ad esempio pl ay, pl ayi ng, pause e
wai t i ng; per la lista completa rimandiamo alle specifiche W3C (http://dev.w3.org/html5/spec/Overview.html#mediaevents).
MediaController API
Solo un piccolo accenno ad un set di API di recentissima pubblicazione; grazie alle MediaController API e con l'ausilio di un nuovo attibuto mediagroup, disponibile sia
per elementi audio che video, possibile chiedere allo user agent di gestire la riproduzione di pi oggetti multimediali in modo sincronizzato. Facciamo un esempio:
<vi deo post er =" bi g_buck_bunny/ post er . j pg" cont r ol s medi agr oup=" ant epr i me" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . webm" t ype=" vi deo/ webm" >
</ vi deo>
<vi deo post er =" bi g_buck_bunny/ post er . j pg" cont r ol s medi agr oup=" ant epr i me" >
<sour ce sr c=" mi xer / movi es/ sr c/ bal l o_gr een_scr een. mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" mi xer / movi es/ sr c/ bal l o_gr een_scr een. ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" mi xer / movi es/ sr c/ bal l o_gr een_scr een. webm" t ype=" vi deo/ webm" >
</ vi deo>
in questo caso, avendo lo stesso valore per l'attributo medi agr oup, entrambi i video vengono associati allo stesso oggetto di tipo MediaController generato a runtime dal
browser. Questo oggetto diventa quindi responsabile della gestione temporale dei due filmati e ne coordina la riproduzione in sincrono. Per accedere a questo oggetto la
sintassi estremamente semplice:
/ / r i t or na i l Medi aCont r ol l er associ at o al vi deo, se pr esent e
document . quer ySel ect or ( " vi deo" ) . cont r ol l er
cos come semplici sono i metodi e gli eventi disponibili in quanto coincidono quasi completamente con quelli dei MediaElements (es: play, pause, volume e tutto quanto
visto in questa lezione).
Purtroppo nessun browser ad oggi implementa questo promettente set di API ma, visto l'interesse sul tema, l'attesa non dovrebbe rivelarsi troppo lunga.
Video e Canvas: un esempio pratico
In questa lezione vedremo come manipolare flussi video in tempo reale con l'ausilio di un canvas. Perch il tutto funzioni necessario che sia il video che la pagina che
costruiremo risiedano sullo stesso dominio. Questo per prevenire l'intervento di alcune policy di sicurezza del browser che impediscono di fatto la modifica di materiale
multimediale che non provenga dalla stessa origine della pagina. Ecco uno schema di quanto realizzeremo:
Figura 4 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_video/4.png)
Utilizzeremo due canvas. Nel primo replicheremo i fotogrammi del video, mentre nel secondo andremo a inserire il risultato della nostra elaborazione sull'array di pixel
estratti dal primo. Il procedimento sar quindi il seguente:
z Avviare la riproduzione del video;
z Utilizzare la funzione dr awI mage per disegnare sul primo canvas il contenuto del fotogramma corrente del video;
z Con la funzione get I mageDat a recuperare dal canvas il fotogramma precedentemente disegnato, questa volta per come array di pixel modificabili;
z Effettuare un ciclo su tutti i pixel recuperati apportando le modifiche volute;
z Utilizzare la funzione put I mageDat a per disegnare l'array di pixel modificato sul secondo canvas;
z Ripetere dal secondo punto la procedura.
Ecco il codice necessario:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e> Canvas e Vi deo </ t i t l e>
<scr i pt >
decomposi zi oneCol or i = f unct i on( vi deo, cont ext , cont ext _nascost o, col or i ) {
i f ( vi deo. paused | | vi deo. ended) r et ur n f al se;
cont ext _nascost o. dr awI mage( vi deo, 0, 0) ;
var f ot ogr amma = cont ext _nascost o. get I mageDat a( 0, 0,
cont ext _nascost o. canvas. wi dt h, cont ext _nascost o. canvas. hei ght ) ;
var f ot ogr amma_dat a = f ot ogr amma. dat a;
var r osso = col or i . r osso. checked;
var ver de = col or i . ver de. checked;
var bl u = col or i . bl u. checked;
f or ( var i =0; i < f ot ogr amma_dat a. l engt h; i +=4) {
i f ( ! r osso) f ot ogr amma_dat a[ i ] = 0;
i f ( ! ver de) f ot ogr amma_dat a[ i +1] = 0;
i f ( ! bl u ) f ot ogr amma_dat a[ i +2] = 0;
}
f ot ogr amma. dat a = f ot ogr amma_dat a;
cont ext . put I mageDat a( f ot ogr amma, 0, 0) ;
set Ti meout ( f unct i on( ) {
decomposi zi oneCol or i ( vi deo, cont ext , cont ext _nascost o, col or i )
}, 0) ;
}
aspet t aI l Pl ay = f unct i on( event o) {
var vi deo = document . quer ySel ect or ( ' vi deo' ) ;
vi deo. addEvent Li st ener ( " pl ay" , f unct i on( event o) {
var cont ext = document . quer ySel ect or ( ' #canvas_pr i nci pal e' ) . get Cont ext ( ' 2d' ) ;
var cont ext _nascost o = document . quer ySel ect or ( ' #canvas_el abor azi one' ) . get Cont ext ( ' 2d' ) ;
cont ext . canvas. wi dt h = cont ext _nascost o. canvas. wi dt h = vi deo. cl i ent Wi dt h;
cont ext . canvas. hei ght = cont ext _nascost o. canvas. hei ght = vi deo. cl i ent Hei ght ;
decomposi zi oneCol or i ( event o. t ar get , cont ext , cont ext _nascost o, document . f or ms. col or i ) ;
}, t r ue) ;
}
wi ndow. addEvent Li st ener ( " l oad" , aspet t aI l Pl ay, t r ue) ;
</ scr i pt >
</ head>
<body>
<canvas i d=" canvas_pr i nci pal e" ></ canvas>
<canvas i d=" canvas_el abor azi one" st yl e=" di spl ay: none; " ></ canvas>
<vi deo post er =" bi g_buck_bunny/ post er . j pg" cont r ol s>
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . mp4" t ype=" vi deo/ mp4" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . ogg" t ype=" vi deo/ ogg" >
<sour ce sr c=" bi g_buck_bunny/ t r ai l er . webm" t ype=" vi deo/ webm">
</ vi deo>
<f or mname=" col or i " >
<f i el dset >
<l egend>Usa l e checkbox per cont r ol l ar e i t r e canal i ( RGB) </ l egend>
<l abel > Rosso <i nput t ype=" checkbox" name=" r osso" checked></ l abel >
<l abel > Ver de <i nput t ype=" checkbox" name=" ver de" checked></ l abel >
<l abel > Bl ue <i nput t ype=" checkbox" name=" bl u" checked></ l abel >
</ f i el dset >
</ f or m>
</ body>
</ ht ml >
Il funzionamento si concentra in decomposi zi oneCol or i ; qui vengono eseguite tutte le operazioni che abbiamo citato. All'interno del ciclo che scorre tutti i pixel (nelle
componenti RGBA) un semplice controllo pilotato da una form'spegne' le componenti di colore corrispondenti ad una checkbox non spuntata con un risultato simile a
quello dell'immagine seguente:
Figura 5
Merita un cenno anche l'interessante uso della funzione requestAnimationFrame (http://www.w3.org/TR/animation-timing/); il W3C ha predisposto questo metodo per
meglio coordinare la gestione di animazioni all'interno di documenti web. A differenza dei suoi 'cugini' setTimeout e setInterval questa funzione applica alcune tecniche
per ottimizzare le perfomance e mantenere basso l'utilizzo delle risorse del sistema. Purtroppo la maggior parte dei browser la considera ancora sperimentale e quindi
antepone il proprio prefisso (moz, o, ms o webkit). Per risolvere questo problema esistono alcuni snippet di codice come quello proposto da Paul Irish
(http://paulirish.com/2011/requestanimationframe-for-smart-animating/).
Possiamo verificare il tutto nella demo conclusiva (http://www.html.it/guide/esempi/html5/esempi/lezione_video/video_canvas.html).
Conclusioni
In queste ultime due lezioni abbiamo esplorato tutto l'ecosistema che circonda la nascita del tag vi deo. Prima di passare alla prossima lezione ricordiamo che intorno a
questo elemento gi si affacciano le prime librerie, capaci di aiutare nella personalizzazione del player e nella gestione di fallback su altre tecnologie nel caso l'HTML5
non sia supportato. In particolare segnaliamo l'ottimo video.js (http://videojs.com/), che sicuramente merita una visita di approfondimento.
Audio
La presenza del tag audio naturale conseguenza dell'esistenza di vi deo (http://xhtml.html.it/guide_preview/lezione/5003/video/). Fra l'altro i due elementi si
assomigliano molto, sia in materia di markup che di API, al punto che nelle specifiche sono raggruppati all'interno della definizione di HTML Media Elements. L'utilizzo
del tag audio sottende per aspetti assolutamente originali ed interessanti; soprattutto quando utilizzato per arricchire con effetti sonori una struttura HTML classica.
Le specifiche
La rappresentazione a markup dell'elemento ricalca perfettamente quella del video, anche se vi sono meno attributi disponibili, vediamo un esempio:
<audi o cont r ol s aut opl ay l oop sr c=" f i l e_musi cal e. mp3" >
In questo caso la definizione si risolve su di una singola linea e senza utilizzo del tag sour ce perch stato utilizzato l'attributo sr c, il cui compito quello di evitare una
scrittura troppo prolissa nel caso in cui il formato disponibile sia unico. Questo attributo anche se non stato presentato nella lezione precedente valido anche per il tag
vi deo, anche se a meno di un reale processo di unificazione dei codec ad oggi perde molta della sua utilit. In ogni caso la stessa definizione appena espressa si pu
scrivere anche nel formato esteso:
<audi o cont r ol s aut opl ay l oop>
<sour ce sr c=" f i l e_musi cal e. mp3" t ype=" audi o/ mp3" >
</ audi o>
Oltre agli attributi presentati nel codice qui sopra, deve essere citato anche pr el oad; ognuno di questi gi stato illustrato nella lezione precedente e mantiene intatto il suo
funzionamento anche su questo elemento. A differenza di vi deo, l'elemento audio dispone anche di un proprio costruttore J avaScript, ecco la sintassi:
var audi o = new Audi o( " f i l e_musi cal e. mp3" ) ;
In questo modo possibile utilizzare musiche ed effetti audio senza necessariamente creare l'elemento HTML n ricorrere a di spl ay: none o similari; tratteremo pi
approfonditamente di questo aspetto nella sezione dedicata all'esempio.
Per quanto riguarda invece le API e gli eventi associati a questo elemento l'elenco pressoch congruente con quello dell'elemento video; le stesse funzioni pl ay, pause,
pl aybackRat e, dur at i on, cur r ent Ti me e tutto quanto legato ai Ti meRanges mantengono inalterato il proprio comportamento in quanto appartenenti al gruppo
HTMLMediaElements al quale entrambi gli elementi fanno parte.
Un esempio
Sfruttiamo la possibilit di creare oggetti audio utilizzando il costruttore J avaScript per studiare un meccanismo che ci consenta di associare ad ogni bottone un suono
predefinito da riprodurre al click. Ecco il markup che useremo all'interno del body della pagina:
<but t on t ype=" but t on" dat a- ef f et t o- audi o=" gat t o_che_mi agol a. mp3" di sabl ed>
I l ver so del gat t o. . .
</ but t on>
<but t on t ype=" but t on" dat a- ef f et t o- audi o=" cane_che_abbai a. mp3" di sabl ed>
I l ver so del cane. . .
</ but t on>
L'utilizzo degli attributi dat a- * ci consente in modo elegante di aggiungere un'informazione caratterizzante al pulsante, senza creare strane sovrastrutture. Ora il codice
J avaScript dovr occuparsi di scandagliare la pagina alla ricerca di pulsanti con suono associato e creare un oggetto audio con la sorgente che punti all'attributo che
abbiamo definito. L'evento canpl ayt hr ough, verr utilizzato per intercettare il momento in cui un dato oggetto audio ritiene di aver collezionato dati sufficienti per
garantire la riproduzione dell'intero brano. All'accadere di tale evento il pulsante associato al suono verr abilitato e un listener in ascolto sull'evento cl i ck garantir
l'esecuzione del suono alla pressione del bottone. Ecco il codice della demo completa:
<! doct ype ht ml >
<ht ml >
<head>
<t i t l e>I l suono degl i ani mal i </ t i t l e>
<scr i pt >
i ni t = f unct i on( event o) {
var bot t oni = document . quer ySel ect or Al l ( ' but t on' ) ;
f or ( var b=0; b < bot t oni . l engt h; b ++) {
var ef f et t o_audi o = bot t oni [ b] . dat aset . ef f et t oAudi o;
i f ( ef f et t o_audi o ! = " " ) {
var audi o = new Audi o( ef f et t o_audi o) ;
audi o. bot t one_di _r i f er i ment o = bot t oni [ b] ;
audi o. addEvent Li st ener ( ' canpl ayt hr ough' ,
f unct i on( event o_l oad) {
var bot t one = event o_l oad. t ar get . bot t one_di _r i f er i ment o;
bot t one. di sabl ed = f al se;
bot t one. audi o_di _r i f er i ment o = event o_l oad. t ar get ;
bot t one. addEvent Li st ener ( ' cl i ck' ,
f unct i on( event o_cl i ck) {
event o_cl i ck. t ar get . audi o_di _r i f er i ment o. pl ay( ) ;
}
) ;
}
) ;
}
}
}
wi ndow. addEvent Li st ener ( ' l oad' , i ni t ) ; </ scr i pt >
</ head>
<body>
<but t on t ype=" but t on" dat a- ef f et t o- audi o=" gat t o_che_mi agol a. mp3" di sabl ed>
I l ver so del gat t o. . .
</ but t on>
<but t on t ype=" but t on" dat a- ef f et t o- audi o=" cane_che_abbai a. mp3" di sabl ed>
I l ver so del cane. . .
</ but t on>
</ body>
</ ht ml >
Il codice sembra a prima vista complicato ma facilmente decomponibile in 3 fasi principali:
z Un ciclo f or viene eseguito al caricamento della pagina su tutti gli elementi di tipo but t on; per ognuno di questi elementi viene istanziato un oggetto Audi o. Su tale
oggetto viene memorizzato un riferimento al bottone associato tramite la variabile bot t one_di _r i f er i ment o e viene registrato un handler sull'evento
canpl ayt hr ough.
z Quando un oggetto Audi o colleziona un buffer di dati ritenuto dal browser tale da consentire la riproduzione integrale del suono, l'evento canpl ayt hr ough viene
lanciato ed intercettato dalla nostra funzione che a quel punto crea, con un meccanismo simile al punto precedente, un handler sul pulsante presente nella variabile
bot t one_di _r i f er i ment o da attivarsi alla pressione dello stesso. Inoltre il pulsante viene abilitato (bot t one. di sabl ed=f al se) in modo da poter ricevere i click
degli utenti.
z Il click dell'utente su di un pulsante attiva l'handler appena definito che non fa altro che riprodurre il suono presente nell'oggetto Audi o ad esso associato.
Eseguiamo l'applicazione appena sviluppata e sinceriamoci del suo corretto funzionamento: ecco l'esempio
(http://www.html.it/guide/esempi/html5/esempi/lezione_audio/audio.html).
Conclusioni
L'elemento che abbiamo illustrato in questa sezione corre di pari passo con l'implementazione HTML5 del video, dal quale, abbiamo visto, eredita pressoch la totalit
delle propriet. Nonostante questo l'utilizzo dell'elemento audio si presta a scenari molto pi variegati rispetto a quanto ci si potrebbe immaginare: parte di questa
interessante flessibilit risiede proprio nella sua predisposizione ad essere creato direttamente da J avaScript.
Tabella del supporto sui browser
Grafica e Multimedia
<audio> 9.0+3.5+4.0+5.0+10.5+
Codec audio
MP3 S No S S No
Wav No S S No S
AAC S No S S No
Ogg/Vorbis No S No S S
SVG e MathML
SVG
SVG un acronimo che significa Scalable Vector Graphic e indica una specifica modalit di definire elementi di natura grafica attraverso una sintassi XML, ecco un
esempio:
<?xml ver si on=" 1. 0" st andal one=" no" ?>
<! DOCTYPE svg PUBLI C " - / / W3C/ / DTD SVG 1. 1/ / EN"
" ht t p: / / www. w3. or g/ Gr aphi cs/ SVG/ 1. 1/ DTD/ svg11. dt d" >
<svg wi dt h=" 300px" hei ght =" 300px" vi ewbox=" 0 0 300 300"
xml ns=" ht t p: / / www. w3. or g/ 2000/ svg" ver si on=" 1. 1" >
<t i t l e>Una bar chet t a i n SVG</ t i t l e>
<desc>La st essa bar chet t a del l a l ezi one sui canvas or a i n SVG</ desc>
<pat h d=" M40, 170 h220 A150, 150 0 0, 1 40, 170 h110 v- 130 v130 h- 110 z"
f i l l =" bl ack" st r oke=" bl ack" st r oke- wi dt h=" 1" / >
<r ect x=" 150" y=" 40" wi dt h=" 60" hei ght =" 30"
f i l l =" bl ack" st r oke=" bl ack" st r oke- wi dt h=" 1" / >
</ svg>
La maggior parte dei browser in circolazione interpreta correttamente lo standard SVG, se proviamo a visualizzare questa pagina
(http://www.html.it/guide/esempi/html5/esempi/lezione_svg/barchetta.svg) in Chrome otterremo questo risultato (figura 1):
Figura 1
Nonostante il risultato sia a prima vista identico rispetto alla barchetta disegnata allinterno della lezione sullelemento canvas, si pu notare come a livello di codice ci sia
una enorme differenza: mentre sul canvas necessario insistere con istruzioni J avaScript che pilotano la creazione del disegno, qui ci troviamo di fronte ad un linguaggio
XML fatto per descrivere limmagine. Ma non finita: da un lato (canvas) stiamo lavorando su di una matrice di pixel, che quindi non pu essere ridimensionata senza
subire perdite di qualit; dallaltro, con SVG, operiamo con grafica vettoriale, che preserva in modo assoluto lo stesso risultato a prescindere dalle operazioni di
trasformazione applicate ad essa.
MathML
Anche MathML un acronimo: Mathematical Markup Language; il fine di questa sintassi quello di rendere possibile la visualizzazione a schermo di formule
complesse, senza ricorrere al classico espediente dellutilizzo di immagini create a partire da screenshot di applicazioni scientifiche. Anche in questo caso stiamo parlando
di sintassi XML-like. A seguire un esempio della famosa equazione di Einstein secondo queste specifiche:
<?xml ver si on=" 1. 0" encodi ng=" UTF- 8" ?>
<mat h xml ns=" ht t p: / / www. w3. or g/ 1998/ Mat h/ Mat hML" >
<semant i cs>
<mr ow>
<mi >E</ mi >
<mi mat hvar i ant =" nor mal " >=</ mi >
<msup>
<mi mat hvar i ant =" i t al i c" >mc</ mi >
<mn>2</ mn>
</ msup>
</ mr ow>
<annot at i on>E=mc^2</ annot at i on>
</ semant i cs>
</ mat h>
Per testare la sintassi del nostro esempio (http://www.html.it/guide/esempi/html5/esempi/lezione_svg/emc2.mml.html) necessario munirsi della versione nightly
(sperimentale) del browser WebKit (http://nightly.webkit.org/), tra i pochi a supportare queste specifiche. Questo il risultato (figura 2):
Figura 2
Novit in HTML5
Ed ecco la novit: le specifiche HTML5 prevedono lintegrazione di entrambi questi markup senza nessuna definizione aggiuntiva (a differenza della precedente
integrazione con XHTML). Sar quindi possibile scrivere:
<! doct ype ht ml >
<ht ml >
<t i t l e>Bi g Buck Bunny, i l t r ai l er </ t i t l e>
<body>
<svg>
<! - - el ement i SVG - - >
</ svg>
<mat h>
<! - - el ement i Mat hML - - >
</ mat h>
</ body>
</ ht ml >
E c di pi: le due sintassi in questionepotranno direttamente beneficiare dellintero ecosistema HTML5 attorno a loro. Questo significa che una espressione MathML
pu, in questo contesto, variare a seguito della ricezione di alcuni dati tramite Ajax, oppure che una rappresentazione SVG pu essere pilotata da alcuni eventi JavaScript
attivati attraverso una form.
Conclusioni
Con queste due nuove frecce al suo arco, le specifiche HTML5 acquistano un nuovo livello di potenza. Forse non capiter troppo spesso di implementare sintassi MathML
per sistemi applicativi ma sicuramente lo stesso non si pu direper SVG. Anche il supporto a queste due specifiche diverso, la Scalable Vector Graphic pressoch
presente su tutte le pi recenti versioni dei browser, mentre il supporto per il markup per definire espressioni matematiche comincia ora ad affacciarsi nelle prime beta,
come ad esempio Firefox 4 o la versione nightly di WebKit. In ogni caso esiste una interessante libreria J avaScript, MathJ ax (http://www.mathjax.org/), capace di
interpretare linguaggio MathML e generare una corretta rappresentazione grafica sulla maggior parte dei browser in commercio.
Una 'lavagna virtuale'
Nel corso delle lezioni abbiamo assistito al graduale arricchimento del progetto guida; in questo articolo ne esploreremo alcunepossibili evoluzioni attraverso lutilizzo
delle API HTML5 apprese finora.
Il canvas nella dashboard
possibile fare in modo che dalla dashboard (dashboard.html) si possa visualizzare il contenuto, attuale e salvato, del canvas di una data fiveboard con un meccanismo
simile a quello utilizzato per la memorizzazione su l ocal St or age. Per ottenere questo risultato possiamo sostituire il blocco legato al comando r i chi edi _t est o nel file
application.js con:
case ' r i chi edi _t est o' :
event o. por t s[ 0] . post Message( ' t est o_cor r ent e: ' +
document . f or ms[ ' f or m_da_r i cor dar e' ] . el ement s[ ' t est o_da_r i cor dar e' ] . val ue) ;
event o. por t s[ 0] . post Message( ' t est o_memor i zzat o: ' +
l ocal St or age. get I t em( " f b_" + t i t ol o_f i veboar d) ) ;
event o. por t s[ 0] . post Message( ' canvas_cor r ent e: ' +
ct x. canvas. t oDat aURL( ' i mage/ png' ) ) ;
event o. por t s[ 0] . post Message( ' canvas_memor i zzat o: ' +
l ocal St or age. get I t em( " canvas_f b_" + t i t ol o_f i veboar d) ) ;
br eak;
A questo punto dobbiamo far s che la dashboard sappia ricevere ed interpretare correttamente questi 4 distinti messaggi, modifichiamo quindi il blocco che fa seguito al
comando at t endi _t est o in dashboard.html:
case ' at t endi _t est o' :
event o. por t s[ 0] . onmessage = f unct i on( e) {
nome_comando= e. dat a. spl i t ( " : " ) [ 0]
val or e_comando = e. dat a. subst r ( nome_comando. l engt h + 1) ;
el ement o = document . get El ement ByI d( nome_comando) ;
swi t ch ( el ement o. t agName) {
case ' CANVAS' :
el ement o. wi dt h = el ement o. wi dt h;
i f ( val or e_comando == ' nul l ' ) r et ur n
var cont ext = el ement o. get Cont ext ( ' 2d' ) ;
var i mmagi ne = new I mage( ) ;
i mmagi ne. sr c = val or e_comando; cont ext . dr awI mage( i mmagi ne, 0, 0) ;
br eak;
case ' TEXTAREA' :
i f ( val or e_comando == ' nul l ' )
val or e_comando = ' ' ;
el ement o. val ue = val or e_comando;
br eak;
}
}
br eak;
Nel frammento di codice appena esposto facciamo uso dellattributo t agName per determinare il tipo di elemento che deve contenere le informazioni appena ricevute. In
questo modo il comando t est o_memor i zzat o: cont enut o_del _t est o inviato dalla fiveboard si traduce nella valorizzazione dellelemento t est o_memor i zzat o a
contenuto_del_testo nella dashboard.
Completiamo questa evoluzione inserendo gli elementi di markup allinterno di dashboard.html:
</ ol >
<sect i on>
<h1>I n Osser vazi one: </ h1>
<t ext ar ea i d=" t est o_cor r ent e" pl acehol der =" t est o_cor r ent e" r eadonl y></ t ext ar ea>
<t ext ar ea i d=" t est o_memor i zzat o" pl acehol der =" t est o_memor i zzat o" r eadonl y></ t ext ar ea>
<canvas i d=" canvas_cor r ent e" >Canvas Cor r ent e</ canvas>
<canvas i d=" canvas_memor i zzat o" >Canvas Memor i zzat o</ canvas>
</ sect i on>
Ecco uno screenshot dellimplementazione funzionante (figura 1):
Figura 1 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_progetto/1.jpg)
Com possibile notare, ora alla pressione sul link pi informazioni la dashboard in grado di mostrare sia testo che canvas, attuali e memorizzati, della fiveboard
richiesta.
Esportazione in SVG
Potrebbe essere interessante, in questo contesto, offrire ai nostri utenti una esportazione in SVG del contenuto del canvas. In un prossimo futuro il task in questione potr
essere risolto in modo efficace utilizzando la funzione canvas. t oDat aUr l con parametro image/ svg+xml ; purtroppo ad oggi i browser supportano soltanto
un'esportazione in formato png e quindi dovremo costruire qualcosa di pi articolato per soddisfare questo comportamento.
Iniziamo con laggiungere questa funzione in canvas.js:
Espor t aI nSVG = f unct i on( ) {
var bb = new Bl obBui l der ( ) ;
bb. append( " " +
" <?xml ver si on=' 1. 0' st andal one=' no' ?>" +
" <! DOCTYPE svg PUBLI C ' - / / W3C/ / DTD SVG 1. 1/ / EN' " +
" ' ht t p: / / www. w3. or g/ Gr aphi cs/ SVG/ 1. 1/ DTD/ svg11. dt d' >" +
" <svg wi dt h=' 300px' hei ght =' 300px' vi ewbox=' 0 0 300 300' " +
" xml ns=' ht t p: / / www. w3. or g/ 2000/ svg' ver si on=' 1. 1' >" +
" <t i t l e>SVG: " + t i t ol o_f i veboar d + " </ t i t l e>" +
" <desc>Un espor t azi one i n SVG del canvas di segnat o</ desc>" +
" <pat h d=' " + svg_pat h + " z' f i l l =' t r anspar ent ' " +
" st r oke=' bl ack' st r oke- wi dt h=' 1' / >" +
" </ svg>"
) ;
wi ndow. open( wi ndow. cr eat eObj ect URL( bb. get Bl ob( ' i mage/ svg+xml ' ) ) ) ;
}
Loggetto Bl obBui l der fa parte delle File API: Writer (http://www.w3.org/TR/file-writer-api/), un set di funzionalit che gravitano attorno alle specifiche HTML5 e
consentono di costruire veri e propri file da far scaricare allutente o ai quali far puntare il browser. Al momento questi metodi sono ancora abbastanza sperimentali,
nonostante gi supportati in Chrome, Firefox e WebKit. In questo esempio la variabile bb viene valorizzata con un file SVG nel quale sono inseriti dinamicamente i
contenuti delle variabili t i t ol o_f i veboar d, il titolo della fiveboard, e svg_pat h, della cui costruzione ci occuperemo a breve. Nellultima riga della funzione il browser
apre una nuova finestra verso una URL univoca generata dal metodo cr eat eObj ect URL. Tale URL punta al contenuto della variabile bb esposto con MIME
i mage/ svg+xml .
Occupiamoci ora della generazione della variabile svg_pat h che dovr contenere le istruzioni per ricostruire il percorso generato dallutente sul canvas. Modifichiamo il
file canvas.js come segue:
var ct x = nul l ;
var st ar t ed = f al se;
var svg_pat h = " " ;
i ni zi aDi segno = f unct i on( event o) {
ct x. begi nPat h( ) ;
ct x. moveTo( event o. of f set X, event o. of f set Y) ;
svg_pat h += " M " + event o. of f set X + " " + event o. of f set Y + " " ;
st ar t ed = t r ue;
}
di segna = f unct i on( event o) {
i f ( st ar t ed) {
ct x. l i neTo( event o. of f set X, event o. of f set Y) ;
svg_pat h += " L " + event o. of f set X + " " + event o. of f set Y + " " ;
ct x. st r oke( ) ;
}
}
Il trucco sta nel far seguire allistruzione che insiste sul canvas la corrispondente variazione da applicare al path svg. In questo modo una particella M x y verr
concatenata a svg_pat h per ogni istruzione moveTo inviata al canvas, lo stesso accadr per listruzione l i neTo, seguita da una concatenazione di L x y.
Lultimo passo prima del completamento di questa evoluzione consiste nellaggiungere il pulsante preposto a far scatenare la funzione Espor t aI nSVG:
</ but t on>
<but t on t ype=" but t on" oncl i ck=" Espor t aI nSVG( ) ; " >
Espor t a i l canvas cor r ent e i n SVG
</ but t on>
</ menu>
Per testare questa modifica ricorriamo a Chrome (figura 2):
Figura 2 (click per ingrandire)
(http://www.html.it/guide/esempi/html5/imgs/lezione_progetto/2.jpg)
Ed ecco il risultato! Mentre la barchetta nella finestra in sfondo risiede su di un canvas quella in primo piano creata a partire da un file SVG; notate inoltra il curioso
URL di questa finestra, generato in tempo reale dalla funzione di cui abbiamo parlato poco fa.
Non ci resta che rimandare alla demo (http://www.html.it/guide/esempi/html5/esempi/lezione_progetto/fiveboard/index.html) per un test. Il codice disponibile per il
download (http://www.html.it/guide/esempi/html5/esempi/lezione_progetto/fiveboard.zip).
Un passo avanti
Con questultima evoluzione ci apprestiamo a congedare il progetto guida, utile assistente durante le passate lezioni. Per chi fosse interessato a mantenere questo
applicativo come base per proprie sperimentazioni ecco alcuni possibili e sfidanti implementazioni effettuabili:
z Fare in modo che il viewer.html possa seguire in tempo reale anche latto del disegno sul canvas della fiveboard che sta osservando, cos come oggi avviene per il
testo. Questa modifica coinvolge la definizione di un protocollo snello per la trasmissione di dati di questo tipo attraverso un WebSocket.
z Refactoring! Perch non provare a fare in modo che i comandi che giungono alle pagine web nel formato scelto per convenzione come
nome_comando: val or e_comando siano trasformati in eventi custome propagati attraverso il DOM ? La sintassi potrebbe essere questa:
wor ker . por t . onmessage = f unct i on( event o) {
nome_comando = event o. dat a. spl i t ( " : " ) [ 0]
val or e_comando = event o. dat a. subst r ( nome_comando. l engt h + 1) ;
var event o_cust om= document . cr eat eEvent ( " Cust omEvent " ) ;
event o_cust om. i ni t Cust omEvent ( nome_comando, t r ue, t r ue, val or e_comando) ;
document . di spat chEvent ( event o_cust om) ;
}
In questo modo si potrebbe ottenere una struttura molto pi elegante, nella quale ogni aspetto dellapplicazione si sottoscrive autonomamente agli eventi dei quali
necessita.
Conclusioni
Con questa lezione si conclude il ciclo dedicato allesplorazione delle nuove API rese disponibili dallHTML5. Prima della conclusione di questa guida trova spazio
un'ultima lezione, la prossima, incentrata su tutte le tematiche che legano le specifiche al mondo reale. Verranno quindi trattati temi come il feature detection ed elencate
librerie che possono, di caso in caso, sopperire alla mancanza di particolari funzionalit. Proprio a questo tema ricordiamo cheil progetto guida nato e cresciuto con
finalit didattiche e di sperimentazione e per questa ragione molto carente in termini di compatibilit tra browser e graceful degradation; a ben pensare anche perseguire
queste tematiche potrebbe essere un ottimo esercizio da svolgere in autonomia dopo aver letto la prossima lezione!
Feature detection e strategie di fallback
Come si comportano le API e i nuovi tag proposti dall'HTML5 nel mondo reale? Come dobbiamo comportarci se vogliamo beneficiarne? In quest'ultima lezione
risponderemo a questa importantissima domanda esaminando alcune best-practice per una implementazione che possa arricchire le nostre applicazioni e portali web senza
causare grattacapi e disagi.
Una pioggia di tag
Possiamo usare <article>, <section> o <footer> su browser come Internet Explorer 6? La risposta s, a patto di premunirsi di alcuni semplici e comodi strumenti
capaci di far recepire questi nuovi elementi HTML5 anche a user-agent non pi giovanissimi. Uno di questi tool, specificatamente progettato per i browser di casa
Microsoft, prende il nome di html5shim(http://code.google.com/p/html5shim/) e pu essere incluso nelle proprie applicazioni molto facilmente:
<! - - [ i f l t I E 9] >
<scr i pt sr c=" ht t p: / / ht ml 5shi m. googl ecode. com/ svn/ t r unk/ ht ml 5. j s" ></ scr i pt >
<! [ endi f ] - - >
Questo strumento fa s che Internet Explorer possa applicare gli stili ai nuovi tag introdotti dall'HTML5. Ma ancora non basta. La maggior parte dei browser di non ultima
generazione, infatti, non conoscendo direttamente i nuovi elementi, applica a loro un foglio di stile di base errato, assegnando ad esempio di spl ay: i nl i ne a tag come
<ar t i cl e>o <sect i on>.
Per risolvere questa fastidiosa incombenza la soluzione migliore utilizzare un foglio di stile capace di resettare le propriet di questi e altri elementi attivando il
comportamento atteso. HTML5 reset stylesheet (http://html5doctor.com/html-5-reset-stylesheet/) si presta in modo ottimale a questo obiettivo; l'unico passo da compiere
includerlo all'interno del proprio sito prima degli altri documenti . css.
Feature detection vs. browser detection
La corsa all'HTML5 intrapresa dai vari browser nell'ultimo periodo si pu descrivere come una incrementale implementazione dellefeature proposte dal W3C; il criterio
con cui viene stabilita la priorit nella 'scaletta delle API da aggiungere' influenzato da moltissimi fattori e differisce da prodotto a prodotto. Allo stato attuale delle cose
non ha quindi particolarmente senso determinare il comportamento della propria applicazione sulla base dello user-agent che la sta eseguendo, quanto pi cercare di
intercettare la presenza o meno di una specifica feature.
L'attivit, potenzialmente noiosa di per s, viene facilitata in modo estremo dalla presenza sul mercato di un utilissimo tool: Modernizr.js (http://www.modernizr.com/).
Facciamo un esempio, sinceriamoci del supporto per il l ocal St or age:
i f ( Moder ni zr . l ocal st or age) {
al er t ( " Ri l evat o i l suppor t o per i l l ocal St or age" ) ;
} el se {
al er t ( " Oh oh, nessun suppor t o per i l l ocal St or age" ) ;
}
Semplice, elegante e molto comodo. L'installazione di questa libreria si risolve con una semplice inclusione e una speciale classe da applicare al tag <ht ml >:
<ht ml cl ass=" no- j s" >
<head>
<scr i pt sr c=" / moder ni zr - 1. 6. mi n. j s" ></ scr i pt >
<scr i pt >
/ / Or a puoi ut i l i zzar e Moder ni zr !
</ scr i pt >
</ head>
Fallback e alternative
Abbiamo scoperto che il nostro utente non supporta una certa funzionalit... e ora? Niente panico: nella maggior parte dei casi esistono valide alternative, o quantomeno
interessanti opzioni di fallback. Vediamole nel dettaglio.
Audio e Video
In questo caso l'alternativa migliore rimane la collaudata tecnologia Flash. Esistono parecchie librerie sulla rete capaci di determinare autonomamente il supporto o
meno al tag <vi deo>e agire di conseguenza. Noi abbiamo scelto video.js (http://videojs.com/) per la sua maturit e per l'ottimo supporto di skin con le quali
personalizzare il proprio player. L'utilizzo semplicissimo e ben illustrato nella pagina di Getting Started (http://videojs.com/#getting-started).
Canvas
Abbiamo due soluzioni da segnalare come alternativa all'assenza canvas: la prima si chiama explorercanvas (http://code.google.com/p/explorercanvas/), una libreria
J avascript sviluppata da Google per simulare il comportamento del <canvas>all'interno di Internet Explorer. Per attivarla sufficiente richiamare lo script excanvas. j s
all'interno del proprio tag <head>:
<! - - [ i f I E] ><scr i pt sr c=" excanvas. j s" ></ scr i pt ><! [ endi f ] - - >
Da qui in poi possibile utilizzare all'interno della pagina il tag <canvas>ed invocare su questo la maggior parte dei metodi previsti dalle specifiche W3C.
L'altra tecnica di fallback prende invece il nome di FlashCanvas (http://flashcanvas.net/) ed emula il comportamento delle API HTML5 attraverso il sapiente utilizzo della
tecnologia Flash. La versione 1.5, supera pi del 70% dei test proposti da Philip Taylor (http://philip.html5.org/tests/canvas/suite/tests/), piazzandosi in questo modo sul
primo gradino del podio delle alternative disponibili. Anche in questo caso per beneficiare di questa libreria necessario solamente richiamare l'apposito file javascript:
<! - - [ i f l t I E 9] >
<scr i pt t ype=" t ext / j avascr i pt " sr c=" pat h/ t o/ f l ashcanvas. j s" ></ scr i pt >
<! [ endi f ] - - >
Geolocation
Come simulare le API di geolocazione quando non sono supportate? Prima di disperare importante ricordare che seppur non tutti browser implementano queste
specifiche comunque possibile alle volte accedere ad informazioni geospaziali utilizzando API proprietarie messe a disposizione da particolari device o plug-in esterni,
come ad esempio Google Gears. geo-location-javascript (http://code.google.com/p/geo-location-javascript/) una libreria che identifica le varie estensioni disponibili sul
portatile (o smartphone) dell'utente e ne uniforma e centralizza le API permettendo di accedere ad informazioni come latitudine e longitudine usando gli stessi metodi
proposti dal W3C. Ecco un esempio. Per prima cosa necessario includere i necessari file javascript:
<scr i pt sr c=" ht t p: / / code. googl e. com/ api s/ gear s/ gear s_i ni t . j s" t ype=" t ext / j avascr i pt " ></ scr i pt >
<scr i pt sr c=" geo. j s" t ype=" t ext / j avascr i pt " ></ scr i pt >
Quindi necessario inizializzare la libreria con il comando:
i f ( ! geo_posi t i on_j s. i ni t ( ) ) {
/ / f unzi onal i t di geol ocazi one non pr esent i ( ne HTML5 ne at t r aver so est ensi oni
/ / pr opr i et ar i e. . . )
}
A questo punto possibile invocare i classici metodi come da specifiche W3C, stando attendi a preporre l'oggetto geo_posi t i on_j s:
geo_posi t i on_j s. get Cur r ent Posi t i on( f unzi one_se_successo, f unzi one_se_er r or e) ;
Drag and Drop
In questo caso ci sono due tematiche da affrontare: la prima di carattere 'workaround' e si focalizza sull'identificare soluzioni alternative che preservino lo stesso
meccanismo di interazione del Drag and Drop HTML5. Per questo tipo di eventualit esistono potentissime librerie capaci di offrire esattamente questo tipo di
comportamento: le pi famose sono ovviamente J QueryUI (http://jqueryui.com/demos/draggable/), ma anche Scriptaculous
(http://madrobby.github.com/scriptaculous/draggable/) e il nuovo Scripty2 (http://scripty2.com/doc/scripty2%20ui/s2/ui/behavior/drag.html). Tutto questa interazione di
fallback, invece, viene meno nel caso le API previste dal W3C siano utilizzate espressamente per la loro funzione di input, quindi, ad esempio, per trascinare file
all'interno della pagina web. In questo caso si pu pensare di mantenere la funzionalit riducendo il potere dell'interfaccia e dell'interazione, realisticamente con l'utilizzo
di normalissime forme di campi <i nput t ype=f i l e>.
WebSocket
Appurata l'assenza del supporto WebSocket l'alternativa migliore rimane ripiegare su una tra le tecniche per soppiantare le quali sono nate proprio queste API HTML5:
stiamo parlando di Comet e di websocket in Flash. Proprio a proposito di quest'ultima opzione merita un cenno l'ottimo, anche se poco documentato, web-socket-js
(https://github.com/gimite/web-socket-js/blob/master/README.txt) capace di replicare il comportamento delle specifiche W3C utilizzando per un piccolo componente
Flash iniettato dinamicamente all'interno della pagina. A questo indirizzo (https://github.com/gimite/web-socket-js/blob/master/sample.html) un esempio di utilizzo.
WebWorkers
Non esistono, al momento, soluzioni di ripiego per riparare l'assenza del supporto di questa parte delle specifiche HTML5 senza ricorrere ad estensioni di terze parti come
le ottime WorkerPool API (http://code.google.com/intl/it-IT/apis/gears/api_workerpool.html) di Google Gears. L'unico workaround possibile scrivere una versione del
codice eseguito dal worker capace di funzionare all'interno del contesto della pagina ed eseguire quella nel caso in cui venga verificata l'assenza della feature (chiaramente
perdendo il vantaggio dell'esecuzione asincrona). Nel caso invece si stia trattando si SharedWebWorkers il discorso si complica ulteriormente; in linea teorica possibile
emulare artigianalmente un comportamento di questo tipo utilizzando un area di storage comune (es: localStorage) per lo scambio di messaggi convenzionati tra le pagine
dello stesso dominio.
WebStorage e IndexedDB
Come per i WebWorkers, anche qui la soluzione di fallback pi completa in termini di funzionalit passa attraverso Google Gears: stiamo parlando delle Database API
(http://code.google.com/intl/it-IT/apis/gears/api_database.html). E' per importante sottolineare che, mentre WebStorage e IndexedDB basano la loro filosofia di
funzionamento su array associativi, Google Gears si appoggia ad una istanza di SQLite, un database relazionale che opera tramite classiche istruzioni SQL, In questo caso
quindi offrire una soluzione alternativa all'assenza di questi componenti HTML5 potrebbe rivelarsi decisamente costoso.
Offline Web Application
Google Gears anche in questo caso. Le API si chiamano LocalServer (http://code.google.com/intl/it-IT/apis/gears/api_localserver.html) e presentano funzionalit simili a
quelle offerte dalle implementazioni delle specifiche W3C.
Shim e Polyfill a profusione
Abbiamo dato solo un piccolo assaggio della quantit di librerie alternative disponibili per sopperire alle pi svariate API HTML5. In realt il numero di questi software di
fallback decisamente sostanzioso ed bene introdurre alcune differenze di massima tra le varie tipologie di librerie disponibili.
Definiamo come Shim una libreria che sopperisce ad una funzione mancante emulandone il comportamento ma richiedendo allo sviluppatore uno sforzo aggiuntivo in
quando le API che mette a disposizione differiscono da quelle native in HTML5. Con Polyfill indichiamo invece uno Shimche per fornisce allo sviluppatore le
medesime API offerte dalla controparte HTML5 rendendo cos necessaria una singola implementazione.
Quindi, ove possibile meglio preferire un Polyfill ad uno Shim. Gi, ma come trovarli? Si pu consultare la lista dei migliori polyfill
(https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills) redatta dagli sviluppatori di Modernizr.
Un ultimo appunto: se il numero di file javascript dovesse diventare troppo sostanzioso ricordiamoci che sempre possibile ricorrere ad un loader condizionale, come
yepnope.js (http://yepnopejs.com/).
Conclusioni
Siamo alla fine, con queste ultime righe si conclude la guida HTML5 di html.it, in circa 50 lezioni abbiamo sorvolato un pianeta ricco di nuove ed interessanti opportunit,
capaci di far evolvere le nostre creazioni web fino a dove pochi anni fa non ritenevamo possibile. In questa lezione abbiamo scoperto come le specifiche si intreccino con
il mondo reale e quali sono i potenziali comportamenti di fallback da implementare nel caso di assenza di qualche particolare feature. In particolare ci siamo accorti che
per tematiche di basso livello (WebStorage, IndexedDB e Offline Web Application) non esistono soluzioni alternative, se si esclude Google Gears, che per necessita di
una installazione manuale da parte dell'utente finale.
Un ultimo punto importante prima di concludere: non tutte le funzionalit proposte dall'HTML5 sono da considerarsi pronte per un uso in fase di produzione, alcune di
esse infatti sono ancora in uno stadio di implementazione poco stabile, oppure subiranno a breve importanti cambiamenti nelle loro API; per avere un elenco aggiornato di
cosa considerato utilizzabile in produzione e cosa no potete consultare la tabella di compatibilit posta in appendice a questa guida.
Appendice: Tabelle del supporto sui browser di HTML5
Per visualizzare in una forma efficace lo stato dell'arte dell'implementazione di HTML5 abbiamo allegato in appendice alla guidauna serie di tabelle che sintetizzano il
supporto sui principali browser dei nuovi tag, attributi e API HTML5. Per ciascun browser viene indicata la versione pi bassa che supporta una specifica funzionalit. I
link puntano alle lezioni dedicate a ciascun tag e API.
Figura 1 - Anteprima della tabella
Visualizza le tabelle (http://www.html.it/guide/esempi/html5/tabella_supporto/tabella.html).