Datei wird geladen, bitte warten...
Zitiervorschau
Tytuł oryginału: HTML5 Developer's Cookbook Tłumaczenie: Grzegorz Balcerek ISBN: 978-83-246-4966-2 Authorized translation from the English language edition, entitled: HTML5 DEVELOPER’S COOKBOOK; ISBN 0321769384; by Chuck Hudson and Tom Leadbetter; published by Pearson Education, Inc, publishing as Addison Wesley. Copyright © 2012 Pearson Education, Inc. All rights reserved. No part of this book may by reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. Polish language edition published by HELION S.A. Copyright © 2013. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: [email protected] WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/html5p Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/html5p.zip Printed in Poland. • Poleć książkę na Facebook.com • Kup w wersji papierowej • Oceń książkę
• Księgarnia internetowa • Lubię to! » Nasza społeczność
Dla Alexa, mojego dziadka — dziękuję ci za dzielenie się swoją miłością do życia i książek — Chuck Dla Lucy — dzięki za bycie sobą — Tom
Spis treści Wstęp . ......................................................................................................13 Podziękowania . .........................................................................................21 O autorach . ...............................................................................................23 Rozdział 1
Nowe elementy strukturalne w HTML5 ........................................................25 PRZEPIS DLA POCZĄTKUJĄCYCH Budowa startowego dokumentu HTML5 . ................................................................... 26 doctype . ........................................................................................................... 26 Kodowanie znaków . ........................................................................................... 26 JavaScript i łącza CSS . ...................................................................................... 27 Styl używanej składni . ........................................................................................ 27 Skąd pochodzą wszystkie nowe elementy? . .............................................................. 28 PRZEPIS DLA POCZĄTKUJĄCYCH Wykorzystanie elementu header do utworzenia nagłówka witryny . ............................... 29 PRZEPIS DLA POCZĄTKUJĄCYCH Wykorzystanie elementu hgroup do grupowania nagłówków . ....................................... 31 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie nawigacji przy użyciu elementu nav . .......................................................... 31 PRZEPIS DLA POCZĄTKUJĄCYCH Użycie elementu article . .......................................................................................... 34 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Grupowanie treści przy użyciu elementu section . ....................................................... 35 Którego elementu powinieneś używać: article czy section? . ................................... 36 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie paska bocznego za pomocą elementu aside . ............................................. 37 PRZEPIS DLA POCZĄTKUJĄCYCH Użycie elementu footer . ........................................................................................... 39 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Wykorzystanie narzędzia HTML5 Outliner do utworzenia prawidłowej struktury dokumentu . ............................................................................................ 41 PRZEPIS DLA ZAAWANSOWANYCH Wykorzystanie wszystkich nowych elementów do utworzenia strony z wiadomościami .... 43
6
Spis treści
PRZEPIS DLA ZAAWANSOWANYCH Wykorzystanie wszystkich nowych elementów do utworzenia strony z wynikami wyszukiwania . ...................................................................................... 46 Podsumowanie . ................................................................................................. 50
Rozdział 2
Grupowanie, poziom tekstu i zmiany semantyczne .......................................51 PRZEPIS DLA POCZĄTKUJĄCYCH Oznaczanie rysunków i ich podpisów elementami figure i figcaption ............................. 51 PRZEPIS DLA POCZĄTKUJĄCYCH Oznaczanie daty i czasu za pomocą elementu time . ................................................... 53 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie widżetu przełącznika za pomocą elementu details . ..................................... 54 PRZEPIS DLA POCZĄTKUJĄCYCH Użycie elementu address do danych kontaktowych . ................................................... 56 PRZEPIS DLA POCZĄTKUJĄCYCH Podświetlanie tekstu za pomocą elementu mark . ...................................................... 57 PRZEPIS DLA POCZĄTKUJĄCYCH Użycie elementu s do pokazania niepoprawnej lub nieistotnej treści . .......................... 58 Zmiany dotyczące istniejących elementów . ................................................................ 58 Element cite . ..................................................................................................... 58 Element ol . ....................................................................................................... 59 Element dl . ....................................................................................................... 61 Element small . .................................................................................................. 63 Elementy b oraz strong . ..................................................................................... 63 Elementy i oraz em . ........................................................................................... 64 Element abbr . ................................................................................................... 64 Element hr . ....................................................................................................... 64 Elementy, których już nie ma . ............................................................................. 64 PRZEPIS DLA POCZĄTKUJĄCYCH Opakowywanie elementów łączami . .......................................................................... 65 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Dodawanie informacji semantycznych za pomocą mikrodanych . .................................. 66 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Stosowanie WAI-ARIA z HTML5 . ................................................................................ 67 PRZEPIS DLA ZAAWANSOWANYCH Oznaczanie komentarzami strony z artykułem . ........................................................... 69 Podsumowanie . ...................................................................................................... 71
Rozdział 3
Obsługa przeglądarek w HTML5 ..................................................................73 PRZEPIS DLA POCZĄTKUJĄCYCH Obsługa Internet Explorera . ..................................................................................... 73 Użycie JavaScriptu do uzyskania kompatybilności z HTML5 . .................................. 73 Uzyskiwanie kompatybilności CSS-a . ................................................................... 74 Szablony (boilerplates) . ........................................................................................... 75 PRZEPIS DLA POCZĄTKUJĄCYCH Testowanie działania nowych możliwości HTML5 . ...................................................... 75 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Wykorzystanie jQuery do zastąpienia kalendarza . ....................................................... 77
Spis treści
7
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Wykorzystanie biblioteki Modernizr do wykrywania możliwości . .................................... 79 Polyfilling (wielowypełnianie) . ................................................................................... 82 Użyteczne strony sprawdzające HTML5 . .................................................................... 84 Podsumowanie . ...................................................................................................... 84
Rozdział 4
Nowe techniki dotyczące układu i stylizacji w CSS3 ....................................85 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie dostosowującego się projektu za pomocą CSS3 Media Queries ................... 85 Kiedy używać zapytań o media . ........................................................................... 90 Obsługa iPhone’a i urządzeń z systemem Android . ............................................... 91 PRZEPIS DLA POCZĄTKUJĄCYCH Korzystanie z własnych czcionek przy użyciu @font-face . ............................................ 92 Formaty plików i działanie czcionek w różnych przeglądarkach . .............................. 93 Usługi związane z krojami pisma . ........................................................................ 94 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie przycisków za pomocą gradientów CSS i wielu teł . ...................................... 95 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Upiększanie witryny za pomocą transformacji i przejść . .............................................. 98 PRZEPIS DLA ZAAWANSOWANYCH Tworzenie animacji za pomocą CSS-a . .................................................................... 103 Podsumowanie . .................................................................................................... 106
Rozdział 5
Formularze internetowe HTML5 . ..............................................................107 Walidacja . ............................................................................................................ 107 Typy wejściowe HTML 4 . ........................................................................................ 107 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie formularza do danych kontaktowych . ....................................................... 109 input type="email" . ......................................................................................... 109 input type="tel" . .............................................................................................. 110 input type="url" . .............................................................................................. 111 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie formularza wyszukiwania przy użyciu input type="search" . ........................ 112 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie kontrolek kalendarza i czasu . ................................................................. 113 input type="datetime" . .................................................................................... 113 input type="datetime-local" . ............................................................................. 113 input type="date" . ........................................................................................... 114 input type="time" . ........................................................................................... 114 input type="month" . ........................................................................................ 115 input type="week" . .......................................................................................... 115 Nakładanie ograniczeń na daty i godziny . ........................................................... 115 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie pola do wprowadzania liczby . .................................................................. 116 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie suwaka (bez potrzeby użycia JavaScriptu) . ............................................... 117 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie próbnika kolorów . .................................................................................. 117
8
Spis treści
PRZEPIS DLA POCZĄTKUJĄCYCH Wyświetlanie wyników za pomocą elementu output . ................................................. 118 PRZEPIS DLA POCZĄTKUJĄCYCH Użycie tekstu zastępczego formularza . .................................................................... 119 PRZEPIS DLA POCZĄTKUJĄCYCH Autouzupełnianie za pomocą atrybutu list i elementu datalist . .................................. 120 PRZEPIS DLA POCZĄTKUJĄCYCH Śledzenie postępu wykonania zadania za pomocą elementu progress ........................ 121 PRZEPIS DLA POCZĄTKUJĄCYCH Wskazywanie wyniku pomiaru za pomocą elementu meter . ....................................... 122 PRZEPIS DLA POCZĄTKUJĄCYCH Przechodzenie do elementu form po załadowaniu strony . ......................................... 123 PRZEPIS DLA POCZĄTKUJĄCYCH Zezwalanie na wiele wartości . ................................................................................ 124 PRZEPIS DLA POCZĄTKUJĄCYCH Prosta walidacja przy użyciu atrybutu required . ........................................................ 125 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Pisanie własnych reguł walidacji . ............................................................................ 126 PRZEPIS DLA POCZĄTKUJĄCYCH Nakładanie ograniczeń na wprowadzane dane . ........................................................ 126 step . .............................................................................................................. 126 min i max . ....................................................................................................... 127 formnovalidate i novalidate . ............................................................................. 127 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Dostosowywanie formularza i nadawanie mu stylu . .................................................. 128 Komunikaty błędów . .............................................................................................. 129 PRZEPIS DLA ZAAWANSOWANYCH Wszystko razem — tworzenie formularza rejestracyjnego . ........................................ 130 Podsumowanie . .................................................................................................... 132
Rozdział 6
Rysowanie na płótnie . .............................................................................133 Element canvas — informacje ogólne . .................................................................... 133 Początki . ......................................................................................................... 134 Współrzędne x i y . ........................................................................................... 135 PRZEPIS DLA POCZĄTKUJĄCYCH Nałożenie siatki na płótno . .................................................................................... 135 Narzędzia płótna . .................................................................................................. 139 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie prostych kształtów i linii . ........................................................................ 139 Rysowanie i formatowanie prostokąta lub kwadratu . ........................................... 139 Stosowanie gradientów w kształtach . ................................................................ 141 Rysowanie linii i ścieżek . .................................................................................. 142 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Rysowanie wielokątów za pomocą ścieżki . .............................................................. 144 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Rysowanie łuków i okręgów . .................................................................................. 146 Rysowanie krzywych . ........................................................................................ 147
Spis treści
9
PRZEPIS DLA POCZĄTKUJĄCYCH Dodawanie tekstu . ................................................................................................ 147 PRZEPIS DLA POCZĄTKUJĄCYCH Wstawianie obrazka . ............................................................................................. 148 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Przycinanie obrazka . ............................................................................................. 149 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Animacja mapy sprite’ów . ...................................................................................... 150 Przekształcenia płótna . ......................................................................................... 153 PRZEPIS DLA ZAAWANSOWANYCH Animowanie obrazka . ............................................................................................ 154 PRZEPIS DLA ZAAWANSOWANYCH Animacja pionowego wykresu słupkowego . .............................................................. 157 Podsumowanie . .................................................................................................... 162
Rozdział 7
Osadzanie wideo w HTML5 . .....................................................................163 PRZEPIS DLA POCZĄTKUJĄCYCH Dołączanie filmów za pomocą elementu video . ........................................................ 163 Obsługa w przeglądarkach i urządzeniach . ......................................................... 164 HTML5 i kodeki wideo . ..................................................................................... 164 Dlaczego kodeki powinny Cię interesować? . ....................................................... 165 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Włączanie wideo we wszystkich przeglądarkach . ...................................................... 166 Dodawanie zastępczej treści dla starszych przeglądarek . .................................... 166 Nowe atrybuty wideo . ....................................................................................... 169 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie wideo z napisami . .................................................................................. 172 Inne możliwości formatowania napisów . ............................................................ 174 API mediów . ......................................................................................................... 175 PRZEPIS DLA ZAAWANSOWANYCH Tworzenie niestandardowych kontrolek . .................................................................. 176 Podsumowanie . .................................................................................................... 183
Rozdział 8
Osadzanie dźwięku w HTML5 . ..................................................................185 PRZEPIS DLA POCZĄTKUJĄCYCH Umieszczanie dźwięku za pomocą elementu audio . ................................................. 185 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Umieszczanie dźwięku we wszystkich przeglądarkach . ............................................. 186 Dodawanie zastępczej treści dla starszych przeglądarek . .................................... 186 Nowe atrybuty elementu audio . .............................................................................. 187 API mediów . ......................................................................................................... 189 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie miksera . ............................................................................................... 190 PRZEPIS DLA ZAAWANSOWANYCH Dodawanie internetowego radia . ............................................................................ 194 Podsumowanie . .................................................................................................... 201
10
Spis treści
Rozdział 9
Dokonywanie zmian w historii przeglądarki ................................................203 Podstawy historii . ................................................................................................. 203 Kompatybilność przeglądarek . .......................................................................... 204 PRZEPIS DLA POCZĄTKUJĄCYCH Dodawanie do historii wpisów za pomocą pushState . .............................................. 204 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie przeglądarki obrazków . ........................................................................... 207 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Pobieranie stanu w przeglądarce obrazków . ............................................................ 209 PRZEPIS DLA POCZĄTKUJĄCYCH Zmiana historii za pomocą replaceState . ................................................................ 211 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Zmiana historii strony . .......................................................................................... 213 PRZEPIS DLA ZAAWANSOWANYCH Używanie zaawansowanych obiektów danych stanu do przenoszenia informacji pomiędzy stronami . ............................................................................................ 215 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Testowanie bezpieczeństwa historii . ....................................................................... 218 Pomocne biblioteki . .............................................................................................. 220 Podsumowanie . .................................................................................................... 221
Rozdział 10 Wykorzystanie Geolocation API do uzyskania informacji o położeniu geograficznym . ......................................................................223 Omówienie Geolocation API . .................................................................................. 223 Kompatybilność przeglądarek . .......................................................................... 224 Gdzie na świecie się znajdujesz — getCurrentPosition . ....................................... 224 PRZEPIS DLA POCZĄTKUJĄCYCH Ustalanie położenia geograficznego za pomocą zwykłego wywołania getCurrentPosition . ............................................................................................. 225 Poufność informacji o położeniu . ...................................................................... 228 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Wyświetlanie na mapie informacji o lokalizacji przy użyciu getCurrentPosition ............. 228 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Określanie odległości za pomocą opcji lokalizacji . ................................................... 233 PRZEPIS DLA ZAAWANSOWANYCH Podążanie za poruszającym się obiektem dzięki watchPosition . ................................ 239 Podsumowanie . .................................................................................................... 245
Rozdział 11 Przechowywanie danych po stronie klienta ................................................247 Przechowywanie danych po stronie klienta — przegląd . ............................................ 247 Bezpieczeństwo danych . .................................................................................. 248 Klucze i wartości — sessionStorage i localStorage . ........................................... 249 PRZEPIS DLA POCZĄTKUJĄCYCH Pobieranie i ustawianie danych w pamięci sesji . ...................................................... 250 Narzędzia dla programistów Chrome służące do oglądania zawartości pamięci . .... 252 PRZEPIS DLA POCZĄTKUJĄCYCH Nadawanie stylów z pamięci sesji . ......................................................................... 253
Spis treści
11
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Zapisywanie formularzy za pomocą lokalnego przechowywania danych ....................... 257 PRZEPIS DLA ZAAWANSOWANYCH Przechwytywanie zdarzeń w pamięci lokalnej . .......................................................... 261 Web SQL Database API . ........................................................................................ 267 PRZEPIS DLA ZAAWANSOWANYCH Użycie sieciowej bazy danych do stworzenia listy zakupów . ....................................... 270 Podsumowanie . .................................................................................................... 277
Rozdział 12 Komunikacja i wątki . ...............................................................................279 Przegląd WebSocket API . ....................................................................................... 279 PRZEPIS DLA POCZĄTKUJĄCYCH Rozmawianie przez gniazda sieciowe . ..................................................................... 280 Realizacja wielowątkowości za pomocą wątków roboczych . ....................................... 283 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie wątku roboczego . .................................................................................. 285 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Dodawanie dwukierunkowej komunikacji . ................................................................ 288 PRZEPIS DLA ZAAWANSOWANYCH Wykorzystywanie współdzielonych wątków roboczych . ............................................... 291 Podsumowanie . .................................................................................................... 296
Rozdział 13 Zachowanie przeglądarek w HTML5 ..........................................................297 Drag and Drop API . ............................................................................................... 297 PRZEPIS DLA POCZĄTKUJĄCYCH Przeciąganie i upuszczanie pomiędzy elementami div . ............................................. 299 PRZEPIS DLA ZAAWANSOWANYCH Wykorzystanie zdarzeń i obiektu dataTransfer . ........................................................ 302 Pamięć podręczna aplikacji i jej API . ....................................................................... 309 Pamięć podręczna przeglądarki a bezpieczeństwo . ............................................. 310 Odwołania do pliku manifestu . .......................................................................... 310 PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie pliku manifestu . .................................................................................... 310 CACHE . ........................................................................................................... 311 FALLBACK . ...................................................................................................... 311 NETWORK . ...................................................................................................... 312 Aktualizacja pamięci podręcznej poprzez manifest . ............................................. 312 PRZEPIS DLA POCZĄTKUJĄCYCH Korzystanie ze stron internetowych offline . .............................................................. 312 API pamięci podręcznej aplikacji . ............................................................................ 315 Notification API . .................................................................................................... 316 Uprawnienia dotyczące powiadomień . ............................................................... 317 Kompatybilność przeglądarek . .......................................................................... 318 PRZEPIS DLA POCZĄTKUJĄCYCH Wyświetlanie prostego powiadomienia . ................................................................... 318 PRZEPIS DLA ZAAWANSOWANYCH Tworzenie strony powiadomień o tweetach . ............................................................. 322 Podsumowanie . .................................................................................................... 329
12
Spis treści
Rozdział 14 Praca z plikami lokalnymi . .......................................................................331 Przegląd File API . .................................................................................................. 331 Bezpieczeństwo File API . .................................................................................. 331 PRZEPIS DLA POCZĄTKUJĄCYCH Odczyt atrybutów pliku . .......................................................................................... 332 PRZEPIS DLA POCZĄTKUJĄCYCH Przetwarzanie wielu plików za pomocą przeciągania i upuszczania ............................. 334 Interfejs FileReader . .............................................................................................. 337 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Podgląd obrazków przy użyciu readAsDataURL . ........................................................ 338 PRZEPIS DLA ZAAWANSOWANYCH Parsowanie pliku CSV za pomocą readAsText . ......................................................... 342 Rozszerzone specyfikacje File API . .......................................................................... 349 PRZEPIS DLA ZAAWANSOWANYCH Tworzenie lokalnego pliku . ..................................................................................... 350 Podsumowanie . .................................................................................................... 355
Rozdział 15 Integracja z urządzeniami przenośnymi ......................................................357 Krótka historia API urządzeń . ................................................................................. 357 Contacts API . ....................................................................................................... 359 PRZEPIS DLA POCZĄTKUJĄCYCH Pobieranie wszystkich kontaktów i numerów telefonu . ............................................. 360 Messaging API . ..................................................................................................... 363 Network Information API . ....................................................................................... 364 HTML Media Capture . ........................................................................................... 365 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Przechwytywanie obrazu za pomocą elementu input typu file . ................................... 365 DeviceOrientation Event Specification . .................................................................... 368 PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie poziomicy . ............................................................................................ 369 Podsumowanie . .................................................................................................... 373
Przepisy . .................................................................................................375 Skorowidz . ..............................................................................................379
Wstęp HTML
(ang. Hypertext Markup Language) jest podstawowym językiem służącym do tworzenia i budowania witryn internetowych. Używany przez programistów od ponad 20 lat, przez pierwszych kilka był poddawany radykalnym zmianom, ale w końcówce minionego stulecia jego rozwój nieco się spowolnił. Aż do teraz.
Krótka historia HTML-a W 1991 roku sir Tim Berners-Lee napisał dokument pod tytułem HTML Tags, przedstawiający 20 elementów, które miałyby służyć do tworzenia dokumentów internetowych. W 1993 roku stowarzyszenie Internet Engineering Task Force (IETF) opublikowało propozycję pierwszej specyfikacji HTML. Projekt tej propozycji wygasł, a pierwsza specyfikacja — nie HTML 1.0, ale HTML 2.0 — została opublikowana dopiero w listopadzie 1995. W 1997 roku została opublikowana specyfikacja HTML 3.2, a po niej, w 1998 roku, HTML 4. HTML 4 miał trzy warianty: Strict, Transitional oraz Frameset. W tym okresie producenci przeglądarek, tacy jak Microsoft i Netscape, rozpoczęli implementowanie HTML-a w odrobinę różny sposób, co rozpoczęło pierwszą rundę wojen przeglądarek (http://pl.wikipedia.org/wiki/Historia_przegl%C4%85darek_internetowych).
XHTML Po publikacji HTML 4 organizacja World Wide Web Consortium (W3C) zdecydowała się na wstrzymanie rozwoju HTML-a i zajęła się pracą nad opartym o XML językiem XHTML (ang. Extensible Hypertext Markup Language), który był uważany za przyszłość internetu. W XHTML-u nie było nowych elementów — specyfikacja była dokładnie taka sama jak w przypadku HTML 4, ale programiści mieli stosować się do nowych reguł składniowych: zamykania znaczników i umieszczania wartości atrybutów w cudzysłowach. Oznaczało to bardziej ścisłe, sztywne standardy kodowania i wymuszało na programistach stosowanie tego samego stylu pisania kodu. Mniej więcej w tym samym czasie, w 2001 roku, coraz ważniejsze i popularniejsze zaczęły się stawać kaskadowe arkusze stylów (CSS), a wraz z upowszechnieniem się blogowania wzrosło znaczenie standardów sieciowych. Począwszy od 2002 roku, W3C publikowało szkice XHTML 1.1. Podczas gdy XHTML 1 był w gruncie rzeczy HTML-em z odrobiną XML-a, XHTML 1.1 był właściwie XML-em. Chociaż miał być standardem
14
Wstęp
przyszłościowym, nie był kompatybilny wstecz — jeżeli był używany do tworzenia witryny, nie działała ona w starszych przeglądarkach. Wywołało to niepokój w społeczności sieciowej, u producentów przeglądarek, a nawet w samym W3C. Nie każdy był przekonany, że XML jest przyszłością języka znaczników w sieci.
Web Forms i Web Applications oraz WHATWG W 2004 roku przedstawiciele firm Apple, Mozilla i Opera rozpoczęli prace nad własną specyfikacją, nakierowaną na utworzenie kompatybilnego wstecz kodu, który mógłby być używany do tworzenia aplikacji internetowych. W3C odrzuciło tę propozycję, co doprowadziło do uformowania się grupy pod nazwą Web Hypertext Application Technology Working Group (WHATWG). Grupa WHATWG rozpoczęła prace nad standardami Web Forms 2.0 oraz Web Applications 1.0. Redaktorem specyfikacji został Ian „Hixie” Hickson, a problemy i pomysły rozpatrywano przy użyciu publicznej listy mailowej. Chociaż początkowo pracowano nad dwoma specyfikacjami, Web Forms 2.0 i Web Applications 1.0, zostały one połączone w jedną — HTML5.
XHTML 2 kontra HTML5 A zatem, podczas gdy WHATWG rozwijał HTML5, w W3C marniała specyfikacja XHTML 2. W 2006 roku W3C przyznało się do błędnej decyzji o niegdysiejszym porzuceniu HTML-a i chociaż nadal rozwijało XHTML 2, zaczęło ponownie przyglądać się rozwojowi tego pierwszego. W3C zdecydowało się wykorzystać pracę wykonaną dotychczas przez WHATWG jako punkt początkowy dla nowej wersji HTML-a. Chociaż była to dobra wiadomość, doprowadziła ona do niejasnej sytuacji, gdyż prace obejmowały teraz trzy specyfikacje: dwie w W3C (HTML 5 oraz XHTML 2) i jedną (HTML5) w WHATWG (zauważ brak spacji w porównaniu z „HTML 5” organizacji W3C). A zatem specyfikacja HTML5/HTML 5 była rozwijana w tym samym czasie przez dwie grupy. WHATWG operuje w odmienny od W3C sposób i jest zdolna do działania w znacznie szybszym tempie. Dzięki istnieniu w WHATWG publicznej listy mailowej pomysły były przedstawiane regularnie, a programiści stron internetowych mieli możliwość kwestionowania niektórych spośród podjętych decyzji. Zespół pracujący nad specyfikacją był w stanie, i nadal jest, szybko implementować dobre pomysły, odrzucać złe oraz zmieniać lub usuwać części specyfikacji na podstawie reakcji społeczności. HTML5 był rozwijany znacznie szybciej w WHATWG niż w W3C. Po kilku latach, w 2009 roku, W3C ogłosiło zaprzestanie prac nad XHTML 2. HTML5 zwyciężył. W jakim punkcie znajduje się zatem specyfikacja? Cóż, nadal jest rozwijana głównie przez WHATWG, a następnie przejmuje ją W3C i poddaje przeglądowi. Proces nie jest w pełni idealny, ale wyniki są obiecujące.
Z której specyfikacji korzystać? Jedna wersja specyfikacji znajduje się na witrynie W3C (http://dev.w3.org/html5/spec/spec.html), a druga na witrynie WHATWG (http://www.whatwg.org/specs/web-apps/current-work/multipage/). Obie są naprawdę potężnymi dokumentami. W marcu 2011 roku Ben Schwarz uruchomił stronę zawierającą specyfikację HTML5 dla programistów witryn internetowych (http://developers.whatwg.org), której sugerujemy używać. Jeśli jesteś zainteresowany codziennymi dyskusjami, możesz również śledzić na bieżąco prace nad specyfikacją poprzez listę mailową: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org.
Czym dokładnie jest HTML5?
15
Podstawowa specyfikacja HTML5 jest dokładnie taka — podstawowa. Nastąpiła istotna zmiana mająca na celu dopasowanie się do szybkości, z jaką rozwija się technologia. Nowe, dodatkowe specyfikacje są przez cały czas opracowywane — zarówno przez zespoły w WHATWG, jak i w W3C — i dotyczą różnych kwestii, takich jak informacje o połączeniach sieciowych czy urządzeniach rejestrujących obraz. Producenci przeglądarek współpracują, by pomóc zdefiniować te funkcjonalności i przyspieszyć ich włączenie do swoich przeglądarek. Następne lata będą na pewno niezwykle ekscytujące.
Założenia HTML5 HTML5 utworzono tak, aby obsługiwał istniejącą treść, czyli innymi słowy, jest on kompatybilny wstecz. Główną przeszkodą w pracach nad specyfikacją XHTML 2 była obawa przed nieprawidłowym wyświetlaniem większości witryn. HTML5 został zbudowany na fundamentach HTML 4, tak aby przeglądarki mogły nadal obsługiwać HTML — nie tylko nowe elementy HTML5, ale wszystko to, co znajduje się w HTML 4. Witryny, które działają teraz w HTML 4 lub XHTML, powinny prawidłowo działać w HTML5. Używanie HTML5 oznacza, że możesz nadal kodować w stylu, z którego korzystałeś wcześniej. Przy projektowaniu HTML5 wzięto pod uwagę głosy programistów, więc nadal możesz używać składni HTML lub XHTML, a przeglądarki będą wiedziały, co robić. Opiszemy to dokładniej w rozdziale 1. HTML5 wskazuje również przeglądarkom, jak powinny reagować na błędy spowodowane przez nieprawidłową implementację znaczników. Wcześniej przeglądarki interpretowały błędy samodzielnie, a więc każda przeglądarka miała własne standardy zachowania. HTML5 utworzono dla programistów takich jak my oraz dla producentów przeglądarek, tak aby w niezbyt odległej przyszłości wszyscy pracowali według tych samych standardów. Być może prawdziwą siłą HTML5 jest to, jak odpowiada na potrzeby programistów aplikacji internetowych. Ze względu na coraz większe możliwości przeglądarek możemy tworzyć przypominające aplikacje witryny, które umożliwiają współdzielenie zdjęć, rysowanie, edycję plików oraz wykonywanie innych zadań. Wcześniej funkcje te wymagały warstw JavaScriptu oraz wtyczek, takich jak Java lub Flash — oznaczało to problemy z dostępnością oraz zależność od stabilności zewnętrznego oprogramowania. HTML5 daje nam nowe standardy dotyczące tworzenia aplikacji internetowych z posiadającymi ogromne możliwości API dla takich dziedzin jak obszary, na których można rysować, przeciąganie i upuszczanie, lokalne przechowywanie danych oraz bezpośrednia obsługa wideo w przeglądarce. Wraz z wyspecyfikowaniem standardów przeglądarki za jakiś czas będą obsługiwać te funkcje prawidłowo oraz w stabilny sposób. Społeczność sieciowa będzie pomagać w rozwijaniu standardów, stale je weryfikując i ulepszając, a programiści nie będą musieli używać sztuczek umożliwiających działanie tych funkcji.
Czym dokładnie jest HTML5? HTML5 nie jest jedną technologią. To raczej nadrzędne pojęcie, którym przyjęto oznaczać połączenie nowych oraz ulepszonych elementów HTML, stylów CSS oraz javascriptowych API i zdarzeń. Technologie te udostępniają wspólnie szeroki zakres nowych funkcji zwiększających łatwość użycia witryn, sprawiających, że bardziej przypominają one zwykłe aplikacje, oraz służących do integracji z urządzeniami. Na poniższej liście przedstawiono jedynie niektóre spośród dostępnych nowych lub ulepszonych funkcji: ulepszona semantyka, formularze,
16
Wstęp rysowanie na płótnie, funkcja „przeciągnij i upuść”, lokalne przechowywanie danych, przesyłanie wiadomości między stronami, powiadomienia na pulpicie, audio i wideo, gniazda sieciowe, geolokalizacja, historia, mikrodane.
Chociaż, ściśle rzecz biorąc, geolokalizacja nie jest częścią specyfikacji HTML5, stanowi przydatną, nową technologię rozwijaną równolegle, w związku z czym mówi się o niej w kontekście HTML5. A zatem tak, my również będziemy mówić o geolokalizacji w tej książce. Nie wszystko, co w programowaniu internetowym nowe, jest związane z HTML5. CSS3 nie jest tym samym co HTML5, ale ponieważ jest nowy i niezwykle popularny, jest zaliczany do tej samej kategorii. CSS jest zupełnie innym językiem i technologią niż HTML. CSS dotyczy prezentacji; HTML — struktury. Możesz zrobić kilka całkiem fantastycznych rzeczy przy użyciu CSS3, ale programiści i społeczność powinni być świadomi tego, że istnieje między tymi językami różnica. A chociaż nie chcemy włączać się do debaty na temat tego, czy HTML5 jest zabójcą Flasha (nie jest), istotą HTML5 jest to, że istnieje teraz ogromna ilość funkcji bezpośrednio wbudowanych w przeglądarkę i wszystkie one należą do standardu.
Czy HTML5 ma logo? Tak, HTML5 ma logo. W przeszłości programiści stron internetowych i właściciele witryn umieszczali na swoich witrynach ikony, by za ich pośrednictwem poinformować, że przestrzegają różnych wytycznych W3C, takich jak te dotyczące (X)HTML-a, CSS-a albo dostępności. Tendencja ta ostatnio nieco osłabła, lecz na początku 2011 roku W3C opublikowało szereg różnych logo, które początkowo wywołały dość duże zamieszanie w społeczności sieciowej, ponieważ zgrupowały wiele technologii internetowych, włącznie z CSS3, pod szyldem HTML5. Tak jak wspomnieliśmy, CSS3 nie jest tym samym co HTML5, a ponieważ W3C pozornie twierdziło coś przeciwnego, społeczność sieciowa wyraziła swój niepokój. Na szczęście W3C zmieniło cele i definicje swoich logo, więc główne logo (rysunek W.1) „reprezentuje HTML5, kamień węgielny nowoczesnych aplikacji internetowych”, a mniejsze logo (rysunek W.2) „reprezentują aspekty nowoczesnych aplikacji i witryn internetowych — styl, semantykę, grafikę i tak dalej”. A zatem logo są przeznaczone dla programistów, którzy chcą zademonstrować swoje wsparcie dla kluczowych standardów sieciowych. Używanie ikon albo logo nie jest wymagane, ale możesz z nich skorzystać, jeśli chciałbyś poinformować użytkowników o zastosowaniu przez Ciebie różnych funkcji. Pod adresem http://w3.org/html/logo są dostępne logo, a także ich kreator, który pozwala wybierać różne ikony i style.
Styl przepisów kulinarnych
17
Rysunek W.1. Logo HTML5 (logo HTML5 jest autorstwa organizacji W3C, www.w3.org)
Rysunek W.2. Mniejsze ikony reprezentujące różne technologie (od lewej do prawej): dostęp do urządzeń, 3D, grafika i efekty, CSS3, semantyka, multimedia, łączność, wydajność i integracja, lokalne przechowywanie danych (te ikony również są autorstwa organizacji W3C, www.w3.org)
Styl przepisów kulinarnych Niniejsza książka jest zaprojektowana w taki sposób, by uczyć poprzez pokazywanie przykładów, i nawiązuje do stylu przepisów kulinarnych, czyli objaśnia temat i udostępnia przepisy z nim związane. W większości przypadków przepisy są próbą zobrazowania możliwości zastosowania technologii do rozwiązywania problemów związanych z kodowaniem raczej w świecie rzeczywistym niż w przykładach, które nie mają konkretnego celu. Mamy nadzieję, że analogicznie do przepisów używanych w kuchni, i te przepisy uznasz za wartościowe punkty odniesienia do własnych rozwiązań programistycznych. Ogólnie rzecz biorąc, książka została podzielona w taki sposób, by na początku zaprezentować prostsze tematy, a na ich podstawie przejść do tematów bardziej złożonych. W pierwszych rozdziałach zajmiemy się elementami HTML5 i uzupełnieniami CSS3, a w kolejnych omówimy różne javascriptowe API i zdarzenia. Zdajemy sobie sprawę z tego, że na temat każdego z tych zagadnień można by napisać całą książkę. Dotyczy to szczególnie standardów, takich jak CSS3, na którego temat dostępnych jest wiele dobrych książek. Do wszystkich zagadnień omówionych w danym rozdziale dołączyliśmy tabele, które pokazują poziom obsługi danej funkcji w popularnych przeglądarkach. Uwzględniliśmy co najmniej jeden przepis obrazujący, w jaki sposób daną technologię można zastosować. W większości przypadków przepisy składają się z podanej w krokach instrukcji oraz co najmniej jednego fragmentu kodu (listingu), po którym następuje opis przepisu. Listingi zostały również opublikowane pod adresem ftp://ftp.helion.pl/przyklady/html5p.zip.
Uwaga Niektóre komponenty HTML5, takie jak javascriptowe API, są wciąż dopracowywane w specyfikacjach i implementowane w różnych przeglądarkach. W tej książce skupiliśmy się na elementach, które są dobrze wyspecyfikowane oraz obsługiwane przez co najmniej jedną spośród najpopularniejszych przeglądarek. Należy jednak pamiętać o tym, że HTML5 jest stale rozbudowywany o nowe dodatki oraz funkcje. W rozdziale 15. omówiliśmy niektóre spośród możliwości i nowych funkcji dotyczących integracji urządzeń.
18
Wstęp
Zaprezentowane w książce przepisy zostały podzielone na trzy kategorie: dla początkujących, średnio zaawansowanych oraz zaawansowanych. Kategorie te służą zobrazowaniu trudności omawianego tematu i jednocześnie stanowią podstawę oszacowania wysiłku i czasu, który musisz przeznaczyć na ukończenie przepisu. To oczywiście kategorie subiektywne — wiemy, że czas i wysiłek dla różnych czytelników mogą być zupełnie różne.
Zewnętrzne biblioteki Jeśli kiedykolwiek byłeś zaangażowany w tworzenie stron internetowych, jedną z pierwszych rzeczy, którą zauważysz w przepisach z niniejszej książki, jest znikoma liczba odwołań do javascriptowych bibliotek zewnętrznych, takich jak choćby jQuery. Jest kilka drobnych wyjątków od tej reguły, kiedy staramy się przezwyciężyć określone przeszkody przy użyciu zewnętrznych bibliotek. Jednak ogólnie rzecz biorąc, próbowaliśmy się skupić na rdzeniu technologii HTML5, gdyż każdy czytelnik będzie miał swój własny zbiór ulubionych bibliotek, a każda biblioteka będzie miała swoje własne metody obsługi funkcji HTML5 i integracji z nimi. Mocno wierzymy, że biblioteki odgrywają istotną rolę w codziennym projektowaniu stron internetowych oraz rozwijaniu witryn i aplikacji. Sami również mamy ulubione biblioteki. W wielu przypadkach wykorzystanie funkcji HTML5 w bibliotekach, które już takie funkcje udostępniają, przypomina ich użycie w czystym HTML5. A zatem zrozumienie tego, jak używać komponentu w zwykłym JavaScripcie, pozwoli Ci łatwiej wykorzystać komponent w bibliotece, którą wybrałeś.
Materiały towarzyszące książce Z założenia książka taka jak ta zawiera mnóstwo listingów uzupełniających tekst podawanych przepisów. Przykłady kodu zostały udostępnione na serwerze FTP pod adresem ftp://ftp.helion.pl/przyklady/html5p.zip.
Kiedy HTML5 będzie gotowy? Mówi się, że programiści nie mogą lub nie powinni rozpoczynać pracy z HTML5 już teraz, ale to błędne podejście.
Czy trzeba czekać aż do 2022 roku? Nie, nie musisz czekać aż do 2022 roku! W wywiadzie z 2008 roku redaktor HTML5, Ian Hickson, nakreślił horyzont czasowy, zgodnie z którym HTML5 będzie gotowy dopiero w 2022 roku. Stwierdzenie to zostało przesadnie rozdmuchane w mediach i społeczności sieciowej. Wydaje nam się, że Hickson miał na myśli to, iż ostateczne zalecenia zostaną opublikowane dopiero około 2022 roku, ale to nie oznacza, że nie możesz zrobić użytku z wszystkich tych funkcji, które już zostały zdefiniowane i włączone do specyfikacji. Jak mogłeś wywnioskować z dyskusji dotyczącej historii HTML-a, przygotowanie specyfikacji wymaga dużego wysiłku i zajmuje ogromne ilości czasu, a specyfikacja musi przejść przez wiele etapów, zanim zostanie ukończona. Można tutaj przytoczyć argument związany ze standardem CSS 2.1. CSS 2.1 był w fazie rozwoju przez ponad 10 lat i został ukończony dopiero latem 2011 roku, ale w latach, kiedy był rozwijany, wszyscy i tak używaliśmy CSS-a, prawda? Jesteśmy teraz na etapie CSS3 i kto wie, kiedy będzie on „gotowy”. To doskonały przykład na to, jak społeczność sieciowa posuwa technologię i przyszłość sieci naprzód, wyprzedzając specyfikacje.
Kiedy HTML5 będzie gotowy?
19
Czy wobec tego mogę już używać HTML5? Tak, możesz już teraz używać HTML5! Nie będzie momentu, w którym będziesz musiał zaprzestać używania HTML 4 i rozpocząć korzystanie z HTML5. Kto wie, kiedy W3C ogłosi, że HTML5 jest oficjalnie gotowy — możemy już wszyscy używać wówczas funkcji HTML6. Producenci przeglądarek jednak całym sercem akceptują i przez cały czas implementują nowe funkcje HTML5. Ponieważ w ramach głównej i dodatkowych specyfikacji zawarto tak wiele różnych elementów i technologii, możesz swobodnie wybierać te części HTML5, z których chcesz korzystać — nie ma mowy o wyborze na zasadzie „wszystko albo nic”. Nie wszystkie przeglądarki zachowują się zawsze prawidłowo, lecz w rozdziale 3., „Obsługa przeglądarek w HTML5”, pokażemy niektóre metody radzenia sobie z przeglądarkami. Wszystkie najnowsze wersje przeglądarek Firefox, Safari, Opera, Chrome i Internet Explorer obsługują szeroki, choć w każdym przypadku nieco inny, zakres funkcji HTML5. Jednak nawet w czasie pisania tej książki z dnia na dzień napotykaliśmy w przeglądarkach znaczące ulepszenia, a dopóki przeglądarki będą ze sobą konkurować, taka tendencja się utrzyma. A zatem zaopatrz się w zestaw przeglądarek, edytor tekstu lub HTML-a i rozpocznij przygodę z HTML5.
20
Wstęp
Podziękowania
Podziękowania od Chucka Hudsona Ilekroć podejmowany jest wymagający (taki jak ten) projekt, w doprowadzenie go do szczęśliwego końca zaangażowanych jest wielu ludzi. Miałem szczęście, by podjąć się pisania tej książki wraz z Tomem Leadbetterem, który jest niezwykle utalentowanym projektantem i programistą. Dziękuję ci, Tom, za dzielenie się swoją wiedzą, testowanie mojej i bycie wspaniałym krytykiem wielu moich szalonych pomysłów. Podziękowania dla mojej rodziny: mamie dziękuję za wsparcie; tacie za skrócenie ścieżki biznesowej, a dziadkom za ich miłość. Dla mojej malutkiej Sierry: ty zawsze sprowadzasz uśmiech na moją twarz, wciąż pytając „dlaczego”; zawsze bądź ciekawa świata. A szczególnie dla Michele — za jej nieustanne wsparcie dla mojego uzależnienia od najnowszych technologii i niekończących się „projektów”. Twoje zrozumienie, gdy wielokrotnie byłem pełen udręki z powodu jednego wiersza kodu, znaczy dla mnie wszystko. Tomie S., dzięki za wiele śmiechu przez te wszystkie lata. Nie mogę się doczekać kolejnych przygód, jakie są przed nami. Na koniec podziękowania dla wszystkich moich przyjaciół i mojej rodziny za czas dany mi na ukończenie tego projektu; wy wszyscy nauczyliście mnie, że dzięki pasji i wytrwałości wszystko jest możliwe.
Podziękowania od Toma Leadbettera Przede wszystkim niech mi będzie wolno podziękować mojemu współautorowi, Chuckowi Hudsonowi, który pomógł mi w trakcie pisania i udzielał wartościowych uwag wtedy, gdy było to najbardziej potrzebne, nie wspominając już o napisanych przez niego niektórych fantastycznych fragmentach kodu! Podziękowania dla „Doktorów HTML5” — Richa Clarka, Bruce’a Lawsona, Remy’ego Sharpa, Jacka Osborne’a, Mike’a Robinsona, Oliego Studholme’a i Brandana Lennoxa — za wasz czas, umiejętności i poświęcenie witrynie HTML5Doctor.com, która niezmiennie dostarcza społeczności sieciowej wspaniałej wiedzy i tematów do dyskusji. Wreszcie dla mojej żony, Lucy: dziękuję ci bardzo za wsparcie, gdy się męczyłem, i za cierpliwość, gdy znikałem na wiele wieczorów i weekendów. Przygotowałem tę książkę najlepiej, jak potrafiłem, a ty pomagałaś mi przez cały czas.
22
Podziękowania
Wspólne podziękowania Dziękujemy Trinie MacDonald i wydawnictwu Pearson za postawienie na nas i nieustającą cierpliwość związaną z naszymi niekończącymi się próbami ulepszania tekstu. Dziękujemy redaktorom, Michaelowi Thurstonowi, Evanowi Burchardowi, Timowi Wrightowi, Siddharthowi Ramowi i Kimowi Wimpsettowi, za rady i szczegółowe oraz wnikliwe uwagi, a także za dostrzeganie rzeczy, których sami nigdy byśmy nie zauważyli. Wielokrotnie pozwoliliście nam dostrzec zza drzew las, a efekt końcowy jest dzięki temu znacznie lepszy. Dziękujemy za cały poświęcony czas i wysiłek. Wiemy, że było to spore wyzwanie, które łączyło się z poświęceniem. Na końcu chcielibyśmy podziękować całej społeczności HTML5 za dzielenie się swoją wiedzą oraz Tobie, czytelniku, za bycie pionierem w prawdziwie ekscytujących czasach. Mamy nadzieję, że będziesz czerpał tyle radości z czytania tej książki, ile my mieliśmy przy jej tworzeniu.
O autorach Chuck Hudson od lat dziewięćdziesiątych zajmuje się pisaniem oprogramowania w branżach związanych z siecią i urządzeniami przenośnymi. Jest odnoszącym sukcesy przedsiębiorcą. Dzięki swojej pasji do rozwiązywania problemów biznesowych za pomocą technologii przeprowadzał na rzecz firm konsultacje związane z różnymi technologiami sieciowymi oraz wygłaszał prezentacje na rozmaitych konferencjach. Będąc stale szkolącym się maniakiem komputerowym, Hudson jest również certyfikowanym programistą PHP, deweloperem PayPal oraz nauczycielem programowania internetowego, technologii mobilnych i przedsiębiorczości w okolicach Bostonu i Atlanty. W 2008 roku otrzymał nagrodę eBay Star Developer za pierwsze internetowe i natywne aplikacje przeznaczone na platformę iOS.
Tom Leadbetter jest projektantem stron internetowych i programistą z Liverpoolu (Wielka Brytania). Od 2005 roku działa w branży internetowej na rzecz różnych organizacji i klientów, a od początku 2009 roku eksperymentuje z HTML5, na którego temat bloguje na witrynie HTML5Doctor.com.
24
O autorach
1 Nowe elementy strukturalne w HTML5 W
HTML5 nie chodzi tylko o interaktywną magię związaną z javascriptowymi API i wyświetlaniem filmów. Przy tworzeniu stron internetowych możesz używać ponad 20 nowych elementów, które wzbogacają semantykę i pozwalają tworzyć bardziej dostępne i łatwiejsze do ponownego wykorzystania treści. W kolejnych rozdziałach poznasz nowe kontrolki formularzy oraz elementy HTML5 związane z multimediami. W tym rozdziale dowiesz się o nowych elementach strukturalnych: header, hgroup, nav, footer, article, section oraz aside — skupimy się na tym, jak, kiedy i dlaczego używać tych elementów, czy to osobno, czy łącznie. Ściśle rzecz biorąc, zbudujesz prosty szablon strony internetowej zawierającej nowe elementy, taki jak pokazany na rysunku 1.1.
Rysunek 1.1. Struktura prostej strony zawierającej nowe elementy HTML5
26
Rozdział 1. Nowe elementy strukturalne w HTML5
PRZEPIS DLA POCZĄTKUJĄCYCH Budowa startowego dokumentu HTML5 Skoro masz zacząć programować w HTML5, rozpocznijmy od początku dokumentu HTML. Chociaż zawartość tego podrozdziału nie obejmuje omówienia nowych elementów, trzeba wspomnieć, że pojawił się nowy sposób zapisu elementów, o czym warto wiedzieć, zanim przejdziemy do elementu body.
doctype Czy to wygląda znajomo?
Na samym początku, w pierwszym wierszu dokumentu HTML, powinna się znaleźć wymagana przez standardy sieciowe definicja typu dokumentu (ang. Document Type Definition, DTD), czyli element doctype. Informuje on przeglądarkę, jak przetwarzać dokument, i właśnie dlatego powinien być pierwszym fragmentem pliku HTML. Gdybyś nie użył definicji doctype lub umieścił przed nią jakikolwiek inny kod, przeglądarka zadziałałaby w tzw. trybie osobliwości i być może w niektórych przeglądarkach napisany przez Ciebie kod nie zostałby prawidłowo zinterpretowany. Nie sądzę, abyś chciał zapamiętywać podany doctype, bo niby z jakiej racji? Jest okropny i niezgrabny. W HTML5 masz teraz ładny i łatwy do zapamiętania doctype:
To naprawdę wszystko. Wszystko, czego potrzebujesz, by poinformować przeglądarkę, że działasz w trybie standardów. Jeśli przeglądarka nie implementuje HTML5, strona wciąż będzie działać. Gdybyś użył , również spowodowałoby to przejście do trybu osobliwości. Ten doctype został wybrany w taki sposób, aby zawsze działał w przeglądarkach, niezależnie od tego, jaka jest najnowsza wersja języka.
Uwaga Pod adresem http://infomesh.net/html/history/early/ możesz odnaleźć najwcześniejszy dokument HTML z 13 listopada 1990 roku. Użyty kod znaczników jest naprawdę prosty, co przypomina nam doctype z HTML5. Prawdę mówiąc, jeśli dodałbyś do tej strony nowy doctype, przeszłaby ona walidację.
Kodowanie znaków Pierwszym wierszem, który powinien się znaleźć w treści elementu head, jest deklaracja charset, mówiąca przeglądarce, w jaki sposób dany plik powinien być interpretowany; w tym przypadku chcesz jej wysłać dokument HTML. W HTML 4 deklaracja ta wyglądała w ten sposób:
Tak jak w przypadku definicji doctype, w HTML5 jest to znacznie prostsze:
To łatwe! Pamiętaj, że potrzebujesz definicji doctype oraz powyższej deklaracji na swojej stronie.
Budowa startowego dokumentu HTML5
27
JavaScript i łącza CSS Przez ten krótki podrozdział możemy przejść równie szybko jak przez poprzedni. HTML5 pomaga się pozbyć z Twoich stron wielu znaczników i możesz dzięki niemu uprościć odwołania do JavaScriptu (a także innych plików skryptowych po stronie klienta) oraz CSS-a. W HTML 4 elementy script i link wymagały atrybutu type, tak jak w poniższym przykładzie:
W HTML5 wiersze te wyglądają następująco:
Czy zastanawiasz się, dlaczego możesz tak zrobić? Cóż, jedną z intencji autorów HTML5 było umożliwienie kodowania w sposób bardziej zdroworozsądkowy. Jeśli więc umieszczasz łącze do skryptu, przeglądarka zakłada, że jest to plik javascriptowy, a jeśli używasz rel="stylesheet", oznacza to, że podłączasz plik CSS-owy. I nie martw się, pominięcie atrybutu type nie powoduje żadnych problemów w starszych przeglądarkach.
Styl używanej składni Pozostając przy wcześniejszych przykładach, w HTML5 możesz zakodować stronę na kilka nieznacznie różniących się sposobów. Możesz kodować, używając wielkich liter:
Możesz kodować, nie używając znaków cudzysłowu:
Możesz pominąć zamykający ukośnik:
Lub możesz wykorzystać kombinację powyższych sposobów!
Wszystkie te sposoby są dozwolone, jednak stanowczo zaleca się, aby wybrać jakiś styl i konsekwentnie się go trzymać. Będzie to użyteczne nie tylko dla Ciebie, ale także dla innych programistów, którzy mogą być kiedyś zmuszeni do używania Twojego kodu. Styl składni powinien być spójny. Mamy doświadczenie związane z XHTML-em, więc w tej książce zamykamy wszystkie tagi i używamy małych liter oraz znaków cudzysłowu w atrybutach. Zbierając razem to wszystko, o czym powyżej napisaliśmy, utwórzmy stronę startową w HTML5 — taką jak pokazana na listingu 1.1. To wszystko! Zapisz stronę jako plik .htm (lub .html) — od teraz możesz już rozpocząć wypełnianie jej wspaniałą treścią.
28
Rozdział 1. Nowe elementy strukturalne w HTML5
Listing 1.1. Prosta strona startowa w HTML5
tytuł strony
Ta wiadomość została opublikowana 1 kwietnia 2011 przez Toma ´Leadbettera
Przeczytaj następny artykuł Toma
© Copyright Podręcznik HTML5 2011
Rysunek 1.10. Układ strony z wieloma elementami footer
W tym przykładzie w elemencie article zostały umieszczone dwa elementy footer. Wyświetlanie autora lub daty na górze i dole pojedynczej wiadomości lub wpisu na blogu to typowa praktyka, a elementu footer możesz używać tyle razy, ile chcesz. W poprzednim przykładzie wprowadziliśmy element time, o którym opowiemy w następnym rozdziale. Możesz umieścić w elemencie footer inne treści, dotyczące przykładowo nawigacji (oczywiście z wykorzystaniem elementu nav), logo partnerów i umów licencyjnych. Możesz także często zobaczyć tekst w rodzaju: „Ta witryna jest obsługiwana przez ”. Specyfikacja HTML5 mówi, że element footer może zawierać łącza do powiązanych dokumentów, i chociaż wcześniej używałeś w tym celu kombinacji elementów aside i nav, możesz również użyć do takiej treści elementu footer, jeśli tylko znajduje się on wewnątrz elementu article. Element footer może zawierać na przykład łącza do poprzedniego i następnego artykułu, co wyglądałoby mniej więcej tak:
Wykorzystanie narzędzia HTML5 Outliner
41
...cała treść tego artykułu...
Poprzedni artykuł | Następny artykuł
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Wykorzystanie narzędzia HTML5 Outliner do utworzenia prawidłowej struktury dokumentu Dzięki nowym elementom HTML5 możesz sprawić, by Twoja treść układała się w logiczny sposób, a użytkownicy poruszali się po niej (na przykład z wykorzystaniem czytników ekranu) za pomocą hierarchii przypominającej spis treści. Testowanie konspektu pozwala Ci sprawdzić, czy poprawnie używasz nagłówków i elementów section. Do Twojej dyspozycji pozostają rozmaite rozszerzenia przeglądarek i witryny, ale tutaj skupimy się na rozszerzeniu Google Chrome: http://code.google.com/p/h5o/. Pobierz rozszerzenie Chrome. Po jego zainstalowaniu na pasku adresu pojawi się ikona — taka, jaką pokazano na rysunku 1.11.
Rysunek 1.11. Witryna z ikoną rozszerzenia HTML5 Outliner w Google Chrome
Kiedy wybierzesz to narzędzie, zostaną wyświetlone dane przypominające wyglądem spis treści, zwykle z wcięciami. Jeśli właściwie zorganizowałeś treść strony, spis treści powinien być ustrukturyzowany i logiczny. Komunikat „Untitled section/article” jest niepożądany — jeśli został wyświetlony, być może użyłeś nieprawidłowych znaczników, musisz zatem ponownie się im przyjrzeć. Zauważ jednak, że w przypadku nav i aside komunikat „Untitled section” jest jak najbardziej dozwolony. Poprawny konspekt mógłby wyglądać następująco: 1. Nazwa witryny a. Blog i. Tytuł artykułu ii. Tytuł artykułu b. O mnie i. Moje imię i nazwisko ii. Rzeczy, które lubię iii. Rzeczy, których nie lubię c. Kontakt
42
Rozdział 1. Nowe elementy strukturalne w HTML5
Rysunek 1.12 pokazuje przykład konspektu dokumentu. Wcięcia są prawidłowe i nie ma niezatytułowanych punktów (poza elementem nav, ale to dopuszczalne).
Rysunek 1.12. Konspekt prostego dokumentu HTML5 w Google Chrome
Konspekt, który utworzysz w tym przepisie, wygląda następująco: 1. Mnóstwo wiadomości 1. Untitled NAV 2. Sport 3. Rozrywka 4. Komputery Listing 1.12 pokazuje kod źródłowy tej strony. Listing 1.12. Tworzenie prostego konspektu dokumentu
Mnóstwo wiadomości Dostarczamy Ci najróżniejszych wiadomości!
- Strona główna
- O witrynie
- Kontakt
- Strona główna
Tworzenie strony z wiadomościami
43
Sport
Rozrywka
Komputery
Strona zawiera na początku element header, użyty jako pierwszy węzeł konspektu (nie tytuł strony), a następnie elementy section, które zawierają nagłówki. W elemencie header znajduje się element hgroup z elementem h2 zawierającym tekst: „Dostarczamy Ci najróżniejszych wiadomości!”, ale nie widzisz go w konspekcie, ponieważ konspekt czyta wyłącznie pierwszy nagłówek (h1, h2, h3, h4, h5 lub h6) w danym elemencie. Elementy section, article, nav i aside rozpoczynają kolejne poziomy wcięć (podpunkty) w konspekcie. Elementy section zawierają nagłówki h1, których treść jest wyświetlana w konspekcie. Mógłbyś tu użyć elementów h2 albo h3, gdybyś chciał; to nie ma znaczenia. Jeśli element section zawierałby treść, ale nie nagłówek, w konspekcie byłby wyświetlany tekst „Untitled section”, czego powinieneś unikać.
PRZEPIS DLA ZAAWANSOWANYCH Wykorzystanie wszystkich nowych elementów do utworzenia strony z wiadomościami Rysunek 1.13 oraz kod z listingu 1.13 ilustrują wykorzystanie wszystkich nowych elementów HTML5 do utworzenia układu strony z wiadomościami. Znajdują się tu pewne podstawowe instrukcje CSS służące do spozycjonowania elementów, ale nie jest to jeszcze nic skomplikowanego — takimi rzeczami zajmiemy się dopiero w jednym z późniejszych rozdziałów. Listing 1.13. Tworzenie strony domowej z wiadomościami
Mnóstwo wiadomości — najlepsza witryna z wiadomościami, jaka kiedykolwiek istniała
44
Rozdział 1. Nowe elementy strukturalne w HTML5
Mnóstwo wiadomości Dostarczamy Ci najróżniejszych wiadomości!
- Strona główna
- Sport
- Rozrywka
- Komputery
- O witrynie
- Kontakt
Główny artykuł
To jest nasz najważniejszy artykuł
10 listopada 2010
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
Sport
Rozrywka — tytuł 1
10 listopada 2010
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
Komputery
turpis egestas.
turpis egestas.
turpis egestas.
turpis egestas.
Tworzenie strony z wiadomościami
45
Witryna używa systemu zarządzania treścią bez nazwy
Witryna znajduje się na serwerze bez nazwy
Wszystkie zdjęcia w tej witrynie są własnością fotografa
© Copyright Nikt 2011
Rysunek 1.13. Układ strony z wiadomościami utworzonej z wykorzystaniem nowych elementów HTML5
Teraz, kiedy uporałeś się z podstawowym układem i kodem, powinieneś sprawdzić konspekt dokumentu. Na podstawie powyższego kodu zostanie utworzony następujący konspekt:
46
Rozdział 1. Nowe elementy strukturalne w HTML5
1. Mnóstwo wiadomości a. Untitled NAV 2. Główny artykuł a. To jest nasz najważniejszy artykuł 3. Sport a. Sport — tytuł 1 b. Sport — tytuł 2 c. Sport — tytuł 3 4. Rozrywka a. Rozrywka — tytuł 1 b. Rozrywka — tytuł 2 c. Rozrywka — tytuł 3 5. Komputery a. Komputery — tytuł 1 b. Komputery — tytuł 2 c. Komputery — tytuł 3 6. Untitled ASIDE Wygląda to wspaniale! W przeciwieństwie do elementów section, article, nav i aside, element footer nie dzieli treści na fragmenty, więc nie pojawia się w konspekcie. Elementy nav i aside nie są zatytułowane, ale to nie problem. Gdybyś chciał, mógłbyś nadać elementowi aside tytuł, jednak czy reklama produktu zewnętrznego zasługuje na tytuł?
PRZEPIS DLA ZAAWANSOWANYCH Wykorzystanie wszystkich nowych elementów do utworzenia strony z wynikami wyszukiwania Na listingu 1.14 wykorzystasz kilka nowych elementów HTML5 do utworzenia struktury strony z rezultatami wyszukiwania (rysunek 1.14). Pamiętaj, że w tym przepisie nie ma CSS-a, a jedynie HTML. Listing 1.14. Strona z wynikami wyszukiwania zbudowana z wykorzystaniem omówionych elementów
Wyszukiwanie
- Sieć
Tworzenie strony z wynikami wyszukiwania
- Zdjęcia
- Wideo
- Mapy
Wyszukiwania powiązane z "Test" - Inna witryna
- Inna witryna
- Inna witryna
- Inna witryna
Szukaj Szukaj
Szukanie zaawansowane
Tworzenie strony z wynikami wyszukiwania
49
- Regulamin
- Polityka prywatności
Listing 4.4. CSS domyślnego układu ekranu
Tworzenie dostosowującego się projektu za pomocą CSS3 Media Queries
89
Rysunek 4.1. Witryna z wiadomościami z domyślnym CSS-em
Rysunek 4.2 pokazuje układ na mniejszym ekranie z wykorzystaniem zapytań o media z listingu 4.5. Listing 4.5. CSS przeznaczony dla mniejszych ekranów /* style dla rozdzielczości ekranu większych od smartfonów, ale mniejszych lub równych 1280px */ @media only screen and (min-width: 481px) and (max-width: 1259px) { body {width: 800px;} section {margin: 0 0 0 10px;} section:nth-of-type(1), section {clear: none; float: left; padding: 10px; width: 375px;} section:nth-of-type(1) article img {float: left; height: auto; position: relative; width: auto;} section:nth-of-type(2) {margin-left: 10px;} section:nth-of-type(3) {clear: both; margin-left: 0;} aside {clear: both; float: left; width: 100%;} aside img {float: left; margin: 0 10px 0 0;} }
Wreszcie, listing 4.6 zawiera zapytania o media w CSS-ie przeznaczone dla smartfonów albo znacznie zmniejszonego okna przeglądarki (rysunek 4.3). Zasadniczo tych kilka dodatkowych wierszy CSS-a sprawia, że w porównaniu z ekranem o mniejszych rozmiarach niektóre elementy są ukrywane lub zmniejszane.
90
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
Rysunek 4.2. Witryna z wiadomościami na mniejszym ekranie Listing 4.6. CSS przeznaczony dla smartfonów /* style dla smartfonów i bardzo małych rozdzielczości ekranu */ @media only screen and (max-width: 480px), only screen and (max-device-width: 480px) { body {width: 100%;} header[role=banner] h1 {background-image: url(images/logo-small.gif); font-size: 3em; padding: 50px 0 0;} section:nth-of-type(1), section {margin: 0 0 10px; min-height: inherit; padding: 0 1%; width: 98%;} header[role=banner] h2, img, section article p, aside {display: none;} section h2 a {border-bottom: 1px dotted #999; display: block; text-decoration: none;} nav, section article:last-of-type h2 a {border: none;} }
Kiedy używać zapytań o media Choć możesz tworzyć oddzielne style dla różnych urządzeń i rozmiarów ekranu, powstaje pytanie, czy zawsze powinieneś korzystać z zapytań o media. Bez wątpienia mogą być one użyteczne na komputerach stacjonarnych i laptopach, ale rynek urządzeń przenośnych od pewnego czasu się zmienia. Bardziej nowoczesne smartfony, takie jak iPhone i urządzenia z systemem Android, posiadają przeglądarki, które są prawie identyczne jak przeglądarki desktopowe i z większością rzeczy sobie radzą, a interaktywność urządzeń pozwala użytkownikowi stosunkowo łatwo wybierać i powiększać fragmenty witryn.
Tworzenie dostosowującego się projektu za pomocą CSS3 Media Queries
91
Rysunek 4.3. Witryna z wiadomościami na smartfonie
Korzystanie z zapytań o media oznacza na ogół pokazywanie lub ukrywanie treści w zależności od rozmiaru ekranu. Wiele witryn, takich jak http://youtube.com/, http://facebook.com/, http://cnn.com/ oraz http://nfl.com/, wykrywa, czy użytkownik używa urządzenia przenośnego, i przekierowuje go na wersje przeznaczone dla takich urządzeń. Witryny te zawierają dużo treści z mnóstwem danych, zdjęć, filmów wideo, reklam, Flasha i innych rzeczy — gdyby korzystać tylko z zapytań o media, smartfon nadal musiałby pobierać wszystkie te dane, mimo że użytkownik nie mógłby ich zobaczyć. A zatem to, czy potrzebujesz jedynie nowych stylów, czy zupełnie oddzielnej witryny dla urządzeń przenośnych, zależy od treści witryny, ale jeśli masz zmienić jedynie układ i dodać kilka szczegółów, wtedy powinieneś prawdopodobnie użyć zapytań o media. Kilka znakomitych sposobów ich użycia znajdziesz na http://mediaqueri.es/.
Obsługa iPhone’a i urządzeń z systemem Android Jeśli używałeś zapytań o media do obsługi iPhone’a albo urządzeń z systemem Android, być może zauważyłeś, że nie uwzględniają one zmian CSS-a dotyczących małych ekranów. Jest tak dlatego, że nowoczesne przeglądarki na smartfonach mają duże możliwości i domyślnie wyświetlają stronę internetową tak samo jak przeglądarki desktopowe. Następnie przeglądarka zmniejsza witrynę, tak aby mieściła się ona na małym ekranie, co może często skutkować wyświetlaniem drobnego tekstu i obrazków, przez co użytkownik musi powiększać fragmenty witryny, by ją czytać i przeglądać. Możesz zmusić przeglądarkę do używania szerokości urządzenia jako szerokości obszaru, w którym przeglądarka pokazuje obraz, znanego również jako viewport. W tagu head należy umieścić następujący kod:
92
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
PRZEPIS DLA POCZĄTKUJĄCYCH Korzystanie z własnych czcionek przy użyciu @font-face Chociaż deklaracja @font-face nie pojawiła się dopiero w CSS3, została w nim uatrakcyjniona. Projektanci i twórcy stron internetowych mają teraz do dyspozycji wiele możliwości wyboru i sposobów implementacji czcionek w swojej witrynie. Tabela 4.2 pokazuje, które wersje każdej z przeglądarek obsługują @font-face. Tabela 4.2. Obsługa @font-face w przeglądarkach i urządzeniach Android
2.3+
Chrome
13.0+
Firefox
4.0+
Internet Explorer
6.0+
iOS Safari
4.0+
Opera
11.0+
Safari
5.0+
Uwaga Deklaracja @font-face została włączona do specyfikacji CSS2 w 1998 roku, jednak była w zasadzie nieużywana z powodu słabej implementacji w przeglądarkach, zamieszania z rodzajami plików czcionek i obaw dotyczących problemów prawnych i licencyjnych związanych z wykorzystywaniem czcionek. Internet Explorer w wersji 4 obsługiwał nawet dodatkowe, zewnętrzne czcionki, choć tylko w formacie EOT.
Używając deklaracji @font-face, możesz osadzić na stronie swoje własne czcionki za pomocą jedynie kilku wierszy CSS-a. Na rysunku 4.4 pokazaliśmy czcionkę Anagram (dalej podamy informacje o tym, skąd zdobyć czcionki) w elemencie h1, chociaż może być ona użyta w dowolnym elemencie.
Rysunek 4.4. Własna czcionka wyświetlona przy użyciu @font-face
Listing 4.7 pokazuje kod potrzebny do uzyskania efektu z rysunku 4.4 i prezentuje przykład najprostszego użycia @font-face. Podajemy nazwę czcionki Anagram jako wartość właściwości font-family (można nazwać ją dowolnie), a później będziemy się ponownie do niej odwoływać; spójrz na wartości czcionek h1. W deklaracji @font-face właściwość src wykorzystuje ten sam katalog, w którym znajduje się strona HTML; jeśli chcesz, możesz umieścić czcionkę w innym katalogu. Listing 4.7. Deklaracja @font-face w swojej najprostszej postaci
Mnóstwo wiadomości Dostarczamy Ci najróżniejszych wiadomości!
Formaty plików i działanie czcionek w różnych przeglądarkach Na listingu 4.7 użyliśmy tylko czcionek typu .ttf (TrueType/OpenType). Jak można się spodziewać, między przeglądarkami występują różnice implementacyjne. Istnieje wiele różnych formatów plików czcionek: Embedded OpenType (.eot), OpenType PS (.otf), TrueType/OpenType (.ttf), SVG (.svg), WOFF (.woff).
WOFF jest nowym sieciowym standardem krojów pisma. Internet Explorer w wersjach 8 i starszych wymaga czcionki .eot, ale Internet Explorer 9 obsługuje nowy format WOFF. A chociaż Safari obsługuje .ttf już od jakiegoś czasu, dopiero niedawno iPhone i iPad zaczęły wspierać ten format; wcześniej potrzebowały czcionki .svg. Powinieneś więc dostarczać tę samą czcionkę w różnych formatach. W tym celu musisz albo samodzielnie przekonwertować czcionki, albo użyć narzędzia, takiego jak Font Squirrel z http://www.fontsquirrel. com/. Narzędzie @font-face Generator pozwala Ci wgrać czcionki, a następnie przekształcić je na inny format. Generuje ono również odpowiedni CSS, który umożliwia działanie czcionki w różnych przeglądarkach, co pokazano na listingu 4.8. Listing 4.8. Działający w różnych przeglądarkach @font-face @font-face { font-family: 'AnagramRegular'; src: url('type/anagram-webfont.eot'); src: url('type/anagram-webfont.eot?#iefix') format('embedded-opentype'), url('type/anagram-webfont.woff') format('woff'), url('type/anagram-webfont.ttf') format('truetype'), url('type/anagram-webfont.svg#AnagramRegular') format('svg'); font-weight: normal; font-style: normal; }
Na listingu 4.8 odwołujemy się do czterech różnych formatów tej samej czcionki. Warto być może umieścić swoje czcionki w oddzielnych katalogach, tak jak robisz to z obrazkami. Kolejność czcionek
94
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
w powyższym kodzie jest związana z problemem dotyczącym działania Internet Explorera. Było już wiele wersji powyższego kodu, ale w miarę rozwoju przeglądarek zniknęło kilka problemów. Powyższy kod jest obecnie2 dostarczany przez Font Squirrel, gdy generujesz pakiet z czcionkami, lecz oczywiście w przyszłości może się on zmienić.
Usługi związane z krojami pisma Znalezienie odpowiedniego kroju pisma może być trudne, a znalezienie takiego, który może być użyty w sieci zgodnie z prawem, może być jeszcze trudniejsze. Font Squirrel pozwala Ci przekształcić czcionki na różne potrzebne formaty. By to zrobić, musisz zaznaczyć przycisk wyboru, przy którym jest napisane „Yes, the fonts I am uploading are legally eligible for web embedding”3. Jeśli go zaznaczysz, a nie jesteś w pełni przekonany, że tak jest, możesz mieć problemy prawne. Jeśli potrzebujesz darmowej czcionki, sugerujemy przejrzenie biblioteki krojów na witrynie Font Squirrel, ponieważ ta witryna oferuje nie tylko generator czcionek — jej głównym celem jest udostępnianie czcionek, które są darmowe i które można wykorzystywać w zastosowaniach komercyjnych. Ponadto witryna nie zawiera po prostu jakichkolwiek darmowych czcionek, ale zawiera czcionki wysokiej jakości. Font Squirrel nie jest jedynym miejscem, w którym można pobrać darmowe czcionki do użytku w sieci, ale gdy będziesz szukał ich gdzie indziej, bądź świadomy aspektów prawnych. Innym rozwiązaniem dotyczącym darmowych czcionek jest Google Font Directory (http://www.google. com/webfonts). Za pomocą dostępnego API bardzo łatwo skorzystać z oferowanych tam czcionek. Ponieważ czcionki znajdują się na serwerach Google, czasy ładowania są minimalne. Musisz tylko znaleźć czcionkę i wybrać „Quick-use”4. Narzędzie przygotowuje HTML i CSS, których potrzebujesz, a dodatkowo oferuje inne grubości czcionki, jeśli dana czcionka je posiada. Dostarczany przez to narzędzie kod HTML, który należy umieścić w znaczniku head, jest podobny do poniższego:
Google daje Ci również nazwę czcionki, którą możesz umieścić w swoim kodzie CSS: h1 {font-family: 'Yanone Kaffeesatz', arial, serif;}
Tak, to naprawdę proste.
Wskazówka W poprzednich przykładach mogłeś zauważyć, że po deklaracji dodatkowej czcionki podajemy listę niektórych „bezpiecznych” do stosowania w sieci czcionek, jak na przykład rodzinę czcionek 'Yanone Kaffeesatz', arial, serif. Rezerwową czcionkę podajemy, na wypadek gdyby cokolwiek poszło nie tak podczas pobierania dodatkowej czcionki. Może się pojawić problem z serwerem i przeglądarka może być niezdolna do pozyskania dodatkowej czcionki, którą chcemy wykorzystać, a poprzez zamieszczenie listy czcionek dajemy możliwość awaryjnego użycia czcionki, o której wiemy, że jest dostępna. Listy czcionek powinny być dodawane zawsze wtedy, kiedy używa się CSS-owej właściwości font-family.
2
W kwietniu 2012 roku — przyp. tłum.
3
Tak, czcionki, które wgrywam, mogą być zgodnie z prawem używane na witrynach internetowych — przyp. tłum.
4
Szybki wybór — przyp. tłum.
Tworzenie przycisków za pomocą gradientów CSS i wielu teł
95
Jeśli Font Squirrel albo Google Font Directory nie mogą udostępnić czcionki, której szukasz, wypróbuj inne serwisy. Ponieważ licencjonowanie stanowi problem już od lat, wielu spośród głównych producentów czcionek zaczęło albo tworzyć swoje własne struktury pozwalające Ci zgodnie z prawem i bezpiecznie używać ich czcionek, albo współpracować z inną organizacją, która pomaga dostarczać czcionki. Serwisy takie jak FontDeck i TypeKit umożliwiają Ci zarejestrowanie się i dokonanie wyboru spośród szeregu czcionek, z których wszystkie zostały poprawione w celu uzyskania lepszej czytelności na ekranie. FontDeck i TypeKit dostarczają czcionki na odrobinę różne sposoby, ale konfiguracja, wybór i aktywacja czcionek w obu serwisach nie powinny nikomu sprawiać problemów. Oba serwisy mają darmowe konta z pewnymi ograniczeniami i oba oferują różne pakiety cenowe.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie przycisków za pomocą gradientów CSS i wielu teł Gradientów CSS3 możesz używać do tworzenia miłych i subtelnych albo jakichś zwariowanych, pokracznych gradientów. Nie musisz tworzyć obrazków, a gradienty są skalowalne, więc kiedy już się z nimi oswoisz, sprawiają dużo mniej kłopotu w porównaniu z tworzeniem, edycją i ponownym tworzeniem obrazków, ponieważ możesz zrobić wszystko za pomocą kodu. Tabela 4.3 pokazuje, które wersje każdej z przeglądarek obsługują gradienty CSS3. Tabela 4.3. Obsługa gradientów w przeglądarkach i urządzeniach Android
2.3+
Chrome
13.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
4.0+
Opera
11.0+
Safari
5.0+
Listing 4.9 zawiera kod prostego gradientu od białego do czarnego koloru, który pokazano na rysunku 4.5. Listing 4.9. Prosty liniowy gradient CSS div { height: 200px; width: 200px; background: url(gradient.gif); /* dla przeglądarek, które nie potrafią tworzyć gradientów */ background: -moz-linear-gradient(white, black); background: -webkit-linear-gradient(white, black); background: -linear-gradient(white, black); }
96
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
Rysunek 4.5. Prosty liniowy gradient CSS
Najpierw zostaje określony rodzaj gradientu (liniowy lub radialny), po czym następują nawiasy, w których zapisany jest początkowy i końcowy kolor gradientu. Zauważ, że kod ma cztery różne deklaracje. Pierwsza zawiera gradient w postaci pliku graficznego, na wypadek gdyby przeglądarka nie obsługiwała gradientów CSS3; -moz-linear-gradient jest przeznaczona dla przeglądarek Mozilla (Firefox); -webkit-linear-gradient dla przeglądarek opartych na WebKit (Safari i Chrome); ostatnia deklaracja tła jest oficjalną składnią gradientu CSS3, ale obecnie żadna przeglądarka jej nie obsługuje.
Uwaga W 2008 roku WebKit był pierwszym silnikiem, który zaczął używać gradientów, lecz miał swoją własną składnię. W miarę jak gradienty CSS stawały się bardziej popularne, Mozilla zaimplementowała składnię znacznie bliższą tej z oficjalnej specyfikacji. Jednak w styczniu 2011 roku ogłoszono, że WebKit zmieni składnię gradientów i zacznie używać tego samego stylu co Mozilla i oficjalna specyfikacja, co jest wspaniałą wiadomością dla każdego, ponieważ oryginalna składnia WebKit była bardziej skomplikowana i nie była oparta na standardach. W tej książce używamy nowej składni WebKit.
Na listingu 4.10 używamy przycisków i kombinacji selektorów atrybutów, właściwości box-shadow i border-radius, wielu teł oraz gradientów CSS do uzyskania efektów z rysunku 4.6. We właściwości background oddzielamy poszczególne style tła przy użyciu przecinka. Wobec tego najpierw umieszczamy obrazek, z którego chcemy skorzystać, a potem ustawiamy style gradientu. Jeśli style gradientu byłyby użyte wcześniej, przykryłyby obrazek. Listing 4.10. Efekty gradientu na przyciskach input { border: none; -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, .4); box-shadow: 0 1px 5px rgba(0, 0, 0, .4); -webkit-border-radius: 10px; border-radius: 10px; cursor: pointer; color: #fff; font: bold 1.2em Arial, Helvetica, sans-serif; margin: 0 10px 0 0; padding: 10px 10px 10px 30px; text-shadow: 0 2px 2px rgba(0, 0, 0, 0.25); } input[type="submit"] { background: url(images/accept.png) 8px 55% no-repeat #91BD09; background: url(images/accept.png) 8px 55% no-repeat, -webkit-linear-gradient(#91BD09, #578730); background: url(images/accept.png) 8px 55% no-repeat, -moz-linear-gradient(#91BD09, #578730);
Tworzenie przycisków za pomocą gradientów CSS i wielu teł
97
background: url(images/accept.png) 8px 55% no-repeat, -linear-gradient(#91BD09, #578730); } input[value="Anuluj"] { background: url(images/cross.png) background: url(images/cross.png) background: url(images/cross.png) background: url(images/cross.png) }
8px 8px 8px 8px
55% 55% 55% 55%
no-repeat #b53109; no-repeat, -webkit-linear-gradient(#b53109, #540303); no-repeat, -moz-linear-gradient(#b53109, #540303); no-repeat, -linear-gradient(#b53109, #540303);
input[type="reset"] { background: url(images/error.png) background: url(images/error.png) background: url(images/error.png) background: url(images/error.png) }
8px 8px 8px 8px
55% 55% 55% 55%
no-repeat #f0bb18; no-repeat, -webkit-linear-gradient(#f0bb18, #a46b07); no-repeat, -moz-linear-gradient(#f0bb18, #a46b07); no-repeat, -linear-gradient(#f0bb18, #a46b07);
Rysunek 4.6. Gradienty CSS3 na przyciskach
Możesz uzyskać znacznie więcej niż tylko zwykłe przenikanie dwóch kolorów. Używając zatrzymania, możesz dodać wiele kolorów do gradientu, co pokazano na rysunku 4.7. Zatrzymania są dodawane po każdym przecinku i mogą zawierać pozycję, w której się zaczynają, jak pokazano na listingu 4.11. Listing 4.11. Gradienty z wieloma zatrzymaniami div { height: 200px; width: 200px; background-color: #000; background: -moz-linear-gradient(left, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); background: -webkit-linear-gradient(left, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); background: -linear-gradient(left, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); }
Rysunek 4.7. Gradienty CSS3 z wieloma zatrzymaniami
Listing 4.11 pokazuje kod użyty do utworzenia lewego obrazka z rysunku 4.7. Gradient staje się bardziej skomplikowany, ale zasadniczo każdy przecinek rozpoczyna nowy fragment informacji o gradiencie, w którym przekazujesz wartość koloru, a następnie procent oznaczający miejsce, w którym ten kolor się zaczyna.
98
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
Ponadto możesz obrócić gradient przez zmianę deklaracji left, na przykład na 45deg albo left top, jak pokazano na listingu 4.12, który tworzy prawy obrazek z rysunku 4.7. Listing 4.12. Obrócone gradienty z wieloma zatrzymaniami div { height: 200px; width: 200px; background-color: #000; background: -moz-linear-gradient(45deg, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); background: -webkit-linear-gradient(45deg, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); background: -linear-gradient(45deg, #000000 0%, #FFFFFF 25%, #000000 50%, #FFFFFF 75%, #000000 100%); }
Istnieje mnóstwo opcji związanych z gradientami CSS3, włączając w to tworzenie gradientów radialnych. Zalecamy wypróbowanie niektórych spośród generatorów gradientów, by nabrać wprawy: http://colorzilla.com/gradient-editor/, http://display-inline.fr/projects/css-gradient/.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Upiększanie witryny za pomocą transformacji i przejść Dawniej twórcy stron internetowych musieli używać JavaScriptu albo wtyczek, takich jak Flash, żeby uzyskać na stronie internetowej efekty i animacje. Teraz jednak możesz robić takie rzeczy jak obracanie i zmiana rozmiaru elementów HTML przy użyciu jedynie CSS-a. Ponieważ żadna przeglądarka nie przyjęła jeszcze oficjalnej składni CSS-owej, musisz dodawać CSS dla każdego producenta. Oznacza to, że będziesz mieć zduplikowany CSS, ale na razie jest to konieczne, a nie wiąże się tak naprawdę z dużą ilością dodatkowej pracy. Tabela 4.4 pokazuje, które wersje każdej z przeglądarek obsługują transformacje i przejścia. Tabela 4.4. Obsługa transformacji i przejść w przeglądarkach i urządzeniach Android
2.3+
Chrome
13.0+
Firefox
4.0+
Internet Explorer
9.0+
iOS Safari
4.0+
Opera
11.0+
Safari
5.0+
Rysunek 4.8 pokazuje transformację obracającą zastosowaną do elementu figure. Aby utworzyć efekt z rysunku 4.8, zastosuj właściwość transform z wartością rotate do elementów figure i h1. Jak pokazano na listingu 4.13, musisz użyć CSS-owych prefiksów kilku producentów, aby efekty działały w WebKit, Mozilli, Operze i Internet Explorerze.
Upiększanie witryny za pomocą transformacji i przejść
Rysunek 4.8. Obrazek i tekst obrócone za pomocą CSS-a Listing 4.13. Transformacje CSS * { margin: 0; padding: 0; } body { font: normal .9em Arial, Helvetica, sans-serif; position: relative; padding: 30px 10px 10px 75px; width: 600px; } h1 { left: -100px; position: absolute; top: 160px; text-align: left; -webkit-transform: rotate(270deg); -moz-transform: rotate(270deg); -o-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); } figure { background: #fff; border: 1px solid #BFBFBF; -webkit-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); -moz-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); display: block; float: right; margin: 20px 20px 50px 50px; padding: 5px; text-align: center; -webkit-transform: rotate(10deg);
99
100
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
-moz-transform: rotate(10deg); -o-transform: rotate(10deg); -ms-transform: rotate(10deg); transform: rotate(10deg); } figcaption { clear: both; display: block; font-weight: bold; padding: .5em 0; } p { margin: 0 0 1em; } To jest tytuł strony Pellentesque habitant morbi tristique sen……
Widok z naszego pokoju hotelowego
Pellentesque habitant morbi tristique sen……
Na rysunku 4.8 widać efekt użycia funkcji rotate CSS-owej właściwości transform, lecz istnieją jeszcze inne, których możesz używać: translate, scale i skew. Listing 4.14 pokazuje przykład kodu potrzebnego do implementacji tych efektów (nie zapomnij dodać prefiksów specyficznych dla przeglądarek). Kod pokazuje efekty transformacji zastosowanych na tekście, ale mogą być one wykorzystane na dowolnym elemencie, włączając w to body. Listing 4.14. Więcej możliwości transformacji CSS h1 {transform: translate(100px, 200px)} h1 {transform: skew(40deg);} h1 {transform: scale(2);} /* Możesz również połączyć je razem w pojedynczej deklaracji */ h1{transform: translate(100px, 200px) skew(40deg) scale(2) rotate(40deg);}
Możesz również stosować przejścia i animacje. Istnieje różnica między przejściami i animacjami w CSS-ie. Przejście jest procesem zmiany między dwoma stanami, wywołanym przesunięciem myszą kursora nad obiekt (:hover) albo kliknięciem przyciskiem myszy (:active). Animacje CSS działają natomiast samodzielnie. Przejścia były dostępne od dawna w WebKit, a Mozilla i Opera już je implementują; niestety, obecnie nie robi tego IE. Przejścia wykorzystują pokazaną wcześniej właściwość transform i mogą być zastosowane w przypadku pseudoklas :hover albo :active. Zamiast natychmiastowego zmieniania wartości elementu, gdy przesuwasz nad nim kursor myszą, możesz utworzyć animację przechodzącą do tych nowych wartości przy użyciu właściwości CSS transition. Rysunek 4.9 pokazuje prosty przykład zwykłego tekstowego łącza.
Rysunek 4.9. Łącze tekstowe z efektem hover
Upiększanie witryny za pomocą transformacji i przejść
101
Rysunek 4.10 pokazuje efekt w trakcie przechodzenia tła łącza do koloru czarnego i tekstu do koloru białego oraz ostateczny efekt przesunięcia kursora nad łącze. Trudno jest oddać ten efekt w drukowanej, czarno-białej książce, więc zachęcamy Cię do wypróbowania tego w przeglądarce.
Rysunek 4.10. Efekty przejścia
Listing 4.15 pokazuje kod potrzebny do uzyskania efektu związanego z przesunięciem kursora myszy. Docelowy kolor animacji jest zdefiniowany w deklaracji :hover. Bez żadnego przejścia kolory natychmiast zmieniłyby się na docelowe, ale dla uzyskania efektu stopniowej zmiany koloru używasz właściwości transition (oraz prefiksów producentów dla WebKit, Mozilli i Opery). Kluczowy w tym przypadku fragment CSS-a — transition: all 1s ease-in — przekazuje przeglądarce, by animowała wszystkie właściwości (background i color) i użyła funkcji czasowej ease-in, oraz informację, że całkowity czas trwania przejścia to jedna sekunda (1s). Możesz opcjonalnie umieścić wartość opóźnienia, tak jak w transition: all 1s ease-in 1s, opóźniającą rozpoczęcie przejścia oraz moment, w którym element powraca do swojego domyślnego stanu. Listing 4.15. Animowana zmiana koloru po najechaniu kursorem a { background: #fff; border-radius: 5px; display: block; float: left; padding: 5px; text-align: center; width: 125px; -webkit-transition: all 1s ease-in; -moz-transition: all 1s ease-in; -o-transition: all 1s ease-in; transition: all 1s ease-in; } a:hover { background: #000; color: #fff; }
Za pomocą przejść uzyskujesz zatem drobne, subtelne efekty, ale możesz również używać ich do poprawienia ogólnych wrażeń użytkownika strony. Weź jako przykład galerię miniatur zdjęć z rysunku 4.11. Używając kodu z listingu 4.16, dzięki kombinacji rotate i scale tworzysz ładny efekt wyświetlenia obrazka w jego pełnym rozmiarze po najechaniu na niego kursorem, i to bez potrzeby użycia JavaScriptu, co pokazano na rysunku 4.12. Listing 4.16. Animowane powiększenie obrazka po najechaniu kursorem img { background: #fff; border: 1px solid #BFBFBF; display: block;
102
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
float: left; height: 125px; margin: 0 10px 0 0; padding: 5px; width: 125px; -webkit-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); -moz-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3); -webkit-transition: all 1s ease-in-out; -moz-transition: all 1s ease-in-out; -o-transition: all 1s ease-in-out; } img:hover { -webkit-transform: rotate(10deg) scale(2); -moz-transform: rotate(10deg) scale(2); -o-transform: rotate(10deg) scale(2); -ms-transform: rotate(10deg) scale(2); transform: rotate(10deg) scale(2); }
Rysunek 4.11. Galeria zdjęć przed przejściami
Rysunek 4.12. Obrazek z galerii zdjęć po najechaniu na niego kursorem
Tworzenie animacji za pomocą CSS-a
103
PRZEPIS DLA ZAAWANSOWANYCH Tworzenie animacji za pomocą CSS-a W przeciwieństwie do przejść, animacje nie wymagają aktywacji poprzez najechanie kursorem lub kliknięcie. Obecnie animacje są dostępne tylko w przeglądarkach opartych na WebKit i w Firefoksie, ale wykorzystując różne techniki javascriptowe, możesz uzyskać animacje także w innych przeglądarkach. Tabela 4.5 pokazuje, które wersje każdej z przeglądarek obsługują animację CSS. Tabela 4.5. Obsługa animacji CSS w przeglądarkach i urządzeniach Android
2.3+
Chrome
13.0+
Firefox
5.0+
Internet Explorer
-
iOS Safari
4.0+
Opera
-
Safari
5.0+
W pierwszym, prostym przykładzie przesuniesz obrazek z lewej strony ekranu do prawej i jednocześnie go obrócisz. Pokazywanie zrzutu ekranu z tego przykładu nie ma większego sensu, więc otwórz przeglądarkę Chrome, Firefox albo Safari i uruchom kod z listingu 4.17. Listing 4.17. Animacja CSS /* CSS */ div { float: left; height: 100%; position: relative; width: 100%; } img { position: absolute; -webkit-animation-name: moveIt; -webkit-animation-duration: 5s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -moz-animation-name: moveIt; -moz-animation-duration: 5s; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear; animation-name: moveIt; animation-duration: 5s; animation-iteration-count: infinite; animation-timing-function: linear; } @-webkit-keyframes moveIt { from { left: 0; -webkit-transform:rotate(0deg); } to { left: 100%; -webkit-transform:rotate(360deg);
104
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
} } @-moz-keyframes moveIt { from { left: 0; -moz-transform:rotate(0deg); } to { left: 100%; -moz-transform:rotate(360deg); } } keyframes moveIt { from { left: 0; transform:rotate(0deg); } to { left: 100%; transform:rotate(360deg); } } /* HTML */
Przy selektorze img znajdują się cztery właściwości CSS dotyczące animacji. Są powtórzone, ponieważ muszą się jawnie odwoływać do przedrostków -webkit- i -moz-. Na końcu umieść nazwy właściwości bez przedrostków z myślą o dniu, w którym wszystkie przeglądarki będą obsługiwać animacje CSS: -webkit/moz-animation-name — nazwa animacji, której chcesz użyć; -webkit/moz-animation-duration — jak długo animacja będzie trwać; -webkit/moz-animation-iteration-count — ile razy animacja będzie powtórzona; -webkit/moz-animation-timing-function — rodzaj animacji; wybierz spośród ease, linear,
ease-in, ease-out, ease-in-out i cubic-bezier, którą można dostosowywać.
Teraz zdefiniuj animację @-webkit/moz-keyframes MoveIt. Jest to prosta animacja, więc zacznij od właściwości from, a skończ na wartości to. Wewnątrz tych właściwości użyj zwykłego CSS-a, by przemieścić oraz obrócić obrazek. W tych animacjach można zmienić prawie każdą właściwość CSS, masz więc dużo różnych możliwości. Korzystanie z właściwości from i to to jeszcze nie wszystko. Możesz również umieszczać klatki kluczowe, używając procentów, co pozwoli Ci na większą elastyczność. Rysunek 4.13 pokazuje baner, który znajduje się w prawym górnym rogu strony. Dzięki użyciu kodu z listingu 4.18 kolor tła zmienia się płynnie, a klatki kluczowe są umieszczone co 25 procent czasu animacji. Listing 4.18. Animowany baner p { background: #000; color: #fff; font: bold 20px Tahoma, Geneva, sans-serif; padding: 10px;
Tworzenie animacji za pomocą CSS-a
position: absolute; right: -65px; text-align: center; top: 75px; width: 300px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -o-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); -webkit-animation-name: glow; -webkit-animation-duration: 5s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: ease-in; -webkit-backface-visibility: hidden; -moz-animation-name: glow; -moz-animation-duration: 5s; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: ease-in; -moz-backface-visibility: hidden; animation-name: glow; animation-duration: 5s; animation-iteration-count: infinite; animation-timing-function: ease-in; backface-visibility: hidden; } @-webkit-keyframes glow { 0% { background: #F00; } 25% { background: #06C; } 50% { background: #000; } 75% { background: #06C; } 100% { background: #F00; } } @-moz-keyframes glow { 0% { background: #F00; } 25% { background: #06C; } 50% { background: #000; } 75% { background: #06C; } 100% { background: #F00;
105
106
Rozdział 4. Nowe techniki dotyczące układu i stylizacji w CSS3
} } keyframes glow { 0% { background: #F00; } 25% { background: #06C; } 50% { background: #000; } 75% { background: #06C; } 100% { background: #F00; } }
Rysunek 4.13. Animowany kolor tła
Wskazówka Przejścia i animacje mają wiele zastosowań. Nie tylko pozwalają dodawać fajne efekty do stron internetowych, ale mogą być także w prosty sposób tworzone i poprawiane przez projektantów i programistów. Pokazaliśmy w tym rozdziale jedynie proste przykłady, by pobudzić Twój apetyt, a od Ciebie zależy, jak je wykorzystasz. Dużym możliwościom towarzyszy jednak duża odpowiedzialność, więc staraj się nie przesadzać z rozmaitymi efektami, ponieważ mogą one szybko zamienić fajną witrynę w kiczowatą. Zbyt wiele przejść i animacji może również wpłynąć na wydajność przeglądarki. Sugerujemy spędzić trochę czasu na poszukiwaniu w internecie przykładów i badaniu sposobów, w jakie inni projektanci i programiści użyli CSS3 do ulepszania witryn.
Podsumowanie W tym rozdziale poznałeś kilka nowych możliwości CSS-a: zapytania o media, własne czcionki, gradienty, transformacje, przejścia oraz animacje. Istnieje o wiele więcej funkcji niż te, które opisaliśmy; dotknęliśmy jedynie powierzchni. Jeśli jesteś zainteresowany CSS-em, sugerujemy, żebyś kontynuował poszukiwania i naukę, ponieważ istnieje wiele innych technik i sugerowanych praktyk dotyczących użycia niektórych spośród tych nowych możliwości. A zatem zgłębiaj CSS i baw się nim.
5 Formularze internetowe HTML5 W
tym rozdziale poznasz formularze internetowe HTML5 oraz ich nowe funkcjonalności dostępne teraz dla twórców stron internetowych. Oczywiście nie wszystkie te nowe możliwości są w pełni obsługiwane przez wszystkie przeglądarki, ale jak zobaczysz w przepisach w tym rozdziale, mimo to nieźle działają i wyglądają. Przy tworzeniu formularzy do wyboru masz ponad dziesięć nowych typów elementu input, kilka nowych atrybutów oraz parę nowych trików CSS-owych.
Walidacja Mimo udostępnienia kilku nowych typów elementu input, bez wątpienia najważniejszą nową możliwością oferowaną przez HTML jest wbudowana walidacja formularzy. Dawniej trzeba było używać kodu po stronie serwera, takiego jak PHP albo C#, do sprawdzania treści przesłanego formularza, a następnie musiałeś zwracać stronę i wyświetlać użytkownikowi błędy. Alternatywnie można było używać jakiegoś wymyślnego JavaScriptu do sprawdzania na bieżąco treści wprowadzanych danych i informowania użytkownika, czy wystąpiły błędy. Przy użyciu HTML5 walidacja formularzy jest prosta. Możesz dać użytkownikom wbudowaną walidację, dzięki której otrzymują informację zwrotną, w momencie gdy próbują wysłać formularz, co powoduje, że formularze łatwiej jest wypełniać, i zwiększa szanse wysłania poprawnych informacji. Oczywiście będziesz potrzebował jakiegoś kodu po stronie serwera do przetworzenia formularzy. W przepisach w tym rozdziale do większości elementów formularzy dodajemy atrybut required. Robimy tak, byś podczas testowania mógł zobaczyć, jakie komunikaty dotyczące walidacji pokazuje przeglądarka (jeśli je pokazuje). Ten atrybut mówi przeglądarce, że formularz nie może być wysłany, zanim element nie zostanie wypełniony.
Typy wejściowe HTML 4 Jedynie napomkniemy o elementach formularzy, które były używane od lat przy tworzeniu stron internetowych. Są one nadal podstawowymi i zupełnie prawidłowymi elementami formularzy i nie są zastępowane innymi. W HTML5 nadal pozostają w użyciu przy tworzeniu formularzy. Zasadniczo masz do dyspozycji elementy form, fieldset (fieldset jest elementem grupującym powiązane pola formularza) oraz zwykłe elementy formularzy, co daje Ci możliwość stosowania kontrolek formularzy pokazanych na rysunku 5.1.
108
Rozdział 5. Formularze internetowe HTML5
Rysunek 5.1. Kontrolki formularzy przed HTML5
Listing 5.1 pokazuje HTML wyświetlający rysunek 5.1. Zauważ, że do sformatowania tego formularza zostały użyte lista nieuporządkowana (ul) i elementy listy (li). Nie jest to jedyny sposób organizacji formularza, ale dzięki niemu nie musisz niepotrzebnie używać w tym kodzie
. Listing 5.1. Strona zawierająca różne składniki formularzy
Legenda elementu fieldset — podpis/tytuł tego zbioru pól - Zwykłe pole wejściowe
- Jestem przyciskiem ´wyboru
- Jestem przyciskiem opcji
- Prześlij plik
- Hasło
- Pole tekstowe To jest ´pole tekstowe
- Wybór
Opcja 1 Opcja 2 Opcja 3 Opcja 4
Tworzenie formularza do danych kontaktowych
109
Istnieje kilka nowych typów wejściowych w HTML5, które są użyteczne przy tworzeniu albo modyfikacji starych formularzy. Ułatwią Ci one jako programiście pracę, lecz pomogą również użytkownikowi wprowadzać poprawne dane.
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie formularza do danych kontaktowych Na listingu 5.2 użyliśmy trzech spośród nowych typów wejściowych do gromadzenia danych kontaktowych użytkownika: email, tel i url. Spójrz na kod. Typy wejściowe są zaznaczone pogrubioną czcionką i są omówione dalej w kolejnych podpunktach. Listing 5.2. Formularz kontaktowy z nowymi elementami formularzy HTML5
Dane kontaktowe - E-mail
- Numer telefonu
- Witryna
input type="email" Typ wejściowy email mówi przeglądarce, że treść tego pola powinna wyglądać jak adres e-mail. Na listingu 5.3 przy polu wejściowym email umieściliśmy atrybut required. Poinformuje on kompatybilne przeglądarki, by sprawdziły treść tego pola przed wysłaniem formularza. To, czy adres e-mail rzeczywiście istnieje, nie jest sprawdzane. Listing 5.3. Typ wejściowy email
E-mail
110
Rozdział 5. Formularze internetowe HTML5
Tabela 5.1. Obsługa typu wejściowego email w przeglądarkach i urządzeniach Android
2.3+*
Chrome
10.0+
Firefox
4.0+
Internet Explorer
9.0+*
iOS Safari
4.0+*
Opera
10.0+
Safari
5.0+*
* brak walidacji
Coraz szybszy rozwój przeglądarek, których producenci nieustannie starają się wyprzedzić konkurencję, sprawił, że pomiędzy nimi istnieją różnice w sposobie obsługiwania walidacji. Testy przedstawione w tabeli 5.2 pokazują różnice w sposobie obsługi formularzy, ich walidacji i informacji zwrotnych. Wcześniejsze wersje zwracają komunikaty walidacji inne od tych pokazanych w testach.
Uwaga Być może zastanawiasz się, czy możesz nadawać style informacjom zwrotnym pokazywanym przez formularz. Cóż, w pewnym sensie możesz. Służący do tego CSS omówimy w dalszej części rozdziału. Tabela 5.2. Testy walidacji typu wejściowego email Firefox 11.0: czy formularz został wysłany?
Odpowiedź Opery 11.62
Opera 11.62: czy formularz został wysłany?
Odpowiedź Chrome 18
Chrome 18: czy formularz został wysłany?
Wprowadzone dane
Odpowiedź Firefoksa 11.0
puste pole
„Proszę wypełnić to pole.”
Nie
„To pole jest wymagane”
Nie
„Wypełnij to pole.”
Nie
test
„Proszę wprowadzić adres e-mail.”
Nie
„Wpisz prawidłowy adres e-mail”
Nie
„Wprowadź adres e-mail.”
Nie
[email protected]
Nie ma błędu
Tak
Nie ma błędu
Tak
Nie ma błędu
Tak
test@test
Nie ma błędu
Tak
Nie ma błędu
Tak
Nie ma błędu
Tak
input type="tel" Podobnie jak w przypadku nowego typu wejściowego do wyszukiwania, typ wejściowy tel jest wyświetlany jak zwykłe pole tekstowe (patrz rysunek 5.2). W tym polu akceptowane są dowolne znaki, nie tylko liczby, ponieważ numery telefonów mogą mieć znaki nienumeryczne, takie jak + lub (. Jeśli chcesz, by pole akceptowało tylko liczby, możesz użyć atrybutu pattern, który jest opisany w dalszej części rozdziału.
Rysunek 5.2. Element input type="tel" w Operze. Wygląda jak zwykłe pole tekstowe
Tworzenie formularza do danych kontaktowych
111
Tabela 5.3. Obsługa typu wejściowego tel w przeglądarkach i urządzeniach Android
2.3+*
Chrome
10.0+
Firefox
4.0+
Internet Explorer
9.0+*
iOS Safari
4.0+*
Opera
10.0+
Safari
5.0+*
* brak walidacji
input type="url" Częstym wymaganiem w formularzach internetowych, takich jak formularz komentarzy do bloga, jest podanie przez użytkownika adresu URL jego własnej strony internetowej. Pytanie o adres URL w HTML5 jest łatwe i przyjemne, jak pokazuje listing 5.4. Listing 5.4. Typ wejściowy url Witryna
Tabela 5.4. Obsługa typu wejściowego url w przeglądarkach i urządzeniach Android
2.3+*
Chrome
10.0+
Firefox
4.0+
Internet Explorer
9.0+*
iOS Safari
4.0+*
Opera
10.0+
Safari
5.0+*
* brak walidacji
Treść typu wejściowego url powinna być prawidłowym URL-em. Znowu, podobnie jak w przypadku typu email, to, czy adres rzeczywiście istnieje, nie jest sprawdzane (można to zrobić za pomocą dodatkowego kodu skryptowego). Tradycyjnym URL-em będzie adres strony internetowej, taki jak http://mojawitryna.com. Firefox 10 nie akceptuje mojawitryna.com ani www.mojawitryna.com; wymaga adresu zawierającego http://. Jednak Opera 11 automatycznie zamienia mojawitryna.com na prawidłowy adres http://mojawitryna.com, który pozwala wysłać formularz. W większości przypadków zawartością tego pola będzie http://mojawitryna.com; jednak zaakceptuje ono również inne rodzaje adresów URL: ftp://użytkownik:hasło@serwer, javascript:window.alert (należy z tym uważać; możesz napisać swoją własną walidację,
aby nie dopuścić do przesyłania JavaScriptu),
112
Rozdział 5. Formularze internetowe HTML5
file://serwer/ścieżka, tel:12345.
Ze względu na te dodatkowe typy adresów URL w chwili obecnej formularz przeszedłby walidację z zawartością hello:world. Jest tak dlatego, że większość przeglądarek ma swoje własne typy adresów URL, jak na przykład Firefox, który ma about:config. A zatem obecnie wszystko, co zawiera dwukropek w URL-u, przejdzie walidację. W przyszłości, gdy walidacja w przeglądarkach zostanie udoskonalona, może się to zmienić.
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie formularza wyszukiwania przy użyciu input type="search" Typ wejściowy search powinien być wypełniony frazą do wyszukania. Wygląda jak zwykłe pole tekstowe, ponieważ w istocie jest to po prostu normalne pole tekstowe. Nie ma w nim naprawdę nic szczególnego, ale pozwala przeglądarkom rozpoznawać, że jest to pole wyszukiwania. Listing 5.5 pokazuje, w jaki sposób używać go w kontrolce wyszukiwania. Listing 5.5. Typ wejściowy search
Wyszukiwana fraza
Tabela 5.5. Obsługa typu wejściowego search w przeglądarkach i urządzeniach Android
2.3+
Chrome
10.0+
Firefox
4.0+
Internet Explorer
9.0+
iOS Safari
4.0+
Opera
10.0+
Safari
5.0+
Ciekawym dodatkiem w przeglądarkach opartych na silniku WebKit (takich jak Safari i Chrome) jest atrybut results, który daje dodatkową funkcjonalność: Wyszukiwana fraza
Powyższy kod powoduje pokazanie pola wyszukiwania zaprezentowanego na rysunku 5.3. Zwróć uwagę na ikonę lupy dodaną do pola wejściowego, która wyświetli poprzednio wyszukiwane frazy (jeśli takie istnieją). Niestety, nie można jeszcze nadawać stylów takim podpowiedziom za pomocą CSS-a lub JavaScriptu.
Tworzenie kontrolek kalendarza i czasu
113
Rysunek 5.3. Element input type="search" z informacjami i szczegółami specyficznymi dla przeglądarki opartej na silniku WebKit
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie kontrolek kalendarza i czasu Problemem, z którym twórcy stron internetowych mają często do czynienia, jest stworzenie widżetu kalendarza pozwalającego użytkownikom wybierać datę, tak aby nie musieli jej wprowadzać samodzielnie. Tworzenie widżetu zawsze wymagało JavaScriptu, ale teraz się to zmienia. W tym przepisie poznasz różnego rodzaju nowe typy pól wejściowych, które tworzą różne kontrolki kalendarza, a dla przeglądarek, które nie udostępniają widżetu kalendarza (spójrz do rozdziału 3.), istnieje kilka rozwiązań awaryjnych. Tabela 5.6. Obsługa typu wejściowego datetime w przeglądarkach i urządzeniach Android
*
Chrome
*
Firefox
*
Internet Explorer
*
iOS Safari
5.0+
Opera
10.0+
Safari
*
* brak widżetu kalendarza, ale zamiast niego pojawia się awaryjnie pole tekstowe
input type="datetime" Nowy typ wejściowy datetime z pewnością będzie dla wielu ulubionym. Jeszcze nie wiadomo, co kilku głównych producentów przeglądarek zdecyduje się z nim zrobić, ale Opera natywnie generuje znakomity kalendarz będący widżetem wyboru daty, pokazany na rysunku 5.4. Wcześniej musiałeś użyć JavaScriptu, aby udostępnić tak złożoną kontrolkę. Ponieważ teraz przeglądarki mogą coś takiego obsługiwać, możliwa stała się integracja z innymi usługami, takimi jak kalendarz wydarzeń Facebooka albo kalendarz programu Outlook. Ponadto, ponieważ to przeglądarka obsługuje kalendarz, jeśli system użytkownika jest skonfigurowany w innym języku, wyświetli go w nim (na przykład Novembre po włosku), w przeciwieństwie choćby do widżetu kalendarza jQuery (http://docs.jquery.com/UI/Datepicker).
input type="datetime-local" Niemal identyczny z poprzednim polem wejściowym datetime, typ datetime-local również generuje kalendarz, z tą drobną różnicą, że nie ma etykiety „UTC” po prawej stronie, więc nie jest z nim związana strefa czasowa (patrz rysunek 5.5).
114
Rozdział 5. Formularze internetowe HTML5
Rysunek 5.4. Element input type="datetime" w Operze 11 zapewnia użytkownikowi widżet wyboru daty z kalendarza
Rysunek 5.5. Element input type="datetime-local" wyświetlony w Operze 11
input type="date" Na rysunku 5.6 widać, że typ wejściowy date jest podobny do typu wejściowego datetime pokazanego na rysunku 5.4, ale tutaj kontrolka nie wyświetla pola czasu.
Rysunek 5.6. Element input type="date" wyświetlony w Operze 11
input type="time" Typ wejściowy time pozwala użytkownikowi wprowadzić czas w formacie 24-godzinnym. Obecnie tylko Opera obsługuje ten element. Rysunek 5.7 pokazuje, jak typ wejściowy time wygląda w Operze.
Rysunek 5.7. Element input type="time" wyświetlony w Operze 11
Użytkownik może albo wpisać cyfry, na przykład 22:11, albo użyć przycisków do przewijania czasu dostępnych w Operze.
Tworzenie kontrolek kalendarza i czasu
115
input type="month" Typ wejściowy month wyświetla kalendarz przedstawiony na rysunku 5.4, ale pozwala wybierać jedynie miesiące. Wartością typu wejściowego jest wtedy RRRR-MM. Na rysunku 5.8 można w polu miesiąca wybrać inny miesiąc niż grudzień; można również przejść do poprzedniego lub następnego miesiąca.
Rysunek 5.8. Element input type="month" wyświetlony w Operze 11
input type="week" Bardzo podobny do typów wejściowych date i month, week pozwala użytkownikowi wybrać tylko któryś tydzień w roku. Wartością typu wejściowego jest RRRR-W00. Na rysunku 5.9 można wybrać tydzień, a w lewej kolumnie udostępniony jest numer tygodnia.
Rysunek 5.9. Element input type="week" wyświetlony w Operze 11
Nakładanie ograniczeń na daty i godziny Istnieją dwa nowe atrybuty, min i max, o których opowiemy w dalszej części rozdziału. Mogą one być wykorzystane do kontroli i ograniczania dat lub czasów w widżetach. W przypadku daty, jeśli chcesz mieć pewność, że użytkownik nie będzie mógł wybrać daty z przeszłości, możesz dodać wartość atrybutu min w następującym formacie: RRRR-MM-DD. Tak samo jest w przypadku wartości atrybutu max, który uniemożliwia użytkownikom wybieranie daty ze zbyt odległej przyszłości. W przypadku typu wejściowego time format miałby postać HH:MM.
116
Rozdział 5. Formularze internetowe HTML5
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie pola do wprowadzania liczby Typ wejściowy number jest używany do wprowadzania liczb. Akceptuje tylko liczby; w przypadku innych znaków zwraca błąd walidacji. Dopuszcza atrybuty min, max i step, dzięki czemu możesz ograniczyć zakres liczb do takich, które odpowiadają Twoim potrzebom. Atrybut step pozwala określić wartości przyrostu, które mogą być wprowadzone. Tabela 5.7. Obsługa pola wprowadzania liczby w przeglądarkach i urządzeniach Android
*
Chrome
11.0+
Firefox
*
Internet Explorer
*
iOS Safari
*
Opera
10.0+
Safari
5.1
* brak pola do wprowadzania liczby, ale zamiast niego pojawia się awaryjnie pole tekstowe
Wyświetlając kod z listingu 5.6, Opera tworzy kontrolkę, która pozwala użytkownikowi przełączać się między liczbami (patrz rysunek 5.10). Liczba może być ujemna, a jeśli nie podasz maksimum lub minimum, może być dowolnie duża. Przy użyciu atrybutu step możesz precyzyjniej określić wymagania. Na rysunku 5.10 użytkownik może wybierać kolejne liczby od 0 do 10 (min i max) co 0,5. A zatem może wybrać 0; 0,5; 1; 1,5 i tak dalej. Użytkownik może albo użyć udostępnionych kontrolek, albo wprowadzić liczbę z klawiatury. Listing 5.6. Typ wejściowy number z określoną wartością kroku
Rysunek 5.10. Element input type="number" wyświetlony w Operze 11
Ponieważ określiłeś zakres kroku, wszystkie wartości spoza zakresu spowodują błędy walidacji, więc wpisanie liczby 9,99, jak na rysunku 5.11, jest niedozwolone.
Rysunek 5.11. Element input type="number" z nieprawidłową liczbą (w tym przykładzie dozwolone są tylko liczby całkowite lub mające wartość pięciu dziesiątych po przecinku)
Tworzenie próbnika kolorów
117
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie suwaka (bez potrzeby użycia JavaScriptu) Typ wejściowy range generuje kontrolkę suwaka. Nie posiada obszaru do wpisywania tekstu przez użytkownika i, tak jak typ wejściowy number, może korzystać z atrybutów min, max i step. Tabela 5.8. Obsługa suwaka w przeglądarkach i urządzeniach Android
*
Chrome
10
Firefox
*
Internet Explorer
*
iOS Safari
5.0+
Opera
10.0+
Safari
5.0+
* brak suwaka, ale zamiast niego pojawia się awaryjnie pole tekstowe
Możliwym zastosowaniem typu wejściowego range może być sekcja strony lub formularza w rodzaju „oceń moje coś tam” albo sterowanie głośnością odtwarzacza wideo lub audio. Na listingu 5.7 pokazaliśmy jedynie HTML potrzebny do utworzenia prostej kontrolki range, a w jednym z kolejnych rozdziałów dowiesz się, jak zrobić z niej działającą regulację głośności. Listing 5.7. Typ wejściowy range Głośność
Mamy ograniczoną kontrolę nad tym, jak wygląda suwak, ponieważ obecnie wygląd kontrolek zależy od przeglądarki. Możesz jednak określić wysokość i szerokość kontrolki zakresu. Jeśli ustawisz wysokość, która jest większa niż szerokość, regulacja głośności wyświetli się pionowo zamiast domyślnego układu poziomego. W chwili pisania tej książki ten typ wejściowy obsługują Opera, Chrome i Safari, co ilustruje rysunek 5.12. Główną różnicą jest to, że Opera domyślnie pokazuje podziałkę.
Rysunek 5.12. input type="range" w Operze 11 (po lewej) i Chrome 18 (po prawej)
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie próbnika kolorów Jak pokazuje rysunek 5.13, daje użytkownikowi możliwość wyboru podstawowych kolorów i pozwala na wprowadzenie wartości szesnastkowej (#12ff00) albo użycie próbnika kolorów podobnego do takiego, jaki jest wykorzystywany w wielu pakietach oprogramowania. Jedyną przeglądarką
118
Rozdział 5. Formularze internetowe HTML5
Rysunek 5.13. input type="color" w Operze 11
desktopową, która obecnie obsługuje ten przydatny typ wejściowy, jest Opera 11 (choć nowe przeglądarki BlackBerry również obsługują próbnik kolorów). Tabela 5.9. Obsługa próbnika kolorów w przeglądarkach i urządzeniach Android
*
Chrome
*
Firefox
*
Internet Explorer
*
iOS Safari
*
Opera
10.0+
Safari
*
* brak próbnika kolorów, ale zamiast niego pojawia się awaryjnie pole tekstowe
PRZEPIS DLA POCZĄTKUJĄCYCH Wyświetlanie wyników za pomocą elementu output Element output wykorzystuje JavaScript do wyświetlania wyników, zazwyczaj obliczeń lub skryptu. Może wyświetlić wynik w kalkulatorze lub umieścić na stronie jakąś dodatkową funkcjonalność, taką jak wyświetlenie imienia użytkownika. Jeśli nie musisz umieszczać w nim żadnych dodatkowych treści, może być znacznikiem zamkniętym; masz więc wybór pomiędzy albo .
Użycie tekstu zastępczego formularza
119
Tabela 5.10. Obsługa elementu output w przeglądarkach i urządzeniach Android
-
Chrome
10.0
Firefox
4.0
Internet Explorer
-
iOS Safari
4.0
Opera
10.0+
Safari
5.0
W przykładzie pokazanym na rysunku 5.14 podajemy wartości typu wejściowego range w trakcie przesuwania suwaka. Wartość domyślna jest pusta, ale gdy użytkownik przesuwa suwak, wartość elementu output zmienia się i jest pokazywana użytkownikowi w czasie rzeczywistym. Listing 5.8 przedstawia kod tego przykładu. Listing 5.8. Element output
Głośność
Rysunek 5.14. Element output użyty do wyświetlenia wartości typu wejściowego range w Operze 11
PRZEPIS DLA POCZĄTKUJĄCYCH Użycie tekstu zastępczego formularza Jak już się zorientowałeś, w HTML5 istnieje wiele nowych typów wejściowych, ale również mnóstwo nowych atrybutów, których możesz używać razem z nowymi typami wejściowymi, by poprawić swoje formularze. Tekst zastępczy to tekst wyświetlany wewnątrz pola tekstowego po załadowaniu formularza. Gdy użytkownik kliknie w polu lub przejdzie do niego za pomocą klawisza tabulacji, tekst znika. Zazwyczaj daje on wskazówkę dotyczącą tego, co wpisać w polu, albo sugeruje format tego, co powinno być wpisane. Przykładem może być formularz wyszukiwania z tekstem „Wyszukaj na stronie” albo, jak widziałeś w przypadku typu wejściowego url, podpowiedź, która sugeruje użytkownikowi rozpocząć URL od http:// (rysunek 5.15).
Rysunek 5.15. Atrybut placeholder w Safari przed aktywacją pola i po niej
Wcześniej uzyskanie takiego efektu wymagało użycia JavaScriptu, lecz teraz możesz pozwolić przeglądarce, by zrobiła to za Ciebie.
120
Rozdział 5. Formularze internetowe HTML5
Tekst zastępczy może być słabo widoczny, ponieważ obecnie kolor tekstu jest domyślnie jasnoszary, co nie daje wystarczającego kontrastu z domyślnym kolorem tła. Możesz zmienić kolor tekstu w Mozilli i przeglądarkach opartych na silniku WebKit za pomocą następujących reguł CSS: input::-webkit-input-placeholder {color: red;} input:-moz-placeholder {color: red;}
Tabela 5.11. Obsługa atrybutu placeholder w przeglądarkach i urządzeniach Android
2.2
Chrome
9.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
4.0+
Opera
10.0+
Safari
4.0+
PRZEPIS DLA POCZĄTKUJĄCYCH Autouzupełnianie za pomocą atrybutu list i elementu datalist Element datalist jest w HTML5 nowością. W połączeniu z atrybutem list jest on wykorzystywany w celu udostępnienia predefiniowanej listy opcji (patrz rysunek 5.16), co powoduje, że proces tworzenia listy przypomina samouzupełniający się formularz. Użytkownicy nie muszą wybierać predefiniowanych opcji; jeśli chcą, mogą wpisać swoją własną odpowiedź.
Rysunek 5.16. Element datalist użyty do uzyskania listy rozwijanej z uzupełnieniami Tabela 5.12. Obsługa elementu datalist w przeglądarkach i urządzeniach Android
*
Chrome
*
Firefox
4.0+
Internet Explorer
*
iOS Safari
*
Opera
10.0+
Safari
*
* brak listy rozwijanej, ale zamiast niej pojawia się awaryjnie pole tekstowe
Śledzenie postępu wykonania zadania za pomocą elementu progress
121
Kod elementu datalist (pokazany na listingu 5.9) jest podobny do kodu dla elementu select. Jednak w przypadku elementu select użytkownik nie może wpisać swojej własnej wartości. Z datalist nie ma takiego problemu. Wykorzystując atrybut list, powiązujesz z elementem datalist zwykły element input (może to być również typ url, email, search albo tel). Listing 5.9. Przykład użycia datalist Jaki jest Twój ulubiony sport?
W powyższym przykładzie mamy cztery opcje samouzupełniania. Jedynie Firefox i Opera pokazują obecnie opcje autouzupełniania, ale robią to nieco inaczej: Firefox pokazuje tylko opcje, które są podobne do tego, co zostało wpisane, natomiast Opera pokazuje całą listę, gdy pole jest aktywne. Element datalist mógłby być generowany z bazy danych lub wywołania AJAX (podobnie do funkcji autouzupełniania wyszukiwarki Google) i dostarczać użytkownikowi, powiedzmy, 10 najbardziej popularnych odpowiedzi na pytanie. Piękno tego nowego elementu i atrybutu polega na tym, że jeśli użytkownik korzysta z przeglądarki, która nie wyświetla tego elementu HTML5, nie posiada JavaScriptu albo wystąpił problem z połączeniem ajaksowym, kontrolki formularza wyświetlają się jak zwykłe pole tekstowe, a użytkownik może normalnie wpisywać tekst.
PRZEPIS DLA POCZĄTKUJĄCYCH Śledzenie postępu wykonania zadania za pomocą elementu progress Nowy element progress służy do śledzenia statusu i stopnia wykonania zadania. Może być używany do wyświetlania postępu pobierania danych, na przykład pliku lub ładowania danych z wywołania AJAX. Element progress ma dwa opcjonalne atrybuty: value — atrybut value wskazuje, jak duża część zadania została ukończona; max — atrybut max reprezentuje wartość oznaczającą całkowite wykonanie tego zadania. Zarówno
zawartość atrybutu value, jak i max powinna być wyświetlana wewnątrz elementu progress, tak aby użytkownik miał informację zwrotną dotyczącą stanu zaawansowania wykonania zadania. Następujący kod wyświetli element progress w przeglądarce Chrome (rysunek 5.17). Pasek postępu jest podświetlony, dzięki czemu lepiej się prezentuje. Pobierasz bardzo ważny plik, proszę czekać.
ukończono 45%
W przeglądarkach, które nie obsługują elementu progress, uzyskasz rezultat pokazany na rysunku 5.18 (zrzut ekranu z IE9).
122
Rozdział 5. Formularze internetowe HTML5
Rysunek 5.17. Element progress w przeglądarce Chrome
Rysunek 5.18. Awaryjne wyświetlanie w przeglądarkach nieobsługujących elementu progress
Chodzi tu o to, że zielony (lub niebieski — w zależności od systemu operacyjnego i wersji przeglądarki) pasek lub opis tekstowy powinny być aktualizowane na bieżąco, tak aby użytkownik wiedział, jaka część pracy została ukończona, a jaka pozostaje do wykonania. Tabela 5.13. Obsługa elementu progress w przeglądarkach i urządzeniach Android
*
Chrome
13+
Firefox
9.0+
Internet Explorer
*
iOS Safari
*
Opera
11.0+
Safari
*
* brak stylizowanego paska, ale zamiast niego pojawia się awaryjnie tekst
PRZEPIS DLA POCZĄTKUJĄCYCH Wskazywanie wyniku pomiaru za pomocą elementu meter Element meter jest używany do wyświetlania pomiaru, takiego jak temperatura, albo wartości ułamkowej. Ma on sześć możliwych do użycia atrybutów: min — minimalna dozwolona wartość. Jeśli nie ma atrybutu min, wartością jest zero. Jeśli chcesz, możesz używać liczb ujemnych. max — maksymalna dozwolona wartość. value — rzeczywista wartość, która musi być wpisana w przypadku użycia elementu meter. low — dolna część zakresu wartości. high — górna część zakresu wartości. optimum — wartość optymalna. Ta wartość musi się mieścić między min i max. Może być jednak większa niż wartość atrybutu high. Oto kilka prostych przykładów: Twoja punktacja: 2 z 10
Twoja punktacja: bardzo ´dobrze
Przechodzenie do elementu form po załadowaniu strony
123
Element meter (pokazany na rysunku 5.19) może być także użyty do wskazania ilości miejsca na dysku twardym: Używasz dokładnie 50% pojemności Twojego twardego dysku
Rysunek 5.19. Element meter w przeglądarce Chrome Tabela 5.14. Obsługa elementu meter w przeglądarkach i urządzeniach Android
*
Chrome
13+
Firefox
*
Internet Explorer
*
iOS Safari
*
Opera
11.0+
Safari
*
* brak stylizowanego paska, ale zamiast niego pojawia się awaryjnie tekst
PRZEPIS DLA POCZĄTKUJĄCYCH Przechodzenie do elementu form po załadowaniu strony Atrybut autofocus daje szansę uaktywnienia klawiatury na kontrolce formularza po załadowaniu strony. Jeśli byłaby ona uaktywniona na elemencie input albo textarea, użytkownik mógłby rozpocząć pisanie, kiedy tylko strona zostałaby załadowana. Jeśli pole, na którym klawiatura zostanie automatycznie uaktywniona, posiada tekst zastępczy, nie będzie on widoczny, ponieważ w polu będzie się znajdował kursor tekstowy. Dawniej do wykonania tego zadania trzeba było użyć JavaScriptu. Atrybut autofocus jest atrybutem logicznym, więc albo jest włączony, albo wyłączony. Rysunek 5.20 pokazuje przykład.
Rysunek 5 20. Atrybut autofocus użyty na polu tekstowym w przeglądarce Safari Tabela 5.15. Obsługa atrybutu autofocus w przeglądarkach i urządzeniach Android
-
Chrome
9.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
-
Opera
10.0+
Safari
5.0+
124
Rozdział 5. Formularze internetowe HTML5
Atrybut autofocus należy stosować ostrożnie. Automatyczne przeskakiwanie lub przewijanie strony do jakiegoś miejsca nie jest najlepszą praktyką przy projektowaniu stron, ponieważ użytkownicy wykorzystujący urządzenia przenośne, czytniki ekranu albo mający niską rozdzielczość ekranu nie zobaczą być może istotnych treści powyżej tego miejsca. Zaleca się, aby autofocus był używany na stronach, w których element formularza stanowi główną treść, takich jak strona kontaktowa albo, co pokazano na rysunku 5.20, strona wyszukiwarki (jak formularz na Google.com, który posiada autofocus, lecz wykonany za pomocą JavaScriptu). Listing 5.10 pokazuje kod użyty do utworzenia rysunku 5.20. Listing 5.10. Atrybut autofocus na typie wejściowym search Przeszukaj witrynę
Uwaga Atrybut autofocus powinien być użyty na stronie tylko raz. Co ciekawe, jeśli masz kilka pól na stronie, wszystkie z atrybutem autofocus, Opera, Chrome i Safari umieszczają kursor w ostatnim polu, a Firefox w pierwszym.
PRZEPIS DLA POCZĄTKUJĄCYCH Zezwalanie na wiele wartości Atrybut multiple pozwala użytkownikom wprowadzić więcej niż jedną wartość w danym polu. Można go stosować w przypadku każdego rodzaju elementu input, więc może być użyty do utworzenia formularza „Wyślij do przyjaciela” albo aplikacji e-mail pozwalającej użytkownikowi na wprowadzenie wielu adresów e-mail w polach Do, DW i UDW. Tabela 5.16. Obsługa atrybutu multiple w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
5.0+
Kolejnym przykładem może być przesyłanie wielu plików. Dawniej wymagałoby to JavaScriptu lub kodu po stronie serwera, wykrywającego, że plik został wybrany, a następnie wyświetlającego kolejną pozycję pozwalającą wysłać plik. Teraz, przy użyciu kodu z listingu 5.11, możesz to zrobić w HTML5. Listing 5.11. Zezwalanie na przesyłanie wielu plików Prześlij pliki
Prosta walidacja przy użyciu atrybutu required
125
Firefox, Opera, Safari i Chrome obsługują już ten nowy atrybut. Safari i Chrome wyświetlają liczbę wybranych plików. W przykładzie pokazanym na rysunku 5.21 zostały wybrane trzy pliki. Firefox nie wyświetla automatycznie, ile plików zostało wybranych; zamiast tego pokazuje pełne ścieżki plików wewnątrz pola tekstowego, rozdzielając je przecinkami, na przykład: „C:\plik1.doc, C:\plik2.pdf”. Opera również pokazuje pełne ścieżki, przy czym umieszcza każdą z nich w cudzysłowach i rozdziela je średnikami.
Rysunek 5 21. Atrybut multiple użyty na polu input typu file
PRZEPIS DLA POCZĄTKUJĄCYCH Prosta walidacja przy użyciu atrybutu required Atrybut required jest wykorzystywany w wielu przykładach w tym rozdziale. Jeśli atrybut został użyty, przeglądarka nie będzie próbowała wysyłać formularza, kiedy wymagane pola będą puste. W przeglądarkach, które obsługują ten atrybut, jeśli wymagane pola są puste, wyświetli się komunikat błędu, jak pokazano na rysunku 5.22.
Rysunek 5 22. Komunikat błędu dotyczący niewypełnionego wymaganego pola w Operze 11 Tabela 5.17. Obsługa atrybutu required w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
5.0+
Wskazówka Oprócz atrybutu required możesz również dodać aria-required="true", co przyczyni się do poprawy dostępności elementów formularza. Może zainteresuje Cię informacja, że WordPress robi tak domyślnie w formularzach komentarzy.
126
Rozdział 5. Formularze internetowe HTML5
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Pisanie własnych reguł walidacji Mimo że HTML5 ma wbudowaną walidację, możesz ustanowić własne reguły, wykorzystując atrybut pattern i wyrażenia regularne. Tabela 5.18. Obsługa atrybutu pattern w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
-
Widziałeś na przykład, że typ wejściowy url akceptuje różne rodzaje adresów URL. Możesz temu zapobiec i zmusić użytkownika do wpisania adresu rozpoczynającego się od http://. Możesz to zrobić za pomocą własnego wyrażenia regularnego. Wyrażenie regularne wykorzystane na listingu 5.12 waliduje tylko adresy URL zaczynające się od http:// albo https://. Akceptuje również subdomeny i łańcuchy zapytań, więc http://ty.witryna.pl/search.aspx?=test jest prawidłową zawartością, ale mailto:adres nie jest. Listing 5.12. Atrybut pattern z wyrażeniem regularnym
Wyrażenia regularne mogą być zawiłe i szybko się komplikują, więc najlepiej, jeśli będziesz stosować jak najprostsze wyrażenia. A jeśli utknąłeś na jakimś problemie, skorzystaj z niezliczonych podpowiedzi zamieszczanych w internecie.
PRZEPIS DLA POCZĄTKUJĄCYCH Nakładanie ograniczeń na wprowadzane dane Wpisy w formularzu HTML5 mogą być ograniczane, jeśli jest taka potrzeba, poprzez różne atrybuty.
step Atrybut step może być stosowany w przypadku typów wejściowych number, range i time. Określa on przyrosty wartości liczb, które dany element input może przyjąć. Spójrz dla przykładu na znajdujący się wcześniej w tym rozdziale listing 5.6 (dotyczący typu wejściowego number).
Nakładanie ograniczeń na wprowadzane dane
127
Tabela 5.19. Obsługa atrybutu step w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
-
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
5.1
min i max Użyte na elemencie meter i na typach wejściowych number oraz range atrybuty min i max ustalają dozwolony zakres wartości elementu. Nie są to wymagane atrybuty i możesz użyć albo min, albo max, albo ich obu. Ustalają one reguły walidacji i jeśli wartość elementu nie będzie się mieścić w zakresie od min do max, formularz nie zostanie wysłany. Mogą być użyte na typach wejściowych date i time do nałożenia ograniczenia na wartość wybieraną przez użytkownika, na przykład w przypadku kalendarza wydarzeń lub wyszukiwania pomiędzy datami. Tabela 5.20. Obsługa atrybutów min i max w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
-
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
5.1
formnovalidate i novalidate Jeśli masz formularz, przy którym nie chcesz korzystać z walidacji dokonywanej przez przeglądarkę, możesz użyć atrybutu formnovalidate albo novalidate. Użycie jednego z nich jest szczególnie przydatne, jeśli chcesz zapisać aktualny stan formularza, zamiast wysyłać go, kiedy jest na przykład duży lub jeśli na obecnym etapie procesu nie jesteś zainteresowany walidowaniem danych, ponieważ użytkownik ma inne etapy do dokończenia przed ostatecznym wysłaniem danych. Tabela 5 21. Obsługa atrybutów formnovalidate i novalidate w przeglądarkach i urządzeniach Android
-
Chrome
10.0+
Firefox
5.0+
Internet Explorer
-
iOS Safari
-
Opera
11.0+
Safari
-
128
Rozdział 5. Formularze internetowe HTML5
Możesz umieścić novalidate w elemencie formularza, dzięki czemu w momencie wysyłania go wszelkie nieprawidłowe formaty lub puste pola zostaną zignorowane:
Możesz również umieścić atrybut formnovalidate w każdym poszczególnym elemencie formularza. Na przykład mógłbyś umieścić go przy typie wejściowym url, a przeglądarka będzie ignorować walidację tego elementu (choć wątpliwe jest, żebyś chciał podjąć wysiłek używania typu wejściowego url, a następnie ignorował walidację).
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Dostosowywanie formularza i nadawanie mu stylu Jedną z pierwszych rzeczy, o którą pytają projektanci, jest możliwość nadawania stylu nowym elementom. Cóż, w pewnym sensie można to zrobić. Chociaż nie można zmienić wyglądu pola wyboru daty, ponieważ jest ono generowane przez przeglądarkę (w przyszłości może się to zmienić), możesz nadawać styl pojemnikom elementów input, na przykład krawędziom, czcionkom i kolorowi tła, ponieważ w CSS3 istnieją sposoby, których możesz użyć do nadania polom różnych stylów w zależności od ich stanu. Kod z listingu 5.13 generuje widok z rysunku 5.23; zauważ różne stany pól. Pola początkowo są pomarańczowe i pokazują ikonkę gwiazdki, gdyż są wymagane. Listing 5.13. Nowe możliwości CSS3 dotyczące elementu form
- Tel.:
- Witryna:
- E-mail:
Komunikaty błędów
129
Rysunek 5.23. CSS3 użyty do odwołania się do różnych stanów pól formularza
Gdy pole jest aktywne, ale jest puste lub zawiera nieprawidłową treść, pojemnik jest czerwony i pokazuje ikonkę wskazującą błąd. Jeśli zawartość jest poprawna, przeglądarka zmienia kolor pola na zielony i ikonkę na symbol fajki. A wszystko to bez JavaScriptu! Nie omówimy wszystkich nowych możliwości CSS-a, ale na rysunku 5.23 użyliśmy następujących pseudoklas z CSS3 Basic User Interface Module1 (http://www.w3.org/TR/css3-ui): :valid — element formularza otrzymuje tę klasę, gdy jego zawartość jest zgodna z typem elementu i przeszła walidację. :invalid — jeśli element formularza ma niepoprawną zawartość, stosowana jest ta klasa. :required — do tej klasy będzie przypisany każdy element formularza, który ma ten atrybut.
Komunikaty błędów Mamy nadzieję, że śledziłeś poprzednie przykłady i zauważyłeś, iż komunikaty o błędach są wyświetlane inaczej w Operze i Firefoksie. Opera wyświetla drgający, różowy komunikat o błędzie, podczas gdy Firefox pokazuje spokojniejszy, nieruchomy komunikat. Obecnie nie można zmienić sposobu, w jaki te komunikaty są wyświetlane, ponieważ są generowane przez przeglądarkę. W przyszłości może się to zmienić, ponieważ obecnie ma miejsce dyskusja, czy umożliwić ich edycję za pomocą CSS-a. A zatem chociaż możesz narzekać, że komunikaty o błędach wyglądają okropnie lub nie spełniają firmowych wytycznych odnośnie do wyglądu stron, będą one w danej przeglądarce spójne, co z pewnością oznacza zwycięstwo użyteczności, gdyż użytkownicy oczekują jednego stylu błędów podczas korzystania z wybranej przez siebie przeglądarki. Chociaż nie możesz jeszcze zmienić stylu błędów, możesz zmodyfikować tekst komunikatu błędu przy użyciu JavaScriptu i metody setCustomValidity(). Listing 5.14 zawiera przykład, w którym domyślny komunikat o błędzie zostaje nadpisany, gdy zostaną dodane nieprawidłowe treści. Listing 5.14. Formularz rejestracji w HTML5
E-mail
1
Podstawowy moduł interfejsu użytkownika — przyp. tłum.
130
Rozdział 5. Formularze internetowe HTML5
PRZEPIS DLA ZAAWANSOWANYCH Wszystko razem — tworzenie formularza rejestracyjnego Teraz, kiedy poznałeś wszystkie nowe funkcje formularzy HTML5, wykorzystajmy kilka z nich, dodając odrobinę CSS-a, by zobaczyć, w jaki sposób nowe funkcje umożliwią tworzenie formularza rejestracyjnego. HTML i CSS z listingu 5.15 dają wynik zaprezentowany na rysunku 5.24. Listing 5.15. Solidny formularz rejestracyjny
Duży formularz rejestracyjny
Zapisz się, by otrzymać nasz niezwykły produkt.
Dane osobowe
- Imię i nazwisko
- Data urodzenia
- Witryna
Wszystko razem — tworzenie formularza rejestracyjnego
131
- Praca
- Przybliżone roczne dochody
Dane kontaktowe
- Pierwszy wiersz adresu
- Drugi wiersz adresu
- Kraj
- Tel.
- E-mail
Dostosuj swój profil Wybierz kolor strony
Jak w skali od 1 do 10 podobają Ci się formularze HTML5?
Na rysunku 5.24 użyliśmy typów wejściowych tel, date, url, number, text, email, color i range. W kilku przypadkach został także użyty element datalist, choć mogliśmy alternatywnie wykorzystać element select, ale w tym formularzu chcemy, aby ludzie wpisywali swoje stanowiska lub kraje z klawiatury. Pod koniec formularza został wykorzystany typ wejściowy range i wraz z nim element output. Wszystkie elementy zawierające dane, które musimy uzyskać, mają atrybut required, który uruchomi wbudowany w przeglądarkę mechanizm walidacji. Aby formularz wyglądał trochę ładniej, dodaliśmy kilka nowych selektorów CSS3, dzięki czemu pokazaliśmy stany wymagany, prawidłowy i nieprawidłowy elementów.
132
Rozdział 5. Formularze internetowe HTML5
Rysunek 5.24. Formularz rejestracyjny w Operze 11 utworzony przy użyciu kilku elementów HTML 4, nowych elementów formularzy HTML5 oraz CSS-a
Podsumowanie W tym rozdziale poznałeś wszystkie nowe typy wejściowe i dowiedziałeś się, jak działają w przeglądarkach, jeśli są w pełni obsługiwane. Te nowe typy wejściowe wraz z wbudowaną natywną walidacją i nowymi funkcjami CSS w dobrych przeglądarkach bardzo ułatwiają tworzenie formularzy i przekazywanie użytkownikowi informacji zwrotnych. Chociaż czeka nas jeszcze długa droga, zanim wszystkie przeglądarki nadrobią zaległości, pewnego dnia — im szybciej, tym lepiej — nie będziesz musiał polegać na JavaScripcie, by tworzyć użyteczne funkcje, takie jak kontrolki wyboru daty, suwaki czy walidacja. Wszystkie nowe typy wejściowe, takie jak email, tel i date, działają w przeglądarkach choćby poprzez pokazywanie pola tekstowego, więc nie ma żadnego usprawiedliwienia, by nie zacząć z nich korzystać.
6 Rysowanie na płótnie W
2004 roku firma Apple opracowała na potrzeby aplikacji Dashboard systemu operacyjnego Mac OS X element o nazwie canvas (płótno), przeznaczony do rysowania, który został później zaimplementowany w przeglądarce Safari. Specyfikacja HTML5 wykorzystała ten element i powiązany z nim zestaw interfejsów API, aby zapewnić realizację podstawowych funkcji rysowania — przed wprowadzeniem elementu canvas przeglądarki wymagały do tego celu zastosowania zewnętrznej wtyczki. Ponieważ canvas jest mechanizmem rysowania bazującym na pikselach, a nie wektorach czy warstwach, podstawowa funkcjonalność jest dość prymitywna, ale jak dowiesz się w tym rozdziale, i tak umożliwia tworzenie zaawansowanych obrazów.
Element canvas — informacje ogólne Implementacja płótna opiera się na dwóch filarach: elemencie canvas w HTML-u oraz JavaScripcie umożliwiającym wykonywanie na nim operacji. W przypadku malowania obrazu płótno jest puste, dopóki malarz nie użyje pędzli, narzędzi i innych środków do stworzenia za ich pomocą dzieła sztuki. W JavaScripcie w podobnym celu używane są narzędzia kształtu, efekty oraz przekształcenia — ich wykorzystanie skutkuje uaktualnionym widokiem nowych pikseli na płótnie. Element canvas udostępnia pustą powierzchnię, której możesz użyć do dynamicznego renderowania grafiki, obrazków i tekstu. Funkcjonalność płótna jest ogromna, więc najpierw omówimy podstawy, takie jak rysowanie kształtów, a następnie przejdziemy do niektórych bardziej skomplikowanych efektów i przekształceń. A jeśli podoba Ci się tego typu zabawa, zachęcamy do samodzielnego poszerzania wiedzy, ponieważ w tej książce tak naprawdę zaledwie dotknęliśmy tematu. Przed rozpoczęciem intensywnego użytkowania płótna zajmijmy się jednak podstawami. Tabela 6.1 pokazuje, które wersje najpopularniejszych przeglądarek obsługują element canvas. Tabela 6.1. Dostępność elementu canvas w przeglądarkach Android
2.1+
Chrome
10.0+
Firefox
3.6+
Internet Explorer
9.0+
iOS Safari
3.2+
Opera
10.6+
Safari
3.2+
134
Rozdział 6. Rysowanie na płótnie
Uwaga W przypadku Internet Explorera 8 i starszych wersji będziesz potrzebował zewnętrznej biblioteki. Możesz w tym celu użyć biblioteki explorercanvas (http://code.google.com/p/explorercanvas). Jako że potrzebujesz jej tylko w przypadku IE8, możesz umieścić ją w poleceniu warunkowym:
168
Rozdział 7. Osadzanie wideo w HTML5
Nie musisz wybierać serwisu YouTube jako witryny przechowującej wideo; plik możesz przechowywać samodzielnie, a do jego odtwarzania używać własnego odtwarzacza Flash. Mógłbyś zaprojektować odtwarzacz samodzielnie albo użyć jednego z wielu dostępnych w internecie, takich jak popularny, łatwy do skonfigurowania JW Player, jak pokazano na listingu 7.5. Listing 7.5. Zastępcze wideo niezwiązane z witryną YouTube
Pobierz wideo: plik MP4, 3 MB; plik webM, ´3 MB; plik Ogg, 3 MB
Pobierz napisy: plik VTT, 1 kB; plik ´tekstowy, 1 kB
Inne możliwości formatowania napisów Listingi 7.6 i 7.7 przedstawiały prosty przykład użycia WebVTT, wtyczki jQuery i podstawowego CSS-a do wyświetlania i formatowania napisów. Istnieją alternatywy, które kiedyś będą obsługiwane przez przeglądarki. Przy użyciu wewnętrznych znaczników b, i oraz u możesz dodać do napisów pogrubienie, kursywę albo podkreślenie:
API mediów
175
1 00:00:0,000 --> 00:00:2,000 To jest pierwszy fragment napisów
Możesz również zastosować klasę CSS, gdybyś chciał dołączyć inne formatowanie — na przykład użyć niestandardowej czcionki. Aby to zrobić, należy dodać wewnętrzny znacznik c z jakąś klasą CSS: 1 00:00:0,000 --> 00:00:2,000 To jest pierwszy fragment napisów
Dostępnych jest więcej możliwości, takich jak położenie czy wielkość tekstu. Aby znaleźć więcej informacji na temat tego rozwijającego się standardu, sprawdź witrynę http://www.delphiki.com/webvtt/.
API mediów HTML5 udostępnia rozwinięte i ekscytujące API dla multimediów. Korzystając z tego API i JavaScriptu, możesz wpływać na działanie wideo na stronach internetowych. Poniżej znajduje się lista dostępnych zdarzeń API: abort canplay canplaythrough canshowcurrentframe dataunavailable durationchange emptied empty ended error loadeddata loadedmetadata
loadstart pause play playing progress ratechange seeked seeking suspend timeupdate volumechange waiting
Dostępnych jest również wiele właściwości mediów: audioTracks autoplay buffered controls controller currentSrc currentTime defaultMuted defaultPlaybackRate duration ended error initialTime loop
muted networkState paused preload played playbackRate readyState seekable seeking startOffsetTime src textTracks videoTracks volume
Nie wszystkie z powyższych zdarzeń i właściwości są już dostępne, ale większości, w tym tych istotnych, które pozwalają tworzyć własne kontrolki odtwarzacza wideo, można już używać. Nie będziemy tu wyjaśniać wszystkich możliwości API — ograniczymy się tylko do potrzebnych do utworzenia własnego odtwarzacza;
176
Rozdział 7. Osadzanie wideo w HTML5
jeśli jednak jesteś zainteresowany zdobyciem większej wiedzy na temat tego API, polecamy materiały na stronie http://www.w3.org/2010/05/video/mediaevents.html oraz bardzo szczegółową specyfikację pod adresem http://www.w3.org/TR/html5/media-elements.html#mediaevents.
PRZEPIS DLA ZAAWANSOWANYCH Tworzenie niestandardowych kontrolek HTML5 udostępnia javascriptowe API mediów dla elementów video i audio. Jak pokazano w poprzednim podrozdziale, obejmuje ono wiele metod i zdarzeń, dzięki którym możesz na przykład utworzyć własny odtwarzacz wideo i niestandardowe kontrolki. W tym przepisie bazujemy na kodzie wideo z listingu 7.4, do którego dodajemy przycisk Odtwórz/ Wstrzymaj, pasek postępu, regulację głośności, wyświetlacz czasu oraz przyciski szybkiego przewijania do przodu i do tyłu. Jak wyjaśnimy później, przeglądarki mają swoje dziwactwa, więc efekt zastosowania tego przepisu najlepiej jest oglądać w Operze albo Chrome, jak pokazano na rysunku 7.4.
Rysunek 7.4. Wideo z niestandardowymi kontrolkami oglądane w Operze 11
Podstawową funkcją potrzebną w przypadku własnych kontrolek jest przycisk Odtwórz, ale za pomocą JavaScriptu i API mediów możesz zrobić znacznie więcej, co ilustruje kod z listingu 7.8. 1. Możesz opakować element video elementem i dodać , który będzie zawierał przyciski, suwaki i inne komponenty przydatne do wyświetlenia kontrolek. Uwzględniliśmy ten fragment na początku sekcji body strony z tego przepisu, aby był on bardziej przejrzysty, ale w praktyce powinieneś unikać umieszczania kontrolek w zasadniczym kodzie, a zamiast tego tworzyć je „w locie” za pomocą JavaScriptu, tak by widzieli je tylko użytkownicy z włączonym JavaScriptem. 2. Możesz zadeklarować element video jako obiekt, do którego można się odwoływać, a następnie usunąć domyślne kontrolki przeglądarki przez pozbycie się atrybutu controls umieszczonego na potrzeby użytkowników bez JavaScriptu. Przycisk Odtwórz pozostanie nieaktywny do momentu, kiedy film będzie gotowy do odtwarzania.
Tworzenie niestandardowych kontrolek
3. Dla poprawy wydajności i „międzyprzeglądarkowej” przyjazności możesz zaczekać, aż film będzie gotowy i będziesz mógł pobrać informacje, takie jak jego czas trwania. A kiedy film będzie gotowy do odtworzenia, zostanie aktywowany przycisk Odtwórz. 4. Możesz dodawać funkcje i procedury nasłuchu do przycisków, innych kontrolek i wyświetlaczy. Listing 7.8. Niestandardowe kontrolki wideo
7.8. Niestandardowe kontrolki wideo
Tworzenie niestandardowych kontrolek
181
Odtwórz 0:00
0:00
Głośność: Wycisz
Do tyłu Do przodu Pełny ekran
Na początku kodu umieściliśmy trochę CSS-a dotyczącego pewnych podstawowych stylów i rozmieszczenia przycisków. W tym przykładzie nie przesadzaliśmy z obstylowaniem, ale za pomocą CSS-a i API JavaScriptu mógłbyś stworzyć właściwie każdy układ odtwarzacza wideo, jaki byś tylko chciał. Przejdźmy teraz do JavaScriptu. Najpierw należy powiązać zmienne z niektórymi elementami: samym wideo, paskiem przewijania i przyciskiem Odtwórz. Dla wygody użytkowników bez obsługi JavaScriptu dołączyliśmy do elementu video atrybut controls, który następnie za pomocą JavaScriptu usuwamy, gdyż nie chcemy, żeby domyślne kontrolki były widoczne. W kolejnym fragmencie kodu mamy do czynienia z bardzo istotnym procesem. Zanim będzie można rozpocząć odtwarzanie filmu, przeglądarka musi zdobyć wystarczającą ilość związanych z nim informacji. Niektóre przeglądarki nie potrafią na przykład pozyskać długości filmu, ponieważ nadal pobierają jego części. Zatem w przypadku dużego pliku wideo będziesz być może musiał trochę poczekać, zanim przeglądarka będzie gotowa do jego odtworzenia. W niniejszym przepisie wykrywamy wartość readyState, która może przyjąć jedną z pięciu wartości: have_nothing (0), have_metadata (1), have_current_data (2), have_future_data (3), have_enough_data (4).
Wartość have_nothing oznacza, że przeglądarka nie posiada żadnych informacji na temat filmu. Pozostałe wartości wskazują, że przeglądarka posiada jakieś informacje na jego temat, w tym czas trwania, wysokość i szerokość, aktualną pozycję oraz następną ramkę. W bieżącym przepisie oczekujemy momentu, w którym
182
Rozdział 7. Osadzanie wideo w HTML5
wartość readyState będzie większa od 0; kiedy tak się stanie, czas trwania zostanie zwrócony, a jego wartość na ekranie — zaktualizowana. Aktywowany zostaje również przycisk Odtwórz, dzięki czemu użytkownik może uruchomić film. W niniejszym przepisie, kiedy film jest gotowy, niewiele się już w kodzie dzieje, ale mógłby to być moment, w którym tworzone są kontrolki wideo, pokazywane lub ukrywane ładowanie grafiki, a może nawet wyświetlany film. Alternatywnie mógłbyś użyć obiektu nasłuchującego zdarzenia loadeddata, które nastąpi, gdy przeglądarka będzie miała na tyle dużo informacji na temat filmu, aby umożliwić rozpoczęcie odtwarzania: video.addEventListener("loadeddata", function(){//zrób, co trzeba}, false);
Znasz już teraz czas trwania filmu, więc przy użyciu video.duration możesz uzyskać jego całkowitą długość, którą przypiszesz do paska przewijania input[type="range"], tak aby miał on punkt końcowy. Następnie należy umieścić punkt początkowy suwaka na początku (zero sekund). Niektóre zdarzenia addEventListener są wykorzystywane do wykrycia, czy czas odtwarzania filmu wideo został zaktualizowany (timeupdate), a jeśli tak się stało, aktualizowane są ekran odtwarzania i pasek przewijania. Nawet jeśli usunąłeś domyślne kontrolki wideo i utworzyłeś własne przyciski, także Odtwórz i Wycisz, użytkownik może, w zależności od przeglądarki, uzyskać po kliknięciu wideo prawym przyciskiem myszy dostęp do podstawowych opcji: odtwarzania i zatrzymania, pokazania kontrolek, wyciszenia, zapisu wideo i innych. Tych domyślnych ustawień przeglądarki nie można usunąć ani zmienić, ale odpowiednie zdarzenia można śledzić — w przepisie znajduje się fragment kodu, w którym pobierana jest informacja o rozpoczęciu lub zatrzymaniu odtwarzania, a w odpowiedzi zostaje zmieniony tekst przycisku. Aby zmienić tekst przycisku Odtwórz, warto potwierdzić moment zakończenia filmu — to o tyle przydatna informacja, że wraz z zakończeniem filmu mogłyby mieć miejsce kolejne działania, takie jak rozpoczęcie kolejnego filmu z listy odtwarzania. Zakończenie filmu możesz potwierdzić przez wykrycie przy użyciu obiektu nasłuchującego zdarzenia ended: video.addEventListener("ended", function(){//zrób, co trzeba}, false);
W wywołaniach addEventListener znajdują się różne funkcje używane do wywołania innych funkcji wideo, takich jak sprawdzenie, czy wideo jest odtwarzane, ustawienie głośności (video.volume = volume.value), odtwarzanie wideo w trybie pełnego ekranu (video.webkitEnterFullscreen() — działa tylko w przeglądarkach WebKit) czy sprawdzenie tempa odtwarzania (playbackRate). Została również dodana funkcjonalność odtwarzania, aby użytkownik mógł sterować pozycją i kierunkiem wideo — dzięki paskowi przewijania użytkownik może przejść do dowolnego miejsca na osi czasu (video.currentTime = seekbar.value), dostępne są również przyciski przewijania do przodu i do tyłu. Przeglądarki mają jednak swoje dziwactwa, jeśli chodzi o pracę z niestandardowymi kontrolkami: W chwili pisania tej książki jedynym sposobem, aby wyświetlić film na pełnym ekranie, było użycie
funkcji webkitEnterFullscreen, która działała wyłącznie w przeglądarce Safari. Sądząc po nazwie, nie jest to jeszcze standard odtwarzania filmów na pełnym ekranie i taki standard może się nigdy nie pojawić w specyfikacji. Producenci przeglądarek wiedzą jednak, czego pragną użytkownicy, więc jest bardzo prawdopodobne, że w przyszłości pojawią się pewne niestandardowe rozwiązania właściwe dla poszczególnych przeglądarek. Istnieją także inne sposoby odtwarzania wideo na pełnym ekranie, wykorzystujące kombinację JavaScriptu i CSS-a, a niektóre przeglądarki dodatkowo umożliwiają przejście do trybu pełnoekranowego po kliknięciu prawym przyciskiem myszy samego filmu wideo.
Podsumowanie
183
Pasek przewijania obsługują obecnie tylko Safari, Chrome i Opera, przy
czym tylko w Operze może on posiadać przezroczyste tło — w Chrome prezentuje się raczej brzydko, a w Safari po prostu nie jest widoczny. Firefox i IE9 wyświetlają domyślnie pole tekstowe, w którym jest prezentowany aktualizujący się czas.
Przycisk przewijania do przodu w IE9 nie działa płynnie, a w Firefoksie w ogóle nie działa. Przycisk
przewijania do tyłu nie działa jeszcze w żadnej przeglądarce.
Z powodu powyższych rozbieżności w przeglądarkach — dotyczących zarówno wyświetlania kontrolek, jak i działania API — warto rozważyć użycie innych kontrolek. Na przykład kontrolki wideo widoczne na rysunku 7.5 zostały utworzone przy użyciu suwaka jQuery. Dostępne są także inne odtwarzacze wideo, na przykład na stronach http://sublimevideo.net oraz http://videojs.com.
Rysunek 7.5. Wideo z niestandardowymi kontrolkami jQuery oglądane w Firefoksie 4
Podsumowanie W tym rozdziale przeanalizowałeś różne kwestie związane z elementem video, takie jak jego obsługa w przeglądarkach, ale największy problem dotyczy obsługi kodeków, i to właśnie ten aspekt szczególnie warto śledzić. Oprócz informacji o kodekach zdobyłeś również wiedzę na temat sposobów natywnego odtwarzania filmów wideo we wszystkich aktualnych wersjach najpopularniejszych przeglądarek, bez konieczności korzystania z zewnętrznych wtyczek, takich jak Flash. W przypadku starszych przeglądarek, które nie obsługują elementu video, możesz użyć awaryjnie łącza albo osadzonego pliku Flash. Stworzyłeś również odtwarzacz wideo z napisami, używając najnowszego standardu plików WebVTT, choć jest to raczkujący jeszcze standard, więc należy na bieżąco śledzić wszelkie zmiany i sposoby jego zastosowania. Na koniec omówiliśmy kilka składników API mediów, umożliwiającego tworzenie własnych kontrolek, które możesz formatować za pomocą CSS-a.
184
Rozdział 7. Osadzanie wideo w HTML5
8 Osadzanie dźwięku w HTML5 A
nalogicznie do elementu video, nowy element audio pozwala na osadzenie pliku dźwiękowego na stronie bez potrzeby używania dodatkowych wtyczek, takich jak Flash. W nowoczesnych przeglądarkach internetowych, włącznie z przeglądarkami dostępnymi na wielu urządzeniach przenośnych, dźwięk jest odtwarzany natywnie — nie muszą one już polegać na zewnętrznych wtyczkach. W tym rozdziale omówimy podstawowe zagadnienia związane z elementem audio, a następnie przyjrzymy się sposobom rozwiązywania problemów pojawiających się w różnych przeglądarkach. Następnie poznasz API, dzięki któremu możesz stworzyć swój własny odtwarzacz dźwięku.
PRZEPIS DLA POCZĄTKUJĄCYCH Umieszczanie dźwięku za pomocą elementu audio Prosty przykład umieszczenia dźwięku na stronie przy użyciu nowego elementu audio został przedstawiony na listingu 8.1. Dodany został atrybut controls, bez którego na interfejsie użytkownika nic by się nie wyświetliło. Listing 8.1. Prosty przykład elementu audio
8.1. Prosty przykład audio
Kod jest bardzo prosty, ale tak jak w przypadku elementu video, mogą się pojawić pewne problemy. Jeśli kod z listingu 8.1 spróbujesz zastosować z plikiem .mp3 i nie usłyszysz dźwięku, przyczyną może być problem z kodekami. Męki z kodekami opisaliśmy bardziej szczegółowo w rozdziale 7., a chociaż informacje tam podane dotyczą konkretnie typów plików wideo, sytuacja z typami plików dźwiękowych jest analogiczna.
186
Rozdział 8. Osadzanie dźwięku w HTML5
Dwa główne kodeki audio to Ogg Vorbis (.ogg) i MP3 (.mp3). Możesz również pomyśleć o formacie WAV (.wav), ale pliki tego typu są zazwyczaj duże, przez co nie nadają się do ładowania przez sieć, a dodatkowo nie obsługują metadanych, takich jak wykonawca i tytuł. W tej książce skoncentrujemy się więc na obu głównych kodekach. Chociaż format MP3 może być uważany niemal za standardowy typ pliku, jest on częścią grupy MPEG4/H.264, a więc jest typem „zamkniętym” i komercyjnym. Z drugiej strony Ogg uważa się za „wolny” i „otwarty”. Zdania co do tego, który typ pliku daje dźwięk o lepszej jakości, są podzielone, ale podstawową kwestię stanowi zróżnicowana obsługa w przeglądarkach. W tabeli 8.1 przedstawiono aktualną sytuację dotyczącą odtwarzania w przeglądarkach dźwięku w różnych formatach. Tabela 8.1. Typy plików i ich obsługa w przeglądarkach Kodek
Android
Chrome
Firefox
Internet Explorer
iPhone
Opera
Safari
Ogg Vorbis
-
13+
4+
-
-
11+
-
MP3
2.3
13+
-
9+
4+
-
5+
WAV
-
-
-
-
-
-
-
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Umieszczanie dźwięku we wszystkich przeglądarkach Tak jak w przypadku wideo w rozdziale 7., chciałbyś, aby dźwięk był odtwarzany i obsługiwany we wszystkich najpopularniejszych przeglądarkach. W tym celu możesz wykorzystać zagnieżdżony w elemencie audio element source, wskazujący po kolei różne pliki dźwiękowe, a przeglądarka wybierze, który z nich może odtworzyć. Listing 8.2 prezentuje kod potrzebny do udostępnienia najpopularniejszym przeglądarkom pliku dźwiękowego, który mogą one odtworzyć. Listing 8.2. Zestaw plików dźwiękowych
Element audio nie wymaga określenia wysokości lub szerokości, ponieważ domyślnie każda przeglądarka posiada swój własny odtwarzacz dźwięku, ale możesz wskazać wysokość i szerokość przy użyciu CSS-a: audio {display: block; width: 90px; height: 28px;}
Dodawanie zastępczej treści dla starszych przeglądarek Po elementach source możesz umieścić dodatkowy kod dla przeglądarek, które nie mogą odtworzyć dźwięku natywnie — przede wszystkim mówimy o Internet Explorerze 6, 7 i 8. Podobnie jak w przypadku elementu video, istnieje kilka możliwości. Możesz przechowywać plik dźwiękowy na stronie takiej jak http://soundcloud. com i używać pochodzącego z niej kodu służącego do osadzania pliku, aby dostarczyć dźwięk, ale w celu dostarczenia zawartości dźwiękowej do starszych przeglądarek możesz także użyć programu Flash Player. Na listingu 8.3 używamy JW Playera, bardzo popularnego i łatwego do skonfigurowania odtwarzacza
Nowe atrybuty elementu audio
187
multimedialnego, ale dostępnych jest wiele innych odtwarzaczy. Mógłbyś też zresztą utworzyć własny odtwarzacz, a niezbędne pliki — w naszym przypadku player.swf i swfobject.js — bez problemu znajdziesz w internecie. Listing 8.3. Użycie JW Playera
Tylko starsze przeglądarki pobierają pliki swfobject.swf oraz player.swf i odtwarzają plik dźwiękowy w programie Flash Player. Listing 8.4 przedstawia cały kod. Zapewnia on odtwarzanie dźwięku we wszystkich najpopularniejszych przeglądarkach — czy to za pomocą natywnego elementu audio, czy to, w razie potrzeby, przy użyciu zastępczego odtwarzacza Flash Player. Listing 8.4. Odtwarzanie dźwięku w różnych przeglądarkach
8.4. Odtwarzanie dźwięku w różnych przeglądarkach
Pobierz plik dźwiękowy: plik MP3, 3 MB; plik Ogg, 3 MB
Nowe atrybuty elementu audio Omówimy teraz kilka nowych atrybutów elementu audio.
188
Rozdział 8. Osadzanie dźwięku w HTML5
Atrybut src Listing 8.1 z początku rozdziału pokazuje prosty przykład elementu audio i zawiera atrybut src. Użycie src oznacza jednak, że jesteś ograniczony do jednego pliku dźwiękowego. Kiedyś, w idealnym świecie, będzie to wszystko, czego będziesz potrzebować, jednak w chwili obecnej — ze względu na problemy z kodekami i przeglądarkami — sposób ten jest w zasadzie bezużyteczny. Zamiast korzystać z src, rozważ zastosowanie w obrębie elementu audio elementu source (jak na listingu 8.4), tak abyś mógł odtwarzać dźwięk w różnych przeglądarkach.
Atrybut preload Jeśli plik dźwiękowy osadzony na Twojej stronie ma dużą objętość albo jesteś pewien, że użytkownik będzie chciał go słuchać, możesz nakazać przeglądarce rozpoczęcie pobierania pliku po wczytaniu strony. Atrybut preload może przyjąć jedną z trzech wartości: preload="auto"
Wartość auto (możesz też po prostu pozostawić samo preload) informuje przeglądarkę, aby pobrała plik dźwiękowy po załadowaniu strony. preload="none"
Wartość preload="none" mówi przeglądarce, aby nie pobierała zawartości dźwiękowej. Dopiero kiedy użytkownik uruchomi odtwarzanie dźwięku, przeglądarka zacznie go pobierać. preload="metadata"
Atrybut metadata pobiera informacje (metadane) o ścieżce dźwiękowej, w tym jej czas trwania i listę utworów. Przeglądarka nie powinna pobrać samej zawartości dźwiękowej, dopóki użytkownik jej nie uruchomi.
Atrybut loop Jeśli element audio posiada atrybut loop, po zakończeniu odtwarzania rozpocznie się ono od początku. Atrybut ten jest atrybutem logicznym — albo jest włączony, albo wyłączony.
Atrybut autoplay Atrybut logiczny autoplay wymusza na przeglądarce rozpoczęcie pobierania i odtwarzania dźwięku po wczytaniu strony. W ten sposób odtwarzanych jest na przykład wiele reklam. Istnieją pewne obawy związane z dostępnością i łatwością wykorzystania odtwarzanych automatycznie dźwięków, nie wspominając już o tym, jak dźwięki mogą być irytujące, ale atrybut autoplay znajduje się w specyfikacji ze względu na to, że pozwala w ustandaryzowany sposób wymusić automatyczne odtwarzanie dźwięku, gdybyś naprawdę tego potrzebował. Nie musisz uciekać się do różnych javascriptowych sztuczek, aby osiągnąć ten efekt. Zauważ, że dostępne są też różne rozszerzenia przeglądarek wyłączające autoplay.
Uwaga W systemie iOS atrybuty autoplay i preload zostały celowo wyłączone ze względu na potencjalne koszty i problemy związane z prędkością wczytywania u użytkownika. Żadne dane nie są pobierane, dopóki użytkownik nie zdecyduje się ręcznie uruchomić dźwięku. Istnieje kilka technik (a raczej sztuczek) pozwalających na obejście tej blokady, ponieważ jednak są to techniki nieoficjalne, nie powinny być wykorzystywane i nie zostały omówione w tej książce.
API mediów
189
Atrybut controls Atrybut controls dodaje do pliku dźwiękowego domyślne, właściwe dla danej przeglądarki kontrolki zawierające przycisk odtwarzania/pauzy, pasek przewijania, informację o czasie trwania i czasie od początku utworu oraz kontrolki sterowania głośnością. Oto przykład:
…
Jest to atrybut logiczny, więc albo go dołączasz, albo nie. Jeśli nie zostanie dołączony, nic nie zostanie wyświetlone i wówczas oczywiście użytkownik nie będzie mógł sterować dźwiękiem. Zdajesz sobie chyba zatem sprawę, jak ważne jest, aby nie korzystać z atrybutu autoplay bez równoczesnego użycia atrybutu controls. Jeśli chcesz, możesz wykorzystać API do utworzenia własnych kontrolek rozpoczynania i wstrzymywania odtwarzania — podyskutujemy o tym w dalszej części tego rozdziału. Rysunek 8.1 pokazuje domyślne kontrolki w najpopularniejszych przeglądarkach.
Rysunek 8.1. Domyślne kontrolki w Chrome (na górze), Firefoksie, Internet Explorerze 9, Operze i Safari
Wskazówka Co dziwne, jeśli w Firefoksie nie masz włączonej obsługi JavaScriptu, kontrolki nie są wyświetlane. Inne przeglądarki wyświetlają kontrolki poprawnie bez pomocy JavaScriptu.
Darmowe pliki audio do testowania Prawdopodobnie do celów testowych będziesz potrzebował jakichś darmowych plików dźwiękowych. Istnieją dziesiątki możliwości. My wykorzystaliśmy pliki z takich witryn jak http://beatstorm.com, http://freesoundtrackmusic.com, http://www.vocaldownloads.com i http://www.freesound.org. Pliki mają różne formaty i, jak już wiesz, aby odtwarzać je w różnych przeglądarkach, będziesz je musiał przekonwertować. Sugerujemy wypróbowanie strony http://media.io albo aplikacji Free MP3/ WMA/OGG Converter, dostępnej na stronie http://download.cnet.com/Free-MP3-WMA-OGG-Converter/ 3000-2140_4-10793572.html.
API mediów HTML5 udostępnia rozwinięte i ekscytujące API dla multimediów. Korzystając z tego API i JavaScriptu, możesz wpływać na odtwarzanie plików dźwiękowych na stronach internetowych. Poniżej znajduje się lista dostępnych zdarzeń API:
190
Rozdział 8. Osadzanie dźwięku w HTML5
abort canplay canplaythrough canshowcurrentframe dataunavailable durationchange emptied empty ended error loadeddata loadedmetadata
loadstart pause play playing progress ratechange seeked seeking suspend timeupdate volumechange waiting
Dostępnych jest również wiele właściwości mediów: audioTracks autoplay buffered controls controller currentSrc currentTime defaultMuted defaultPlaybackRate duration ended error initialTime loop mediaGroup
muted networkState paused preload played playbackRate readyState seekable seeking startOffsetTime src textTracks videoTracks volume
Nie wszystkie z powyższych zdarzeń i właściwości są już dostępne, ale większości, w tym tych istotnych, które pozwalają tworzyć własne kontrolki odtwarzacza dźwięku, można już używać. Nie będziemy tu opisywać wszystkich możliwości API — ograniczymy się do tych, które są istotne dla kolejnych przepisów. Jeśli jednak jesteś zainteresowany zdobyciem większej wiedzy na temat tego API, polecamy materiały na stronie http://www.w3.org/2010/05/video/mediaevents.html (to demonstracja wideo, ale API dotyczy również odtwarzania dźwięku) oraz bardzo szczegółową specyfikację pod adresem http://www.w3.org/TR/ html5/media-elements.html#mediaevents.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie miksera Dotychczas dowiedziałeś się, jak uzyskać natywne odtwarzanie dźwięku w nowoczesnych przeglądarkach. W tym przepisie utworzysz mikser, dzięki czemu przetestujesz, jak przeglądarka radzi sobie z obsługą wielu jednocześnie odtwarzanych elementów audio. To proste zadanie, odpowiednie do rozpoczęcia pracy z dźwiękiem i API. W tym przepisie wykorzystujemy pliki .mp3 dla Safari i Internet Explorera oraz pliki .ogg dla Chrome, Firefoksa i Opery. Przeglądarki mają swoje dziwactwa, więc zalecamy używanie Chrome i Opery. Starszymi wersjami Internet Explorera zupełnie nie będziemy się interesować.
Tworzenie miksera
191
Rozpoczynamy od sześciu elementów dźwiękowych na liście, choć teoretycznie moglibyśmy na bieżąco ładować kolejne pliki. Do opracowania układu i nadania podstawowych stylów zastosujemy nieco CSS-a; odpowiednia klasa przyda się także w sytuacji, gdy dźwięk nie jest odtwarzany. Dla każdego elementu audio dostępne jest zdarzenie onclick do przełączania stanu odtwarzania pliku. Stronę możesz zobaczyć na rysunku 8.2, a kod zawarty jest na listingu 8.5.
Rysunek 8.2. Działający mikser oglądany w Firefoksie Listing 8.5. Tworzenie miksera
8.5. Mikser
Utwory z beatstorm.com; vocaldownloads.com; freesound.org
W pierwszej kolejności ukrywane są domyślne kontrolki i dzięki zastosowaniu CSS-a wyświetlany jest przycisk Odtwórz. Kiedy użytkownik kliknie element audio, sprawdzamy, czy plik był wcześniej wstrzymany. Jeśli tak było, za pomocą metody play dźwięk zostaje uruchomiony. Jeśli plik był odtwarzany, zostaje
194
Rozdział 8. Osadzanie dźwięku w HTML5
wstrzymany za pomocą metody pause. Podczas odtwarzania lub wstrzymywania przełączana jest klasa, która obrazuje różne działania przycisków. Kiedy dźwięk jest wstrzymywany, odtwarzanie pliku zostaje faktycznie zatrzymane, gdyż jego atrybut currentTime przyjmuje wartość 0. Natomiast do pokazania w trakcie odtwarzania czasu, jaki upłynął od początku utworu, wykorzystywane jest zdarzenie nasłuchu timeupdate.
Dziwactwa przeglądarek dotyczące miksera Przy realizacji tego przepisu możesz się natknąć na pewne nietypowe zachowania przeglądarek. Chociaż JavaScript jest obsługiwany w IE9 i Safari, w tych przeglądarkach przykład nie zadziała, ponieważ nie obsługują one jeszcze formatowania elementu audio. Kod powinien zostać zinterpretowany poprawnie dopiero wtedy, gdy usuniesz wiersz, który ukrywa atrybut controls, choć nawet wówczas przeglądarki wcale nie muszą reagować właściwie. Możesz także sformatować element li, tak aby zawierał ikony odtwarzania/wstrzymania.
PRZEPIS DLA ZAAWANSOWANYCH Dodawanie internetowego radia Dotychczas w tym rozdziale zajmowaliśmy się odtwarzaniem „fizycznych” plików (.mp3 i .ogg). A co z treścią strumieniowaną? Aby móc odtwarzać muzykę strumieniowaną, potrzebowaliśmy dotychczas Flasha, ale obecnie można to zrobić natywnie. W tym przepisie użyjemy listy JSON publicznie dostępnych strumieni radiowych. Użytkownik może wybrać z rozwijanej listy strumień, którego odtwarzanie zostanie za pomocą API rozpoczęte. Fajnie, prawda? Oto radio internetowe w przeglądarce, bez żadnych wtyczek. Podgląd odtwarzacza jest widoczny na rysunku 8.3, a kod do tego przepisu znajduje się na listingu 8.6.
Rysunek 8.3. Odtwarzacz internetowego radia w HTML5 oglądany w Chrome
Listing 8.6. Odtwarzacz radia internetowego
8.6. Odtwarzacz radia internetowego
Dodawanie internetowego radia
Odtwarzacz internetowego radia w HTML5
Twoja przeglądarka nie obsługuje elementu audio.
Rozgłośnie
Głośność
Strumienie są albo w formacie OGG, albo MP3. Strumienie OGG będą działać w Firefoksie, Operze i Chrome; strumienie MP3 — w Chrome, IE9 i Safari. Jeśli dany format nie jest obsługiwany w przeglądarce, powinien zostać wyświetlony komunikat o błędzie. 1. Użyj HTML-a oraz CSS-a, aby utworzyć układ i kontrolki odtwarzacza. 2. Utwórz opartą o JSON listę stacji radiowych i ich adresów URL. 3. Jeśli wystąpił błąd, użyj API do wykrycia, jakiego jest on typu. 4. Dodaj każdą stację jako element option do listy stacji. 5. Gdy stacja zostanie wybrana, uruchom funkcję setStation, która zmienia src elementu audio i natychmiast odtwarza dźwięk. Po wczytaniu strony uruchamiana jest funkcja init. Odpowiada ona za skonfigurowanie odtwarzacza dźwięku, tak abyś mógł się do niego odwołać i nim manipulować, a także ustawia kontrolki, takie jak Odtwórz i regulacja głośności. Następnie wczytuje stacje za pomocą funkcji loadStations. Funkcja ta przechodzi w pętli przez listę JSON stacji radiowych i tworzy listę wyboru dla użytkownika. Element select zawiera zdarzenie onChange, wywołujące funkcję setStation, która pobiera wybraną stację radiową i przypisuje jej adres URL jako src elementu audio, a także zmienia atrybut type (na MP3 albo OGG) tego elementu, tak aby prawidłowo się on odtworzył. Jeśli przeglądarka nie może odtworzyć danego typu dźwięku (np. w Firefoksie albo Operze nie da się odtworzyć Radia Jazz FM, którego strumień jest zapisany w formacie MP3), sygnalizowany jest błąd z tekstem błędu zależnym od jego typu.
Podsumowanie
201
Mimo że źródło odtwarzacza zostało określone, nie zadziała on, dopóki mu tego nie nakażesz, co jest realizowane za pomocą radioPlayer.play(). Podczas odtwarzania strumienia generowane są zdarzenia o nazwie durationchange. Zdarzenie to uruchamia funkcję o nazwie streamPlaying, która uaktualnia na ekranie tekst mówiący o tym, co stacja nadaje, zmienia przycisk Odtwórz na Wstrzymaj oraz wyświetla pozostałe kontrolki. Ostatnie kontrolki dotyczą przycisku Odtwórz/Wstrzymaj oraz regulacji głośności. Kiedy zostaje kliknięty przycisk Odtwórz/Wstrzymaj, uruchamiana jest funkcja sprawdzająca aktualny status: jeśli dźwięk jest wstrzymany lub odtwarzanie się zakończyło, uruchamiane jest .play(), a w przeciwnym przypadku .pause(). W poprzednim rozdziale, dotyczącym wideo, do regulacji głośności użyłeś nowego elementu HTML5 — range input. Tutaj tworzona jest wersja przyjazna dla wielu przeglądarek, która wykrywa punkt, w jakim pasek głośności został kliknięty, i aktualizuje poziom głośności dźwięku za pomocą .volume.
Podsumowanie W tym rozdziale dowiedziałeś się, jak odtworzyć plik dźwiękowy w przeglądarce bez potrzeby użycia zewnętrznej wtyczki, zwykle Flasha. Ponieważ jest to nowa funkcja przeglądarek, czasami zachowują się one niezgodnie z oczekiwaniami. Podobnie jak w przypadku elementu video, należy wziąć pod uwagę problemy z kodekami, ale w przypadku starszych przeglądarek można zastosować rozwiązania zastępcze. Poznałeś również różne elementy nowego API, dzięki którym możesz wpływać na zachowanie pliku dźwiękowego w przeglądarce, sterując jego odtwarzaniem i wstrzymywaniem, regulacją głośności, a także zmianą odtwarzanego pliku.
202
Rozdział 8. Osadzanie dźwięku w HTML5
9 Dokonywanie zmian w historii przeglądarki W
tym rozdziale omówimy aktualizacje interfejsu historii w HTML5, szczególnie dwie nowe metody w History API (pushState i replaceState), oraz zapoznamy się z kilkoma przepisami dotyczącymi używania ich do przechodzenia między stronami w sesji. Ponadto poznasz zdarzenie popstate, nauczysz się używać History API do przechowywania czegoś więcej niż tylko informacji o odwiedzanych stronach oraz zaznajomisz się z zaawansowanymi zagadnieniami, takimi jak bezpieczeństwo i dodatkowe biblioteki.
Podstawy historii Javascriptowe History API jest używane w witrynach internetowych od JavaScriptu 1.0, lecz przed pojawieniem się HTML5 nie było znacząco aktualizowane. Wraz z pojawieniem się AJAX-a i aplikacji działających bez użycia kolejno ładowanych stron korzystanie z obiektu historii do przechodzenia dalej, wstecz albo do określonego wpisu w sesji stało się problematyczne. W związku z tym wiele frameworków aplikacyjnych, w tym YUI, zawiera własne techniki zarządzania sesją przeglądarki. Dawniej, aby dodać stronę do historii przeglądarki bez konieczności przejścia na inną stronę, trzeba było zmienić adres URL poprzez dodanie do niego kotwicy za pomocą symbolu #. Za pomocą metod history.pushState i history.replaceState możesz teraz, odpowiednio, dodawać wpisy do historii i ją modyfikować, a jeśli połączysz je ze zdarzeniem popstate okna, będziesz w stanie dać użytkownikowi ulepszone możliwości nawigowania między stronami. Dzięki możliwości dodawania do historii i modyfikowania historii stron na witrynie History API lepiej obsługuje przycisk Wstecz w bogatych aplikacjach korzystających z technologii AJAX. Możesz teraz zmieniać „stan widoku” aplikacji po prostu przez pozorne dodanie strony albo kontekstu do historii. Możesz myśleć o historii sesji przeglądarki albo o stronach, do których użytkownik przechodził na Twojej witrynie, jak o stosie, na szczyt którego są odkładane oglądane strony. Gdy użytkownik klika lub dotyka przycisk Wstecz przeglądarki, strony są zdejmowane ze stosu jedna po drugiej. Korzystając jedynie z JavaScriptu, możesz przejść dalej, wstecz albo o określoną liczbę stron w obu kierunkach za pomocą poniższych poleceń:
204
Rozdział 9. Dokonywanie zmian w historii przeglądarki
window.history.forward, window.history.back, window.history.go([delta]).
Metody te są nadal dostępne w History API, ale teraz, w HTML5, za pośrednictwem tego API możesz dodatkowo dynamicznie dodawać wpisy do historii, przechwytywać zdarzenia przejścia między stronami, a nawet kontrolować kontekst stron.
Kompatybilność przeglądarek Rozszerzenia History API są obecnie obsługiwane w przeglądarkach pokazanych w tabeli 9.1. Tabela 9.1. Obsługa History API w przeglądarkach Android
2.2+
Chrome
5.0+
Firefox
4.0+
Internet Explorer
-
iOS Safari
3.0+
Opera
11.0+
Safari
5.0+
PRZEPIS DLA POCZĄTKUJĄCYCH Dodawanie do historii wpisów za pomocą pushState Użyjemy metody pushState dostępnej w History API do dodania przez bieżącą stronę w przeglądarce nowego wpisu do stosu sesji. Metoda pobiera dwa parametry, data i title, z opcjonalnym trzecim parametrem url: history.pushState(data, title [,url])
Parametry metody pushState są następujące: data — ciąg znaków lub obiekt przekazany jako reprezentacja stanu strony, title — tekst dotyczący strony wyświetlany w nagłówku przeglądarki, url — (opcjonalny) nowy adres URL do dodania do stosu historii.
Parametr data reprezentuje stan strony i zostaje automatycznie powiązany z nowym wpisem. Jak później zobaczysz, wpis ten może być pobrany przez zdarzenie okna popstate. Przez stan rozumiemy bieżący kontekst wyświetlania strony. Może to być na przykład przepis, który dana osoba aktualnie przegląda, pochodzący z wywołania bazy danych wykonanego choćby przez AJAX. Niektóre przeglądarki nakładają ograniczenia na wielkość parametru data, gdyż obiekt stanu jest przechowywany przez przeglądarkę lokalnie na dysku użytkownika. W Firefoksie ten limit wynosi 640 000 znaków serializowanej reprezentacji obiektu stanu. Jeśli masz zamiar przekroczyć ten limit lub mógłbyś potencjalnie to zrobić, powinieneś użyć sessionStorage albo localStorage (patrz rozdział 11.).
Dodawanie do historii wpisów za pomocą pushState
205
Uwaga Niektóre przeglądarki, na przykład Firefox, ignorują parametr title i nie wyświetlają użytkownikowi tej wartości na liście historii sesji. Zachowanie to zależy od przeglądarki i mamy nadzieję, że zostanie poprawione w przyszłych aktualizacjach.
Jeśli podany jest parametr url, to zastąpi on adres URL w pasku adresu przeglądarki, ale nie spowoduje, że przeglądarka ściągnie stronę z witryny. Pozwala to użytkownikom dodać zakładkę z adresem URL i powrócić do niego później. Oczywiście po stronie serwera potrzebny jest kod do obsługi adresów z zakładek, które nie reprezentują prawdziwych stron. Przekazany URL może być ścieżką względną albo bezwzględną, jednak musi się ona znajdować w tej samej domenie co aktualny adres URL. Jeśli użyta jest ścieżka względna, będzie ona oparta na bieżącym adresie dokumentu. Domyślną ścieżką w przypadku nieprzekazania parametru URL albo przekazania tylko łańcucha zapytania (takiego jak "?page=5") jest aktualny adres URL dokumentu. Wykorzystanie metody pushState przypomina używanie znaku kratki (hash, #) do kontrolowania kontekstu strony, powszechnego w dynamicznych aplikacjach zbudowanych w oparciu o AJAX: window.location = "#foo";
Jednak metoda pushState zapewnia większą elastyczność niż dostęp oparty na znaku kratki: Metoda pushState pozwala na pozostanie na tej samej stronie albo zmianę adresu URL. Jeśli zostanie
użyty znak kratki, przeglądarka pozostaje przy tym samym adresie URL.
Metoda pushState pozwala zachować informacje kontekstowe w stanie historii. Jak zobaczysz
w dalszej części rozdziału, może to być pomocne.
Warto podkreślić ostatni punkt, ponieważ oznacza on znaczny postęp w porównaniu ze sposobem związanym z dodawaniem znaku kratki do adresów URL. Przy każdym wpisie w historii pushState pozwala zapisać obiekt danych, który może przechowywać informacje kontekstowe o stanie strony. Dane mogą być tak proste jak ciąg znaków lub tak złożone jak zserializowany obiekt JSON. Załóżmy na przykład, że masz stronę, która pokazuje slajdy z prezentacji. Każdy slajd może mieć powiązane ze sobą informacje o tym, jak ma być wyświetlony, na przykład dotyczące napisów, ramki, podziękowań i tak dalej. Informacje te przechowuje obiekt stanu, dzięki czemu możesz łatwo zmienić styl strony w oparciu o slajd, przy którym się znajdujesz. W dalszej części tego rozdziału znajdziesz przepis dotyczący wykorzystania obiektu stanu. Użyjmy metody pushState obiektu history do dodania nowego wpisu do historii sesji. Po załadowaniu strona sprawdzi dostępność History API w przeglądarce przez wywołanie typeof na metodzie history.pushState. Jeżeli metoda zwraca „undefined”, to znaczy, że przeglądarka nie obsługuje History API. Po zastosowaniu tego testu możesz użyć innego sposobu implementacji historii albo ograniczyć użytkownikowi funkcjonalność w oparciu o jego aktualną przeglądarkę: 1. Utwórz pustą stronę HTML z elementem div, aby pokazać aktualny widok (exhibit). 2. Dodaj przycisk, który po kliknięciu uruchamia javascriptową funkcję nextExhibit. 3. Dodaj funkcję nextExhibit, by wykonać metodę pushState. 4. Dodaj wywołanie metody pushState, aby dopisać kontekst widoku surykatki do historii: history.pushState('Surykatka','Widok surykatki','meerkats.html');
5. Zaktualizuj div widoku, aby pokazać użytkownikowi, że jest przy widoku surykatki: document.getElementById("exhibit").innerHTML = "Przy surykatkach.";
206
Rozdział 9. Dokonywanie zmian w historii przeglądarki
Listing 9.1 zawiera cały kod strony. Listing 9.1. Wykorzystanie pushState do dodawania stron do historii
9.1. W zoo
Witaj w zoo. Jesteś przy wejściu do zoo. Odwiedź surykatki
Gdy załadujesz stronę w przeglądarce, na podstawie tytułu strony oraz wyświetlonego na niej komunikatu stwierdzisz, że jesteś przy wejściu do zoo. Jeśli klikniesz przycisk Odwiedź surykatki, w historii zostanie zapisana bieżąca strona, a następnie zmieni się tytuł i adres URL okna przeglądarki bez faktycznego przejścia do nowej strony. JavaScript zmieni komunikat informujący użytkownika o widoku surykatki. Pod każdym względem będzie to z punktu widzenia użytkownika wyglądało tak, jakby z serwera została załadowana nowa strona. Jest to jednak tylko nowy kontekst, który dodałeś do historii poprzez pushState.
Tworzenie przeglądarki obrazków
207
Wskazówka W niektórych przeglądarkach, na przykład Firefox, podanie w metodzie pushState parametru url, który ma wartość nieprawidłowej strony, spowoduje wyjątek zabezpieczeń. Aby temu zaradzić, podaj prawidłowy adres URL lub użyj opcjonalnego parametru stanu, co usunie wyjątek.
Jeśli wyświetlisz w przeglądarce listę historii, jako ostatnią zobaczysz stronę „W zoo”, a po kliknięciu przycisku Wstecz zostaniesz przeniesiony z powrotem do tej strony. Komunikat na stronie nie zmieni się na „Jesteś przy wejściu do zoo.” — później dowiesz się, jak to zmienić. Pamiętaj, że adres URL jest opcjonalny, ale może być użyteczny dla powracających na stronę użytkowników. Oczywiście zapisane wpisy, którym na serwerze nie odpowiada prawdziwa strona, będą musiały być obsłużone przez kod znajdujący się na serwerze.
PRZEPIS DLA POCZĄTKUJĄCYCH Tworzenie przeglądarki obrazków W poprzednim przepisie, który przeprowadził Cię przez Twoje pierwsze wywołanie pushState, zapisałeś w sesji historii jeden prosty wpis. Ten przepis idzie o krok dalej i daje użytkownikowi możliwość wyboru różnych wariantów oraz przechowywania każdego z nich w powiększającej się historii sesji. Wiele dostępnych witryn pozwala użytkownikom przeglądać zdjęcia, filmy lub inne treści poprzez udostępnienie łączy będących miniaturami zdjęć i dynamiczne zastępowanie wybranego elementu. W tym przepisie pokażesz użytkownikowi szereg miniatur obrazków, umożliwisz mu wybranie obrazka do obejrzenia oraz dodasz nowy wpis do historii, aby śledzić, co było oglądane, i umożliwić użytkownikowi powrót do wcześniej oglądanych obrazków. Listing 9.2 pokazuje pełny kod strony tworzący przeglądarkę obrazków przy użyciu wpisów historii. Umieść obrazki w folderze images, aby kod funkcji showImage mógł się do nich prawidłowo odwoływać. Listing 9.2. Przeglądarka obrazków — tworzenie wielu wpisów w historii
Obrazek 1
Slajd 1
218
Rozdział 9. Dokonywanie zmian w historii przeglądarki
Strona klienta 1 Strona klienta 2 Strona klienta 3
Następnie, wykorzystując kod pokazany na listingu 12.7, należy utworzyć stronę klienta, która będzie załadowana do każdego elementu iframe pojemnika i wyświetli użytkownikowi pole wejściowe do wprowadzania liczby. 1. Utwórz pustą stronę HTML z pokazaną na listingu 12.7 zawartością znacznika body, obejmującą znacznik input, przycisk Wyślij liczbę do współdzielonego wątku roboczego i element zawierający dziennik. 2. Dodaj znaczniki script i globalne odwołanie do instancji współdzielonego wątku o nazwie sworker. Będzie to instancja SharedWorker, służąca do wysyłania i otrzymywania wiadomości. 3. Dodaj wiersz window.addEventListener i funkcję init, która tworzy połączenie ze współdzielonym wątkiem roboczym oraz rejestruje procedurę obsługi onmessage dotyczącą portu tego klienta współdzielonego wątku roboczego. 4. Dodaj funkcję sendNumber, która pobiera wartość wejściową i przesyła liczbę do współdzielonego wątku roboczego w celu przetwarzania. Listing 12.7. Tworzenie stron klienta
12.7. Klient współdzielonego wątku roboczego
Bieżąca średnia:
Wyślij liczbę do współdzielonego wątku roboczego
Komunikaty ze współdzielonego wątku roboczego:
293
294
Rozdział 12. Komunikacja i wątki
Po załadowaniu strony klienta z listingu 12.7 inicjalizowane jest połączenie ze współdzielonym wątkiem roboczym, utworzonym na podstawie pliku listing.12.8.js. Ostatnim krokiem jest utworzenie javascriptowego pliku współdzielonego wątku roboczego. Plik ten, pokazany na listingu 12.8, został utworzony za pomocą następujących kroków: 1. Utwórz javascriptowy plik o nazwie listing.12.8.js (lub jakiejkolwiek nazwie, którą wybierzesz, pod warunkiem że odpowiada ona parametrowi pliku wątku współdzielonego na Twojej stronie klienta HTML-owego). 2. Dodaj zmienne globalne w początkowej części skryptu oraz procedurę obsługi zdarzenia onconnect. 3. Dodaj do skryptu funkcje sendAllConnections i updateAverage. Listing 12.8. Dodawanie pliku .js współdzielonego wątku roboczego // 12.8. Plik js współdzielonego przez różne strony wątku roboczego do obliczania średniej liczb // inicjalizuj tablicę przechowującą porty połączeń var count = 0; var connections = new Array(); // inicjalizuj zmienne wzoru na średnią var average = 0; var numValues = 0; var sumValues = 0; // zdarzenie onconnect współdzielonego wątku roboczego onconnect = function(msg) { // pobierz odwołanie do tego połączenia var port = msg.ports[0]; // zapisz to odwołanie do połączenia dla przyszłych komunikatów connections[count] = port; // powiększ liczbę połączeń, które mamy count += 1; // odpowiedz klientowi i inicjalizuj jego średnią port.postMessage({msgType:'LOG',msgText:'[WWR] Teraz połączony [' + count + '].'}); port.postMessage({msgType:'AVE',msgText:'[WWR] Średnia zaktualizowana: ' + average + '.', ´aveValue:average}); // utwórz procedurę obsługi dla przypadku otrzymania komunikatu od klienta port.onmessage = function(msg) { // ustaw wartość przekazaną do współdzielonego wątku roboczego var newValue = msg.data; // potwierdź otrzymanie wartości port.postMessage({msgType:'LOG',msgText:'[WWR] Otrzymano: ' + newValue + '.'}); // zastąp średnią nową wartością updateAverage(newValue); } }
Wykorzystywanie współdzielonych wątków roboczych
295
// funkcja pomocnicza do wysyłania wiadomości do wszystkich klientów function sendAllConnections(msgTypeVal,msgVal) { // przejdź w pętli przez klienty i wykonaj postMessage for (var i=0; i=0; i--) { // pobierz obrazek profilu, nazwę do wyświetlenia i tweet tIcon = data[i].user.profile_image_url; tTitle = data[i].user.screen_name; tBody = data[i].text; // zwróć informację o tweecie z powrotem do głównego wątku w celu wyświetlenia tweeta postMessage({msgType:'TWEET',icon:tIcon,title:tTitle,body:tBody}); // zapisz id_str jako największy identyfikator, aby nie pokazywać tweetów ponownie maxId = data[i].id_str; } } // poinformuj główny wątek, że w tej pętli to wszystko, co było do zrobienia postMessage({msgType:'END',lastTweetId:maxId}); } // przechwyć komunikat z głównego wątku onmessage = function(event) { // pobierz identyfikator ostatniego tweeta var lastId = event.data; var qString = ''; // sprawdź, czy identyfikator ostatniego tweeta to identyfikator istniejącego tweeta if (lastId != 0) { // jeśli to identyfikator istniejącego tweeta, użyj since_id qString = '&since_id='+lastId; } else { // brak wcześniej przeczytanych tweetów, więc pobierz maksymalnie trzy qString = '&count=3'; } // użyj importScripts jako metody JSONP zamiast znacznika script // obecnie wyświetlane są tweety dla screen name mającego wartość HelionPL, ale możesz to zmienić // na jakiegokolwiek użytkownika Twittera, którego tweety chciałbyś wyświetlać importScripts('http://api.twitter.com/1/statuses/user_timeline.json? ´screen_name=HelionPL'+qString+'&callback=getResult'); }
Po załadowaniu w przeglądarce głównej strony, ale przed kliknięciem przycisku Ustaw uprawnienia, kliknij przycisk Sprawdź poziom uprawnień. Spowoduje to wywołanie funkcji checkPermissionLevel, która sprawdzi, czy webkitNotifications jest dostępny, a następnie wykona metodę checkPermission, pobierając
328
Rozdział 13. Zachowanie przeglądarek w HTML5
aktualny poziom uprawnień w postaci wartości liczbowej, oraz wyświetli odpowiadające tej wartości wyjaśnienie w postaci okna dialogowego. Dzięki temu szybko stwierdzisz, czy uprawnienia do wyświetlania powiadomień na pulpicie są dla domeny poprawnie nadane. Możesz poćwiczyć, usuwając uprawnienia w ustawieniach przeglądarki, blokując powiadomienia, zezwalając na nie oraz oglądając zmiany poziomu uprawnień. Jeśli nie nadałeś uprawnień do wyświetlania powiadomień, zrób to przed kontynuowaniem pracy z przepisem. Po wczytaniu kodu skrypt ustawia globalne odwołanie do wątku roboczego o nazwie tworker oraz zmienną globalną o nazwie lastTweetId, która będzie przechowywać „zakładkę” dotyczącą ostatniego tweeta odczytanego dla użytkownika. Podczas ładowania strony skrypt ustawia wartość tej zmiennej na zero, co oznacza, że strona została właśnie załadowana i żadne tweety nie zostały odczytane. Po uruchomieniu wątku roboczego w celu pobrania listy tweetów zostanie mu przekazana wartość zmiennej lastTweetId służąca do określenia, które tweety należy wyświetlić. Wartość tej zmiennej należy przechowywać na głównej stronie, gdyż po zakończeniu pobierania i parsowania tweetów wątek roboczy zniknie. Przy każdym odpytywaniu o tweety tworzony jest nowy wątek roboczy. Aby rozpocząć proces pobierania tweetów dla użytkownika i wyświetlania powiadomień, kliknij przycisk Pobierz tweety. Spowoduje to uruchomienie funkcji grabTweets, która najpierw doda do dziennika konsoli komunikat potwierdzający rozpoczęcie procesu pobierania tweetów, a następnie utworzy nowy wątek roboczy z pliku listing.13.7.js. Wątek roboczy jest tak zaprojektowany, że nie podejmie żadnych działań, dopóki za pomocą komunikatu nie zostanie poinstruowany, aby rozpocząć przetwarzanie, więc w tym miejscu przyjrzyjmy się pozostałej części funkcji grabTweets. W kolejnym kroku funkcja ustawia procedurę obsługi zdarzenia message wątku roboczego, tak aby po wysłaniu przez wątek roboczy komunikatu można go było obsłużyć. Wykorzystany będzie tu podobny sposób przekazywania wiadomości jak w przypadku wątków roboczych z przepisów z rozdziału 12. — wątek może wysyłać różne rodzaje komunikatów o treści w formacie JSON, zawierającej typ komunikatu i związane z tym typem parametry. Z wątku roboczego do głównej strony są przesyłane dwa różne rodzaje komunikatów: TWEET oraz END. Jeśli otrzymasz msgType o wartości TWEET, oznacza to, że wątek roboczy znalazł tweet do wyświetlenia. W takim przypadku pozostała część komunikatu posłuży do wyświetlenia powiadomienia zawierającego ikonę z awatarem użytkownika, nazwę użytkownika jako tytuł oraz tweet jako treść powiadomienia. W tym przepisie kod tworzy powiadomienie, dodaje procedury obsługi zdarzeń ondisplay, onclose oraz onerror i w końcu wyświetla powiadomienie — procedury obsługi zdarzeń onclose i onerror po prostu zapisują w dzienniku konsoli komunikat informujący o przechwyceniu zdarzenia; procedura obsługi zdarzenia ondisplay służy do odtworzenia dźwięku przy wyświetleniu powiadomienia. Następnie zostaje ustawiony limit czasu, aby automatycznie usunąć z pulpitu powiadomienie, jeśli użytkownik go jeszcze nie zamknął. Wreszcie, metoda show() wyświetla powiadomienie. Komunikat END będzie oznaczać, że wątek roboczy zakończył pobieranie i przetwarzanie tweetów. Dzięki temu, że wątek roboczy informuje o zakończeniu pracy, możesz się upewnić, iż w tym samym czasie nie działa wiele wątków, oraz odczekać pewien czas pomiędzy zakończeniem pracy przez jeden z wątków a jej rozpoczęciem przez następny. Komunikat END może zawierać identyfikator ostatniego tweeta albo, jeśli nie pobrano żadnych tweetów, wartość zero. W razie potrzeby skrypt aktualizuje zakładkę wartością identyfikatora ostatniego tweeta, aby zaznaczyć, która wiadomość została pobrana jako ostatnia. Po ustawieniu identyfikatora ostatniego tweeta skrypt — w celu ponownego uruchomienia funkcji grabTweets — ustawia odmierzanie czasu. W tym przepisie nie zawracaliśmy sobie głowy dodawaniem funkcji zatrzymywania działania, ale można to łatwo zrealizować — czy to przy użyciu flagi zapobiegającej przyszłemu pobieraniu danych, czy też, w razie potrzeby, poprzez anulowanie działania wątku roboczego. Na końcu funkcji
Podsumowanie
329
grabTweets kod nakazuje wątkowi roboczemu rozpoczęcie pracy, przesyłając do niego komunikat zawierający zakładkę lastTweetId.
Przejdźmy teraz do wątku roboczego i omówmy pokrótce proces pobierania tweetów użytkownika. Wątek roboczy obejmuje zasadniczo dwie sekcje: żądanie podania informacji za pomocą procedury obsługi zdarzenia onmessage oraz parsowanie zbioru wyników w funkcji getResult. Działanie wątku roboczego jest uruchamiane za pomocą komunikatu zawierającego identyfikator ostatniego tweeta — procedura obsługi onmessage wątku pobiera ten identyfikator i tworzy adres URL żądania REST, wykorzystując metodę importScripts wątków. Podobnie jak przy wykorzystaniu znaczników script, importScripts po prostu ładuje do wątku roboczego zewnętrzny skrypt albo zbiór skryptów. Pozwala to obejść kwestie dotyczące bezpieczeństwa związane z pracą z różnymi domenami. W żądaniu URL używamy parametru callback łańcucha zapytania, aby przekazać nazwę funkcji getResult, która ma być uruchomiona wraz z wynikami żądania. Ponadto pewne parametry ustawiamy dynamicznie, zależnie od tego, czy chodzi o pierwsze, czy kolejne żądanie. Dalszych wyjaśnień dotyczących opcji wyszukiwania szukaj w dokumentacji API Twittera. Po wywołaniu funkcji zwrotnej getResult z wynikami JSON wątek roboczy sprawdza, czy są jakieś tweety, badając, czy długość danych jest większa od zera. Jeśli tak jest, co oznacza obecność tweetów do sparsowania, skrypt przechodzi w pętli przez każdy element w wynikach i wydobywa z niego adres URL obrazka, nazwę użytkownika oraz sam tweet. Kiedy skrypt wydobędzie już wartości tych pól, wątek roboczy wysyła do głównego wątku komunikat z informacjami dotyczącymi powiadomienia. Po wysłaniu komunikatu wątek roboczy zapisuje identyfikator tweeta w zmiennej, aby w końcowej fazie przetwarzania wysłać ją do strony głównej jako następną zakładkę, informującą, od którego tweeta należy zacząć. Można zauważyć, że skrypt parsuje zbiór wyników z tweetami w odwrotnej kolejności. Wynika to z faktu, że pierwszy rekord reprezentuje najnowszy tweet, a ostatni najstarszy — a skoro chcemy wyświetlać powiadomienia w porządku, w jakim zostały napisane, muszą one być wyświetlane w odwrotnej kolejności. W tym przepisie pokazaliśmy, w jaki sposób wyświetlać i automatycznie usuwać powiadomienia. Zademonstrowaliśmy także, w jaki sposób łączyć je z innymi API, tak aby powiadamiać użytkowników o zdarzeniach na stronie, nawet jeśli nie oglądają oni okna przeglądarki.
Podsumowanie W tym rozdziale dowiedziałeś się o pewnych pomniejszych rozszerzeniach API. Przeciąganie i upuszczanie, pamięć offline oraz powiadomienia pozwalają znacznie poprawić działanie witryn i aplikacji. Zapewniają również wyższy poziom integracji, szybko niwelujący różnice między aplikacjami działającymi w przeglądarce a aplikacjami natywnymi. Będziemy się z zainteresowaniem przyglądać, w jaki sposób rozszerzenia te będą wykorzystywane w przyszłości.
330
Rozdział 13. Zachowanie przeglądarek w HTML5
14 Praca z plikami lokalnymi P
rzed pojawieniem się HTML5 działania na plikach przeprowadzane w przeglądarce były słabo obsługiwane i nie wzbudzały dużego zainteresowania. Zakres funkcjonalności obejmował zwykle tylko prosty wybór pliku, który miał być wysłany do serwera. Teraz, dzięki HTML5 i uzupełniającemu go File API, mamy do dyspozycji powiększony zestaw funkcjonalności oraz, co ważniejsze, ustandaryzowany zestaw funkcji, który pozwala odczytać różne rodzaje plików oraz ich podstawowe atrybuty w przeglądarce za pomocą JavaScriptu. W tym rozdziale poznasz nowy zbiór funkcji dotyczących File API i wykorzystasz przepisy, w których omówimy podstawy oraz pewne nowe specyfikacje File API pojawiające się na horyzoncie.
Przegląd File API File API zapewnia ustandaryzowany sposób interakcji z plikami wybranymi przez użytkownika w przeglądarce. Interfejsy File API można podzielić na trzy obszary funkcjonalne: wybór pliku lub plików za pomocą interfejsu FileList, pobieranie atrybutów plików poprzez interfejs File, odczyt pliku poprzez interfejs FileReader.
Interfejs FileList jest listą plików wybranych przez użytkownika, po której elementach można po kolei iterować, tak jak w przypadku tablic. Interfejs File udostępnia właściwości wybranego pliku. Za pomocą tych dwóch interfejsów skrypty mogą przejść w pętli przez wybrane pliki i odczytać następujące najważniejsze właściwości tych plików: name — nazwa pliku, type — typ pliku w formacie MIME i kodowaniu ASCII, size — rozmiar pliku w bajtach, lastModifiedDate — data i czas ostatniej modyfikacji pliku.
Bezpieczeństwo File API File API przetwarza informacje i dane spoza przeglądarki w urządzeniu klienta. Ta interakcja z lokalnym systemem plików w naturalny sposób budzi obawy związane z bezpieczeństwem. Jednak specyfikacja HTML5 File API pozwala JavaScriptowi na interakcję jedynie z plikami, które użytkownik udostępnił. File API nie
332
Rozdział 14. Praca z plikami lokalnymi
może się poruszać po strukturze katalogów albo wybierać plików samodzielnie, bez interakcji użytkownika wybierającego plik. Tabela 14.1 pokazuje, które wersje każdej przeglądarki obsługują File API. Zakres obsługi w poszczególnych przeglądarkach jest różny, o czym będziemy wspominać w odpowiednich miejscach w przepisach tego rozdziału. Tabela 14.1. Dostępność File API w przeglądarkach Android
3.0+
Chrome
9.0+
Firefox
3.6+
Internet Explorer
10.0+
iOS Safari
-
Opera
11.1+
Safari
-
PRZEPIS DLA POCZĄTKUJĄCYCH Odczyt atrybutów pliku W tym przepisie wykorzystamy interfejs File do odczytania nazwy, rodzaju, rozmiaru i daty ostatniej modyfikacji pliku, który został wybrany przez odwiedzającego stronę za pomocą standardowego elementu input służącego do wyboru pliku. Zanim zademonstrujemy, jak uzyskać te informacje, pokażemy, jak stwierdzić, czy interfejs FileList jest dostępny w przeglądarce. Aby wyświetlić atrybuty pliku, tak jak to pokazano na listingu 14.1, wykonaj następujące kroki: 1. Utwórz pustą stronę HTML z elementem input służącym do wyboru pliku i dodaj procedurę obsługi zdarzenia onchange, wywoływaną po wyborze pliku. 2. Dodaj do elementu body element section o identyfikatorze fileAttributes, w którym przepis będzie wyświetlać atrybuty plików. 3. Dodaj funkcję handleFile przyjmującą parametr fileInput. Listing 14.1. Wyświetlanie atrybutów pliku
14.1. Odczyt atrybutów pliku
Wybierz plik:
Kiedy odwiedzający stronę utworzoną na podstawie listingu 14.1 wybierze jakiś plik, używając służącego do tego przycisku, procedura obsługi zdarzenia onchange wywoła funkcję handleFile z elementem input typu file jako parametrem. Wewnątrz tej funkcji najpierw pobierane jest odwołanie do elementu section, służącego do pokazania wyników, po czym następuje weryfikacja, czy przeglądarka obsługuje interfejs FileList, poprzez sprawdzenie obecności tablicy files. Jeśli przeglądarka nie obsługuje tego interfejsu, w elemencie section o atrybucie fileAttributes jest wyświetlany odpowiedni komunikat, ale na taką sytuację możesz zareagować według własnego pomysłu albo poprosić odwiedzającego o więcej informacji. Jeśli interfejs FileList jest obsługiwany, za pomocą odwołania do pierwszego pliku w tablicy files (fileInput.files[0]) jest pobierana instancja typu File, która następnie zostaje użyta do odczytania właściwości name, type, size oraz lastModifiedDate. Ponieważ jednostką miary atrybutu size jest bajt, a bardziej powszechne jest podawanie rozmiaru plików w kilobajtach, trzeba przeprowadzić odpowiednią konwersję za pomocą wyrażenia, które przekształca bajty na kilobajty. Możesz poprawić to wyrażenie, tworząc funkcję, która pobierze liczbę bajtów i pokaże konwersję na kilobajty, megabajty albo inną jednostkę, zależnie od całkowitej liczby bajtów, tak jak jest to robione w zwykłych listach plików w katalogach.
Uwaga Interfejs File dziedziczy z interfejsu Blob, w związku z czym zawiera atrybuty size oraz type. Atrybuty name i lastModifiedDate są dodane w interfejsie File. Jednak w kilku przeglądarkach lastModifiedDate nie jest dostępny i poproszony o wartość będzie zwracał undefined.
W tym przepisie pokazaliśmy atrybuty pliku wybranego przez odwiedzającego. Przydaje się to do filtrowania plików przed przesłaniem do serwerów albo po prostu do pokazania użytkownikowi jakiegoś komunikatu. W następnym przepisie rozwiniemy ten temat, udostępniając odwiedzającemu interfejs pozwalający na wybranie wielu plików do przetworzenia.
334
Rozdział 14. Praca z plikami lokalnymi
PRZEPIS DLA POCZĄTKUJĄCYCH Przetwarzanie wielu plików za pomocą przeciągania i upuszczania Interfejs FileList udostępnia możliwość obsługiwania tablicy obiektów File reprezentujących pliki z lokalnego systemu plików. Ten przepis pokazuje, jak można użyć obszaru przeciągania i upuszczania oraz interfejsu FileList do obsługi wielu plików wybranych przez użytkownika, co może mieć wiele zastosowań, takich jak filtrowanie plików według nazwy, rozmiaru czy typu oraz potwierdzanie przez użytkownika wyboru plików. Po przeciągnięciu i upuszczeniu plików na strefę upuszczania skrypt wykorzysta właściwość length i przejdzie w pętli przez sekwencję FileList. Właściwość length zwraca liczbę elementów albo obiektów File w FileList i może być użyta do „przejścia” przez sekwencję plików. Dla każdego obiektu File strona wyświetli atrybuty pliku w tabeli, aby poinformować użytkownika, co zostało upuszczone na strefę upuszczania strony. Aby utworzyć stronę, wykonaj następujące kroki oraz skorzystaj z kodu z listingu 14.2: 1. Utwórz stronę z listingu 14.2, zawierającą znaczniki style i body, strefę upuszczania i element section o identyfikatorze filesSelected. Upewnij się, że element input ma atrybut multiple oraz procedurę obsługi zdarzenia onchange. 2. W funkcji init dodaj procedury nasłuchu zdarzeń strefy upuszczania. Dodaj funkcje handleFileDrop oraz handleDragOver, służące do aktywacji tej strefy. 3. Dodaj funkcję displayFiles służącą do przejścia w pętli przez wybrane pliki i wyświetlania atrybutów w tabeli. 4. Dodaj funkcję clearTable oraz wyzwalacz addEventListener zdarzenia load. Listing 14.2. Przechodzenie w pętli przez wiele plików za pomocą FileList
14.2. Przetwarzanie wielu plików za pomocą FileList
Przeciągnij kilka plików i upuść na poniższą strefę:
--> Tutaj upuszczaj pliki
Interfejs FileReader
337
Po załadowaniu strony przeglądarka inicjalizuje strefę upuszczania za pomocą wywołania funkcji init przez procedurę nasłuchu zdarzenia load okna. Funkcja init ustawia zmienną dropzone na element div o identyfikatorze dropZone oraz rejestruje dwie procedury nasłuchu dla zdarzeń dragover i drop. Po aktywowaniu zdarzenia dragover przeglądarka wywołuje funkcję handleDragOver, a po aktywowaniu zdarzenia drop — funkcję handleFileDrop. Po upuszczeniu plików na strefie upuszczania i wywołaniu handleFileDrop skrypt pobierze listę plików i przekaże ją metodzie displayFiles. Funkcja displayFiles wywołuje funkcję pomocniczą clearTable, by wyczyścić wszystkie poprzednie wyniki. clearTable usuwa po kolei wszystkie wiersze z tabeli. Następnie displayFiles sprawdza długość FileList, aby dowiedzieć się, czy na strefę upuszczania zostały upuszczone jakieś pliki. Skrypt przechodzi w pętli przez elementy tablicy, korzystając z indeksu do odczytu każdego interfejsu File. Funkcja pobiera i do nowego wiersza tabeli dodaje jako nową komórkę atrybuty każdego obiektu File. Wreszcie, skrypt wyświetla tabelę poprzez spowodowanie, że staje się widoczna, jak pokazano w przykładowym wykonaniu na rysunku 14.1.
Rysunek 14.1. Przykładowy wynik pokazujący wiele atrybutów z przeciągniętych i upuszczonych na stronę plików
Wykorzystując strefę upuszczania i sekwencję FileList, HTML5 ułatwia odwiedzającym przesyłanie plików na stronę klienta. Do tego momentu odczytywaliśmy atrybuty plików, a nie dane z pliku. W pozostałej części tego rozdziału pokażemy, jak odczytywać różne rodzaje plików w JavaScripcie.
Wskazówka Atrybut type interfejsu File, który jest dziedziczony z interfejsu Blob, zwraca typ pliku MIME (ang. Multipurpose Internet Mail Extensions). Typ MIME jest typu DOMString, w którym wszystkie litery są małe i który jest zapisany przy użyciu kodowania ASCII. Ciąg tekstowy typu MIME może być używany do filtrowania rodzajów plików, na przykład obrazków (image) lub innych. Mimo że na rysunku 14.1 zaprezentowano dwa obrazki różnych rodzajów, możesz łatwo stwierdzić, że oba pliki są obrazkami, gdyż MIME zaczyna się od słowa image. Typ MIME udostępnia prosty i skuteczny sposób filtrowania i sprawdzania plików, co pokażemy w następnym podrozdziale.
Interfejs FileReader Specyfikacja HTML5 File API udostępnia nowy interfejs o nazwie FileReader, służący do wczytania plików do pamięci klienta. Interfejs ten udostępnia metody, atrybuty i zdarzenia, które pozwalają programistom odczytywać asynchronicznie pliki z JavaScriptu po stronie klienta. Poprzez zdarzenia tego interfejsu możesz
338
Rozdział 14. Praca z plikami lokalnymi
wyświetlać albo przetwarzać dane z plików. Ponieważ interfejs FileReader posiada trzy różne metody służące do odczytu, umożliwia wczytywanie wielu różnych rodzajów plików: readAsArrayBuffer(Blob) — zwraca zawartość pliku jako ArrayBuffer, readAsText(Blob [, encoding]) — zwraca zawartość pliku jako tekst DOMString, readAsDataURL(Blob) — zwraca zawartość pliku jako DOMString w postaci danych URL.
Ponieważ interfejs FileReader jest asynchroniczny, główny wątek strony może kontynuować przetwarzanie, a do przechwytywania kluczowych etapów odczytu pliku są używane zdarzenia. Tabela 14.2 pokazuje zdarzenia zdefiniowane w ramach interfejsu FileReader. Tabela 14.2. Zdarzenia FileReader Nazwa zdarzenia
Atrybut
Cel
loadstart
onloadstart
Wyzwalane, gdy rozpoczyna się odczyt pliku.
progress
onprogress
Wyzwalane przez przeglądarkę w wybranych przez nią momentach podczas odczytu pliku.
abort
onabort
Wyzwalane przy przerwaniu odczytu.
error
onerror
Wyzwalane w razie napotkania błędu podczas odczytu pliku.
load
onload
Wyzwalane, gdy pomyślnie odczytano plik.
loadend
onloadend
Wyzwalane, gdy odczyt się zakończył, pomyślnie lub błędnie.
Metody służące do odczytu treści pliku znajdujące się w interfejsie FileReader oraz zdarzenia z tego interfejsu mogą posłużyć do wykonania w przeglądarce klienta działań, które byłyby zwykle wykonywane na serwerze po przesłaniu tam pliku. W następnym przepisie użyjemy metody readAsDataURL do utworzenia miniatur wybranych obrazków w przeglądarce użytkownika i pokazania ich atrybutów.
Uwaga Pliki mogą być także odczytywane za pomocą interfejsu synchronicznego FileReaderSync wraz z wątkiem roboczym, gdyż Web Workers API pozwala metodom działać w innym wątku niż wątek główny. Interfejs FileReaderSync ma te same metody co FileReader. Aby uzyskać więcej informacji o wykorzystaniu File API w sposób synchroniczny, zajrzyj do W3C Working Draft.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Podgląd obrazków przy użyciu readAsDataURL Metoda readAsDataURL interfejsu FileReader pobiera dostarczone odwołanie do obiektu Blob albo File i odczytuje plik w postaci danych URL, które mogą być załadowane do odpowiedniego pojemnika. W tym przepisie dasz odwiedzającemu możliwość wyboru wielu plików, odfiltrujesz spośród nich obrazki, odczytasz je za pomocą readAsDataURL i załadujesz do pojemników w celu wyświetlenia jako miniatury. Zanim pojawił się HTML5 File API, aby odtworzyć taką funkcjonalność, musiałeś załadować pliki na serwer, tam je przetworzyć, a następnie załadować je na stronę przeglądarki klienta. Nakładało to konieczność wysyłania plików tam i z powrotem i przetwarzania ich na serwerze, co powodowało większe wykorzystanie
Podgląd obrazków przy użyciu readAsDataURL
339
dostępnych zasobów. Korzystając z HTML5 File API, nie musisz wysyłać plików w tę i z powrotem i możesz wykorzystać moc obliczeniową komputera klienta do przetworzenia plików. Ten przepis wykorzysta metodę readAsDataURL wraz ze zdarzeniem onload interfejsu FileReader do odczytania wybranych plików. Ponadto przepis wyświetli atrybuty każdego pliku po najechaniu na jego miniaturkę kursorem. Aby rozpocząć korzystanie z tego przepisu, wykonaj następujące kroki i utwórz listing 14.3: 1. Utwórz pusty plik HTML i dodaj HTML-owy znacznik body z listingu 14.3, zawierający element input typu file z atrybutem multiple oraz elementy służące do wyświetlania miniatur i atrybutów. 2. Dodaj element style zawierający trzy zbiory stylów do obsługi zaznaczonych i niezaznaczonych obrazków. 3. Dodaj w elemencie script funkcję handleFiles, pokazaną na listingu 14.3, która jest uruchamiana po wybraniu plików. 4. Dodaj funkcję showFile pokazującą atrybuty pliku, nad którym znajduje się kursor. 5. Dodaj funkcję clearFile, która po prostu czyści obszar atrybutów, kiedy kursor nie znajduje się już nad obrazkiem. Listing 14.3. Podgląd obrazków z wykorzystaniem readAsDataURL
14.3. FileReader — panel z obrazkami lokalnymi
Wybierz obrazki do podglądu.
Po załadowaniu strony utworzonej na podstawie listingu 14.3 prosi ona odwiedzającego o wybranie pliku lub zbioru plików. Następnie przeglądarka aktywuje zdarzenie onchange elementu input. Główna funkcja skryptu — handleFiles — ustawia najpierw najważniejsze wartości domyślne: maksymalną dozwoloną liczbę plików, maksymalny rozmiar każdego pliku oraz wyrażenie regularne, które będzie używane do dopasowywania typów MIME obrazków. Rozmiar pliku i liczba plików są ograniczone, aby uniknąć przeciążania pamięci przeglądarki, gdyż przetwarzanie będzie wykonywane w pamięci komputera klienta. W tym przepisie skrypt przejdzie w pętli przez pliki i utworzy wiele działających w tym samym czasie instancji interfejsu FileReader. Skrypt mógłby być bardziej inteligentny, jeśli chodzi o przetwarzanie, i posiadać zbiór obiektów odczytujących, które nie pobierałyby kolejnych plików do momentu zwolnienia jakiegoś obiektu odczytującego, ale ewentualną implementację tego mechanizmu zostawiamy Tobie. Skrypt sprawdza, czy liczba wybranych plików nie przekracza maksymalnej, a jeśli przekracza, wyświetla odpowiedni komunikat. Jeśli wybrana jest odpowiednia liczba plików, wtedy przechodzi w pętli przez listę plików (FileList) i sprawdza, czy każdy plik jest obrazkiem, poprzez dopasowywanie typu MIME oraz upewnia się, że rozmiar każdego z plików jest mniejszy od maksimum, które ustanowiłeś. Jeśli każdy plik spełnia te wymagania, przepis tworzy pojemnik obrazków z właściwościami dotyczącymi zdarzeń mouseover i mouseout w celu pokazywania atrybutów. Teraz skrypt jest gotowy do odczytu pliku poprzez utworzenie
342
Rozdział 14. Praca z plikami lokalnymi
nowego obiektu FileReader dla każdego obrazka. Skrypt ustawia na obiekcie FileReader zdarzenie onload, służące do załadowania wyniku (result) obiektu FileReader do atrybutu src elementu obrazka, co spowoduje utworzenie miniatury, jak pokazano na rysunku 14.2.
Rysunek 14.2. Przykładowy wynik pokazujący wybrane przez użytkownika pliki obrazków wyświetlone za pomocą metody readAsDataURL
Na koniec obiekt FileReader odczytuje każdy plik metodą readAsDataURL, która zwróci wynik w postaci danych URL do ustawienia jako źródło obrazka. Pozostała część funkcji obsługuje błędy związane z różnymi testami umieszczonymi w funkcji i wyświetla użytkownikowi odpowiednie komunikaty. Funkcje showFile i clearFile wyświetlają atrybuty plików. Przepis ten pokazuje prosty sposób użycia interfejsu FileReader i jednej z dostępnych metod odczytu. Poza tym mamy nadzieję, że ten przepis pokazał Ci, iż musisz uważać przy uruchamianiu wielu asynchronicznych odczytów jednocześnie w przeglądarce klienta. Aby się przekonać, jak ważne jest to ograniczenie, powiększ limity dotyczące rozmiaru pliku i liczby plików (ale zrób to ostrożnie, ponieważ łatwo osiągnąć maksimum pamięci dostępnej w przeglądarce). W następnym przepisie poznasz pewne dodatkowe funkcje interfejsu FileReader, które pozwolą Ci zatrzymać przetwarzanie i przechwycić mogące wystąpić błędy.
PRZEPIS DLA ZAAWANSOWANYCH Parsowanie pliku CSV za pomocą readAsText Możliwość przetwarzania plików w przeglądarce za pomocą interfejsu FileReader powinna Cię ucieszyć. Dzięki temu możesz przenieść przetwarzanie, które wcześniej było problematyczne, na stronę klienta. Jednym z typowych zastosowań jest import plików, takich jak dokumenty z danymi w formie wartości oddzielonych przecinkami (CSV). Zwykle plik jest przesyłany na serwer, a następnie parsowany albo natychmiast, albo według ustalonego harmonogramu, po czym jest importowany do bazy danych w celu wykorzystania w witrynie lub aplikacji. Proces ten zużywa cenne cykle serwera. W tym przepisie pokażemy Ci alternatywne rozwiązanie dostępne w HTML5, wykorzystujące metodę readAsText. Przepis pozwoli użytkownikowi wybrać lokalny plik CSV, a przeglądarka odczyta go i sparsuje, a następnie pokaże jego wiersze i pola. Zauważ jednak, że algorytm parsowania CSV w tym przepisie nie zajmuje się wszystkimi zawiłościami struktury CSV. W internecie jest wiele miejsc, w których możesz znaleźć solidne algorytmy parsujące pliki CSV. Celem tego przepisu jest raczej pokazanie sposobu użycia interfejsu FileReader i metody readAsText. Po sparsowaniu wartości pól mogą zostać umieszczone w ciągu tekstowym w formacie JSON i wysłane poprzez ajaksowe wywołanie usługi sieciowej do serwera w celu przetwarzania.
Parsowanie pliku CSV za pomocą readAsText
343
Poza nową metodą — readAsText — w przepisie wykorzystamy również funkcję interfejsu FileReader o nazwie abort. Ta metoda pozwala skryptowi albo użytkownikowi zatrzymać proces odczytu. Po poprawnym wywołaniu metody abort FileReader generuje ABORT_ERR, aby potwierdzić, że nastąpiło zatrzymanie. Interfejs FileReader ma pięć możliwych błędów, które mogą być wygenerowane z powodu problemów z odczytem podanego pliku albo obiektu Blob. Pokazuje je tabela 14.3. Tabela 14.3. Możliwe błędy interfejsu FileReader Stała błędu
Wartość
Wyjaśnienie
NOT_FOUND_ERR
1
Plik do odczytu nie został znaleziony.
SECURITY_ERR
2
Plik uległ zmianie podczas odczytywania, plik jest uznany za niebezpieczny albo występuje zbyt dużo odczytów pliku.
ABORT_ERR
3
Została wywołana metoda abort.
NOT_READABLE_ERR
4
Nie można odczytać pliku. Zazwyczaj jest to spowodowane brakiem uprawnień.
ENCODING_ERR
5
Wynik wywołania metody readAsDataURL nie ma formatu danych URL. Nie dotyczy to problemów z kodowaniem przy odczycie pliku jako tekstu.
W tym przepisie zgłębisz jedną z ostatnich procedur obsługi zdarzeń udostępnianą przez FileReader — onprogress. Procedura obsługi zdarzenia onprogress udostępnia powiadomienia dotyczące postępów odczytu pliku i może być używana do wyświetlania użytkownikowi statusu odczytu. Procedura obsługi zdarzenia onprogress zawiera trzy atrybuty: lengthComputable, loaded i total. Atrybut lengthComputable jest flagą logiczną, która mówi, czy atrybuty loaded i total są dostępne. Atrybut loaded jest liczbą bajtów wczytanych dotychczas do pamięci, podczas gdy total jest całkowitą liczbą bajtów do odczytania. Dzieląc progress.loaded przez progress.total, możesz uzyskać procent wykonania zadania, który może być wyświetlony użytkownikowi. W tym przepisie w miarę wczytywania pliku do pamięci strona będzie pokazywać pasek postępu ze statusem procesu odczytu. Zauważ jednak, że wyzwalanie zdarzenia progress zależy od implementacji interfejsu FileReader w przeglądarce, więc nie ma pewności co do tego, kiedy albo jak często zdarzenie to będzie generowane. Następujące kroki pozwolą Ci utworzyć kod z listingu 14.4: 1. Utwórz pustą stronę HTML ze znacznikami body i style, takimi jak pokazane na listingu 14.4, zawierającymi przycisk wyboru pliku, przycisk anulowania, blok informacji o pliku i element div przeznaczony na dane z pliku. 2. Dodaj znaczniki style i nadaj style różnym elementom, między innymi do ukrywania przycisku anulowania. 3. Dodaj znaczniki script i globalne odwołanie do instancji FileReader o nazwie textReader. Będzie to instancja FileReader służąca do odczytu wybranego pliku CSV. 4. Dodaj wiersz zawierający wywołanie addEventListener dotyczące zdarzenia load i funkcji init, która rejestruje funkcje obsługi zdarzeń obiektu textReader. 5. Dodaj odpowiednie funkcje zdarzeń: onErrorHandler, updateProgress, onAbortHandler, onLoadStartHandler i onLoadHandler. 6. Dodaj funkcję cancelFileReader, która umożliwia odwiedzającemu zatrzymanie procesu odczytu. 7. Dodaj funkcję handleFile, która uruchamia proces odczytu wybranego pliku za pomocą metody readAsText interfejsu FileReader.
344
Rozdział 14. Praca z plikami lokalnymi
Listing 14.4. Wyświetlanie zawartości pliku CSV
14.4. Podstawowe File API
Wybierz plik CSV do przetworzenia
Anuluj przetwarzanie
Po załadowaniu strony do przeglądarki odwiedzający może wybrać plik CSV do wczytania. Po wybraniu pliku przeglądarka wywołuje funkcję handleFile, przekazując jej plik. Funkcja ta sprawdza najpierw, czy wybrany plik jest typu CSV, dopasowując wyrażenie regularne do typu MIME. Jeśli typ MIME pliku nie pasuje do wyrażenia, wtedy przeglądarka wyświetla powiadomienie informujące użytkownika, że plik nie ma formatu CSV. Jeśli plik ma format CSV, wtedy kod wywołuje metodę readAsText instancji FileReader z plikiem przekazanym jako parametr. Rozpoczyna to proces odczytu w sposób asynchroniczny, który powoduje wywołanie odpowiednich zdarzeń w miarę postępów odczytu. Aby potwierdzić, że odczyt jest asynchroniczny, po wywołaniu funkcji readAsText umieściliśmy wyświetlanie atrybutów pliku. Przeglądarka pokaże atrybuty zaraz po wywołaniu readAsText, gdyż odczyt nie blokuje głównego wątku skryptu. W funkcji init w skrypcie zarejestrowaliśmy funkcję onLoadStartHandler, wywoływaną, kiedy wystąpi zdarzenie onloadstart, które zostanie aktywowane, kiedy FileReader rozpocznie odczytywanie pliku. Gdy to zdarzenie wystąpi, onLoadStartHandler wyświetli przycisk anulowania, wskaźnik postępu i wynikowy element div. W czasie odczytywania wskaźnik postępu jest aktualizowany poprzez metodę updateProgress, wywoływaną, kiedy FileReader aktywuje zdarzenie onprogress. Metoda updateProgress sprawdza, czy dostępne są atrybuty loaded i total, sprawdzając atrybut lengthComputable. Jeśli atrybut ten ma wartość true, oznacza to, że atrybuty loaded i total są dostępne. updateProgress wykorzystuje je do obliczenia procentowego ukończenia zadania i wyświetlenia tej wartości za pomocą wskaźnika postępu, który jest budowany poprzez ustawienie szerokości elementu div o identyfikatorze progMeter w elemencie div o identyfikatorze progHolder. Po zakończeniu odczytywania pliku przez obiekt FileReader przeglądarka aktywuje zdarzenie onload i wywołuje funkcję onLoadHandler, przekazując jej wyniki w zdarzeniu. W tej metodzie wyłączyliśmy przycisk anulowania i ustawiliśmy wartość postępu na 100 procent, tak aby odwiedzający wiedział, że plik został
348
Rozdział 14. Praca z plikami lokalnymi
wczytany do pamięci. Ponieważ pliki CSV mają dane ułożone w wierszach, dzielimy następnie wynik według znaku przejścia do nowego wiersza, tworząc tablicę wierszy za pomocą następującego polecenia: var fileArr = evt.target.result.split('\n');
Odwołanie result przechowuje tekstową zawartość pliku w pamięci. Po podzieleniu wyniku na tablicę, której wiersze zawierają wartości rozdzielone przecinkami, skrypt przechodzi w pętli przez każdy element tablicy i dzieli wartości według znaku przecinka. Przechodząc przez każdy wiersz, skrypt dodaje wartości do wynikowego ciągu tekstowego, który zostaje wyświetlony w elemencie div przeznaczonym na wyniki odczytania pliku, kiedy wszystkie wiersze są przetworzone, jak pokazano na rysunku 14.3.
Rysunek 14.3. Przykładowy wynik pokazujący wybrany i sparsowany plik CSV
Sposób parsowania pliku z wartościami oddzielonymi przecinkami użyty w tym przepisie jest dość prosty. Nie obsługuje przypadków takich jak przecinki występujące w wartościach i nie rozumie różnicy między wartościami zawartymi i niezawartymi w cudzysłowach. W internecie możesz znaleźć bardziej rozbudowane sposoby parsowania, lecz w celu pokazania, jak działa metoda readAsText, użyliśmy w przepisie prostego modelu. W przepisie zawarliśmy możliwość zatrzymania odczytu za pomocą przycisku anulowania. Jeśli odwiedzający kliknie przycisk anulowania, kiedy FileReader odczytuje plik, przeglądarka wywoła metodę cancelFileReader, która z kolei wywoła metodę abort na instancji FileReader — textReader. Instruuje ona instancję FileReader, aby anulować proces odczytu, usuwa z pamięci wszystkie już odczytane informacje i aktywuje zdarzenie onabort. Skrypt przechwytuje z kolei zdarzenie onabort za pomocą metody onaborthandler i wyświetla odwiedzającemu komunikat potwierdzający anulowanie odczytu. Może zauważyłeś, że skrypt zawiera procedurę obsługi wszystkich błędów przekazywanych w zdarzeniu onerror. Po przerwaniu procesu odczytu przeglądarka tworzy zdarzenie błędu o nazwie ABORT_ERR i wywołuje metodę onErrorHandler z tym błędem. Skrypt po prostu ignoruje ten błąd, gdyż przerwanie odczytu jest obsługiwane gdzie indziej. Jednak inne błędy, które mogą się pojawić, będą obsłużone odpowiednim komunikatem wyświetlanym użytkownikowi. W tym przepisie pokazaliśmy zalety korzystania z interfejsu FileReader do przetwarzania pliku CSV w przeglądarce. Wyniki parsowania pliku CSV mogą być filtrowane, wyświetlane i przygotowywane do przekazania na serwer bez wykonywania działań na serwerze. Przepis zawiera funkcje odczytu pliku, przerywania procesu i obsługi błędów, które mogą wystąpić. Może posłużyć jako wzór pozwalający rozpocząć przetwarzanie plików na Twoich stronach internetowych.
Rozszerzone specyfikacje File API
349
Rozszerzone specyfikacje File API Zastanawiasz się prawdopodobnie, czy możesz przechodzić do katalogu systemowego, tworzyć pliki i zapisywać w nich dane. Do obsługi takich przypadków użycia są przygotowywane dwie nowsze specyfikacje oparte na File API. Pierwszą jest File API: Directories and System, a drugą specyfikacja File API: Writer. Specyfikacje te przeszły już przez wiele etapów prac, ale są ciągle zmieniane, więc nie zostały jeszcze zaimplementowane w przeglądarkach. W rzeczywistości jedyną przeglądarką obsługującą w tym momencie te rozszerzone obiekty i metody File API jest Chrome.
Uwaga Począwszy od wersji 12, przeglądarka Chrome używa niestandardowej wersji wywołania requestFileSystem — webkitRequestFileSystem. Parametry wywołania są takie same, lecz trzeba używać odpowiednich wywołań zależnie od wersji Chrome. Można zakładać, że w miarę krzepnięcia specyfikacji i wzrostu liczby przeglądarek obsługujących specyfikacje File API wywołania będą znowu ogólne i takie same w różnych przeglądarkach.
Istnieje wiele obiektów i metod w obu omawianych API, lecz kilka jest kluczowych dla tego przepisu i pracy z systemem plików oraz plikami. Oto kilka bardziej przydatnych interfejsów Directories and System: FileSystem — reprezentuje system plików, z którym pracujemy, Entry — reprezentuje ogólny wpis w systemie plików, DirectoryEntry — reprezentuje katalog w systemie plików, FileEntry — reprezentuje plik w systemie plików. A oto niektóre z bardziej użytecznych interfejsów File API: Writer: BlobBuilder — służy do zarządzania obiektami Blob danych używanych wraz z interfejsami plików, FileSaver — służy do monitorowania zdarzeń zapisu i postępu, FileWriter — służy do zapisywania i dopisywania do pliku oraz obcinania go.
Interfejsy DirectoryEntry i FileEntry są oparte na interfejsie Entry, który posiada standardowe metody copy, move i remove. Oba omawiane API mają odpowiednie zdarzenia i zbiór możliwych błędów. Dodatkowo API udostępniają zarówno wywołania asynchroniczne do użytku w sposób osadzony, jak i synchroniczne, z których się korzysta w wątkach roboczych. Każdy z interfejsów posiada metody i atrybuty. Zalecamy Ci przejrzenie najnowszych wersji specyfikacji w celu uzyskania aktualnych informacji na ich temat. W tabeli 14.4 opisujemy kilka spośród metod, które będziemy wykorzystywać w tym rozdziale. Interfejs FileWriter ma również atrybuty length oraz position, które mogą być użyte do ustawienia pozycji wskaźnika określającego miejsce dopisywania lub zapisywania informacji w pliku. Jest wiele metod związanych z File API: Directories and System, w tym kopiujących i zmieniających położenie plików. Są również atrybuty pliku i katalogu, które znajdziesz w zwykłym eksploratorze plików i katalogów. Za pomocą tych metod i atrybutów możesz stosunkowo łatwo utworzyć swój własny eksplorator plików i katalogów. Niestety nie mamy tutaj miejsca na utworzenie takiego przepisu, ale wszystkie niezbędne informacje potrzebne do korzystania z tych metod i atrybutów możesz znaleźć w specyfikacji File API: Directories and System. Należy zwrócić jednak uwagę na to, że ze względów bezpieczeństwa interfejsy te mają do czynienia z systemem plików sztucznie „wygenerowanym” przez przeglądarkę dla domeny, z której pochodzi strona. W następnym przepisie utworzymy plik w lokalnym systemie plików i zapiszemy w nim jakieś dane.
350
Rozdział 14. Praca z plikami lokalnymi
Tabela 14.4. Kluczowe metody File API: Directories and System oraz Writer Interfejs
Metoda
Przeznaczenie
FileSystem
requestFileSystem
Żąda udostępnienia systemu plików, w którym można zapisywać dane aplikacji.
Entry
copyTo
Kopiuje Entry typu Directory albo File do podanej lokalizacji.
Entry
getMetadata
Pobiera metadane danego Entry.
Entry
getParent
Pobiera DirectoryEntry rodzica danego Entry.
Entry
moveTo
Przesuwa Entry z bieżącej lokalizacji w systemie plików do innej.
Entry
Remove
Usuwa obiekt Entry, niezależnie od tego, czy reprezentuje on plik, czy katalog.
Entry
toURL
Zwraca adres URL danego obiektu Entry, który może być użyty jako odwołanie.
FileEntry
createWriter
Tworzy instancję obiektu służącego do pisania do pliku.
FileEntry
File
Zwraca plik, na który wskazuje FileEntry.
FileWriter
Seek
Ustawia pozycję wskaźnika w pliku do wykonania następnego zapisu.
FileWriter
Truncate
Zmienia długość pliku przez skrócenie albo wydłużenie go.
FileWriter
Write
Zapisuje na bieżącej pozycji dane dostarczone w obiekcie File.
PRZEPIS DLA ZAAWANSOWANYCH Tworzenie lokalnego pliku W tym przepisie utworzymy stronę, która wykorzystuje lokalny plik tekstowy do przechowywania listy adresów e-mail dodanych przez użytkownika. Strona pozwoli użytkownikowi dodać adres e-mail, który zostanie dopisany do pliku, wyświetlić listę adresów e-mail z pliku oraz usunąć plik.
Uwaga Jako że nie ma obecnie interfejsu związanego z uprawnieniami dotyczącymi bezpieczeństwa, pozwalającego użytkownikowi zezwolić przeglądarce na dostęp do zapisywania pliku lokalnego, musisz poinstruować przeglądarkę Chrome, że zezwolenie zostało udzielone, uruchamiając ją z dwoma argumentami: --unlimited-quota-for-files oraz --allow-file-access-from-files. Aby włączyć przeglądarkę Chrome z tymi argumentami, możesz uruchomić terminal w systemie Mac OS i użyć następującego polecenia: open /Applications/Google\ Chrome.app -n --args --unlimited-quota-for-files --allow-file-access-from-files
To polecenie uruchomi przeglądarkę Chrome, przekazując jej argumenty wiersza poleceń, które nakazują przeglądarce umożliwienie dostępu do plików i ustawienie braku limitu rozmiaru plików. Jeśli nie uruchomisz Chrome w ten sposób, otrzymasz błędy bezpieczeństwa lub uprawnień, które uniemożliwią Ci dostęp do systemu plików1.
1
W czasie pracy nad tłumaczeniem książki udało mi się uruchomić przykład z przepisu w systemie Windows Vista bez potrzeby stosowania opisywanych flag — przyp. tłum.
Tworzenie lokalnego pliku
351
Podany skrypt normalnie użyłby metody requestFileSystem, aby pobrać odwołanie do lokalnego systemu plików. Ponieważ jednak specyfikacja ciągle się zmieniała, w przeglądarce Chrome 12 i nowszych jest stosowana własna wersja tej metody — webkitRequestFileSystem. Ponadto skrypt korzysta z warunku logicznego, tworząc obiekt Blob poprzez BlobBuilder albo WebKitBlobBuilder, w zależności od wersji przeglądarki. Aby utworzyć stronę, wykonaj następujące kroki składające się na listing 14.5: 1. Utwórz pusty plik HTML i dodaj HTML-owe body z listingu 14.5, które zawiera element input typu email, kilka elementów button oraz element div do wyświetlania listy adresów e-mail. 2. Dodaj funkcję fileErrorHandler, która będzie obsługiwać wszystkie błędy dotyczące katalogów albo plików napotkane w kodzie asynchronicznym. 3. Dodaj w skrypcie funkcję fileAction, pokazaną na listingu 14.5, która pobiera odwołanie do pliku i wywołuje odpowiednią funkcję w oparciu o działanie podjęte przez użytkownika. 4. Dodaj funkcje writeToFile, readFromFile oraz removeFile, które obsługują konkretne działania z wykorzystaniem przekazanego odwołania do pliku. 5. Dodaj procedurę nasłuchu zdarzenia dotyczącą załadowania strony, która uruchomi funkcję fileAction, pokazującą adresy e-mail, jeśli istnieje plik lokalny, w którym są zapisane. Listing 14.5. Przechowywanie listy adresów e-mail w pliku lokalnym
14.5. Tworzenie pliku — zapis asynchroniczny
Dodaj adres e-mail Odczytaj adresy e-mail Usuń plik
354
Rozdział 14. Praca z plikami lokalnymi
Aby uruchomić stronę utworzoną na listingu 14.5, włącz Chrome za pomocą polecenia zawierającego argumenty dotyczące uprawnień do lokalnego systemu plików. Jeśli przeglądarka Chrome nie zostanie uruchomiona z tymi parametrami, strona nie będzie mogła wykonywać działań na plikach lokalnych. Po załadowaniu, w przypadku gdy plik już istnieje, strona ma załadować adresy e-mail z pliku i je wyświetlić. W tym celu strona wywołuje funkcję fileAction z wartością read. W funkcji fileAction wykonywany jest szereg asynchronicznych wywołań funkcji. Najpierw pobierane jest odwołanie do systemu plików za pomocą metody webkitRequestFileSystem, której przekazywana jest flaga dotycząca trwałości plików, informacja dotycząca spodziewanej wielkości miejsca potrzebnego na przechowywanie danych, funkcja wywołania zwrotnego oraz procedura obsługi błędów. Flaga trwałości informuje przeglądarkę, co zrobić z plikami, a konkretnie: czy pozwolić przeglądarce usunąć pliki w razie potrzeby (TEMPORARY), czy je pozostawić (PERSISTENT). W tym przykładzie utworzyliśmy jedną, ogólną procedurę obsługi błędów dla wszystkich wywołań metod dotyczących katalogów i plików, mimo że niektóre kody błędów mogą nie mieć zastosowania. Jednak zbiór kodów błędów jest taki sam dla całego File API. Możesz oczywiście mieć oddzielne procedury obsługi błędów z bardziej wyspecjalizowanymi komunikatami błędów i działaniami dostosowanymi do własnych potrzeb. Po uzyskaniu uchwytu systemu plików skrypt wykonuje metodę getFile na głównym obiekcie systemu plików, przekazując jej nazwę pliku, parametr dotyczący otwarcia pliku, funkcję wywołania zwrotnego dotyczącego pomyślnego wykonania metody i procedurę obsługi błędów. W tym przypadku informujemy metodę, żeby tworzyła plik, jeśli go nie ma, poprzez ustawienie flagi create na true. Jeśli ta flaga byłaby ustawiona na false, metoda nie utworzyłaby nowego pliku i działałaby jedynie jako funkcja otwierająca plik. Po uzyskaniu obiektu pliku skrypt wywołuje następnie funkcję readFromFile, która kontynuuje asynchroniczny przebieg działań, pobierając plik i odczytując go poprzez instancję służącego do tego obiektu. Kiedy obiekt zakończy czytanie pliku, skrypt wyświetli wyniki w odpowiednim elemencie div, jak pokazano na rysunku 14.4.
Rysunek 14.4. Przykładowy wynik pokazujący adresy e-mail odczytane z pliku po ich uprzednim dodaniu
Teraz, kiedy plik już istnieje, użytkownik może dodawać adresy e-mail, wprowadzając je i klikając przycisk Dodaj adres e-mail, który uruchomi fileAction. Funkcja fileAction uruchomi writeToFile, w której utworzysz obiekt fileWriter służący do obsługi zapisu tekstu do pliku. Skrypt najpierw ustawia procedury obsługi dotyczące momentu zakończenia działania przez fileWriter (onwriteend) oraz przypadku, kiedy zapis tekstu z jakiegoś powodu się nie powiódł (onerror). Potem za pomocą BlobBuilder tworzy obiekt Blob
Podsumowanie
355
zawierający wprowadzony adres e-mail. Odpowiedni interfejs jest w tym przypadku wybierany za pomocą wyrażenia warunkowego, gdyż jest on różny w różnych wersjach przeglądarki Chrome. Następnie skrypt za pomocą metody seek obiektu fileWriter przesuwa wskaźnik położenia na koniec pliku w oparciu o właściwość length. Pamiętaj, że kiedy adres jest dodawany do pliku, na końcu każdego adresu e-mail należy dopisać HTML-owy znacznik przejścia do nowego wiersza (
) dla ułatwienia wyświetlania wielu adresów e-mail w elemencie div po wczytaniu pliku. Możesz sformatować dane z pliku w układzie, który najlepiej pasuje do pokazywanych informacji. Po zakończeniu zapisywania do pliku nowych adresów e-mail skrypt uruchamia odczyt, aby zaktualizować listę wyświetlaną na stronie. Dodatkowo skrypt udostępnia możliwość usuwania pliku przez wywołanie funkcji remove na obiekcie FileEntry. Spowoduje to usunięcie pliku z systemu plików. Jeśli opuścisz stronę i powrócisz bez usuwania pliku, plik nie zniknie, gdyż w wywołaniu webkitRequestFileSystem poprosiłeś system plików, żeby plik był trwały. W najbliższych miesiącach powinien nastąpić postęp w obsłudze specyfikacji File API: Directories and System oraz File API: Writer przez przeglądarki różnych producentów.
Podsumowanie W tym rozdziale dowiedziałeś się, jak wyświetlać atrybuty plików i odczytywać pliki w przeglądarce za pomocą nowego File API. Dodatkowo poznałeś kilka nowszych specyfikacji dotyczących plików, które dodają funkcje inne niż tylko odczytywanie plików. Przenosząc działania, które normalnie musiałyby być wykonywane za pomocą przetwarzania po stronie serwera, do przeglądarki, możesz rozłożyć przetwarzanie na komputery klienta i poprawić działanie stron z punktu widzenia odwiedzającego.
356
Rozdział 14. Praca z plikami lokalnymi
15 Integracja z urządzeniami przenośnymi W
ciągu ostatnich 20 lat HTML przeszedł długą drogę i cały czas ewoluuje dzięki pracy twórców przeglądarek i różnych grup, takich jak grupy robocze W3C. HTML5, jaki znamy, jest zbiorem HTML-owych znaczników i atrybutów, javascriptowych API oraz stylów CSS. W tej książce omówiliśmy wiele spośród rozszerzających go API, które zostały dodane w ramach HTML5. Jednak prace nad ulepszaniem działania przeglądarek z punktu widzenia użytkownika, w szczególności w związku z coraz powszechniejszym korzystaniem z urządzeń przenośnych, nie zostały zaniechane, a nawet są intensywniejsze niż kiedykolwiek. W ciągu ostatnich kilku lat nastąpiła prawdziwa eksplozja w branży urządzeń przenośnych, które teraz znacząco różnią się od telefonów komórkowych z przeszłości. Nie są to już telefony komórkowe zawierające wiele innych funkcji, lecz urządzenia przenośne, w których telefon jest tylko jedną z funkcji. W tym rozdziale zapoznasz się z jednym z najbardziej ekscytujących i nowych obszarów dotyczących działania przeglądarek: integracją z różnymi funkcjami urządzeń (mowa tu o aparatach fotograficznych, mikrofonach, żyroskopach, akcelerometrach) i aplikacjami, takimi jak bazy danych kontaktowych, aplikacje kalendarza i galerie zdjęć. Te API mają umożliwić stronom internetowym oferowanie szerokiego zakresu funkcji, w tym wideokonferencji, planowania spotkań w kalendarzu użytkownika, dodawania zdjęć z galerii użytkownika, sprawdzania poziomu naładowania akumulatorów lub innych zadań, które zwykle były zarezerwowane dla natywnych aplikacji urządzeń albo wyspecjalizowanych wtyczek. Niedługo również twórcy stron internetowych będą mogli korzystać z tych funkcji.
Krótka historia API urządzeń W maju 2009 roku w organizacji W3C została założona grupa robocza Device APIs and Policy, której celem było utworzenie zbioru API i zdarzeń po stronie klienta, służących do interakcji ze sprzętem i aplikacjami. Pierwotnie w jej statucie zostało zdefiniowanych wiele różnych API, których zakres działania był dosyć rozległy i nakładał się na prace kilku innych grup. Przewidywany termin zakończenia prac został w statucie grupy ustalony na lipiec 2011 roku. Jednak z różnych powodów grupa zmieniła statut w listopadzie 2010 roku na taki, który zawierał zawężony zbiór API. Grupa nosi teraz nazwę Device APIs Working Group i jej celem jest stworzenie kilku API skoncentrowanych na integracji z urządzeniami, a to wszystko pomiędzy listopadem 2010 a czerwcem 2013 roku, który jest nowym terminem ukończenia prac.
358
Rozdział 15. Integracja z urządzeniami przenośnymi
Jak możesz sobie wyobrazić, zakres tematyczny pokrywany przez te API jest dość szeroki. Grupa robocza robi duże postępy w tworzeniu API i specyfikacji zdarzeń, które mogą zostać wykorzystane przez producentów przeglądarek. Mimo że jest jeszcze wcześnie, niektórzy producenci już zaczęli je włączać do swoich produktów. Zbiór API i zdarzeń urządzeń grupy roboczej Device APIs zawiera następujące pozycje: Application Registration API — umożliwia stronom internetowym rejestrowanie się w systemie
jako aplikacje i pozwala im na obsługę wywołań z identyfikatorem rejestracji. Battery Status API* — udostępnia informacje dotyczące akumulatorów urządzenia. Beep API — umożliwia sterowanie sygnałami dźwiękowymi systemu urządzenia. Calendar API* — umożliwia odczyt wpisów w kalendarzu na urządzeniu. Contacts API* — umożliwia odczyt kontaktów oraz zawartych w nich informacji pochodzących
z aplikacji przechowującej kontakty w urządzeniu. Gallery API* — umożliwia dostęp do galerii urządzenia, która może zawierać pliki dźwiękowe,
wideo i zdjęcia1. Generic Sensor API — umożliwia integrację i obsługę różnych czujników w urządzeniu. HTML Media Capture* — udostępnia atrybuty i funkcje HTML-owe do przechwytywania
w urządzeniu mediów, takich jak dźwięk, wideo i obraz. Media Capture API* — udostępnia interfejs programistyczny do przechwytywania mediów
za pomocą kamery i mikrofonu urządzenia. Menu API — udostępnia możliwość kontrolowania menu aplikacji urządzenia. Messaging API* — pozwala stronie klienta wysłać wiadomość opartą o schematy URI mms,
sms albo mailto. Network Information API* — pobiera aktualny typ połączenia sieciowego urządzenia. Tasks API — umożliwia dostęp do zadań użytkownika zarządzanych na urządzeniu. Vibration API — udostępnia kontrolę nad wibracjami urządzenia2.
Wymienione API są bardzo młode i jedynie wyjątkowo są implementowane w przeglądarkach. W rzeczywistości w chwili pisania tej książki tylko Contacts API doszło do stanu zgodnego z ostatnią wersją roboczą specyfikacji3. Specyfikacje oznaczone gwiazdką (*) są opublikowane w jakiejś formie roboczej na witrynie www.w3.org. W tym rozdziale omówimy część z powyższych API, prezentując te bardziej rozwinięte, oraz zamieścimy przepisy oparte na ich implementacjach, które są aktualnie dostępne. Biorąc pod uwagę krótki czas istnienia przedstawionych API, jest zbyt wcześnie, aby stwierdzić, które przeglądarki będą obsługiwać poszczególne funkcje.
1
Prace nad tą specyfikacją nie są kontynuowane, a sama specyfikacja powinna być uważana za historyczną — przyp. tłum.
2
Na stronie www.w3.org znajduje się już opublikowana wersja robocza tej specyfikacji — przyp. tłum.
3
12 lipca 2012 roku została opublikowana wersja robocza specyfikacji Pick Contacts Intent, która docelowo ma zastąpić Contacts API — przyp. red.
Contacts API
359
Contacts API Contacts API umożliwia użytkownikowi komunikującemu się ze stroną w przeglądarce udostępnianie tej stronie informacji o kontakcie (lub kontaktach) z lokalnej aplikacji użytkownika przechowującej kontakty. Użytkownik może się zdecydować na udostępnianie stronie jedynie określonych pól. Dodatkowo użytkownik może się zdecydować udostępnić tylko kontakty spełniające kryteria wymagane przez stronę, na przykład kontakty, które mają w polu przechowującym miasto wartość „Warszawa”. Jest to API tylko do odczytu, w związku z czym obecnie nie mogą być dodawane nowe wpisy. Specyfikacja Contacts API zaleca stosowanie aktualnie używanych formatów, takich jak vCard, do dodawania albo aktualizacji kontaktów w repozytorium kontaktów użytkownika. Ponieważ Contacts API umożliwia dostęp do informacji osobistych i poufnych, przeglądarka musi poprosić o zgodę użytkownika na udzielenie dostępu do tego API. Po udzieleniu zgody JavaScript na stronie może użyć interfejsu Contacts, aby rozpocząć odnajdywanie kontaktów. Interfejs Contacts ma jedną metodę, find, która pozwala mu odnaleźć jeden kontakt lub większą ich liczbę, jak pokazano w poniższej sygnaturze metody find: void find (DOMString[] pola, ContactFindCB funkcjaSukcesu, opcjonalnie ContactErrorCB funkcjaBłędu, ´opcjonalnie ContactFindOptions opcje);
Poniżej wyjaśniamy parametry funkcji find: DOMString[] pola — tablica elementów typu DOMString, reprezentująca pola zwracanego rekordu
kontaktu;
funkcjaSukcesu — funkcja wywołania zwrotnego, uruchamiana w przypadku pomyślnego wykonania
funkcji find;
funkcjaBłędu — opcjonalna funkcja wywołania zwrotnego, uruchamiana w przypadku błędu; opcje — opcje wyszukiwania, służące do filtrowania rekordów kontaktu, na przykład na podstawie
imienia.
Aby uniknąć zablokowania strony podczas wyszukiwania kontaktów, metoda find wykorzystuje funkcje zwrotne, które są uruchamiane w przypadku jej pomyślnego lub niepomyślnego wykonania. Jeśli funkcja odnalazła pasujące kontakty oraz pola, które powinny zostać zwrócone, przeglądarka wywołuje funkcję wywołania zwrotnego dotyczącą pomyślnego wykonania z przekazaną jej w zmiennej tablicą wyników. Jeśli metoda find zakończyła działanie bez błędu, ale nie zwróciła żadnych wyników, do funkcji wywołania zwrotnego dotyczącego pomyślnego wykonania zostanie przekazana wartość null, oznaczająca nieodnalezienie dopasowanych rekordów kontaktów. Zwracany rekord kontaktu jest instancją interfejsu Contacts, który zawiera szereg atrybutów. Typami niektórych z tych atrybutów są inne interfejsy dotyczące kontaktów, takie jak ContactName, ContactAddress i tak dalej, gdyż kontakt może w rzeczywistości mieć wiele elementów składowych, na przykład kilka adresów. W tabeli 15.1 pokazujemy atrybuty interfejsu Contacts. Nie będziemy w tym miejscu opisywać wszystkich tych interfejsów, ale łatwo można je odnaleźć w aktualnej wersji roboczej specyfikacji na stronie http://www.w3.org/TR/contacts-api/.
Uwaga W chwili pisania tej książki nie było przeglądarki obsługującej Contacts API, ale prace nad specyfikacją trwały. Poniższy przepis udostępniamy jako przykład — może on zawierać błędy albo różnice w stosunku do rzeczywistych implementacji w ich ostatecznej postaci.
360
Rozdział 15. Integracja z urządzeniami przenośnymi
Tabela 15.1. Atrybuty interfejsu Contacts Typ atrybutu
Atrybut
Opis
DOMString
id
unikalny identyfikator kontaktu
DOMString
displayName
nazwa kontaktu
ContactName
name
pełna nazwa kontaktu
DOMString
nickname
pseudonim kontaktu
ContactField
phoneNumbers
jeden lub więcej numerów telefonów kontaktu w polu
ContactField
emails
jeden lub więcej adresów e-mail kontaktu w polu ContactField
ContactAddress
addresses
jeden lub więcej adresów kontaktu w obiekcie ContactAddress
ContactField
ims
jeden lub więcej identyfikatorów komunikatora kontaktu w polu
ContactOrganization
organizations
jedna lub więcej organizacji powiązanych z tym kontaktem w obiekcie ContactOrganization
Date
birthday
data urodzenia osoby, której dotyczy kontakt, umieszczona w obiekcie Date
DOMString
note
pole notatek w rekordzie kontaktu
ContactField
photos
jeden lub więcej adresów URL zdjęć dotyczących kontaktu
[DOMString]
categories
tablica wartości typu DOMStrings, reprezentująca kategorie przypisane do tego kontaktu
ContactField
urls
jeden lub więcej adresów URL kontaktu w polu ContactField
ContactField
ContactField
PRZEPIS DLA POCZĄTKUJĄCYCH Pobieranie wszystkich kontaktów i numerów telefonu Mimo że raczej nie jest zalecane pobieranie wszystkich kontaktów użytkownika, czasami może to być przydatne. Ten przepis wykorzysta metodę find interfejsu Contacts wraz z funkcjami wywołania zwrotnego dotyczącymi pomyślnego wykonania oraz błędu, aby pobrać wszystkie kontakty, sprawdzić, czy dany kontakt posiada numer telefonu komórkowego, i wyświetlić nazwę kontaktu oraz numer telefonu komórkowego w elemencie div na stronie. Aby utworzyć kod przepisu, wykonaj następujące kroki, prowadzące do listingu 15.1: 1. Utwórz pustą stronę HTML zawierającą element button oraz element div przeznaczony do pokazywania wyników. Dodaj do przycisku procedurę obsługi kliknięcia, uruchamiającą metodę findAllContacts. 2. Dodaj do strony znaczniki script oraz metodę findAllContacts, która uruchamia żądanie pobrania kontaktów. 3. Dodaj funkcje zwrotnych wywołań contactsFindSuccess oraz contactsError, służących do obsługi zdarzeń dotyczących — odpowiednio — pomyślnego i niepomyślnego wykonania żądania pobrania kontaktów.
Pobieranie wszystkich kontaktów i numerów telefonu
361
Listing 15.1. Pobieranie i wyświetlanie wszystkich numerów telefonów komórkowych z kontaktów
15.1. Pobierz wszystkie kontakty
Pobierz wszystkie kontakty z numerami telefonów komórkowych Znajdź wszystkie kontakty
W powyższym przykładzie, kiedy użytkownik kliknie przycisk Znajdź wszystkie kontakty, przeglądarka wywoła funkcję findAllContacts, która wykonuje zapytanie za pomocą interfejsu Contacts. W funkcji findAllContacts kod najpierw sprawdza, czy interfejs Contacts jest dostępny. Jeśli nie jest, przeglądarka pokazuje powiadomienie, ale możesz zastąpić je alternatywnym zachowaniem, które lepiej sprawdzi się w Twoim przypadku. Jeśli interfejs Contacts jest dostępny, kod tworzy tablicę pól, które mają być zwrócone przez metodę find tego interfejsu. Następnie kod wywołuje metodę find i przekazuje jej tablicę pól oraz funkcje wywołania zwrotnego dotyczące pomyślnego i niepomyślnego wywołania metody. Pole phoneNumbers, pobrane za pośrednictwem interfejsu Contacts, ma format interfejsu ContactField. Ten interfejs składa się z atrybutów type, value oraz pref, jak pokazano w tabeli 15.2. Tabela 15.2. Atrybuty interfejsu ContactField Typ atrybutu
Atrybut
Opis
DOMString
type
Kategoryzacja wartości
DOMString
value
Właściwa wartość pola
Boolean
pref
Flaga wskazująca na to, czy to pole jest główną, czy preferowaną wartością
Atrybut type ma typ DOMString i w przypadku pola phoneNumbers atrybut ten może mieć wartość home albo mobile. Atrybut value to sam numer, a atrybut pref jest wartością logiczną, która mówi, czy mamy do czynienia z wartością preferowaną, czy główną dla tego kontaktu. Przy wywołaniu funkcji zwrotnej dotyczącej pomyślnego wykonania, czyli contactsFindSuccess, przeglądarka przekazuje jej zbiór wyników. Jest on tablicą instancji interfejsu dotyczącego kontaktów, przez które można przejść w pętli. W tym przypadku nazwaliśmy zmienną z wynikami contacts. W funkcji wywołania zwrotnego dotyczącej pomyślnego wykonania przepis najpierw tworzy odwołanie do elementu div, który jest przeznaczony na wyniki i znajduje się na stronie, tak abyś mógł wyświetlać wszystkie pasujące wyniki. Następnie funkcja przechodzi w pętli przez tablicę kontaktów — dla każdego kontaktu przepis przechodzi przez jego numery telefonów (phoneNumbers), a dla każdego numeru telefonu kod sprawdza type, żeby dowiedzieć się, czy to numer telefonu komórkowego. Jeśli tak jest, kod wyświetla nazwę oraz numer telefonu w elemencie div. Użyta w tym przepisie metoda find interfejsu Contacts wykonuje zapytanie o wszystkie kontakty, przekazując funkcje wywołania zwrotnego dotyczące pomyślnego i niepomyślnego wykonania. Metoda
Messaging API
363
ta może przyjąć czwarty, opcjonalny parametr typu ContactFindOptions. Według specyfikacji API Contacts sposób implementacji tego interfejsu zależy od konkretnej przeglądarki, jednak celem tego interfejsu jest stworzenie filtra nakładanego na podane pola kontaktów. Jest to prosta metoda filtrująca i dopasuje do zadanego ciągu dowolne z podanych pól. Na przykład przy podaniu wartości filtra „son” i pobieraniu pól displayName oraz emails dowolny kontakt, który posiada ciąg „son” w którymś z tych zbiorów pól, na przykład „[email protected]” albo „Chuck Hudson”, zostanie dopasowany. W tym przypadku przekazany metodzie czwarty parametr wyglądałby następująco: {filter: 'son'}
Do momentu, kiedy jakaś przeglądarka rzeczywiście zaimplementuje Contacts API z filtrowaniem, możemy się tylko domyślać, w jakim stopniu będziemy mogli je kontrolować, ale wydaje się, że filtr powinien umożliwiać jakiś prosty sposób selekcji kontaktów z urządzenia.
Uwaga Contacts API jest zaprojektowane wyłącznie jako usługa tylko do odczytu danych o kontaktach zapisanych w urządzeniu. Aby wykonać dodawanie i aktualizację kontaktów w pamięci danych urządzenia, powinieneś umieścić dane kontaktu w standardowym formacie aplikacji z kontaktami, na przykład tekstowym vCard, a następnie odwołać się do tekstu tej karty poprzez element href, tak aby użytkownik mógł pobrać kartę do swojej aplikacji.
Messaging API Messaging API zaprojektowano, by umożliwić stronie wykorzystanie schematów URI sms, mms oraz mailto do wysyłania komunikatów na określony adres. API jest stosunkowo proste, ponieważ ma jeden interfejs i jedną metodę: device i sendMessage. Interfejs device ma być częścią interfejsu nawigatora, więc aby sprawdzić obsługiwanie Messaging API, możesz użyć następującego kodu: if (navigator.device.sendMessage) { … tutaj umieść Twój kod sendMessage … }
Jeśli przeglądarka obsługuje Messaging API, możesz użyć metody sendMessage, aby wysłać wiadomość do określonego odbiorcy. Poniżej pokazano składnię tej metody: void sendMessage (DOMString to [,Blob attachments] [, messagingErrorCB]);
Parametr to przyjmuje URI (mające schemat sms, mms albo mailto) i akceptuje łańcuchy zapytania zawierające elementy body i podobne. Pole attachments może być wykorzystane na zdjęcia albo wideo, a ostatni parametr jest opcjonalną procedurą obsługi błędów. Aby wysłać prostą wiadomość poprzez SMS, możesz wywołać sendMessage w następujący sposób: navigator.device.sendMessage('sms:+17705551212?body=Wkrótce%20przyjadę');
Jeśli podana jest funkcja wywołania zwrotnego obsługi błędów — co jest zalecane, ponieważ inaczej nie będziesz wiedzieć, że wywołanie sendMessage się nie powiodło — to przeglądarka przekaże jej obiekt błędu z jego kodem. Tabela 15.3 zawiera listę możliwych kodów błędów.
364
Rozdział 15. Integracja z urządzeniami przenośnymi
Tabela 15.3. Wartości kodów błędów Messaging API Wartość
Nazwa stałej
Opis
0
UNKNOWN_ERROR
Wystąpił nieznany błąd.
1
INVALID_ARGUMENT_ERROR
Metodzie sendMessage został przekazany nieprawidłowy parametr.
3
TIMEOUT_ERROR
Żądanie wysłania wiadomości przekroczyło dozwolony czas oczekiwania.
4
PENDING_OPERATION_ERROR
Przeglądarka oczekuje już wywołania zwrotnego.
5
IO_ERROR
Wystąpił błąd komunikacji.
6
NOT_SUPPORTED_ERROR
Metoda sendMessage nie jest obsługiwana.
20
PERMISSION_DENIED_ERROR
Użytkownik lub przeglądarka nie zezwolili na wywołanie metody.
30
MESSAGE_SIZE_EXCEEDED
Ograniczenie rozmiaru dla tego typu wiadomości zostało przekroczone.
Mimo że Messaging API jest krótką specyfikacją, jej konsekwencje są niezwykłe. Strony będą mogły wysyłać wiadomości tekstowe, wideo i zdjęcia poprzez wiadomości MMS i e-mail prosto z przeglądarki urządzenia.
Wskazówka Oczekuje się, że metoda sendMessage zaimplementowana w przeglądarkach będzie obsługiwać funkcjonalności URI. Wtedy możliwe będzie wysłanie wiadomość SMS do wielu odbiorców, oddzielając po prostu numery przecinkami, na przykład „sms: +48501123456,+48601123456…”.
Network Information API Aby możliwe było ograniczenie funkcjonalności oraz przesyłanych danych, co zapewni lepsze działanie aplikacji, konieczne jest określenie szybkości połączenia przeglądarki z siecią. Network Information API ma na celu udostępnienie prostego atrybutu type, który będzie oznaczać rodzaj połączenia aktualnie wykorzystywanego przez urządzenie. Na podstawie tej wartości strona mogłaby zmienić swoje zachowanie, aby dostosować się do dostępnej prędkości przesyłu danych. Rodzaj połączenia może przyjąć jedną z następujących wartości: unknown, ethernet, wifi, 2g, 3g, 4g oraz none. W HTML5 dostępny jest nowy interfejs o nazwie Connection, który posiada jeden atrybut: type. Aby odczytać aktualny rodzaj połączenia, możesz wykorzystać następujący kod: var connectionType = navigator.connection.type;
Znając rodzaj połączenia, możesz w sposób dynamiczny zmieniać arkusze stylów pomiędzy wersjami pełną i lekką albo modyfikować działanie strony, pobierając jedynie częściowe wyniki w przypadku wolniejszego połączenia. Oprócz interfejsu Connection mamy jeszcze dwa nowe zdarzenia: online i offline. Są one powiązane z obiektem window i mogą być używane do sprawdzania zmian rodzaju połączenia (w przypadku zdarzenia online) albo obsługi sytuacji rozłączania połączenia z siecią.
Wskazówka Zdarzenie online może być wysyłane wiele razy, w przypadku kiedy użytkownik zmienia rodzaje połączenia. Z tego powodu w Twoim kodzie funkcjonalność wykonywana w przypadku tego zdarzenia powinna być zminimalizowana.
Przechwytywanie obrazu za pomocą elementu input typu file
365
HTML Media Capture HTML Media Capture ma instruować przeglądarkę, by uruchomiła narzędzia przechwytywania mediów na podstawie nowych parametrów i atrybutów elementu input typu file. Na podstawie informacji o tym, jakie rodzaje informacji przyjmować w elemencie input typu file oraz czego użyć do „przechwycenia” danych wejściowych, przeglądarka uruchamia w urządzeniu odpowiedni mechanizm przechwytywania. Przechwytywać można obraz, wideo albo dźwięk, ponieważ wszystkie one są rodzajem mediów, które są zazwyczaj dostępne w urządzeniach posiadających kamery i mikrofony, takich jak smartfony, tablety i laptopy. Zazwyczaj element input typu file otwiera okno przeglądania plików, pozwalające wybrać odpowiedni plik. HTML Media Capture używa atrybutu accept elementu input typu file do zalecania sposobu wyboru odpowiedniego pliku, na przykład aparatu fotograficznego w przypadku obrazu. Oto trzy różne dostępne wartości atrybutu accept: image/* — oznacza przyjmowanie zdjęć z aparatu albo galerii zdjęć użytkownika, audio/* — oznacza przyjmowanie danych dźwiękowych poprzez nagrywanie za pomocą
mikrofonu urządzenia,
video/* — oznacza przyjmowanie plików wideo nagranych przez kamerę i mikrofon urządzenia.
Można dodać dodatkowy atrybut, sugerujący, w jaki sposób przeglądarka powinna przechwycić dane wejściowe. Atrybut capture może przyjąć jedną z czterech wartości: camera, camcorder, microphone albo filesystem. Wartością domyślną, jeśli nie podano atrybutu capture, jest filesystem. Przykładowy element input typu file służący do przechwytywania dźwięku z mikrofonu wyglądałby następująco:
Za pomocą atrybutów accept i capture będziesz mógł w ciekawy sposób wykorzystywać mikrofon i kamerę urządzenia. Istnieją już grupy pracujące nad implementacją wywołań dwukierunkowej transmisji strumieniowej audio/wideo pomiędzy urządzeniami wykorzystującymi HTML Media Capture i inne technologie HTML5, na przykład WebSocket.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Przechwytywanie obrazu za pomocą elementu input typu file W tym przepisie wykorzystamy atrybuty accept i capture elementu input typu file do tego, aby przeglądarka uruchomiła ekran służący do wykonywania zdjęć z wykorzystaniem wbudowanego aparatu fotograficznego urządzenia. Za pomocą tego ekranu użytkownik zrobi zdjęcie, które następnie zostanie zwrócone na stronę. HTML Media Capture załaduje plik zwróconego na stronę zdjęcia do nowego elementu image, przeskalowanego do miniatury i dodanego do strony. Aby utworzyć kod z listingu 15.2, wykonaj następujące kroki: 1. Utwórz pustą stronę HTML z elementem input typu file oraz elementem div przeznaczonym na miniatury. 2. Dodaj do strony znaczniki script oraz funkcję handleCapture, która obsługuje dostarczany plik za pomocą metody onChange elementu input.
366
Rozdział 15. Integracja z urządzeniami przenośnymi
Uwaga W momencie pisania tego tekstu ten przepis działał na urządzeniach z systemem Android 3.0 bądź nowszym, które obsługują HTML Media Capture, dlatego zrzuty ekranu do tego przepisu pochodzą z tabletu z systemem Android. Listing 15.2. Przechwytywanie obrazu z aparatu
15.2. Przechwytywanie mediów
Przechwytywanie mediów — aparat fotograficzny
Przechwytywanie obrazu za pomocą elementu input typu file
367
Po załadowaniu w przeglądarce strona pokazuje zwykły przycisk Wybierz plik, jak pokazano na rysunku 15.1.
Rysunek 15.1. Przykładowy wynik działania listingu 15.2, pokazujący stronę gotową do przechwycenia zdjęcia
Kiedy użytkownik kliknie przycisk, przeglądarka po odczytaniu wartości atrybutów accept i capture wie, że ma wykorzystać aparat fotograficzny, co w tym przypadku powoduje uruchomienie ekranu robienia zdjęć systemu Android, jak pokazano na rysunku 15.2.
Rysunek 15 2. Domyślny ekran aparatu fotograficznego wyświetlony na urządzeniu w celu przechwycenia obrazu
Po zrobieniu zdjęcia i przekazaniu na stronę jego pliku przeglądarka wywołuje funkcję handleCapture, jako argument przekazując jej plik. W funkcji handleCapture najpierw sprawdzany jest typ pliku, a po potwierdzeniu, że plik jest obrazkiem, tworzony jest nowy element image, który następnie jest dodawany do strony, a do niego jest ładowany plik. Na rysunku 15.3 przycisk Wybierz plik został kliknięty kilka razy, a uzyskane zdjęcia w postaci miniatur zostały dodane do elementu div, dzięki czemu można je oglądać.
368
Rozdział 15. Integracja z urządzeniami przenośnymi
Rysunek 15.3. Po zrobieniu zdjęcia urządzenie ponownie wyświetla stronę aplikacji wraz z miniaturką zdjęcia
DeviceOrientation Event Specification DeviceOrientation Event Specification powstała w grupie roboczej Device API, ale później przeniesiono ją do grupy roboczej Geolocation, więc nie zobaczysz jej już na aktualnej liście grupy roboczej Device API. Pozostawiliśmy ją w tym rozdziale, gdyż jest ona w szczególny sposób skoncentrowana na integracji z wewnętrznym żyroskopem urządzenia, którego użytkownik w danym momencie używa. Wiele telefonów, tabletów, a nawet komputerów ma wbudowany taki wewnętrzny żyroskop, a przeglądarki, takie jak Chrome, mają już zaimplementowane odpowiednie zdarzenia w swoich javascriptowych silnikach. Specyfikacja DeviceOrientation organizacji W3C opisuje trzy nowe zdarzenia, które zostały wymienione poniżej: deviceorientation — udostępnia kierunki w formacie alfa, beta, gamma, pokazujące położenie
przestrzenne urządzenia, compassneedscalibration — generowane przez przeglądarkę zdarzenie, które stwierdza, że kompas
urządzenia wymaga kalibracji, devicemotion — przekazuje informacje o przyspieszeniu, przyspieszeniu z uwzględnieniem
grawitacji, szybkości obrotu oraz odstępie czasowym pomiędzy kolejnymi wywołaniami zdarzenia. Wszystkie trzy zdarzenia dotyczące położenia urządzenia są generowane na obiekcie window, a ich rejestracja nie odbiega od rejestracji innych zwykłych zdarzeń na tym obiekcie. Zdarzenie deviceorientation poprzez swoje dane przekazane do procedury obsługi udostępnia cztery możliwe do odczytu atrybuty: alpha, beta, gamma i absolute. Właściwości alpha, beta i gamma odpowiadają ułożeniu urządzenia w trzech wymiarach. Właściwość alpha reprezentuje obrót w płaszczyźnie poziomej, a beta i gamma odpowiadają nachyleniu w lewo/prawo oraz w przód/tył. Na przykład laptop na biurku miałby beta równe 0 i gamma równe 0, podczas gdy alpha miałaby wartość oznaczającą kierunek, w jakim jest ustawiony. W przypadku laptopa zorientowanie w przestrzeni jest wyznaczane dla klawiatury, a nie ekranu, podczas gdy orientacja telefonu komórkowego dotyczy samego telefonu. Właściwość absolute informuje, czy przeglądarka może podać bezwzględne wartości
Tworzenie poziomicy
369
kątów kierunków. Jeśli nie może, jej wartość będzie równa false. W większości naszych testów wartość ta była rzeczywiście równa false, chociaż kąty beta i gamma miały wartości bezwzględne, a alpha miała arbitralną wartość 0 podczas uruchamiania strony. Zdarzenie compassneedscalibration jest proste i powiadamia okno, że wewnętrzny kompas urządzenia wymaga kalibracji. Według specyfikacji zdarzenie to może zostać anulowane przez stronę internetową lub aplikację, a domyślny interfejs użytkownika służący do kalibracji urządzenia może zostać zastąpiony niestandardową kalibracją udostępnioną przez aplikację internetową. Jednak szczegóły dotyczące tego zdarzenia nie są jeszcze ustalone. Zdarzenie devicemotion jest bardziej skomplikowane, ponieważ zawiera atrybuty dotyczące przyspieszenia, rotacji i interwału. Atrybut acceleration jest instancją nowego interfejsu, DeviceAcceleration, który udostępnia atrybuty przyspieszenia x, y, z w formie typu danych double, pokazujące przyspieszenie w kierunkach X, Y i Z. Szybkość rotacji jest również instancją interfejsu, ale interfejsu DeviceRotationRate, który udostępnia dane o obrocie w postaci argumentów alpha, beta, gamma. Wszystkie atrybuty zdarzenia devicemotion są w specyfikacji określone jako opcjonalne. Tabela 15.4 pokazuje atrybuty zdarzenia devicemotion bardziej szczegółowo. Tabela 15.4. Wartości atrybutów zdarzenia devicemotion Atrybut
Typ
Opis
acceleration
DeviceAcceleration
Przyspieszenie urządzenia reprezentowane jako wartości X, Y, Z.
accelerationIncludingGravity
DeviceAcceleration
Przyspieszenie urządzenia uwzględniające efekt grawitacji, reprezentowane poprzez wartości X, Y, Z.
rotationRate
DeviceRotationRate
Obrót urządzenia pokazany za pomocą kątów alpha, beta i gamma.
interval
double
Czas w milisekundach, co jaki są zbierane dane o przyspieszeniu i obrocie. Powinna to być stała.
PRZEPIS DLA ŚREDNIO ZAAWANSOWANYCH Tworzenie poziomicy Jeśli miałeś okazję grania w gry na urządzeniach przenośnych, najprawdopodobniej widziałeś przykładową natywną aplikację poziomicy, która jest dostępna na większości platform przenośnych i służy do pokazywania położenia urządzenia. Możesz wykorzystać zdarzenie deviceorientation, aby udostępnić ten sam rodzaj funkcji w JavaScripcie po stronie klienta dzięki sprawdzaniu pól beta i gamma zdarzenia. (Nie potrzebujesz pola alpha, gdyż poziomica nie wykorzystuje informacji o obrocie urządzenia w płaszczyźnie poziomej). W tym przepisie utworzysz prymitywną poziomicę, złożoną z ułożonych w warstwy elementów canvas, oraz będziesz wyświetlał wartości beta i gamma, jak pokazano na rysunku 15.4. Możesz poprawić algorytmy pozycjonowania, dodając funkcje, takie jak ograniczenie obszaru poruszania się pęcherzyka do okręgu, ale w tym przepisie chcemy pokazać podstawy obsługi danych dotyczących położenia urządzenia. Aby utworzyć poziomicę, użyj listingu 15.3 i wykonaj następujące czynności: 1. Utwórz pustą stronę HTML zawierającą trzy elementy canvas, które obejmują poziomicę, i dodaj elementy span do wyświetlania wartości beta i gamma.
370
Rozdział 15. Integracja z urządzeniami przenośnymi
Rysunek 15.4. Przykładowy wynik pokazujący warstwy elementów canvas poziomicy i wartości beta/gamma na przechylonym urządzeniu
2. Nadaj styl elementom canvas. 3. W znacznikach script dodaj funkcję init, która zawiera definicję procedury obsługi zdarzenia deviceorientation. 4. Dodaj kod uruchamiający funkcję init po załadowaniu strony, wykorzystując window.addEventListener.
Uwaga Ten przepis wymaga od Twojej przeglądarki obsługi elementu canvas oraz tego, żeby urządzenie, na którym uruchamiasz stronę, posiadało wewnętrzny żyroskop udostępniający wartości beta i gamma. Listing 15.3. Tworzenie poziomicy z wartościami beta i gamma
15.3. Poziomica
Rozdział 15. Poziomica
Tło poziomicy.
Pęcherzyk poruszający się i pokazujący poziom.
Nałożone okręgi pokazujące środek.
Wartość beta:
Wartość gamma:
Po załadowaniu strony do przeglądarki i wywołaniu funkcji init skrypt najpierw utworzy różne składniki poziomicy. Poziomnica składa się z trzech elementów canvas: tła, pęcherzyka oraz znajdującego się na pierwszym planie środkowego pierścienia. Cel podzielenia poziomicy na te trzy składniki jest dwojaki. Po pierwsze, umożliwia ułożenie warstwowe z pęcherzykiem znajdującym się ponad tłem, ale pod środkowym
Podsumowanie
373
pierścieniem, aby wyglądało to jak w prawdziwej poziomicy. Po drugie, pozwala Ci to programowo przesuwać pęcherzyk, bez konieczności odrysowywania pozostałych elementów przy każdym ruchu. Po narysowaniu składników poziomicy skrypt ustawia procedurę obsługi zdarzenia deviceorientation. Funkcja obsługi zdarzenia najpierw sprawdza, czy doszło do jakiejkolwiek zmiany wartości beta lub gamma, a następnie przypisuje zmiennym tymczasowym nowe wartości, jeśli taka zmiana zaistniała. Następnie funkcja ustawia pewne zmienne korekty pozycji, które są używane w obliczeniach dotyczących położenia płótna pęcherzyka. Zmienna adjFactor służy do „przyspieszenia” ruchu, podczas gdy zmienna adjMax określa maksymalną odległość, o jaką pęcherzyk można przesunąć. Po obliczeniu nowych współrzędnych górnej i lewej krawędzi płótna pęcherzyka płótno jest przesuwane i wyświetlane są zaktualizowane kąty beta i gamma. Zauważ, że w przypadku kątów beta i gamma używamy jedynie całkowitych części wartości typu double ze zdarzenia. Kąty przekazywane w naszych testach są niezmiernie dokładne, więc chcąc zapobiec przesuwaniu płótna przy najdrobniejszych zmianach kąta, zdecydowaliśmy się przesuwać go tylko wtedy, gdy nastąpiła zmiana o cały stopień.
Podsumowanie W tym rozdziale poznałeś kilka nowych i jeszcze tworzonych specyfikacji API oraz zdarzeń, których celem jest zapewnienie dostępu do wszelkiego rodzaju informacji i funkcji urządzeń. Ukończenie, publikacja i udostępnienie ich do użytku w różnych przeglądarkach jest tylko kwestią czasu. Aplikacje internetowe będą w końcu miały dostęp do funkcji urządzeń, które teraz są wykorzystywane tylko w natywnych aplikacjach. Wiele specyfikacji dotyczących API urządzeń pozostaje jeszcze nieukończonych, ale postępy prac wykazują, że możliwości HTML5 ciągle się zwiększają.
374
Rozdział 15. Integracja z urządzeniami przenośnymi
Przepisy PRZEPISY DLA POCZĄTKUJĄCYCH Budowa startowego dokumentu HTML5 . ....................................................................26 Wykorzystanie elementu header do utworzenia nagłówka witryny ...................................29 Wykorzystanie elementu hgroup do grupowania nagłówków ...........................................31 Tworzenie nawigacji przy użyciu elementu nav . ............................................................31 Użycie elementu article . ............................................................................................34 Tworzenie paska bocznego za pomocą elementu aside ................................................37 Użycie elementu footer . ............................................................................................39 Oznaczanie rysunków i ich podpisów elementami figure i figcaption ...............................51 Oznaczanie daty i czasu za pomocą elementu time ......................................................53 Tworzenie widżetu przełącznika za pomocą elementu details ........................................54 Użycie elementu address do danych kontaktowych .......................................................56 Podświetlanie tekstu za pomocą elementu mark ..........................................................57 Użycie elementu s do pokazania niepoprawnej lub nieistotnej treści ..............................58 Opakowywanie elementów łączami . ...........................................................................65 Obsługa Internet Explorera . .......................................................................................73 Testowanie działania nowych możliwości HTML5 . ........................................................75 Korzystanie z własnych czcionek przy użyciu @font-face ................................................92 Tworzenie formularza do danych kontaktowych ..........................................................109 Tworzenie formularza wyszukiwania przy użyciu input type="search" ............................112 Tworzenie kontrolek kalendarza i czasu . ...................................................................113 Tworzenie pola do wprowadzania liczby . ...................................................................116 Tworzenie suwaka (bez potrzeby użycia JavaScriptu) ...................................................117 Tworzenie próbnika kolorów . ...................................................................................117 Wyświetlanie wyników za pomocą elementu output ....................................................118
376
Przepisy
Użycie tekstu zastępczego formularza . .....................................................................119 Autouzupełnianie za pomocą atrybutu list i elementu datalist ......................................120 Śledzenie postępu wykonania zadania za pomocą elementu progress .........................121 Wskazywanie wyniku pomiaru za pomocą elementu meter ..........................................122 Przechodzenie do elementu form po załadowaniu strony .............................................123 Zezwalanie na wiele wartości . .................................................................................124 Prosta walidacja przy użyciu atrybutu required ............................................................125 Nakładanie ograniczeń na wprowadzane dane ...........................................................126 Nałożenie siatki na płótno . ......................................................................................135 Tworzenie prostych kształtów i linii . .........................................................................139 Dodawanie tekstu . .................................................................................................147 Wstawianie obrazka . ...............................................................................................148 Dołączanie filmów za pomocą elementu video ...........................................................163 Umieszczanie dźwięku za pomocą elementu audio .....................................................185 Dodawanie do historii wpisów za pomocą pushState ..................................................204 Tworzenie przeglądarki obrazków . ............................................................................207 Zmiana historii za pomocą replaceState . ..................................................................211 Ustalanie położenia geograficznego za pomocą zwykłego wywołania getCurrentPosition . ...............................................................................................225 Pobieranie i ustawianie danych w pamięci sesji .........................................................250 Nadawanie stylów z pamięci sesji . ...........................................................................253 Rozmawianie przez gniazda sieciowe . ......................................................................280 Tworzenie wątku roboczego . ....................................................................................285 Przeciąganie i upuszczanie pomiędzy elementami div .................................................299 Tworzenie pliku manifestu . ......................................................................................310 Korzystanie ze stron internetowych offline .................................................................312 Wyświetlanie prostego powiadomienia ......................................................................318 Odczyt atrybutów pliku . ...........................................................................................332 Przetwarzanie wielu plików za pomocą przeciągania i upuszczania ...............................334 Pobieranie wszystkich kontaktów i numerów telefonu .................................................360
PRZEPISY DLA ŚREDNIO ZAAWANSOWANYCH Grupowanie treści przy użyciu elementu section ...........................................................35 Wykorzystanie narzędzia HTML5 Outliner do utworzenia prawidłowej struktury dokumentu . ..............................................................................................41 Dodawanie informacji semantycznych za pomocą mikrodanych .....................................66
Przepisy
377
Stosowanie WAI-ARIA z HTML5 . .................................................................................67 Wykorzystanie jQuery do zastąpienia kalendarza ..........................................................77 Wykorzystanie biblioteki Modernizr do wykrywania możliwości .......................................79 Tworzenie dostosowującego się projektu za pomocą CSS3 Media Queries .....................85 Tworzenie przycisków za pomocą gradientów CSS i wielu teł .........................................95 Upiększanie witryny za pomocą transformacji i przejść ..................................................98 Pisanie własnych reguł walidacji . .............................................................................126 Dostosowywanie formularza i nadawanie mu stylu .....................................................128 Rysowanie wielokątów za pomocą ścieżki . ................................................................144 Rysowanie łuków i okręgów . ....................................................................................146 Przycinanie obrazka . ...............................................................................................149 Animacja mapy sprite’ów . .......................................................................................150 Włączanie wideo we wszystkich przeglądarkach .........................................................166 Tworzenie wideo z napisami . ...................................................................................172 Umieszczanie dźwięku we wszystkich przeglądarkach .................................................186 Tworzenie miksera . ................................................................................................190 Pobieranie stanu w przeglądarce obrazków . ..............................................................209 Zmiana historii strony . ............................................................................................213 Testowanie bezpieczeństwa historii . ........................................................................218 Wyświetlanie na mapie informacji o lokalizacji przy użyciu getCurrentPosition ...............228 Określanie odległości za pomocą opcji lokalizacji .......................................................233 Zapisywanie formularzy za pomocą lokalnego przechowywania danych .........................257 Dodawanie dwukierunkowej komunikacji . .................................................................288 Podgląd obrazków przy użyciu readAsDataURL ...........................................................338 Przechwytywanie obrazu za pomocą elementu input typu file .......................................365 Tworzenie poziomicy . ..............................................................................................369
PRZEPISY DLA ZAAWANSOWANYCH Wykorzystanie wszystkich nowych elementów do utworzenia strony z wiadomościami .....43 Wykorzystanie wszystkich nowych elementów do utworzenia strony z wynikami wyszukiwania . ........................................................................................46 Oznaczanie komentarzami strony z artykułem . ............................................................69 Tworzenie animacji za pomocą CSS-a . ......................................................................103 Wszystko razem — tworzenie formularza rejestracyjnego ............................................130 Animowanie obrazka . ..............................................................................................154 Animacja pionowego wykresu słupkowego .................................................................157
378
Przepisy
Tworzenie niestandardowych kontrolek . ....................................................................176 Dodawanie internetowego radia . ..............................................................................194 Używanie zaawansowanych obiektów danych stanu do przenoszenia informacji pomiędzy stronami . ..............................................................................................215 Podążanie za poruszającym się obiektem dzięki watchPosition ....................................239 Przechwytywanie zdarzeń w pamięci lokalnej ..............................................................261 Użycie sieciowej bazy danych do stworzenia listy zakupów ..........................................270 Wykorzystywanie współdzielonych wątków roboczych ..................................................291 Wykorzystanie zdarzeń i obiektu dataTransfer ............................................................302 Tworzenie strony powiadomień o tweetach . ..............................................................322 Parsowanie pliku CSV za pomocą readAsText . ..........................................................342 Tworzenie lokalnego pliku . ......................................................................................350
Skorowidz A adresy e-mail, 351 aktualizacja pamięci podręcznej, 312 Android, 91 animacja, 103 mapy sprite’ów, 150 wykresu, 157–162 animowana zmiana koloru, 101 animowanie obrazka, 101, 154 animowany baner, 104 API dla multimediów, 175, 189 API HTML5, 220 arkusz stylów smartphone.css, 86 artykuł z komentarzami, 71 atrybut accept, 365 address, 232 audio, 170 autofocus, 123 autoplay, 170, 188 capture, 365 controls, 171, 189 draggable, 297, 299 dropzone, 298, 301 formnovalidate, 127 kind, 172 list, 120 loop, 170, 188 manifest, 310 multiple, 124 novalidate, 127 pattern, 126 placeholder, 119 port, 295 poster, 169 preload, 170, 188 readyState, 280 required, 125
src, 169, 188 step, 126 type, 364 atrybuty elementu audio, 187 interfejsu ContactField, 362 interfejsu Contacts, 360 obiektu adresowego, 232 pliku, 332 storageEvent, 261 wideo, 169 autouzupełnianie, 120
C ciasteczka, 247 Contacts API, 359 CSS, 74 dla ekranów, 89 dla smartfonów, 90 CSS3, 85 CSS3 Media Queries, 85 czcionki, 92, 95 czyszczenie pamięci, 260
B
D
baza danych, 270 bezpieczeństwo, 310 danych, 248 File API, 331 historii, 218 biblioteka Modernizr, 79 biblioteki, 220 bloki try-catch, 253 błąd CONSTRAINT_ERR, 270 DATABASE_ERR, 269 PERMISSION_DENIED, 231 POSITION_UNAVAILABLE, 231 QUOTA_ERR, 270 SYNTAX_ERR, 270 TIMEOUT, 231 TIMEOUT_ERR, 270 TOO_LARGE_ERR, 269 UNKNOWN_ERR, 269 VERSION_ERR, 269 błędy interfejsu FileReader, 343 Messaging API, 364
dane formularza, 257 deklaracja @font-face, 92 dropzone, 298 Device APIs Working Group, 357 DeviceOrientation Event Specification, 368 dodawanie informacji semantycznych, 66 internetowego radia, 194 pliku .js, 294 tekstu, 147 treści zastępczej, 186 wątku roboczego, 290 wpisów do historii, 204 DOM, 73, 284 dostęp do danych, 248 Drag and Drop API, 297 DTD, Document Type Definition, 26
380
Skorowidz
E efekt hover, 100 efekty, 140 gradientu, 96 przejścia, 101 element abbr, 64 address, 56 article, 34, 36 aside, 37 audio, 185 b, 63 canvas, 76, 133, 153 cite, 58 datalist, 120 del, 58 details, 54 div, 37 dl, 61 doctype, 26 em, 64 figcaption, 53 figure, 51 footer, 39 form, 123, 128 header, 29 hgroup, 31 hr, 64 i, 64 image, 365 input, 77 input typu file, 365 link, 27 mark, 57 meter, 122 nav, 31 ol, 59 output, 118 progress, 121 s, 58 script, 27 section, 34–37, 62 small, 63 source, 166 strong, 64 time, 53 track, 172 video, 163, 169, 171 elementy listy, 108 usunięte, 64
F FIFO, first in, first out, 218 File API, 331, 349, 355 Directories and System, 349 Writer, 349, 355 film, 163 filtrowanie plików, 334 flaga trwałości, 354 formatowanie kwadratu, 141 napisów, 174 formaty plików, 93 formularz, 108 kontaktowy, 109, 313 rejestracyjny, 129–132 z obliczeniami, 313 funkcja animateSprite, 152 blockHandleDragStart, 307 calculateDistance, 234 changeField, 260 checkStorage, 260 clearFile, 342 clearRect, 146 displayFiles, 337 dragStartHandler, 301 drawImage, 149 fileAction, 351, 354 geoSuccess, 231 getGroceryItems, 276 getResult, 329 grabTweets, 328 growBars, 162 handleCapture, 367 handleDragOver, 337 handleFileDrop, 337 initGraph, 161 initSettings, 161 loadPages, 214 loadStations, 200 moveGear, 156 nextState, 211 onLoadStartHandler, 347 onOpen, 283 onStorageEvent, 266 remove, 355 reverseGeoCode, 234 sendNumber, 295 setLocation, 234 setPermission, 320 setStation, 200
showFile, 342 showGrid, 136, 138 showImage, 207 startWatch, 244 startWorkerThread, 287 swapCache, 316 towerHandleDragOver, 308 wywołania zwrotnego, 229
G generator czcionek, 94 geokodowanie, 224 Geolocation API, 75, 223, 245 gniazdo sieciowe, 279 Google Font Directory, 94 gra Wieże Hanoi, 303, 307 gradient liniowy, 96 gradienty, 95, 141 gradienty z zatrzymaniami, 97 grupowanie nagłówków, 31 treści, 35
H historia przeglądarki, 203 sesji, 203 strony, 213 History API, 203 HTML, Hypertext Markup Language, 13 HTML Media Capture, 365 HTML5, 15 HTML5 Boilerplate, 75 HTML5 Outliner, 41 HTML5Shiv, 74
I identyfikator stateInfo, 210 implementacja historii, 205 informacje o kontakcie, 359 lokalizacji, 228 położeniu geograficznym, 223 przeglądarce, 84 interfejs BlobBuilder, 349 DataTransfer, 298, 301
Skorowidz
device, 363 DirectoryEntry, 349 Entry, 349 File, 331 FileEntry, 349 FileList, 331, 334 FileReader, 331, 337 FileReaderSync, 338 FileSaver, 349 FileSystem, 349 FileWriter, 349 Notification, 317 NotificationCenter, 316 SharedWorker, 291, 296 Storage, 249 Worker, 284
J JavaScript, 73 jQuery, 77, 78 JSON, 288
K kadry animacji, 157 klasa no-webgl, 80 no-sessionstorage, 81 sessionstorage, 81 klucz themeColor, 257 visits, 252 kodek MP3, 186 Ogg Vorbis, 186 kodeki wideo, 164 kodowanie znaków, 26 kolor motywu, 256 tła, 253 komentarz w pliku, 312 komentarze, 69 kompatybilność przeglądarek, 318 komunikacja dwukierunkowa, 288 z serwerami, 279 komunikat błędu, 125, 200, 351 do klientów, 296 END, 328 TWEET, 328
komunikaty błędów, 129 walidacji, 110 konfiguracja biblioteki Modernizr, 80 elementu canvas, 134 konspekt dokumentu, 42 kontakty, 359 kontrolka wprowadzania daty, 77 kontrolki domyślne, 182 formularzy, 108 niestandardowe, 176 wideo, 177 kroje pisma, 94
L liczba par klucz-wartość, 258 wizyt, 251 licznik idxCounter, 211 lista JSON, 200 nieuporządkowana, 108 uporządkowana, 59 zakupów, 272 listy zagnieżdżone, 60 logo HTML5, 17 lokalizacja, 223, 225, 233 lokalne przechowywanie danych, 257, 262 lokalny plik, 350
Ł ładowanie skryptów, 83 łącza, 65
M manifest aplikacji obliczającej, 314 mapa sprite’ów, 151 Messaging API, 363 metoda abort, 343 cancel, 317 clear, 260, 267 clearWatch, 239 createNotification, 317, 320, 322 createPattern, 150
381
dbPresent, 276 deleteItem, 277 drawImage, 149, 151 executeSql, 269 fillText, 138, 147 find, 359 fireNotification, 320 getContext, 76, 134 getCurrentPosition, 224, 227, 234 getFile, 354 getGroceryItems, 276 history.pushState, 205 importScripts, 329 initShoppingDb, 276 key, 258 Modernizr.load, 83 onaborthandler, 348 onErrorHandler, 348 openDatabase, 268, 276 postMessage, 284, 288 preventDefault, 301, 309 pushState, 204 readAsDataURL, 338–342 readAsText, 342 readTransaction, 276 removeItem, 253, 260 replaceState, 211 requestFileSystem, 351 requestPermission, 320 rotate, 154 scale, 154 setItem, 250 show, 317, 322 showGroceryItems, 276 strokeText, 147 terminate, 284 transaction, 269, 276 translate, 154 watchPosition, 239, 244 webkitRequestFileSystem, 351, 354 window.addEventListener, 136 window.openDatabase, 276 metody DataTransfer, 298 File API, 350 FileReader, 338 mikrodane, 66 mikroformaty, 67 mikser, 190, 194 motyw domyślny, 253
382
Skorowidz
N nadawanie stylu, 141, 253 nagłówek, 30 CACHE, 311 FALLBACK, 311 NETWORK, 312 napisy wideo, 172, 173 narzędzia Google Chrome, 252 płótna, 139 narzędzie @font-face Generator, 93 HTML5 Outliner, 41 nawigacja, 31 nazwy klas, 28 Network Information API, 364 notacja z kropką, 276 notatki, 262 Notification API, 316, 317
O obiekt ApplicationCache, 315 Blob, 351 coords, 227 danych stanu, 215 dataTransfer, 302 FileEntry, 355 FileReader, 342 fileWriter, 355 localStorage, 249, 260 lokalizacji, 227 sessionStorage, 249 storageEvent, 261 sworker, 295 timestamp, 227 WebSocket, 279 WindowDatabase, 268 obrazek, 148 obsługa @font-face, 92 animacji, 103, 104 atrybutu autofocus, 123 formnovalidate, 127 multiple, 124 pattern, 126 required, 125 step, 127 błędów, 231, 269, 276, 354
elementu canvas, 370 datalist, 120 output, 119 progress, 122 video, 164 File API, 332 gradientów, 95 History API, 204 Internet Explorera, 73 iPhone’a, 91 pamięci podręcznej, 309 pola wprowadzania liczby, 116 próbnika kolorów, 118 przejść, 98 transformacji, 98 typu wejściowego datetime, 113 email, 110 search, 112 tel, 111 url, 111 wątków roboczych, 285 WebSocket API, 280 zapytań o media, 86 zdarzenia onmessage, 287 zdarzenia popstate, 210 zdarzeń, 266 odczyt atrybutów pliku, 332 odnajdywanie lokalizacji, 225 odświeżanie pamięci podręcznej, 310 odtwarzacz Flash Player, 186 JW Playera, 186 radia internetowego, 194 odtwarzacze dźwięku, 185 wideo, 183 odwrócone geokodowanie, 224 offline, 313 określanie odległości, 233 opakowywanie łączy, 65 opcje CSS-a, 81 lokalizacji, 233 osadzanie dźwięku, 186 wideo, 167 oznaczanie daty i czasu, 53 rysunków, 51 wiadomości, 34
P pamięć lokalna, 258, 261 podręczna, 309, 312 sesji, 250, 252 para klucz-wartość, 248, 266 parametry funkcji find, 359 metody executeSql, 269 getCurrentPosition, 225 openDatabase, 268 transaction, 269 watchPosition, 239 parsowanie pliku, 348 pliku CSV, 342 tweetów, 326 pasek boczny, 37 postępu, 122 przewijania, 183 plik CSV, 342, 347 httpd.conf, 168 lokalny, 351 manifestu, 309, 310 współdzielonego wątku roboczego, 294 pliki .appcache, 310 .eot, 93 .htm, 27 .js, 294 .mov, 165 .mp3, 185 .mp4, 166 .ogv, 166 .otf, 93 .svg, 93 .ttf, 93 .vtt, 172 .webm, 166 .woff, 93 dźwiękowe, 189 płótno, 135, 153 pobieranie kontaktów, 360 numerów telefonów, 361 stanu z historii, 209 tweetów, 328 z historii, 213
Skorowidz
podgląd obrazków, 338 podświetlanie tekstu, 57 pokazywanie motywu, 256 polecenia SQL, 268 polyfilling, 82 połączenie z gniazdem, 279 położenie geograficzne, 225, 232, 238 port klienta, 296 powiadomienia, 318 powiadomienia o tweetach, 322 poziomica, 369 poziomy uprawnień, 323, 328 prezentacja slajdów, 215 próbnik kolorów, 117 przechowywanie danych, 247, 257 w pamięci lokalnej, 257, 262 przechwytywanie błędu, 253 obrazu, 365 zdarzeń, 261 zdarzeń pamięci, 266 przeciąganie obiektu, 297, 299, 302 plików, 334 przeglądarka obrazków, 207, 209 przeglądarki, 73 przejścia, 98 przekształcenia płótna, 153 przełącznik, 54 przenoszenie informacji, 215 przesyłanie wiadomości do wątku, 285 przycinanie obrazka, 150 przycisk Zastąp stan, 212
R radio internetowe, 194 rodzaje połączeń, 364 składowania, 248 role, 68 rysowanie krzywych, 147 linii, 142 łuku, 146 prostokąta, 139 siatki płótna, 136 ścieżek, 142 trójkąta, 143 wielokąta, 144
S siatka, 135 sieciowe bazy danych, 277 składnia, 27 skrypt Modernizr, 80 MooTools, 172 słownik, 61 specyfikacja Contacts API, 359 DeviceOrientation, 368 File API, 349 HTML5, 15 Microdata, 66 WAI-ARIA, 67, 69 Web SQL Database API, 268 Web Storage, 249 strefa upuszczania, 309 strona startowa, 28 z wiadomościami, 43 z wynikami wyszukiwania, 46, 49 zastępcza, 314 struktura dokumentu, 41 styl formularza, 128 szablony, 75
Ś ścieżki, 144 śledzenie położenia, 239, 240 przepływu danych, 283 tweetów, 326
T tabela departments, 271 groceryitems, 270 tablica connections, 296 zgodności przeglądarek, 84 tekst, 147 tekst zastępczy formularza, 119 testowanie HTML5, 84 obsługi geolokalizacji, 76 transakcja, 269 transformacje, 98
383
transformacje CSS, 99 treści nieistotne, 58 tweety, 322 tworzenie animacji, 103 bazy danych, 270 formularza, 109 formularza rejestracyjnego, 130 formularza wyszukiwania, 112 gradientów, 141 konspektu dokumentu, 42 kontrolek kalendarza, 113 listy zakupów, 272 lokalnego pliku, 350 mikrodanych, 67 miksera, 190 nawigacji, 31 niestandardowych kontrolek, 176 paska bocznego, 37 pliku manifestu, 310 pojemnika, 292 połączenia, 279, 281 powiadomień, 318, 323 poziomicy, 369, 370 próbnika kolorów, 117 przeglądarki obrazków, 207 przycisków, 95 słownika, 61 strony klienta, 288, 292 strony powiadomień, 322 strony z wiadomościami, 43 suwaka, 117 wątku roboczego, 285 wideo z napisami, 172 widżetu przełącznika, 54 zwijalnego spisu treści, 56 typ datetime-local, 113 MIME, 168, 310, 347 wejściowy date, 114 datetime, 113 email, 109 month, 115 number, 116 range, 117 search, 112 tel, 110 time, 114 url, 111 week, 115
384
Skorowidz
U układ domyślny ekranu, 88 strony, 25, 45 witryny z rolami, 69 współrzędnych, 135 uprawnienia, 317, 323 upuszczanie obiektu, 299 plików, 337 ustawianie elementów w CSS-ie, 74 motywu, 253
W WAI-ARIA, 67 walidacja, 107, 126 wątek główny, 323 wątek roboczy, 284 dedykowany, 284 współdzielony, 284 Web Notifications API, 316 Web SQL Database API, 267, 271 Web Storage API, 267 Web Workers API, 283 WebSocket API, 279 wiadomości, 35 wideo, 167 z kontrolkami, 183 z napisami, 172 widżet kalendarza, 82 wielokąt, 146 wielowypełniacz, 83 witryna Font Squirrel, 94 wizualizacja stanu przeglądarek, 84 własne reguły walidacji, 126 właściwości Modernizr, 79 właściwość transform, 100 transition, 100 wpis do historii, 205, 214 wprowadzanie liczb, 116 współdzielony wątek roboczy, 291 wstawianie obrazka, 148
wtyczka VideoSub, 172 wykres słupkowy, 157, 161 wykrywanie CSS3, 79 możliwości HTML5, 81 typów, 79 wyłudzanie informacji, 219 wynik pomiaru, 122 wyszukiwania, 46 wyrażenia regularne, 126 wysyłanie danych, 281 komunikatów, 363 obliczeń, 314 wiadomości, 279 wyświetlanie adresu URL, 218 atrybutów pliku, 332 liczby wizyt, 251 pliku CSV, 344 powiadomień, 318–321 tweetów, 322 wyników, 118 wywołanie REST, 323
Y YouTube, 167
Z zapisywanie formularzy, 257 w historii, 213 w localStorage, 258 zapytania o media, 85–91 zarządzanie powiadomieniami, 320 zastępowanie stanu, 212 zatrzymania, 97 zawartość pamięci, 252 zbiór API, 358 zdarzenia addEventListener, 182 API, 175, 189 ApplicationCache, 315
Drag and Drop API, 302 durationchange, 201 FileReader, 338 wątków roboczych, 284 WebSocket, 280 zdarzenie compassneedscalibration, 369 devicemotion, 369 deviceorientation, 368 domReady, 209 dragover, 337 error, 288 hashChange, 221 message, 328 onchange, 260, 341 onclick, 191 onconnect, 295 ondragstart, 301 onerror, 284 onload, 339 onmessage, 284 popstate, 209, 214, 218 pushState, 210 SharedWorker, 291 window.addEventListener, 250 zmiana historii, 211 historii strony, 213 manifestu, 315 zawartości adresu URL, 218 zmienna dropzone, 337 znacznik body, 136 canvas, 136 czasu, 285 znaczniki nawigacyjne, 32 znak hash, 205 zwijalny spis treści, 56
Ż żądanie REST, 329 żyroskop, 370
Notatki