-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathdetect.html
701 lines (517 loc) · 55.2 KB
/
detect.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
<!DOCTYPE html>
<html lang=pt-br>
<meta charset=utf-8>
<title>Detectando funcionalidade da HTML5 - Dive Into HTML5</title>
<!--[if lt IE 9]><script src=j/html5.js></script><![endif]-->
<link rel=alternate type=application/atom+xml href=https://github.com/zenorocha/diveintohtml5/commits/gh-pages.atom>
<link rel=alternate href=http://diveintohtml5.info/detect.html hreflang=en>
<link rel=stylesheet href=screen.css>
<style>
body{counter-reset:h1 2}
</style>
<link rel=stylesheet media='only screen and (max-device-width: 480px)' href=mobile.css>
<link rel=prefetch href=index.html>
<a href="https://github.com/zenorocha/diveintohtml5"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
<p>Você está aqui: <a href=index.html>Home</a> <span class=u>‣</span> <a href=table-of-contents.html#detect>Dive Into <abbr>HTML5</abbr></a> <span class=u>‣</span>
<h1><br>Detectando funcionalidades da <abbr>HTML5</abbr></h1>
<p id=toc>
<p class=a>❧
<h2 id=divingin>Mergulhando</h2>
<p class=f><img src=i/aoc-v.png alt=V width=109 height=105>ocê pode se perguntar: “Como eu posso começar a usar <abbr>HTML5</abbr> se os navegadores não o suportam?” Mas a questão por si só é enganosa. <abbr>HTML5</abbr> não é uma coisa grande e única; é uma coleção de funcionalidades individuais. Então você não pode detectar “suporte ao <abbr>HTML5</abbr>,” por que isso não faz sentido. Mas você <em>pode</em> verificar o suporte a funcionalidades individuais, como canvas, vídeo, ou geolocalização.
<p class=a>❧
<h2 id=techniques>Técnicas de detecção</h2>
<p>Quando seu navegador renderiza uma página web, ele constrói um Modelo Objeto Documento (<abbr><dfn>DOM</dfn></abbr>, Document Object Model em inglês), uma coleção de objetos que representam os elementos <abbr>HTML</abbr> na página. Cada elemento — todo <code><p></code>, todo <code><div></code>, todo <code><span></code> — é representado no <abbr>DOM</abbr> por um objeto diferente. (Também existem objetos globais, como <code>window</code> e <code>document</code>, que não estão vinculados a elementos específicos.)
<p class=ss style="width:257px"><img src=i/openclipart.org_johnny_automatic_peeking_out_the_window.png width=257 height=436 alt="girl peeking out the window">
<p>Todos os objetos no <abbr>DOM</abbr> compartilham um conjunto comum de propriedades, mas alguns objetos têm mais do que outros. Em navegadores que suportam funcionalidades da <abbr>HTML5</abbr>, alguns objetos terão propriedades únicas. Uma espiada rápida no <abbr>DOM</abbr> irá te dizer quais funcionalidades são suportadas.
<p>Existem quatros técnicas básicas para detectar se o browser suporta uma funcionalidade específica. Do mais simples até o mais complexo:
<ol>
<li>
<p>Verifica se uma determinada propriedade existe em um objeto global (como <code>window</code> ou <code>navigator</code>).
<p>Exemplo: <a href=#geolocation>testando o suporte a geolocalização</a>
<li>
<p>Crie um elemento, então verifique se uma determinada propriedade existe naquele elemento.
<p>Exemplo: <a href=#canvas>testanto suporte ao canvas</a>
<li>
<p>Crie um elemento, verifique se um determinado método existe naquele elemento, então chame o método e verifique o valor que ele retorna.
<p>Exemplo: <a href=#video-formats>testando quais formatos de vídeos são suportados</a>
<li>
<p>Crie um elemento, defina uma propriedade para um determinado valor, então verifique se a propriedade manteve seu valor.
<p>Exemplo: <a href=#input-types>testando quais tipos de <code><input></code> são suportados</a>
</ol>
<p class=a>❧
<h2 id=modernizr>Modernizr, uma biblioteca de detecção HTML5</h2>
<p><a href=http://www.modernizr.com/>Modernizr</a> é um biblioteca JavaScript de código aberto, sob licença <abbr>MIT</abbr>, que detecta suporte a várias funcionalidades de <abbr>HTML5</abbr> <i class=baa>&</i> <abbr>CSS3</abbr>. Você deve usar sempre a última versão. Para usá-la, inclua o seguinte elemento <code><script></code> no topo da sua página.
<pre style="float:left"><code><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Dive Into HTML5</title>
<mark><script src="modernizr.min.js"></script></mark>
</head>
<body>
...
</body>
</html>
</code></pre>
<p class="legend right" style="margin-top:7em"><span class=arrow> ↜</span> Isso vai no seu <head>
<p class=clear>Modernizr executa automaticamente. Não existe uma função <code>modernizr_init()</code> para ser chamada. Quando ela roda, cria um objeto global chamado <code>Modernizr</code>, que contém um conjunto de propriedades Booleanas para cada funcionalidade que ela puder detectar. Por exemplo, se seu navegador suporta a <a href=canvas.html><abbr>API</abbr> do canvas</a>, a propriedade <code>Modernizr.canvas</code> será <code>true</code>. Se seu navagador não suportar a <abbr>API</abbr> do canvas, a propriedade <code>Modernizr.canvas</code> será <code>false</code>.
<pre><code>if (Modernizr.canvas) {
// vamos desenhar algumas formas!
} else {
// o suporte nativo ao canvas não está disponível :(
}</code></pre>
<p class=a>❧
<h2 id=canvas>Canvas</h2>
<p class=ss style="width:300px"><img src=i/openclipart.org_johnny_automatic_fishing_boat.png width=300 height=203 alt="man fishing in a canoe"><br><span id=live-canvas></span>
<p>A <abbr>HTML5</abbr> define <a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html>o elemento <canvas> </a> como “uma tela bitmap de resolução dependente que pode ser usada para renderizar grafos, gráficos de jogos, ou outras imagens visuais em tempo real.” Um <dfn>canvas</dfn> é um retângulo na sua página onde você pode usar JavaScript para desenhar qualquer coisa que você quiser. A <abbr>HTML5</abbr> define um conjunto de funções (“a <abbr>API</abbr> canvas”) para desenhar formas, definindo caminhos, criando gradientes e aplicando transformações.
<p>A verificação da <abbr>API</abbr> do canvas usa a <a href=#techniques>técnica de detecção #2</a>. Se seu navegador suporta a <abbr>API</abbr> do canvas, o objeto <abbr>DOM</abbr> o cria para representar um elemento <code><canvas></code> que terá um <a href=canvas.html#shapes>método <code>getContext()</code></a>. Se seu navegador não suporta a <abbr>API</abbr> do canvas, o objeto <abbr>DOM</abbr> o cria para um elemento <code><canvas></code> que terá apenas um conjunto comum de propriedades, mas nada específico do canvas.
<pre><code>function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
</code></pre>
<p>Essa função começa com a criação do elemento <code><canvas></code> de teste. Mas o elemento nunca é adicionado a sua página, então ninguém nunca o verá. Está apenas flutuando na memória, indo a lugar nenhum e fazendo nada, como uma canoa em um rio calmo.
<pre><code>return !!document.<mark>createElement('canvas')</mark>.getContext;</code></pre>
<p>Assim que você cria o elemento <code><canvas></code> de teste, você testa a existência de um método <code>getContext()</code>. Esse método só existirá se o seu navegador suportar a <abbr>API</abbr> do canvas.
<pre><code>return !!document.createElement('canvas').<mark>getContext</mark>;</code></pre>
<p>Finalmente, você usa o truque da negação dupla para forçar a conversão do resultado em um valor booleano(<code>true</code> ou <code>false</code>).
<pre><code>return <mark>!!</mark>document.createElement('canvas').getContext;</code></pre>
<p>Essa função irá detectar grande parte da <abbr>API</abbr> do canvas, incluindo <a href=canvas.html#shapes>shapes</a>, <a href=canvas.html#paths>paths</a>, <a href=canvas.html#gradients>gradients <i class=baa>&</i> patterns</a>. Ela não detectará a biblioteca de terceiros <a href=canvas.html#ie><code>explorercanvas</code></a> que implementa a <abbr>API</abbr> do canvas no Microsoft Internet Explorer.
<p>Ao invés de escrever essa função você mesmo, você pode usar a <a href=#modernizr>Modernizr</a> para detectar o suporte a <abbr>API</abbr> do canvas.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verifica o suporte ao canvas
<pre><code>if (<mark>Modernizr.canvas</mark>) {
// vamos desenhar algumas formas!
} else {
// o suporte nativo ao canvas não está disponível :(
}</code></pre>
<p>Existe um teste separado para a <abbr>API</abbr> do canvas text, que será demonstrado a seguir.
<p class=a>❧
<h2 id=canvas-text>Texto Canvas</h2>
<p class=ss style="width:414px"><img src=i/openclipart.org_johnny_automatic_baseball_at_bat.png width=414 height=254 alt="baseball player at bat"><br><span id=live-canvas-text></span>
<p>Mesmo que o seu navegador suporte a <a href=#canvas><abbr>API</abbr> canvas</a>, ele pode não suportar a <abbr>API</abbr> do <dfn>texto canvas</dfn>. A <abbr>API</abbr> do canvas cresceu através do tempo, e as funções de texto foram adicionadas por último. Alguns navegadores passaram a suportar o canvas antes da <abbr>API</abbr> de texto estar completa.
<p>A verificação da <abbr>API</abbr> do texto canvas usa a <a href=#techniques>técnica de detecção #2</a>. Se seu navegador suporta a <abbr>API</abbr> do canvas, o objeto <abbr>DOM</abbr> o cria para representar um elemento <code><canvas></code> que terá um <a href=canvas.html#shapes>método <code>getContext()</code></a>. Se seu navegador não suporta a <abbr>API</abbr> do canvas, o objeto <abbr>DOM</abbr> o cria para um elemento <code><canvas></code> que terá apenas um conjunto comum de propriedades, mas nada específico do canvas.
<pre><code>function supports_canvas_text() {
if (!supports_canvas()) { return false; }
var dummy_canvas = document.createElement('canvas');
var context = dummy_canvas.getContext('2d');
return typeof context.fillText == 'function';
}</code></pre>
<p>A função começa <a href=#canvas>verificando o suporte ao canvas</a>, usando a função <code>supports_canvas()</code> que você acabou de ver na seção anterior. Se seu navegador não suporta a <abbr>API</abbr> do canvas, ele certamente não suportará a <abbr>API</abbr> de texto canvas!
<pre><code>if (<mark>!supports_canvas()</mark>) { return false; }</code></pre>
<p>Depois, você cria um elemento <code><canvas></code> de teste e pega seu contexto de desenho. Isso funcionará de forma garantida, porque a função <code>supports_canvas()</code> já verificou que o método <code>getContext()</code> existe em todo objeto canvas.
<pre><code> var dummy_canvas = document.createElement('canvas');
var context = <mark>dummy_canvas.getContext('2d')</mark>;</code></pre>
<p>Finalmente, você verifica se o contexto de desenho tem uma função <code>fillText()</code>. Se tiver, a <abbr>API</abbr> de texto canvas está disponível. Hooray!
<pre><code> return <mark>typeof context.fillText == 'function'</mark>;</code></pre>
<p>Ao invés de escrever essa função você mesmo, você pode usar <a href=#modernizr>Modernizr</a> para detectar o suporte à <abbr>API</abbr> do texto canvas.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verifica o suporte ao texto canvas
<pre><code>if (<mark>Modernizr.canvastext</mark>) {
// vamos desenhar algum texto!
} else {
// sem suporte nativo ao texto canvas disponível :(
}</code></pre>
<p class=a>❧
<h2 id=video>Vídeo</h2>
<p>A <abbr>HTML5</abbr> define um novo elemento chamado <code><video></code> para embutir vídeo nas suas páginas web. Embutir vídeos costuma ser impossível sem plugins de terceiros como Apple QuickTime® ou Adobe Flash®.
<p class=ss style="width:224px"><img src=i/openclipart.org_johnny_automatic_at_the_theater.png alt="audience at the theater" width=224 height=334><br><span id=live-video></span>
<p>O elemento <code><video></code> é projetado para funcionar sem a necessidade de scripts de detecção. Você pode especificar múltiplos arquivos de vídeo, e os navegadores que possuirem suporte ao <abbr>HTML5</abbr> vídeo escolherão um baseado nos formatos suportados por eles.
<p>Navegadores que não possuem suporte a <abbr>HTML5</abbr> vídeo irão ignorar o elemento <code><video></code> completamente, mas você pode usar isso a seu favor dizendo a eles para tocar o vídeo através de plugins. Kroc Camen desenvolveu uma solução chamada <a href=http://camendesign.com/code/video_for_everybody>Video for Everybody!</a> que faz uso da <abbr>HTML5</abbr> vídeo onde estiver disponivel, porém fazendo tratamento para uso de QuickTime ou Flash em navegadores antigos. Essa solução não usa JavaScript, e funciona praticamente em qualquer navegador, inclusive em mobiles.
<p>Se você quiser fazer mais com vídeo do que apenas colocá-lo em sua página e tocá-lo, terá que usar JavaScript. Checar suporte a vídeo utiliza a <a href=#techniques>técnica de detecção #2</a>. Se seu navegador possui suporte para <abbr>HTML5</abbr> vídeo, o objeto <abbr>DOM</abbr> criado para representar o elemento <code><video></code> terá um método <code>canPlayType()</code>. Caso o navegador não tenha suporte para <abbr>HTML5</abbr> vídeo, o objeto <abbr>DOM</abbr> criado para o elemento <code><video></code> terá apenas uma coleção de proprieades comum à todos os elementos. Você pode verificar o suporte a vídeo usando essa função:
<pre><code>function supports_video() {
return !!document.createElement('video').canPlayType;
}</code></pre>
<p>Ao invés de escrever a função você mesmo, você pode usar o <a href=#modernizr>Modernizr</a> para detectar suporte a <abbr>HTML5</abbr> vídeo.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a <abbr>HTML5</abbr> vídeo
<pre><code>if (<mark>Modernizr.video</mark>) {
// vamos tocar alguns vídeos!
} else {
// suporte nativo a vídeos indisponível :(
// verifique suporte a QuickTime ou Flash talvez
}</code></pre>
<p>No <a href=video.html>capítulo de Vídeo</a>, explicarei outra solução que faz uso dessas técnicas de detecção para converter elementos <code><video></code> para players baseados em Flash, para atender a navegadores que não possuem suporte ao <abbr>HTML5</abbr> vídeo.
<p>Existe um teste separado para detectar quais formatos de vídeo seu navegador pode tocar, o qual demonstrarei em seguida.
<p class=a>❧
<h2 id=video-formats>Formatos de Vídeo</h2>
<p>Formatos de vídeo são como linguagens escritas. Um jornal em inglês contém a mesma informação que um jornal em espanhol, mas se você só sabe ler inglês, apenas um dos jornais será útil pra você! Para tocar um vídeo, seu navegador precisa entender o “idioma” no qual o vídeo foi escrito.
<p class=ss style="float:left;margin:0 1.75em 1.75em 0;width:250px"><img src=i/openclipart.org_johnny_automatic_man_reading_newspaper.png alt="man reading newspaper" width=250 height=261><br><span id=live-video-formats></span>
<p>O “idioma” de um vídeo é chamado de “codec” — é um algoritmo usado para codificar o vídeo em uma sequência de bits. Existem vários codecs em uso ao redor do mundo. Qual deles você usa? A triste realidade da <abbr>HTML5</abbr> vídeo é que os navegadores não trabalham com um único codec em comum. Contudo, aparentemente eles se limitaram a dois tipos. Um codec é pago (por causa da licença de patente), mas funciona no <a href=http://www.apple.com/safari/>Safari</a> e no iPhone. (Este também funciona com Flash se você utiliza uma solução como <a href=http://camendesign.com/code/video_for_everybody>Video for Everybody!</a>) O outro codec é gratuito e funciona em navegadores open source como <a href=http://code.google.com/chromium/>Chromium</a> and <a href=http://www.getfirefox.com/>Mozilla Firefox</a>.
<p>A verificação de suporte a formatos de vídeo utiliza a <a href=#techniques>técnica de detecção #3</a>. Se o seu navegador possui suporte a <abbr>HTML5</abbr> vídeo, o objeto <abbr>DOM</abbr> criado para representar um elemento <code><video></code> terá um método <code>canPlayType()</code>. Esse método dirá se seu browser possui suporte a um determinado formato de vídeo.
<p>Essa função verifica formatos suportados por Macs e iPhones.
<pre><code>function supports_h264_baseline_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
}</code></pre>
<p>A função começa <a href=#video>verificando suporte a <abbr>HTML5</abbr> vídeo</a>, usando a função <code>supports_video()</code> que você acabou de ver na seção anterior. Se o seu navegador não possui suporte a <abbr>HTML5</abbr> vídeo, com certeza não terá suporte para formatos de vídeo!
<pre><code> if (<mark>!supports_video()</mark>) { return false; }</code></pre>
<p>Então a função cria um elemento <code><video></code> (mas não o inclui na página, assim ele não será visível) e invoca o método <code>canPlayType()</code>. Este método está lá seguramente, pois a função <code>supports_video()</code> acabou de garantir sua existência.
<pre><code> var <mark>v</mark> = document.createElement("video");</code></pre>
<p>Um “formato de vídeo” é na verdade uma combinação de diferentes coisas. Em termos técnicos, vocês está perguntando ao navegador se ele pode tocar um vídeo de base H.264 e um áudio AAC LC em um container MPEG-4. (Irei explicar o que tudo isso significa no <a href=video.html>capítulo de Vídeo</a>. Você também pode querer ler <a href=http://diveintomark.org/tag/give>Uma breve introdução à codificação de vídeo</a>.)
<pre><code> return v.canPlayType('<mark>video/mp4; codecs="avc1.42E01E, mp4a.40.2"</mark>');</code></pre>
<p>A função <code>canPlayType()</code> não retorna <code>true</code> ou <code>false</code>. Considerando a complexidade que os formatos de vídeo possuem, a função retorna uma string:
<ul>
<li><code>"probably"</code> se o navegador está confiante de que possa tocar este formato
<li><code>"maybe"</code> se o navegador acha que tem condições de tocar este formato
<li><code>""</code> (uma string vazia) se o navegador tem certeza de que não consegue tocar este formato
</ul>
<p>Essa segunda função verifica pelo formato de vídeo livre suportado pelo Mozilla Firefox e outros navegadores de código aberto. O processo é exatamente o mesmo; a única diferença é a string que você passa à função <code>canPlayType()</code>. Em termos técnicos, você pergunta ao navegador se ele é capaz de tocar vídeo Theora e áudio Vorbis em um container Ogg.
<pre><code>function supports_ogg_theora_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType(<mark>'video/ogg; codecs="theora, vorbis"'</mark>);
}</code></pre>
<p>Finalmente, <a href=http://www.webmproject.org/>WebM</a> é um recente codec de vídeo open-source (e livre de patentes) que será incluido nas próximas versões dos principais navegadores, tais como o Chrome, <a href=http://nightly.mozilla.org/webm/>Firefox</a>, e <a href=http://labs.opera.com/news/2010/05/19/>Opera</a>. Você pode utilizar a mesma técnica para detectar suporte ao vídeo livre WebM.
<pre><code>function supports_webm_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType(<mark>'video/webm; codecs="vp8, vorbis"'</mark>);
}</code></pre>
<p>Ao invés de escrever essa função você mesmo, você pode utilizar o <a href=#modernizr>Modernizr</a> (1.5 ou superior) para detectar suporte aos diferentes formatos de <abbr>HTML5</abbr> vídeo.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a formatos para <abbr>HTML5</abbr> vídeo
<pre><code>if (Modernizr.video) {
// vamos tocar alguns vídeos! mas de qual tipo?
if (<mark>Modernizr.video.webm</mark>) {
// tentar o WebM
} else if (<mark>Modernizr.video.ogg</mark>) {
// tentar Ogg Theora + Vorbis em um container Ogg
} else if (<mark>Modernizr.video.h264</mark>){
// tentar vídeo H.264 + áudio AAC em um container MP4
}
}</code></pre>
<p class=a>❧
<h2 id=storage>Armazenamento Local</h2>
<p class=ss style="width:135px"><img src=i/openclipart.org_johnny_automatic_half_stack_of_horizontal_sections.png alt="filing cabinet with drawers of different sizes" width=135 height=341><br><span id=live-storage></span>
<p><a href=http://dev.w3.org/html5/webstorage/><abbr>HTML5</abbr> storage</a> fornece aos web sites uma forma de armazenar informações em seu computador e recuperá-lo mais tarde. O conceito é semelhante ao dos cookies, porém ele é projetado para armazenar quantidades de informação superiores. Cookies possuem tamanho bem limitado, e o seu navegador os envia de volta ao servidor web sempre que uma nova página é solicitada (o que leva um tempo extra e uma banda valiosa). O <abbr>HTML5</abbr> storage permanece em seu computador, e os web sites podem acessá-lo através de JavaScript depois que a página é carregada.
<div class="pf clear">
<h4>Pergunte ao Professor Marcação</h4>
<div class=inner>
<blockquote class=note>
<p><span>☞</span>P: O armazenamento local é realmente parte da <abbr>HTML5</abbr>? Por que ele fica em uma especificação separada?<br>
R: A resposta curta é sim, armazenamento local é parte da <abbr>HTML5</abbr>. A resposta um pouco mais completa é que o armazenamento local fazia parte da especificação principal da <abbr>HTML5</abbr>, mas foi dividido em uma especificação isolada porque algumas pessoas no Working Group da <abbr>HTML5</abbr> se queixaram que a <abbr>HTML5</abbr> estava ficando muito grande. Se partir um bolo em mais pedaços passa a sensação de reduzir o número de calorias, bem, bem vindo ao mundo estranho dos padrões.
</blockquote>
</div>
</div>
<p>A verificação de suporte ao <abbr>HTML5</abbr> storage utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte ao <abbr>HTML5</abbr> storage, haverá uma propriedade chamada <code>localStorage</code> no objeto global <code>window</code>. Se o seu navegador não possui suporte ao <abbr>HTML5</abbr> storage, a propriedade <code>localStorage</code> será undefined. Devido a um bug em versões anteriores do Firefox, este teste causará uma exceção se os cookies estiverem desabilitados, por isso o teste todo é envolvido por um bloco <code>try..catch</code>.
<pre><code>function supports_local_storage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch(e){
return false;
}
}</code></pre>
<p>Ao invés de escrever essa função, você pode usar o <a href=#modernizr>Modernizr</a> (1.1 ou superior) para detectar suporte ao <abbr>HTML5</abbr> local storage.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte ao <abbr>HTML5</abbr> local storage
<pre><code>if (<mark>Modernizr.localstorage</mark>) {
// window.localStorage está disponível!
} else {
// sem suporte nativo ao local storage :(
// tente usar o Gears ou outra solução, talvez
}</code></pre>
<p>Note que o JavaScript faz distinção entre letras maiúsculas e minúsculas. O atributo do Modernizr é chamado <code>localstorage</code> (todas as letras minúsculas), mas a propriedade <abbr>DOM</abbr> é chamada <code>window.localStorage</code> (letras maiúsculas e minúsculas misturadas).
<div class="pf clear">
<h4>Pergunte ao Professor Marcação</h4>
<div class=inner>
<blockquote class=note>
<p><span>☞</span>P: Quão seguro é o banco de dados da <abbr>HTML5</abbr> storage? Qualquer um pode acessá-lo?<br>
R: Qualquer um que possua acesso físico ao seu computador provavelmente poderá ler (ou até mesmo editar) seu banco de dados da <abbr>HTML5</abbr> storage. Com seu navegador, qualquer web site pode ler e modificar seus próprios valores, mas sites não podem acessar valores armazenados por outros sites. Isso é chamado de <a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/origin-0.html#origin-0>same-origin restriction</a>.
</blockquote>
</div>
</div>
<p class=a>❧
<h2 id=workers>Web Workers</h2>
<p class=ss style="margin:1.75em"><span id=live-web-workers></span>
<p><a href=http://www.whatwg.org/specs/web-workers/current-work/>Web Workers</a> fornecem uma maneira padrão aos navegadores de executarem JavaScript ao fundo. Com web workers, você pode disparar múltiplas “threads” que irão todas ser executadas ao mesmo tempo, mais ou menos. (Pense em como o computador pode executar múltiplas aplicações ao mesmo tempo e você terá praticamente entendido tudo.) Essas “threads em background” podem realizar cálculos matemáticos complexos, fazer requisições HTTP ou acessar o <a href=#local-storage>local storage</a> enquanto a página principal atende aos comandos do usuário tais como rolando a página, cliques ou digitação.
<p>Verificar o suporte às web workers utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte à <abbr>API</abbr> do Web Worker, haverá uma propriedade <code>Worker</code> no objeto global <code>window</code>. Se o seu navegador não possui suporte à <abbr>API</abbr> do Web Worker, a propriedade <code>Worker</code> será undefined.
<pre><code>function supports_web_workers() {
return !!window.Worker;
}</code></pre>
<p>Ao invés de escrever essa função, você pode utilizar o <a href=#modernizr>Modernizr</a> (1.1 ou superior) para detectar suporte a web workers.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a web workers
<pre><code>if (<mark>Modernizr.webworkers</mark>) {
// window.Worker está disponível!
} else {
// sem suporte nativo a web workers :(
// tente o Gears ou outra solução
}</code></pre>
<p>Note que o JavaScript faz distinção entre letras maiúsculas e minúsculas. O atributo do Modernizr é chamado <code>webworkers</code> (todas as letras minúsculas), mas a propriedade <abbr>DOM</abbr> é chamada <code>window.Worker</code> (letras maiúsculas e minúsculas misturadas).
<p class=a>❧
<h2 id=offline>Aplicações Web Offline</h2>
<p class=ss style="width:257px"><img src=i/openclipart.org_johnny_automatic_cabin_along_stream.png alt="cabin in the woods" width=257 height=242><br><span id=live-offline></span>
<p>Ler páginas web estáticas é fácil: conecte-se na Internet, carregue uma página, se disconecte da Internet, dirija até uma cabine isolada, e leia a página comodamente. (Para ganhar tempo, pule a parte de ir até uma cabine.) Mas e as aplicações como o <a href=http://mail.google.com/>Gmail</a> ou <a href=http://docs.google.com/>Google Docs</a>? Graças ao <abbr>HTML5</abbr>, qualquer um (não só o Google!) pode construir uma aplicação web que funcione offline.
<p><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#offline>Aplicações web offline</a> começam como aplicações web online. A primeira vez que você visita um site com conteúdo offline habilitado, o servidor web diz ao navegador quais arquivos ele precisa para trabalhar offline. Esses arquivos podem ser qualquer coisa — <abbr>HTML</abbr>, JavaScript, imagens, até mesmo <a href=#video>vídeos</a>. Uma vez que o navegador carregou todos os arquivos necessários, você pode revisitar o web site até mesmo se você não estiver conectado a Internet. Seu navegador perceberá que você está offline e usará os arquivos que ele já havia feito download. Quando você se reconectar, quaisquer alterações que você tenha feito podem ser enviadas ao servidor web.
<p>Verificar o suporte a conteúdo offline utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte à aplicações web offline, haverá uma propriedade <code>applicationCache</code> no objeto global <code>window</code>. Se o seu navegador não possui suporte à aplicações web offline, a propriedade <code>applicationCache</code> será undefined. Você pode verificar a disponibilidade de aplicações web offline através da seguinte função:
<pre><code>function supports_offline() {
return !!window.applicationCache;
}</code></pre>
<p>Ao invés de escrever essa função, você pode utilizar o <a href=#modernizr>Modernizr</a> (1.1 ou superior) para detectar suporte a aplicações web offline.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a aplicações web offline
<pre><code>if (<mark>Modernizr.applicationcache</mark>) {
// window.applicationCache está disponível!
} else {
// sem suporte nativo a conteudo offline :(
// tente usar o Gears ou outra solução
}</code></pre>
<p>Note que o JavaScript faz distinção entre letras maiúsculas e minúsculas. O atributo do Modernizr é chamado <code>applicationcache</code> (todas as letras minúsculas), mas a propriedade <abbr>DOM</abbr> é chamada <code>window.applicationCache</code> (letras maiúsculas e minúsculas misturadas).
<p class=a>❧
<h2 id=geolocation>Geolocalização</h2>
<p>Geolocalização é a arte de descobrir em que lugar do mundo você está e (eventualmente) compartilhar essa informação com as pessoas de sua confiança. Existe mais de uma maneira de saber onde você está — seu endereço <abbr>IP</abbr>, sua conexão de rede sem fio, com qual torre seu celular está se comunicando, ou o <abbr>GPS</abbr> que calcula a latitude e longitude através das informações enviadas pelos satélites no céu.
<p style="margin:0 auto;width:194px" id=geo-wrapper><img src=i/openclipart.org_johnny_automatic_globe_man.png alt="man with a globe for a head" width=194 height=317><br><span id=live-geolocation></span>
<div class="pf clear">
<h4>Pergunte ao Professor Marcação</h4>
<div class=inner>
<blockquote class=note>
<p><span>☞</span>P: A geolocalização faz parte da <abbr>HTML5</abbr>? Por que você está falando sobre ela?<br>
R: O suporte a geolocalização foi adicionado aos navegadores agora há pouco, juntamente com o suporte para novos recursos <abbr>HTML5</abbr>. Na verdade, a geolocalização está sendo padronizada pelo <a href=http://www.w3.org/2008/geolocation/>Geolocation Working Group</a>, o qual está separado da <abbr>HTML5</abbr> Working Group. Porém eu irei falar sobre a geolocalização neste livro assim mesmo, porque ela é parte da evolução da web que está acontecendo nesse momento.
</blockquote>
</div>
</div>
<p>Verificar o suporte à geolocalização utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte à geolocalização, haverá uma propriedade <code>geolocation</code> no objeto global <code>window</code>. Se o seu navegador não possui suporte à geolocalização, a propriedade <code>geolocation</code> será undefined. Veja como você pode verificar se há suporte à geolocalização:
<pre><code>function supports_geolocation() {
return !!navigator.geolocation;
}</code></pre>
<p>Ao invés de escrever essa função, você pode utilizar o <a href=#modernizr>Modernizr</a> para detectar suporte a <abbr>API</abbr> de geolocalização.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a geolocalização
<pre><code>if (<mark>Modernizr.geolocation</mark>) {
// Vamos ver onde você está!
} else {
// suporte nativo à geolocalização indisponível :(
// tente o Gears ou outra solução
}</code></pre>
<p>Se o seu navegador não possui suporte nativo à geolocalização, ainda há esperança. O <a href=http://tools.google.com/gears/>Gears</a> é um plugin para navegadores livre desenvolvido pelo Google que funciona no Windows, Mac, Linux, Windows Mobile e Android. Ele fornece recursos para navegadores mais antigos que não possuem suporte a todas essas novas coisas estilosas que viemos discutindo neste capítulo. Um dos recursos que o Gears fornece é a <abbr>API</abbr> de geolocalização. Não é exatamente a mesma coisa que <code>navigator.geolocation</code>, mas funciona como se fosse.
<p>Existem ainda <abbr>API</abbr>s de geolocalização específicas para determinados dispositivos para alguns celulares antigos, incluindo <a href="http://www.tonybunce.com/2008/05/08/Blackberry-Browser-Amp-GPS.aspx">BlackBerry</a>, <a href="http://www.forum.nokia.com/infocenter/index.jsp?topic=/Web_Developers_Library/GUID-4DDE31C7-EC0D-4EEC-BC3A-A0B0351154F8.html">Nokia</a>, <a href="http://developer.palm.com/index.php?option=com_content&view=article&id=1673#GPS-getCurrentPosition">Palm</a> e <a href=http://bondi.omtp.org/1.0/apis/geolocation.html><abbr title="Open Mobile Terminal Platform">OMTP</abbr> BONDI</a>.
<p>O <a href=geolocation.html>capítulo sobre geolocalização</a> falará nos mínimos detalhes sobre como usar as diferentes <abbr>API</abbr>s.
<p class=a>❧
<h2 id=input-types>Tipos de entrada</h2>
<p class=ss style="width:261px"><img src=i/openclipart.org_johnny_automatic_typewriter.png alt="manual typewriter" width=261 height=228><br><span id=live-input-types></span>
<p>Você sabe tudo sobre formulários web, certo? Fazer um <code><form></code>, adicionar alguns elementos <code><input type="text"></code> e quem sabe um <code><input type="password"></code>, e por fim um botão <code><input type="submit"></code>.
<p>Você não sabe a metade deles. a <abbr>HTML5</abbr> define um monte de novos tipos de entrada de dados que você pode usar em seus formulários.
<ol>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#text-state-and-search-state><code><input type="search"></code></a> para caixas de busca
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#number-state><code><input type="number"></code></a> para campos incrementais
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#range-state><code><input type="range"></code></a> para sliders
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#color-state><code><input type="color"></code></a> para seleção de cores
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#telephone-state><code><input type="tel"></code></a> para números de telefone
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#url-state><code><input type="url"></code></a> para endereços na web
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state><code><input type="email"></code></a> para endereços de e-mail
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#date-state><code><input type="date"></code></a> para calendários
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#month-state><code><input type="month"></code></a> para meses
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#week-state><code><input type="week"></code></a> para semanas
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#time-state><code><input type="time"></code></a> para horas
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#date-and-time-state><code><input type="datetime"></code></a> para precisos e absolutos data+hora
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#local-date-and-time-state><code><input type="datetime-local"></code></a> para datas e horas locais
</ol>
<p>Verificando suporte aos tipos de entrada da <abbr>HTML5</abbr> utiliza a <a href=#techniques>técnica de detecção #4</a>. Primeiro, você cria um elemento <code><input></code> em memória. O tipo padrão para todos os elementos <code><input></code> é <code>"text"</code>.
<pre><code> var i = document.createElement("input");</code></pre>
<p>Em seguida, configure o atributo <code>type</code> ao elemento <code><input></code> para o tipo de entrada que você quer detectar.
<pre><code> i.setAttribute("type", "color");</code></pre>
<p>Se o seu navegador possuir suporte para aquele tipo de entrada em particular, a propriedade <code>type</code> irá reter o valor que você configurou. Se o seu navegador não possuir suporte para aquele tipo de entrada em particular, ele irá ignorar o valor que você configurou e a propriedade <code>type</code> ainda será <code>"text"</code>.
<pre><code> return i.type !== "text";</code></pre>
<p>Ao invés de ter de escrever 13 diferentes funções, você pode usar o <a href=#modernizr>Modernizr</a> para detectar suporte para todos os novos tipos de entrada definidos na <abbr>HTML5</abbr>. O Modernizr reaproveita um único elemento <code><input></code> para eficientemente detectar o suporte aos 13 tipos de entrada. Então ele constrói um hash chamado de <code>Modernizr.inputtypes</code>, que possui 13 chaves (os atributos <code>type</code> da <abbr>HTML5</abbr>) e 13 valores booleanos (<code>true</code> se for suportado, <code>false</code> se não).
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte nativo ao date picker
<pre><code>if (<mark>!Modernizr.inputtypes.date</mark>) {
// sem suporte nativo para <input type="date"> :(
// talvez você deva fazer um você mesmo com <a href=http://docs.dojocampus.org/dojox/widget/Calendar>Dojo</a> ou <a href=http://jqueryui.com/demos/datepicker/>jQueryUI</a>
}</code></pre>
<p class=a>❧
<h2 id=input-placeholder>Placeholder</h2>
<form style="float:right;margin:1.75em"><input placeholder="Your browser supports placeholder text" size=38></form>
<p>Além dos <a href=#input-types>novos tipos de entrada</a>, a <abbr>HTML5</abbr> inclui vários pequenos ajustes aos formulários já existentes. Uma melhoria é colocar um <a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#the-placeholder-attribute>placeholder em um campo de entrada</a>. O placeholder é exibido dentro de um campo de entrada enquanto o campo estiver vazio e sem foco. Assim que você clica no campo (ou navega com o tab até ele), o placeholder some. O <a href=forms.html#placeholder>capítulo sobre formulários web</a> tem screenshots se você está tendo dificuldades em visualizá-lo.
<p>A verificação de suporte ao placeholder utiliza a <a href=#techniques>técnica de detecção #2</a>. Se o seu navegador possui suporte à colocar placeholders em campos de entrada, o objeto <abbr>DOM</abbr> criado para representar o elemento <code><input></code> terá uma propriedade <code>placeholder</code> (mesmo que você não inclua um atributo <code>placeholder</code> em seu <abbr>HTML</abbr>). Se o seu navegador não possui suporte ao placeholder, o objeto <abbr>DOM</abbr> criado para um elemento <code><input></code> não terá uma propriedade <code>placeholder</code>.
<pre><code>function supports_input_placeholder() {
var i = document.createElement('input');
return 'placeholder' in i;
}</code></pre>
<p>Ao invés de escrever essa função, você pode utilizar o <a href=#modernizr>Modernizr</a> (1.1 ou superior) para detectar suporte ao placeholder.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> checa pelo texto de placeholder
<pre><code>if (<mark>Modernizr.input.placeholder</mark>) {
// seu placeholder já deve estar visível!
} else {
// sem suporte ao placeholder :(
// implemente uma solução com script
}</code></pre>
<p class=a>❧
<h2 id=input-autofocus>Auto foco de formulário</h2>
<p class=ss style="width:188px"><img src=i/openclipart.org_johnny_automatic_angry_guy.png alt="angry guy with arms up" width=188 height=262><br><span id="live-input-autofocus"></span>
<p>Os web sites podem usar JavaScript para dar foco ao primeiro campo de um formulário automaticamente. Por exemplo, a página principal do <a href=http://www.google.com/>Google.com</a> dá auto foco no campo de busca para você poder iniciar sua busca sem ter que posicionar o cursor do mouse no campo de busca. Enquanto isso pode ser conveniente para a maioria das pessoas, pode vir a ser incômodo para usuários experientes ou pessoas com necessidades especiais. Se você tentar pressionar a barra de espaço esperando que a página seja rolada para baixo, não ocorrerá conforme o esperado, pois o foco já está em um campo. (Acaba digitando um espaço no campo ao invés de rolar a página.) Se você der foco a um campo diferente antes de a página terminar de carregar, o script de auto foco pode “gentilmente” mover o foco de volta ao campo original ao fim do carregamento da página, atrapalhando seu fluxo de trabalho fazendo com que você digite no lugar errado.
<p>Como o auto foco é feito através do JavaScript, pode ser trabalhoso ter que lidar com todos esses delicados casos, e não há muito o que fazer para evitar a página web de “roubar” o foco.
<p>Para resolver esse problema, a <abbr>HTML5</abbr> apresenta <a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofocusing-a-form-control>um atributo de <code>autofocus</code> em todos os controles de formulário</a>. O atributo <code>autofocus</code> faz exatamente o que o seu nome diz: move o foco para um campo específico. Mas por ser apenas uma marcação ao invés de script, o comportamento será consistente entre todos os sites. Além disso, os desenvolvedores de navegadores podem oferecer formas de desabilitar o comportamento de auto foco.
<p>A verificação de suporte ao auto foco utiliza a <a href=#techniques>técnica de detecção #2</a>. Se o seu navegador possui suporte ao auto foco, o objeto <abbr>DOM</abbr> criado para representar um elemento <code><input></code> terá uma propriedade <code>autofocus</code> (mesmo que você não inclua o atributo <code>autofocus</code> em seu <abbr>HTML</abbr>). Se o seu navegador não possui suporte ao auto foco, o objeto <abbr>DOM</abbr> criado para um elemento <code><input></code> não terá uma propriedade <code>autofocus</code>. Você pode detectar suporte ao auto foco usando essa função:
<pre><code>function supports_input_autofocus() {
var i = document.createElement('input');
return 'autofocus' in i;
}</code></pre>
<p>Ao invés de escrever essa função, você pode usar o <a href=#modernizr>Modernizr</a> (1.1 ou superior) para detectar o suporte a campos com auto foco.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte ao auto foco
<pre><code>if (<mark>Modernizr.input.autofocus</mark>) {
// autofocus funciona!
} else {
// sem suporte a autofocus :(
// contornar com uma solução com script
}</code></pre>
<p class=a>❧
<h2 id=microdata>Micro dados</h2>
<p class=ss style="width:305px"><img src=i/openclipart.org_johnny_automatic_divider_cards.png alt="alphabetized folders" width=305 height=224><br><span id="live-microdata-api"></span>
<p><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#microdata>Microdata</a> é um jeito padronizado de informar semânticas adicionais em suas páginas. Por exemplo, você pode usar micro dados para declarar que uma foto está disponível sob a licença Creative Commons. Como você pode ver no <a href=extensibility.html>capítulo de extensibilidade distribuída</a>, você pode usar micro dados para demarcar uma página “Sobre mim”. Navegadores, extensões e motores de busca podem converter suas marcações de micro dados da <abbr>HTML5</abbr> em um <a href=http://en.wikipedia.org/wiki/VCard>vCard</a>, um formato padrão para compartilhamento de contatos. Você também pode definir seu próprio vocabulário de micro dados.
<p>O padrão de micro dados da <abbr>HTML5</abbr> inclui ambos a marcação <abbr>HTML</abbr> (a princípio para os motores de busca) e uma coleção de funções <abbr>DOM</abbr> (a princípio para os navegadores). Não há problema algum em adicionar marcações de micro dados em suas páginas. Não é nada mais do que alguns poucos atributos bem dispostos, e os motores de busca que não compreendem os atributos de micro dados irão simplesmente ignorá-los. Porém se você precisar acessar ou manipular os micro dados através de <abbr>DOM</abbr>, você terá que checar se o navegador possui ou não suporte a <abbr>API</abbr> <abbr>DOM</abbr> de micro dados.
<p>A verificação de suporte a micro dados da <abbr>HTML5</abbr> utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte aos micro dados da <abbr>HTML5</abbr>, haverá uma função <code>getItems()</code> no objeto global <code>document</code>. Se o seu navegador não possuir suporte a micro dados, a função <code>getItems()</code> será undefined.
<pre><code>function supports_microdata_api() {
return !!document.getItems;
}</code></pre>
<p>O Modernizr ainda não possui suporte aos micro dados, então você terá que usar uma função semelhante a exibida acima.
<p class=a>❧
<h2 id=history><abbr>API</abbr> de Histórico</h2>
<p class=ss style="float:left;margin:0 1.75em 1.75em 0;width:218px"><img src=i/openclipart.org_johnny_automatic_demon_reading_Stewart_Orr.png alt="demon reading book" width=218 height=231><br><span id=live-history-api></span>
<p>A <a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html><abbr>API</abbr> de histórico da <abbr>HTML5</abbr></a> é uma maneira padronizada de manipular o histórico do navegador via script. Uma parte dessa <abbr>API</abbr> — navegando pelo histórico — tem estado disponível em versões anteriores do <abbr>HTML</abbr>. A nova parte em <abbr>HTML5</abbr> é uma maneira de adicionar entradas no histórico do navegador, e obter uma resposta quando essas entradas são removidas da pilha quando o usuário pressionar o botão voltar do navegador. Isso quer dizer que a <abbr>URL</abbr> pode continuar a fazer o seu trabalho como identificador único para o recurso atual, mesmo em aplicações ricas em scripts que nunca realizam uma recarga total da página.
<p>A verificação de suporte a <abbr>API</abbr> de histórico da <abbr>HTML5</abbr> utiliza a <a href=#techniques>técnica de detecção #1</a>. Se o seu navegador possui suporte a <abbr>API</abbr> de histórico da <abbr>HTML5</abbr>, haverá uma função <code>pushState()</code> no objeto global <code>history</code>. Se o seu navegador não possui suporte a <abbr>API</abbr> de histórico, a função <code>pushState()</code> será undefined.
<pre><code>function supports_history_api() {
return !!(window.history && history.pushState);
}</code></pre>
<p>Ao invés de escrever sua função, você pode utilizar o <a href=#modernizr>Modernizr</a> (1.6 ou superior) para detectar suporte a <abbr>API</abbr> de histórico da <abbr>HTML5</abbr>.
<p class="legend top" style="padding-left:6em"><span class=arrow>↶</span> verificando suporte a <abbr>API</abbr> de histórico
<pre><code>if (<mark>Modernizr.history</mark>) {
// o gerenciamento de histórico funciona!
} else {
// sem suporte ao histórico :(
// contornar com uma solução de script <a href=https://github.com/balupton/History.js/>History.js</a>
}</code></pre>
<p class=a>❧
<h2 id=further-reading>Leitura Adicional</h2>
<p>Especificações e padrões:
<ul>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html>o elemento <code><canvas></code> </a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#video>o elemento <code><video></code> </a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute>tipos de <code><input></code></a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#the-placeholder-attribute>o atributo <code><input placeholder></code> </a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofocusing-a-form-control>o atributo <code><input autofocus></code> </a>
<li><a href=http://dev.w3.org/html5/webstorage/>o storage do <abbr>HTML5</abbr></a>
<li><a href=http://www.whatwg.org/specs/web-workers/current-work/>Web Workers</a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#offline>Aplicações Web Offline</a>
<li><a href=http://www.w3.org/TR/geolocation-API/><abbr>API</abbr> de Geolocalização</a>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html>Histórico e navegação</a>
</ul>
<p>Bibliotecas JavaScript:
<ul>
<li><a href=http://www.modernizr.com/>Modernizr</a>, uma biblioteca de detecção para <abbr>HTML5</abbr>
<li><a href=http://code.google.com/p/geo-location-javascript/>geo.js</a>, uma <abbr>API</abbr> para geolocalização
<li><a href=https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills><abbr>HTML5</abbr> Cross-browser Polyfills</a>
</ul>
<p>Outros artigos e tutoriais:
<ul>
<li><a href=http://camendesign.com/code/video_for_everybody>Video for Everybody!</a>
<li><a href=http://diveintomark.org/tag/give>A gentle introduction to video encoding</a>
<li><a href=http://wiki.whatwg.org/wiki/Video_type_parameters>Video type parameters</a>
<li><a href=everything.html>The All-In-One Almost-Alphabetical No-Bullshit Guide to Detecting Everything</a>
<li><a href=http://msdn.microsoft.com/en-us/ie/ff468705.aspx>Internet Explorer 9 Guide for Developers</a>
</ul>
<p class=a>❧
<p>Isso foi “Detectando funcionalidades da <abbr>HTML5</abbr>.” Consulte o <a href=table-of-contents.html>Sumário</a>, caso queira continuar com a leitura.
<div class="pf">
<h4>Você sabia?</h4>
<div class="moneybags">
<blockquote><p>Em associação a <span lang="en">Google Press</span>, O’Reilly está distribuindo este livro em variados formatos, incluindo papel, ePub, Mobi, <abbr>DRM</abbr>-free e <abbr>PDF</abbr>. A edição paga é chamada <span lang="en">“HTML5: Up & Running”</span> e está disponível agora. Este capítulo está incluído na versão paga.
</p><p>Se você gostou deste capítulo e quer mostrar sua apreciação, basta <a href="http://www.amazon.com/HTML5-Up-Running-Mark-Pilgrim/dp/0596806027?ie=UTF8&tag=diveintomark-20&creativeASIN=0596806027">comprar o livro “<abbr>HTML5</abbr>: Up & Running” com esse link afiliado</a> ou <a href="http://oreilly.com/catalog/9780596806033">comprar a edição eletrônica diretamente da O’Reilly</a>. Você vai ganhar um livro, e eu vou ganhar um trocado. Atualmente, não aceito doações diretas.
</p></blockquote>
</div>
</div>
<p class=c>Copyright MMIX–MMXI <a href=about.html>Mark Pilgrim</a>
<form action=https://www.google.com/cse><div><input type=hidden name=cx value=014437924039265546826:2nmoshc8y3y><input type=hidden name=ie value=UTF-8><input type=search name=q size=25 placeholder="powered by Google™"> <input type=submit name=sa value=Search></div></form>
<script src=j/jquery.js></script>
<script src=j/modernizr.js></script>
<script src=j/gears_init.js></script>
<script src=j/geo.js></script>
<script src=j/dih5.js></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>
<script>
function supports(bool, suffix) {
var s = "Seu navegador ";
if (bool) {
s += "possui suporte " + suffix + ".";
} else {
s += "não possui suporte " + suffix + ". :(";
}
return s;
}
function I_CAN_HAS(result) {
if (result == "probably") {
return "pode tocar";
}
if (result == "maybe") {
return "não tem certeza se pode tocar";
}
return "não pode tocar";
}
function lookup_location() {
geo_position_js.getCurrentPosition(show_map, show_map_error);
}
function show_map(loc) {
$("#geo-wrapper").css({'width':'320px','height':'350px'});
var map = new google.maps.Map(document.getElementById("geo-wrapper"), {zoom: 14, mapTypeControl:true, zoomControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP});
var center = new google.maps.LatLng(loc.coords.latitude,loc.coords.longitude);
map.setCenter(center);
var marker = new google.maps.Marker({map: map, position: center, draggable: false, title: "Você está (mais ou menos) aqui "});
}
function show_map_error() {
$("#live-geolocation").html('Não foi possível determinar sua localização.');
}
$(function() {
$("#live-canvas").html(supports(Modernizr.canvas, "a API canvas"));
$("#live-canvas-text").html(supports(Modernizr.canvastext, "API de texto canvas"));
$("#live-video").html(supports(Modernizr.video, "video HTML5"));
if (Modernizr.video) {
var ogg = Modernizr.video.ogg;
var h264 = Modernizr.video.h264;
var webm = Modernizr.video.webm;
var vf = "Seu navegador ";
if ((ogg == "probably") && (h264 == "probably")) {
vf += "pode tocar ambos Ogg Theora e H.264";
} else if (((ogg == "") || (ogg == "no")) && (h264 == "probably")) {
vf += "pode tocar video H.264, mas não Ogg Theora";
} else if (((h264 == "") || (h264 == "no")) && (ogg == "probably")) {
vf += "pode tocar Ogg Theora video, mas não H.264";
} else {
vf += I_CAN_HAS(ogg) + " video Ogg Theora. Seu navegador " + I_CAN_HAS(h264) + " H.264";
}
vf += " video.";
if (webm) {
vf += " Hey, você pode tocar videos WebM video, também!";
}
$("#live-video-formats").html(vf);
} else {
$("#live-video-formats").html(supports(Modernizr.video, "quaisquer formatos de video"));
}
var localstorage = false;
try {
localstorage = Modernizr.localstorage;
} catch(e) {}
$("#live-storage").html(supports(localstorage, "HTML5 storage"));
$("#live-web-workers").html(supports(Modernizr.webworkers, "web workers"));
$("#live-offline").html(supports(Modernizr.applicationcache, "aplicações web offline"));
if (geo_position_js.init()) {
$("#live-geolocation").html(supports(true, "geolocation") + ' <a href="#" onclick="lookup_location();return false">Clique para pesquisar sua localização</a>.');
} else {
$("#live-geolocation").html(supports(false, "geolocation"));
}
var supported_input_types = '';
for (var itype in Modernizr.inputtypes) {
if (Modernizr.inputtypes[itype]) {
supported_input_types += '<code>' + itype + '</code>, ';
}
}
if (!!supported_input_types) {
$("#live-input-types").html('Seu navegador suporta os seguintes tipos de entrada do HTML5: ' + supported_input_types.replace(/, $/, ''));
} else {
$("#live-input-types").html('Seu navegador não suporta nenhum tipo de entrada do HTML5.');
}
$("#live-input-autofocus").html(supports(!!("autofocus" in document.createElement("input")), "auto foco"));
$("#live-microdata-api").html(supports(!!document.getItems, "a API de micro dado do HTML5"));
$("#live-history-api").html(supports(!!Modernizr.history, "a API de histórico do HTML5"));
});
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-4114546-27', 'auto');
ga('send', 'pageview');
</script>
</html>