Академический Документы
Профессиональный Документы
Культура Документы
Фримен э., Робсон э. Изучаем Программирование На Html5 (2013)
Фримен э., Робсон э. Изучаем Программирование На Html5 (2013)
n
Фримен
*
Элизабет
о *
Робсон
„ * V v 4\
--------------------------------------------------------------------------------------------------
Изучаем гт
программирование на
Раскройте
секреты гуру HTML5
«Загрузите* HTML5
Узнайте, почему все, и JavaScript
что вашим друзьям прямо в свой мозг
известно о видео,
может оказаться
ошибочным
Научитесь
избегать
досадных Изучите
проблем подводные камни,
с браузерной связанные
поддержкой I * с браузерами
О REILLY
Отзывы о книге
«HTML5 является самой актуальной технологией создания веб-сайтов. М ногие разработчики го
р ят ж еланием воспользоваться ею для создания гибких, насы щ енны х медиа-сайтов, с которы м и
также будет удобно работать на нланш етны х комнью терах и смартфонах. К нига „Изучаем програм
мирование на H T M L 5“ — наилучший и самый увлекательны й снособ освоить эту восхитительную
технологию . О чень рекомендую».
— М эр иэи и М арк, старш ий ви ц е-и р ези деи т ио техн ол оги я м в B lu e N ile Inc.
«Авторы данной книги нонали в точку — навыки работы с JavaScript являю тся ключом к HTML5.
Даже если вам никогда не доводилось нисать JavaScript-HporpaMMbi, эта книга номож ет быстро
во всем разобраться благодаря наличию увлекательных и нрактичны х нримеров».
— Д эв и д П ауэрс, автор кииги «РНР. С оздан и е ди н ам и ч еск и х страниц» (РН Р Solutions:
D ynam ic Web D esig n M ade Easy)
О других книгах серии Head First
«Будьте осторож ны . Если кто-то из вас лю бит читать неред сном, то лучше отлож ите чтение книги
„Изучаем HTM L, XH TM L и CSS“ (H ead First HTM L with CSS & XHTM L) на дневное время. Эта книга
будоражит мозг».
— П оулии М акнамара, Ц ен т р н ов ы х техн ол оги й и обр азов ан и я,
Ф рибур ск и й ун и в ерси тет, Ш в ей ц ар и я
«Книга „Изучаем HTML, XH TM L и CSS“ нредставляет собой тщ ательно п роработанное соврем ен
ное руководство но дальновидным нрактикам в области разм етки и представления веб-страниц.
А вторы нредвидят, какие моменты могут вызвать у читателя замеш ательство, и своеврем енно
разъясняю т их. И снользованны й нодход, в основе которого леж ат обилие наглядных нрим еров
и последовательность излож ения, является онтимальны м для читателя: он будет вносить неболь
шие изм енения и наблюдать итоговы й эф ф ект в браузере, что нозволит разобраться в назначении
каждого нового элемента».
— Д эи и и Гудмеи, автор книги «Д инам ический HTML: п о д р о б н о е руководство»
(D ynam ic HTML: T h e D efin itive G uide)
«Книга „Изучаем HTM L, XH TM L и CSS“с самого начала создает у читателя ощущение, что весь нро-
цесс обучения окаж ется нросты м и увлекательным. О своение HTM L нри нравильном объяснении
не сложнее изучения основ родного язы ка, н ри этом авторы нроделали отличную работу и нриво-
дят наглядные нрим еры но каждой конценции».
— М айк Д эв и д со н , п р ези д ен т и и сп ол н и тел ьн ы й ди р ек т ор N ew svin e, Inc
«Вместо излож ения материала в стиле традиционны х учебников „Программируем для iPhone и iPad“
нредлагает читателю живую, увлекательную и даже нриятную методику обучения програм м ирова
нию для iOS. М атериал но добран умело и качественно: в книге рассматриваю тся многие клю чевые
технологии, вклю чая Core Data, и даже такие важные аснекты , как проекти рован ие интерф ейса.
И где еще можно нрочитать, как UlWebView и UITextField беседуют у камина?»
— Ш о п М ер ф и , п р оек ти р овщ и к и р азр аботч и к п р и л ож ен и й дл я iO S
«Книга „Программируем для iPhone и iPad“ объясняет н ринцины разработки н рилож ений iOS с са
мого начала. О сновны е и зм енения но сравнению с нервы м изданием относятся к iOS 4, Xcode 4
и нанисанием н рилож ений для iPad. Благодаря нош аговым онисаниям с визуальным стилем из
лож ения м атериала эта книга становится отличны м средством изучения нрограм м ирования для
iP hone и iPad во всех аснектах, от нростейш их до нетривиальных».
— Ри ч Р о зе и , програм м ист и соавтор кииги Mac OS X for U n ix G eeks
Ryan Benedetti
Ronan Cranley
O ’REILLY
Beijing • Cambridge • Koln • Sebastopol • Tokyo
Изучаем программирование на
Создание
Эрик Фримен
Элизабет Робсон
ББК 32.988-02-018.1
УДК 004.43
Права на издание получены по соглашению с O ’Reilly. Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой
бы то ни было форме без письменного разрешения владельцев авторских прав.
Информация, содержащаяся в данной книге, получена из источников, рассматриваемых издательством как надежные. Тем не менее, имея в виду
возможные человеческие или технические ошибки, издательство не может гарантировать абсолютную точность и полноту приводимых сведений
и не несет ответственности за возможные ошибки, связанные с использованием книги.
© Authorized Russian translation of the English edition of Head First HTM L5 Programming,
ISBN 9781449390549 © 2011 Eric Freeman and Elisabeth Robson. This translation is published
and sold by permission of O'Reilly Media, Inc., the owner of all rights to publish and sell the same.
ISBN 978-1449390549 (англ.) © 2011 Eric Freeman and Elisabeth Robson. This translation is published and sold by permission
of O'Reilly Media, Inc., the owner of all rights to publish and sell the same.
ISBN 978-5-459-00952-1 © Перевод на русский язык О О О Издательство «Питер», 2013
© Издание на русском языке, оформление О О О Издательство «Питер», 2013
П о с в я щ а е т с я С т и в у Д ж о б с у , б л а го д а р я к о т о р о м у п о
п у л я р н о с т ь H T M L 5 д о с т и гл а т а к и х в ы со т, ч т о д а н н а я
к н и г а д о л ж н а р а з о й т и с ь о г р о м н ы м т и р а ж о м .. .
Эри к Ф р и м е н
Эрик — один из основонолож ников серии «Head Э лизабет совмещ ает деятельность п роекти ров
First». К эти С иерра так характеризует Эрика: щ ика программного обеспечения, нисателя и
«Один из редких людей, которы е одинаково хоро инструктора. О на увлеклась технологиям и еще
шо владею т язы ком, практическим и навыками и во врем я учебы в Йельском университете, где
знаниям и культуры в разны х областях, будь то сфе нолучила стенень магистра ком пью терны х наук
ра, в которой орудует хакер-хинстер, работает кор и занималась разработкой язы ка нараллельного
п орати вн ы й вице-нрезидент, нроектировщ ик или визуального програм м ирования и нрограм м ной
экснерт-аналитик». архитектуры.
В п роф ессиональном нлане Эрик недавно нодош ел Элизабет увлеклась созданием веб-нрилож ений
к ночти десятилетней отметке в качестве долж на самом раннем этане разви тия И нтернета.
ностного лица в медиа-комнании: он занимает ноет О на участвовала в создании заслужившего нри-
главного технического д иректора Disney O nline
знание веб-сайта T he Ada Project, которы й стал
& Disney.com в Walt Disney Company. В настоящ ее
одним из нервы х ресурсов, нризванны х номочь
врем я Эрик занят W ickedlySmart — стартаном, ко
женщ инам, заняты м в сф ере инф орм атики. О на
то р ы й он организовал совместно с Элизабет.
является одним из основателей W ickedlySmart —
По образованию Эрик —учены й в области компью образовательного онлайн-ресурса, носвящ енно-
терны х наук, и ему довелось заниматься научными го веб-технологиям, на котором нредставлены
исследованиями с таким светилом, как Дэвид Ге- ее книги, статьи, видео и нрочее. Ранее, когда
лерн тер, во врем я его работы в качестве доктора Элизабет была руководителем снециальны х
ф и лософ и и в Йельском университете. нроектов в O ’Reilly M edia, она лично нроводила
В свободное врем я Эрик серьезно увлекается музы семинары и онлайн-лекции на разны е техн и че
кой; результат носледнего нроекта, над которы м ские темы, создавала образовательны е ресурсы.
он работал совместно с н ионером музыкального До сотрудничества с O ’Reilly M edia Элизабет
стиля «эмбиент» Стивом Роачем, им еется в элек довелось ноработать в Walt Disney Company, где
тронном магазине нрилож ени й для iP hone и назы она отвечала за руководство исследованиями
вается Im m ersion Station. и разработкам и в сф ере ц иф рового медиа.
П иш ите Эрику но адресу eric@ w ickedlysm art.com , П иш ите Элизабет на beth@ w ickedlysm art.com ,
а также носетите его сайт h t t p : / / ericfreem an.com н осетите ее блог h t t p : / / elisabethrobson.com
8
содержание
(У д е р ж а н и е (с в о д к а )
В ведение 21
1 Знакомство с HTM L5. Добро пожаловать в Вебвилль 35
2 Знакомство с JavaScript и объектной моделью
документа (D O M ). Немного кода 69
3 События, обработчики и весь этот джаз.
Немного взаимодействия 119
4 Функции и объекты JavaScript. СерьезныйJavaScript 147
5 С оздание HTM L-страниц с поддерж кой оп р едел ения
м естополож ения. API-интерфейс Geolocation 199
6 О бщ ение с веб-службами. Приложения-экстраверты 247
7 Раскрываем в себ е художника. Элемент canvas 315
8 Т елевидение для нового поколения. Элемент video...
и наш особый гость - элемент canvas 383
9 Сохраняем данны е локально. API-интерфейс Web Storage 447
10 П рим еняем JavaScript на деле: API-интерфейс Web Workers 507
П ри лож ен ие. Десять важных тем (которые мы не рассмотрели) 565
(^ « д ер ж ан и е (н а с т о я щ е е )
Введение
Ваш мозг думает о программировании на HTML5. Вы сидите за
книгой и пытаетесь что-нибудь выучить, но ваш мозг считает, что вся
эта писанина не нужна. Ваш мозг говорит: «Выгляни в окно! На свете
есть более важные вещи, например сноуборд». Так как убедить свой
мозг в том, что знание HTML5 и JavaScript не менее важно для вас?
9
зн аком ство с U IM L 5
Немного кода
Благодаря JavaScript вы откроете для себя нечто новое. Вы уже все
знаете о HTML-разметке (иначе называемой структурой) и CSS-стиле (также из
вестном как представление), однако вам недостает знаний о JavaScript (или, как
еще говорят, о поведении). Если ваш багаж знаний ограничивается лишь струк
турой и представлением, то вы, конечно же, сможете создавать прекрасно вы
глядящие страницы, однако они будут лишь простыми страницами. Но если вы
добавите поведение, прибегнув к JavaScript, то сможете обеспечить для своих
пользователей интерактивное взаимодействие; либо, что еще лучше, вы смо
жете создавать роскошные веб-приложения. Добавьте в свой инструментарий
веб-разработчика наиболее интересные и универсальные знания о JavaScript
и программировании!
11
собьшшя, обработчики и Весь эщощ джа£
Немного взаимодействия
Вам все еще не удается соприкоснуться с пользователем. Вы изу
чили основы JavaScript, однако могут ли ваши веб-страницы взаимодей
ствовать с пользователями? Когда страницы откликаются на вводимые
пользователем данные, они уже являются не простыми документами,
а живыми, реагирующими приложениями. Из этой главы вы узнаете, как
обрабатывать одну из форм ввода данных пользователем (извините за
каламбур) и привязывать старомодный HTML-элемент < f o r m > к совре
менному коду. Это может показаться необычным, однако такой подход
также эффективен. Пристегните ремни, поскольку наше путешествие по
данной главе будет проходить на большой скорости: путь от простого
приложения до интерактивного мы пройдем очень быстро.
Серьезный JavaScript
Можете ли вы уже назвать себя создателем сценариев? Впол
не возможно, поскольку вы уже многое знаете о JavaScript, однако кто
захочет быть простым создателем сценариев, когда можно быть про
граммистом? Пора проявить серьезность и поднять планку — настало
время познакомиться с функциями и объектами. Они являются клю
чом к написанию более эффективного, хорошо организованного и лег
кого в сопровождении кода. Функции и объекты активно используются
наряду с API-интерфейсами HTML5 JavaScript, поэтому чем лучше вы
будете в них разбираться, тем быстрее сможете освоиться с тем или
иным новым API-интерфейсом и начать его использовать. Пристегни
тесь, поскольку эта глава потребует вашего всецелого внимания...
13
содержание
API-интерфейс Geolocation
Куда бы вы ни отправились, вас можно найти. Порой бывает так, что знание
того, где вы находитесь, имеет существенное значение (особенно для веб-приложений).
Из этой главы вы узнаете, как создавать веб-страницы с поддержкой определения ме
стоположения. Иногда вы сможете определять местонахождение своих пользователей
вплоть до угла, на котором они стоят, а иногда вам будет удаваться определить лишь
район города, в котором они находятся (однако вы по-прежнему будете знать, какой это
город!). Время от времени вы вообще не сможете получить хоть какую-нибудь информа
цию о местоположении пользователей в силу технических причин или просто потому, что
им не нравится ваше чрезмерное любопытство. Да, представьте себе! Так или иначе, но
в данной главе мы рассмотрим API-интерфейс JavaScript под названием Geolocation. Бе
рите свое самое лучшее устройство с поддержкой определения местоположения (даже
если это будет ваш настольный компьютер), и давайте приступим к работе.
14
содержание
общение с веб—сл уж б а м и
Приложения-экстраверты
Что-то вы слишком засиделись на своей странице. Настало время немного
пообщаться с веб-службами с целью сбора данных и последующего возврата этой
информации, что даст вам возможность создавать более эффективные веб-ресурсы,
которые объединяют собираемые данные. Это важный момент в написании современ
ных НТМ1_5-приложений, и чтобы успешно им заниматься, вам необходимо знать, как
происходит общение с веб-службами. Об этом мы и поговорим, а также научимся вне
дрять данные от веб-служб в свои страницы. Усвоив изложенный материал, вы сможе
те обращаться и взаимодействовать с любой веб-службой по своему выбору. Мы даже
расскажем вам о новомодном жаргоне, которым следует пользоваться при общении с
веб-службами. Вы познакомитесь с некоторыми новыми API-интерфейсами — так на
зываемыми коммуникационными API-интерфейсами..
Элемент canvas
HTML больше не является просто языком «разметки». Благодаря новому
НТМ1_5-элементу c a n v a s у вас появилась возможность собственноручно создавать
и уничтожать пикселы, а также манипулировать ими. В этой главе мы воспользу
емся элементом c a n v a s , чтобы раскрыть таящегося в вас художника, — больше
никаких разговоров о HTML, когда речь идет чисто о семантике и отсутствуют пред
ставления; используя c a n v a s , мы начнем раскрашивать и рисовать цветом. Теперь
все будет опираться на представления. Вы узнаете, как вставлять элемент c a n v a s
в свои страницы, как рисовать текст и графические изображения (естественно, ис
пользуя JavaScript) и даже как поступать в случае с браузерами, не поддерживаю
щими данный элемент. С чудесным элементом c a n v a s вы встретитесь не только
в этой, но и в других главах книги.
16
содержание
с о х р а н я е м Д анны е Л°КаЛьНо
18
содержание
п о м е н я е м J a v a S c rip t н а д е л е
19
приложение: оставш иеся т е м ы
№ 1. M odernizr 566
№ 2. Э лем ент audio и API-ип терф ейс A udio 567
№ 3. j Q uery 568
№ 4. XHTM L мертв, да здравствует XHTM L 570
№ 5. SVG 571
№ 6. А втоном ны е веб-прилож ения 572
№ 7. API-ип терф ейс Web Sockets 573
№ 8. Д ополнительно об API-ин тер ф ейсе Canvas 574
№ 9. API-интерф ейс Selectors 576
№ 10. Однако есть даже ещ е кое-что! 577
HTM L5-pyкoвoдcтвo по новым конструкциям 579
Вебвилльское руководство по семантическим
элементам HTM L5 580
Вебвилльское руководство по CSSS-свойствам 582
введение
Введение
Не могу поверить,
что они включили такое
в книгу о программирова
нии на HTML5!
дальше ► 21
как работать с этой книгой
т о э т а к н и г а — д л я вас.
т о э т а к н и г а — н е д л я вас.
22 введение
введение
дальше ► 23
как работать с этой книгой
Как мы что-то узнаем? Сначала нужно это «что-то» понять, а потом не забыть. Затолкать
в голову побольше фактов недостаточно. Согласно новейшим исследованиям в области
когнитивистики, нейробиологии и психологии обучения, для усвоения мат ериала тре
буется что-то большее, чем простой текст на странице. Мы знаем, как заставить ваш мозг
работать.
24 введение
введение
дальше ► 25
как работать с этой книгой
26 введение
введение
дальше ► 27
как работать с этой книгой
Примите к сведению
Это учебник, а не снравочник. Мы намеренно убрали из книги все, что могло бы номешать
изучению материала, над которым вы работаете. И нри нервом чтении книги начинать следу
ет с самого начала, нотому что книга нреднолагает наличие у читателя определенных знаний
и оныта.
Мы предполагаем, что вы знаете HTML и CSS.
Если вы не знаете разм етки HTM L (то есть ничего о HTM L-документах, об элементах, атрибу
тах, структуре свойств, структуре в сравнении с презен тац и ей ), то н рочи тай те книгу Э. Ф риме
н а ^ . Ф римен «Изучаем HTM L, XHTM L и CSS» (СПб.: П итер, 2012) неред тем, как нристунить
к этой. Если же соответствующ ие знания у вас есть, то все в норядке.
От вас не требуется знание JavaScript.
Если у вас имеется какой-либо оны т нрограм м ирования или нанисания сценариев (пусть и не
на JavaScript), то это вам номожет. Однако в данной книге мы не ждем от вас знаний JavaScript;
ф актически, это издание является продолж ением книги «Изучаем HTM L, XHTM L и CSS», где
нанисание сценариев отсутствует.
Мы рекомендуем использовать разные браузеры.
Тестируйте страницы и веб-нриложения, иснользуя сразу несколько браузеров. Так вы узнае
те, чем отличаю тся разны е браузеры, и научитесь создавать страницы , нормально работаю щ ие
в разны х браузерах. Советуем иснользовать Google C hrom e и Apple Safari, но скольку они наи
более соответствуют соврем енны м стандартам. Также рекомендуем вам нрим енять для тести
р ован ия и новейш ие версии других распространенны х браузеров, таких как In tern et Explorer,
Firefox и O pera, а также мобильные браузеры на устройствах с онерационны м и системами iOS
и A ndroid.
Упражнения ОБЯЗАТЕЛЬНЫ.
Н е игнорируйте унраж нения —они являю тся частью основного м атериала книги. Одни из них
номогут вам заномнить материал, другие —нонять его, а третьи —н рим енить изученное н а нрак-
тике. Н е нронускайте унраж нения. Важны даже головоломки, носкольку они номогаю т мозгу ус
воить конценции и даю т возмож ность обдумывать изучаемые новы е слова и терм ины в разном
контексте.
Повторение применяется намеренно.
У книг этой серии есть одна нринциниальная особенность: мы хотим, чтобы вы действительно
хорош о усвоили материал. И чтобы вы зано мнили все, что узнали. Больш инство снравочников
не ставит своей целью уснеш ное заноминание, но это не снравочник, а учебник, ноэтому неко
торы е конценции излагаю тся в книге но нескольку раз.
Упражнения «Мозговой штурм» не имеют ответов.
В некоторы х из них нравильного ответа вообщ е нет, в других вы долж ны сами реш ить, насколь
ко нравильны ваши ответы (это является частью нроцесса обучения). В некоторы х упраж нени
ях «М озговой штурм» нриводятся но д сказки, которы е номо гут вам найти нужное нанравление.
28 введение
введение
Системные требования
Д ля нанисания и работы с кодом на HTM L5 и JavaScript вам нонадобится текстовы й
редактор, браузер и, врем я от времени, веб-сервер (он мож ет локально располагаться
на вашем настольном ком нью тере).
В онерац и онн ой системе Windows мы рекомендуем иснользовать такие текстовы е р е
дакторы , как PSPad, TextPad или EditPlus (но вы, если нридется, мож ете пользоваться
нрограм м ой N o tepad (Блокнот)). Для нлатф орм ы Мае советуем TextW rangler, TextMate
или TextEdit. Если вы работаете в Linux, то в вашем распоряж ении масса встроенны х
текстовы х редакторов, о которы х, как мы нолагаем, рассказывать не нужно.
Надеемся, что вы н рочи тали нункт о браузерах (см. нредыдущую страницу) и устано
вили как минимум два из них у себя в системе. Если нет, сделайте это. Вам также стоит
уделить время и научиться работать с инструментами разработчика, встроенны м и в
браузеры; в каждом из наиболее распространенны х браузеров имеется встроен н ы й ин
струментарий, которы й можно нрим енять для и нснекти ровани я консоли JavaScript (вы
сможете просм атривать ош ибки и вывод, генерируем ы й носредством c o n s o l e . l o g ,
что является альтернативой a l e r t ) , использования веб-хранилища, объектной модели
документа DOM, CSS-стиля, прим ененного к элементам, и многого другого. Н екоторы е
браузеры даже ноддерж иваю т нлагины , нозволяю щ ие добавлять новы е инструменты
разработчика. Ч тобы освоить книгу, эти инструменты вам не нотребую тся, однако если
у вас есть ж елание н отрати ть врем я на изучение того, как ими пользоваться, то нроцесс
разработки будет легче.
Н екоторы е н арам етры HTM L5 или API-интерф ейсы JavaScript требуют, чтобы файлы
не нросто загружались, а ностунали нри этом с реального веб-сервера (то есть URL-
адрес долж ен начинаться с h t t p : / / , а не с f i l e : / /) . В соответствующ их местах книги
мы указали, в каких случаях вам нотребуется сервер, но если у вас возникло ж елание,
рекомендуем установить веб-сервер у себя в системе нрямо сейчас. В онерационны х
системах Mac OS и Linux им еется встроен н ы й сервер A pache, ноэтому вам нужно лишь
убедиться, что вы знаете, как но лучить к нему достун и где размещ ать свои файлы , что
бы их можно было загружать, иснользуя свой локальны й сервер. В Windows вам н отре
буется установить A pache или IIS; если вы нредночтете A pache, то вам станет достунна
масса инструментов с откры ты м исходным кодом, нанрим ер WAMP и ХАМРР, которы е
довольно нросты в установке.
Вот и все! Удачного вам времянровож дения...
дальше ► 29
обзор команды
^ Дэвцд Пауэрс
Технические рецензенты У _____________
30 введение
введение
Благодарности
За прекрасное техническое рецензирование:
Э то уже превращ ается в традицию в иаш их киигах, и мы Заметка для редактора:
хотим еще раз горячо поблагодарить Дэвида Пауэрса, па- ^ м о ж н о ли застолбить
шего уважаемого технического рец еп зеп та и автора мпо- этого парня на три
гих издапий, вклю чая кпигу «РНР. Создапие дипам ических нами следующие книги?
страпиц» (РНР Solutions: Dynamic Web Design M ade Easy). Причем на эксклюзивных
Благодаря зам ечапиям Д эвида содерж имое кпиг всегда
правах!
зпачительпо улучшается, и пам крепче спится по почам от
зпапия того, что если текст прош ел ч ерез Дэвида, то в тех
ническом плапе там все отличпо. Еще раз спасибо, Дэвид.
Группе O’Reilly:
Н а плечи К ортпи Нэш легла тяж елая обязаппость по руковод
ству пе только проектом кпиги «Изучаем програм м ирование па
HTML5», по и пами. К ортпи расчистила все нути для пас и де-
ликатпо оказывала пе обходимое давлепие па каждого редактора,
чтобы кпига смогла вы йти в свет. Одпако глав пая заслуга К ортпи
заклю чается в том, что опа обеспечила пеоцепимую обратную
связь касаемо кпиги и ее содерж имого, в результате чего текст под
вергся ряду серьезпы х доработок. Благодаря усилиям К ортпи эта
кпига стала пампого лучше. Выражаем ей свою призпательпость.
К ор тн и Нэщ _ У
Лу Б арр также стала неотъем ле
м ой частью процесса работы пад
кпигой и впесла свой вклад, вы
ступив в массе ролей: рецепзепта,
граф ического дизайпера, главпого
художпика, веб-дизайпера и масте
ра Photoshop. Спасибо тебе, Лу,
без тебя у пас пичего бы пе полу
чилось!
,
И спасибо всем остальным людям благодаря труду которых эта книга
увидела свет:
Благодарим остальпых члепов комапды из O ’Reilly за их разпосто-
роппю ю поддержку. Это М ай к Х еи д ри ксои , М ай к Л уки дес, Лоу-
р е л Рума, К а р е й Ш е й и е р , С аи дерс К л я й и ф е л ь д , К р и с т е и Б о р г,
К а р е й М о н тго м ери , Р э й ч е л М оиагаи, Д ж ули Хоукс и Н эи си
Р эй и х ар д т.
дальше ► 31
благодарности
U еще благодарности*
Также спасибо всем остальным
Д ж ейм с Х еистридж паписал оригипальпы й код, легш ий в оспову
и рилож еии я Fractal Explorer из главы 10, которое мы адаптировали
в кпиге под свои нужды. И звипяемся, Джеймс, если приведеппы й в
тексте код окаж ется пе столь элегаптпы м, как в исходпом виде. Ак
тер, художпик и исполпительпы й д иректор Star buzz Л оуреис Заи-
коивски припим ал активпое участие в создапии кпиги и помогал те
стировать видеоприлож епие из главы 8 (пе пропустите!). Городская
ассоциация Б эйибридж Айлеид лю безпо разреш ила пам использо
вать свой зам ечательпы й логотип, придумаппый Д эпиз Х аррис, как
символ ш таб-квартиры W ickedlySmart. Благодарим Э итоии Виззари
и А&А Studios за возможпость приводить ф отоспим ки их прекраспы х
ф отокабипок. В паш ем прим ере со стартапом TweetShirt вы увидите
красивы е икопки, предоставлеппы е C hethStudios.N et. Выражаем
п ризпательпость Internet Archive за кадры из фильмов, которы е мы
использовали для Webville TV. И спасибо Д эииелу Ш тейибергу, ко
то р ы й там работает и всегда готов пам помочь.
К э т ц Сиерра
,
И наконец выражаем благодарность
Кэти и Берту
И последпими, по пичуть пе в мепь-
ш ей степепи, благодарим К эти Си-
ерру и Б ерта Бэйтса — участпиков
и М О ЗГО В О Й Ц ЕН ТР всей паш ей
операции, которы е к тому же являю т
ся осповополож пикам и серии «Head
First». Надеемся, что паша кпига зай
мет достойпое место в этой серии.
5
Усердно п р о в е р я е м на п р а к т и к е
с и с т е м у П арелли
*Так много благодарностей мы высказываем потому, что проверяем теорию о том, что каждый из
упомянутых здесь людей захочет купить минимум один ее экземпляр (возможно даже больше, например,
для своих родственников). Поэтому если вы желаете, чтобы мы упомянули вас в благодарностях
в нашей следующей книге и у вас много родственников, пишите нам.
32 введение
введение
О т издательства
Ваши зам ечапия, предлож ения и вопросы отправляйте по адресу электроп пой
почты vinitski@ m insk.piter.com (издательство «Питер», ком пью терная редакция).
Мы будем рады узпать ваше мпепие!
Н а сайте издательства h t t p : / /w w w .piter.com вы пайдете подробную ипф орм ацию
о паш их кпигах.
дальше ► 33
1 знак°сщВо с htroljj
* Добро пожаловать
в Вебвилль
Мы отправляемся в Вебвилль!
Там столько прекрасных домов в стиле
HTML5, что просто безумие жить в каком-
то другом месте! Давайте с нами, и мы
покажем вам все местные достопримеча-
V тельности. / '
НТМЫЗ-модернизатором
и сделайте зто всего за ТРИ ПРОСТЫХ ШАГА
/
Неужели все действительно так просто? Конечно! Мы даже под
готовили для вас небольшую демонстрацию.
Взгляните на этот старый, потрепанный, видавший лучшие
дни HTML; мы превратим его в HTML5 прямо у вас на глазах:
< ! DOCTYPE h tm l PUBLIC " -//W 3 C //DTD HTML 4 .0 1 //E N "
т
4
" h t t p ://w w w .w3 .org/TR / h t m l 4 / s t r i c t .dtd." >
щк
<meta http-equiv="content-type"
< /h e a d >
<body>
c o n t e n t = " t e x t / h t m l ; cha r s e t = U T F - 8 ">
(
<Ь1>Добро пожаловать в Head First Lounge</hl> с т р а н и ц ы Неа ЯлаЖ^Н
м ■ HTM L 4-.ОИ, к о т о р ы м должен
& бы т ь 6 д м знаком по к н и ^ *5,,
< im g s rc = "d r in k s .g if" a lt= " D r in k s " > цаеМ H T M L » (H e a d F ir s t H T M L )
< /p > (а если и н е т , не беспокойт есь,
3tVV0 $.$COAK}tVVHO и^ ййжно )
Каждый вечер присоединяйтесь к нам для разговора
за напитком <а href="elixirs .html" >elixirs</a>,
и, возможно, игры в two of Тар Тар Revolution.
К вашим услугам беспроводной доступ; ЗССВС (Захватите Свой Собственный Веб-Сервер).
< /р >
< /b o d y >
М 9
Ш ТУРМ
* Г 0 * 9 Й ________________________________________________________________________________________________________________________________________ __________
V
знакомство с HTML5
t
Это указание на файл , который опреде
ляет соответствующий стандарт
Итак, что подсказывают ваши дедуктивные способности в плане того, как будет выглядеть
определение d o c t y p e для HTML5? Напишите ответ здесь (вы сможете проверить его по
сле того, как мы разберемся во всем чуть позже):
Ллихего
Зля
дальше ► 37
обнови свой html
zztzz eQJ
Если вы фанат телешоу «Фабрика красоты» (Extreme Makeovers) или
«Потерявший больше всех» (The Biggest Loser), то шаг 2 вам понравится.
Здесь у нас имеется тег m e ta с атрибутом c o n t e n t . . . впрочем, взгляните
на картину «до» и «после»:
<шеta http-equiv="content-type" content="text/html; charset=UTF-8">
И д О (H T M L 4 )
<meta charset="utf-8">
П OCAB (H T M L S )
Да, новый тег m e ta значитеяы ю -похудел намного более прост При исполь
зовании тега m e ta в HTML5 нужно лишь указать его наряду с кодировкой
символов. Верите вы или нет, но все браузеры (новых и старых версий) уже
понимают такое метаописание, поэтому его можно использовать в коде
любой страницы — и оно будет работать.
38 глава 1
знакомство с HTML5
v a r youR ock = t r u e ; n
y Beet? бяид
</script> J a v a S c rip t Подробнее о JavaScript
ёудет здесь- мы поговорим позже.
дальше ► 39
больше чем разметка
Закончив, напечатайте код (или внесите изменения в файл упражнения, если вам так больше
нравится), загрузите его в браузер и, откинувшись на спинку стула, насладитесь своим первым
творением на HTML5. Ах да, наши ответы вы найдете на следующей странице.
дальше ► 41
решение упражнения
42 глава 1
знакомство с HTML5
Часш°
^адаВ аеМ ы е
В опросы
А как все это работает в старых версиях браузеров? Все 0 : Да, это так, особенно пока HTML5 не обрел 100%-ную под
эти новые doctype, meta и т. д... ведь как-то же могут старые держку всеми браузерами. Об этих аспектах мы поговорим позже.
браузеры работать с этим новым синтаксисом?
А почему вообще все это имеет значение? Я вот написал
0 : Да, могут. Взгляните на атрибуты t y p e тегов l i n k и код веб-страницы без doctype и тега meta, и она отлично рабо
s c r i p t ; сейчас имеет смысл избавиться от них в HTML5, по тает. Зачем мне лишняя головная боль, если в таком подходе
скольку CSS и JavaScript теперь являются стандартами (и, конечно нет абсолютно ничего неправильного?
же, технологиями по умолчанию для работы со стилями и написания
сценариев соответственно). Как оказалось, браузерам уже заранее 0 : Да, браузеры легко пропускают мелкие ошибки в HTML-
было известно, что CSS и JavaScript являются таковыми. Так, по файлах. Однако если вы включите соответствующие d o c t y p e
стечению обстоятельств новый язык разметки HTML5 уже довольно и теги m e ta , то сможете быть уверены в том, что браузеры будут
долгое время поддерживается существующими браузерами. Тоже знать, что именно вы от них хотите, а не гадать об этом. Кроме того,
самое справедливо и в случае с d o c t y p e и тегом m e ta . в случае с людьми, пользующимися старыми версиями браузеров,
указание нового d o c t y p e означает, что они будут использовать
А как насчет нового doctype? Что-то с ним все стало слиш стандартный режим, что как раз вам и нужно. Стандартный режим —
ком просто; у него нет даже версии или идентификатора DTD. это режим, в котором браузер считает, что написанный вами HTML-
код соответствует стандарту, поэтому он будет пользоваться прави
лами данного стандарта при интерпретации вашей страницы. Если
0 : Да, кажется немного необычным, что после многих лет при
вы не укажете d o c t y p e , то некоторые браузеры могут перейти
менения комплексных d o c ty p e теперь мы можем упростить их до
в режим совместимости и посчитать, что ваша страница написана
фразы «мы используем HTML». А произошло вот что: HTML ранее
для старых версий браузеров, когда соответствующий стандарт
основывался на стандарте SGML, который требовал как комплекс
еще не был на должной высоте, и неправильно интерпретировать
ных форм d o c ty p e , так и DTD. Новый стандарт отошел от SGML,
страницу (или решить, что она просто некорректно написана).
преследуя этим цель сделать язык HTML проще и гибче. Таким
образом, нужда в комплексных формах отпала. Здесь не обошлось
А что случилось с XHTML? Ведь еще несколько лет назад
без некоторой доли везения в том плане, что почти все браузеры
казалось, что за ним будущее.
просто ищут HTML в определении d o c t y p e , чтобы убедиться
в том, что они осуществляют разбор именно HTML-документа.
Q j Да, так оно и было. Однако потом гибкость возобладала над
строгим синтаксисом, и XHTML (XHTML 2, если быть точными) по
Это было всерьез, когда вы говорили, что d o c t y p e
степенно стал умирать, поскольку новый HTML5 оказался более
останется неизменным? Как мне казалось, для браузеров
либеральным в плане написания людьми веб-страниц (и осущест
важен контроль версий. Почему бы не использовать <!doctype
вления их рендеринга браузерами). Но пусть вас это не смущает,
html5>? Наверняка в будущем появится HTML6. Ведь так?
так как знание XHTML лишь сделает из вас еще более успешного
HTML5-pa3pa6oT4HKa. Кстати, если вы испытываете привязанность
0 : Подход к использованию d o c t y p e претерпевал изменения, kXML, знайте, что существует также способ написания HTML5-KOfla
и разработчики браузеров применяли его для того, чтобы дать ука в строгой форме. Подробнее об этом мы поговорим позже...
зание своим браузерам осуществлять рендеринг в их собственном
стандартном режиме. Теперь, когда у нас имеется намного более • Что такое UTF-8?
точный стандарт, d o c t y p e в HTML5 сообщает любому браузеру,
что конкретный документ является стандартным HTML, будь он
0 : UTF-8 — это кодировка символов, поддерживающая множе
версии 5, б или любой другой. ство алфавитов, включая незападные. Вам, вероятно, доводилось
сталкиваться с другими наборами символов, использовавшимися
Предполагаю, что разные браузеры пользователей будут в прошлом, однако UTF-8 продвигается как новый стандарт. Она
поддерживать различающиеся наборы возможностей HTML5. также быстрее и легче запоминается, чем предшествующие коди
Что делать в таком случае? ровки символов.
дальше ► 43
что вы должны знать
М С ЛШ ТМ )
Мы все-таки ие ож идаем, что вы зиаете HTML5.
Даже если вы пикогда рапее пе запимались HTML5,
это пе проблема, одпако у вас долж еп иметься опы т
работы с HTM L и зпапие таких базовых аспектов,
как элемепты , теги, атрибуты, влож епия, попима-
пие разп и цы между семаптической разм еткой и до
бавлением стиля и т. д.
Если вы пе зпакомы с даппы ми аспектами, то мы
возьмем па себя смелость дать вам пеболы пой со
вет (и бесстыдпым образом кое-что прореклам и
ровать): есть еще одпа кпига из этой серии, назы
вающ аяся «Изучаем HTM L, XHTM L и CSS», и вам
следует ее прочитать. Если же вы отчасти зпакомы
с язы ками разм етки, мож ете бегло ознаком иться с
даппым издапием или использовать его как спра-
вочпик при чтеп ии даппой кпиги.
44 глава 1
знакомство с HTML5
Интервью недели:
Признания новой версии HTML
Head First: Д обро пож аловать, HTM L5. Весь Ип- пия последпих. К счастью, с людьми, работающими
терп ет просто гудит от разговоров о Вас. Как пам пад специф икациям и HTML5, мы полпостью схо
кажется, Вы во мпогом похож и па HTM L 4. В чем димся во взглядах.
же п р ичи па всеобщ его аж иотаж а вокруг Вас?
Head First: В озвращ аясь к п реды дущ ей в ер си и
HTML5: Всеобщ ий аж иотаж объяспяется тем, что HTML, Вы отмечали, что являетесь расш ирепием
я предоставляю возмож пости по создапию совер- HTM L 4.01. То есть Вы обратпо совместимы с пей,
ш еппо пового п околеп и я веб-прилож епий и обе правильп о? О зп ач ает ли это, ч то Вам п р и д етс я
спечению качествеппого взаимодействия с пими. справляться с пе всегда удачпыми в плапе дизайпа
веб-страпицами из прошлого?
Head First: Согласеп, по почему HTM L 4 или казав
шийся многообещающим XHTML пе сделали этого? HTML5: Обещаю, что приложу максимум усилий для
HTML5: XHTM L 2 оказался тупиковой ветвью эво того, чтобы справиться со всем, что мпе подкинут
лю ции. К аж ды й, кому д овелось п и сать код веб- из прош лого. Но отмечу, что это пе зпачит, что со
стр ап и ц п а это м язы к е , т е р п е т ь его больш е пе мпой так и нужпо обращаться. Я хочу, чтобы созда
может. XHTML запово изобрел подход к паписапию тели веб-страпиц приобщ ались к повейш им стан
разм етки веб-страпиц, которы й уже и так исполь дартам и использовали мепя паилучшим образом.
зуется, и пе привпосил в страпицы пичего пового. Благодаря этому опи смогут получить максимальную
Я сказал: «Постойте-ка, я ведь могу делать повы е отдачу от моего примепепия. Но, с другой сторопы,
вещи и п ри этом заключаю в себе все те возмож я пе спасую и смогу обеспечить отображепие старой
пости , к о то р ы е сущ ествовали до мепя». Я имею веб-страпицы в силу своих возможностей, даже если
в виду, что если что-то работает, то зачем запово опа пе была м одерпизировапа до HTM L5.
и зобретать колесо. Такова моя ф илософ ия. Head First: М ой следующий вопрос звучит так...
Head First: Н о и звестп о ли вам, что п ек о то р ы е HTML5: Стойте, стойте!!! Все эти вопросы касаются
разработчи ки стандартов по-прежпему заявляют, прош лого. Мы с Вами пе говорим о том, что важпо
что И п тер п ету будет лучше, если оп стапет п р и здесь и сейчас. П оскольку реч ь и дет о м оей р аз
держ иваться их «безупречпых» стандартов? метке, хочу сказать, что моя персопальпая миссия
HTML5: Зпаете, мпе все равпо, что опи там говорят. заключается в том, чтобы охватить своими объяти
Я прислушиваюсь к людям, которые реальпо запяты ями весь И птерпет, впедрить повы е структурпые
паписапием веб-страпиц: как опи используют мепя, элементы, облегчающие жизпь веб-разработчикам,
как я могу им помочь. Вторыми в моем списке идут и помочь всем создателям браузеров поддерживать
создатели веб-браузеров. А разработчики стандар согласованную семаптику вокруг разметки HTML5.
тов стоят в этом списке последними. Я стапу п ри Но па самом деле я здесь для того, чтобы рассказать
слушиваться к их словам только при условии, что Вам о своем дополпительпом предпазпачепии: веб-
опи пе расходятся с мпепием пользователей. приложе...
Head First: Почему же? Head First: ...Жаль, HTML5, по паше время истекло.
Спасибо, в следующем иптервью мы обязательно
HTML5: Потому что если пользователи и создатели
поговорим обо всем, о чем Вы пож елаете.
браузеров пе согласпы с разработчикам и стандар
тов, то это пав од ит па мысли о правильности мпе- HML5: Б-р-р -р, терпеть пе могу, когда так случается!
дальше ► 45
отзывы об html5
46 глава 1
знакомство с HTML5
И не забудьте о мо
бильных устройствах. Мне
нравится возможность создавать
страницы с поддержкой опре
деления местоположения.
дальше ► 47
как работает html5
Браузер загружает документ, вклю При загрузке страницы браузер также соз
чающий HTML-разметку и CSS-стили. дает внутреннюю модель документа, ко
торая будет содержать все элементы вашей
HTML-разметки.
г
т
WelcometotheHeadFirst [.nun^e- html
M body
I I I I
title script hi I h2 P
l
em
/
Для каждого элемента ...Это дерево называется объ
в вашей HTML-размет ке ектной моделью документа
браузер создает объект,
объект, (Vocum ent object Model, РОМ),
который будет представ- g w б дете часто ст алки-
лять соответствующий ват ^ся с ней ходу кни
элемент, и размещает ги, поскольку данная модель
его в древовидной ст р ук играет важную роль в т ом ,
туре со всеми остальны как мы добавляем поведение
ми элементами... к веб-странии,ам с помощью
J a va S c r i p t (подробнее в главе £)■
Сг н и е м HTMLS р а з м е н „ р е в е л а ^
48 глава 1
знакомство с HTML5
сЦ еной
JavaScript взаимодействует
с вашей страницей посред API -интерфейсы, также
ством объектной модели известные как интерфейсы
документа (РОМ). прикладного программирова
ния (Application Programming
Interfaces), обеспечат для вас
набор объектов, методов и
свойств, которые вы сможе
API-интерфейсы обеспечат вам до те использовать для дост у
ступ к элементам a u d io и v id e o , па ко всей функциональности
20-рисованию с использованием этих технологий. Многие из
canvas, к lo c a lS to r a g e и прочим этих API -интерфейсов мы
замечательным технологиям, необ рассмот рим далее.
ходимым для создания приложений.
И не забывайте, что для использова
ния всех этих API-интерфейсов необ
ходим JavaScript.
Авто Local
номное
Знакомьтесь: кэширо Storage
API-интерфейсы вание
JavaScript
Web
Workers Geolocation
Forms
дальше ► 49
семейство html5
К Т 9 И НТ<
Мы с вами говорили о «семействе технологий» столько раз, что уже кажется, что мы сами одна семья. Однако мы
по-настоящему так и не разобрались в том, что конкретно они собой представляют, поэтому, наконец, сделаем
это. Ниже представлен перечень большинства членов этого семейства, посмотрите, сможете ли вы разобраться,
кто есть кто. Мы вас опередили и в качестве примера соотнесли одно из описаний с нужной позицией. Не бес
покойтесь, мы знаем, что это ваша первая встреча с членами семейства HTML5, поэтому
ответы вы найдете в конце главы.
Новые элементы Используйте мепя как часть локальпого храпилищ а в браузере лю
бого пользователя. Вам пеобходимо сохрапять устаповки, элемеп
ражетки ты, помещ еппы е в электропную корзину, или, возмож по, даже п ри
п рятать больш ой кэш для увеличения производительпости? Тогда
я нужпый вам API-иптерфейс.
Local Storage
Вам требую тся прилож ения, способпые работать даже тогда, когда
отсутствует подклю чепие к Сети? Я могу вам помочь.
50 глава 1
ВАШ А М и с с и я
■■■вели вы на нее со знакомство с HTML5
4% ,
%
Р СЯ'^ОСКОЛЬКу ИСТИНд
%
Автономные веб
/
Storage
Geolocatoin
Workers
приложения
Canvas
Video
Audio
Web
Web
UJ
Firefox
Safari
Chrome
Устрой Mobile
ства под WebKit
уп р а в-
лением Opera
операци -
онны х с и IE 6, 7
с т е м iO S
и A n d r o id
IE 8
(среди
прочих)
IE 9
дальш е ► 51
брэузерная разе едка
Автономные веб
Возможность
Storage
Geolocation
Workers
приложения
Canvas
0 0
$
Web
Web
0J
В!
i> 1
Firefox
/ / / / / !/ /
Safari
/ / / / / / /
Chrome
/ / / / / /
Mobile
WebKit / / / / / / /
Opera
/ / / / / / /
IE 6, 7
IE 8 /
IE 9 / / / / /
глава 1
Г аС ™ ;“ — про.
И НС m m U ne'
знакомство с HTML5
дальше ► 53
общие вопросы html5
4acm°
Задаваем ы е
БоЭЭроСЬ!
»Я слышал, что стандарт HTML5 не получит статус финаль >Chrome, Safari, Firefox, множество мобильных браузеров...
ной [
НОИ рекомендации до 2022 года! Это правда? вам не кажется, что ситуация лишь усугубляется? Будут ли
наши страницы нормально работать во всех этих браузерах?
Q : W3C - :■это организация по разработке стандартов, которая
формально рекомендует стандарт HTML5. Входящие в W3C люди 0 : Несмотря на конкуренцию на рынке браузеров (для настольных
любят действовать осторожно, причем настолько, что предпочитают компьютеров и мобильных устройств), на самом деле большинство
дождаться, пока сменится несколько поколений НТМ1_5-браузеров, из них основано всего на нескольких общих HTML-движках. Напри
прежде чем решиться сделать данный шаг. И это правильно, по мер, Chrome, Safari и мобильные браузеры для Android и iPhone
скольку со стандартом все окончательно утрясется в ближайшие базируются на Web К it, который представляет собой браузер ный
два года, а разработчики браузеров уверенно движутся по пути его движок с открытым исходным кодом. Поэтому веб-страницы, по
реализации. Так что, да, может пройти какое-то время, прежде чем большей части, смогут успешно работать в разных браузерах.
HTML5 обретет статус «финальной рекомендации». Ожидается,
что он станет стандартом уже к 2014 году, и использовать HTML5
в практических целях следует начинать уже сейчас.
В
б
А почему бы просто не использовать Flash, чтобы из
бежать
ежа проблем с межбраузерной поддержкой?
Что произойдет, когда все окончательно решится с HTML5? Q : Flash - <- отличныи инструмент, который получил повсеместное
распространение в операционных системах и браузерах настоль
0 : Появится HTML6? Мы понятия не имеем, но, вероятно, что бы ного сегмента. HTML5 со своим семейством технологий предлагает
там ни было, оно придет к нам вместе с летающими автомобилями, вам сделать с использованием открытых стандартов многое из того
ракетными костюмами и обедами в таблетках. Помните, что даже же, что и Flash. Что вам предпочесть? Задумайтесь о том, какой
если мы перейдем на HTML6, d o c t y p e не изменится. Если пред объем инвестиций в технологии HTML5 вкладывают такие компании,
полагать, что W3C сдержит свое обещание и будущие версии HTML как Google, Apple, Microsoft и др. В долгосрочной перспективе HTML5
окажутся обратно совместимыми друг с другом, то мы сможем без станет крупным игроком, а в мобильном сегменте он уже является
проблем перейти на нечто новое, что будет следующим на очереди. таковым. Выбор за вами, обе эти технологии будут в обиходе еще
долгое время, индустрия движется по направлению к открытым
стандартам.
археология
Мы провели раскопки и оьнаружили код, вложенный в HTML-страницу. Надеемся, вы
поможете нам взломать данный код и выяснить, что он означает. Мы не ожидаем от вас
толкования этого кода, а просто пытаемся разогреть ваш мозг, заставив его немного
порассуждать дедуктивным путем...
<script>
var w a l k s L i k e " d u c k 11 ;
var s o u n d s L i k e = d o c u m e n t . g e t E l e m e n t B y I d ( " s o u n d s l i k e " ) ;
i f (walksLike = = "dog") { Подсказка: docum ent пред
s o u n d s L i k e .i n n e r H T M L = "Woof! Woo f ! " ;
ставляет целую HTML -
} e l s e if (walksLike == "duck") {
страницу , a getElem entBy Id,
s o u n d s L i k e .i n n e r H T M L = "Quack, Quack"
} else {
возможно, имеет от но
s o u n d s L i k e .i n n e r H T M L = " C r i c k e t s . . . " ; шение к HTML-элемент ам
} и идентификаторам.
< / script>
54 глава 1
знакомство с HTML5
дальше ► 55
что умеет javascript Взаимодействуйте со своими страницами новыми
способами, которые подходят как для настольного
сегмента, так и для портативных устройств.
\ Кзшируйте данньые
локально, используя
исполь
Для воспроизведения
ораузерное хранилище видео больше не нужны
для ускорения работы специальные плагины.
мобильных приложений
Создавайте собственные
элементы управления вос
Интегрируйте свои страницы
произведением, исполь
с Картами Google и давайте
зуя HTML и JavaScript.
пользователям возможность
отслеживать их собственное
перемещение в режиме реаль
ного времени.
56 глава 1
знакомство с HTML5
Попрощайтесь с браузер-
ными cookie-файлами и *
используйте локальное
хранилище в браузере.
Забрать ( D
вещи I Выпить Купить
из хим- ' К0Фе ехце один
чистки гаджет
Используя JavaScript, вы сможете сохра от ^ppie
нять множество установок и данных для
своих пользователей локально в брау
зере и даже сделать так, чтобы к ним Слетать
на Фиджи Помыть
имелся автономный доступ. Испечь
дальше ►
знакомство с javascript
jg ) B C "
С
Интервью недели:
Признания языка сценариев
Head First: Добро пожаловать, JavaScript. Мы рады, что Вы смогли выкроить для пас время в своем
плотпом граф ике. Позвольте сразу спросить вот о чем: HTML5 превращ ается в зпамепитость,
а как пасчет Вас??
JavaScript: Я пе стремлюсь быть в цептре впимапия, а остаюсь за кулисами. Я бы сказал, что пе-
малая часть похвалы, высказы ваем ой в адрес HTML5, долж па отпоситься ко мпе.
Head First: Почему Вы так считаете?
JavaScript: Существует целое семейство техпологий, которы е делаю т работу «HTML5», куда,
паприм ер, входят 2D canvas, localStorage, Web W orkers и др. А правда заклю чается в том, что для
того, чтобы действительно пользоваться ими, нужеп я. К опечпо, HTML5 позволяет создавать
веб-страпицы и представлять их впимапию пользователей, по без мепя у людей пе будет ипте-
респого взаимодействия с пими вообщ е. Но все пормальпо. Ж елаю успеха HTM L5, а я просто
продолжу делать свою работу дальше.
Head First: Что бы Вы посоветовали разработчикам , реш ивш им п ерей ти па HTML5?
JavaScript: Ну, здесь все просто. Если вы действительно хоти те овладеть HTM L5, п отратьте
врем я па изучепие JavaScript и всех библиотек, работаю щ их с HTML5.
Head First: Зпаете, у Вас пе всегда была хорош ая ренутация. В одпой из статей в 1998 году о Вас
высказались так: «JavaScript —это пезрелы й, вычурпый язы к сцепариев».
JavaScript: Это обидпо. Может, я и пе пачал свою ж изпь в безупречпой академической среде
мпогих язы ков програм м ировапия, по смог п реврати ться в одип из паиболее ш ироко использу
емых язы ков всех времеп, поэтому па тот момепт я бы пе стал списывать мепя со счетов столь
опром етчиво. К роме того, в то, чтобы сделать м епя падежпым и крайпе эф ф ективпы м язы ком,
были вложепы огромпые ресурсы. Я стал быстрее по мепыней мере в 100 раз, чем был 10 лет пазад.
Head First: Это впечатляет.
JavaScript: Да, и если Вы еще пе слышали, то проипформирую Вас, что разработчики стапдартов
совсем педавпо пазвали мепя языком сцепариев по умолчапию для HTML5. Таким образом, я здесь,
чтобы остаться падолго. Замечу, что программистам больше пет нужды указывать J a v a S c r i p t
в своих тегах < s c r i p t > . Может, мепя и пазы вали вычурпым в 1998 году, по где теперь все эти
JScript, VBScript, Java-annTieTbi и проваливш иеся попы тки с браузерпыми языками?
Head First: Ч то ж, Вы действительно являетесь ключом к создапию отличпых НТМ Ьб-страпиц.
Но у Вас есть ренутация язы ка, с которы м возпикает нутапица.
JavaScript: Н есмотря па слухи, я являюсь очепь мощпым языком, и чтобы успеш по использовать
мепя, пеобходимо затратить пекоторое время п а изучепие. С другой сторопы , я понуляреп, по
тому что мепя легко освоить. То есть я вобрал лучшее из обоих миров, как Вы считаете?
Head First: П охоже, что так опо и есть! Спасибо вам, JavaScript, заи п тервью .
JavaScript: Всегда пожалуйста.
58 глава 1
знакомство с HTML5
if (cans > 1 ) {
lyrics = lyrics + (cans-1 ) + " cans of "
+ drink + " on the wall <br>";
}
else {
lyrics = lyrics + "No more cans of "
+ drink + " on the wall <br>";
}
cans = cans - 1 ;
document.write(lyrics);
дальше ► 59
ваш первый javascript
ТЕСТАРЛИ*
Вы же не думали, что, провернув всю сложную работу по выполнению упражнения, вы так и не подвергнете
практическому испытанию наш JavaScript-код? Вам необходимо взять код с предыдущей страницы и перенести
его (вместе с HTML-разметкой, приведенной ниже) в файл (например, index.html), а затем загрузить в браузере.
Результат можно увидеть внизу:
^ з а б ы в а й т е , ч т о для т о г о , ч т о б ы з а г р у з и т ь
<! doctype html> эт о№ весь к о д и ф а й л ы п р и м е р о в для к н и г и , с л е д у е т
з а й т и п о а д р е с у h t t p . / / w i c k e d ly s m a ir t . c o m / h f h t m ls .
< html>
<head>
;= s £ g = 2 -
А вот результат нашего тестового про
**c«anоsврo5.fdP--JT,
™
tnin,PMi IktK
'‘rotM
und,
гона данного кода. Он генерирует текст
лирической песни о ЯЯ -бутылках банках w*i
%Scans<vfpn”tPWa
гш&а энергетического напитка на полке » «аз g**ona»'W aJ
и записывает его в документ браузера.
93fans<jf SniUod>
« с*вд^2й22?в,,,1в»«ц
tew»u
дальше ► 61
некоторые тонкости htm!5
Часш°
Задаваем ы е
В сЩ роСъх
0:
поскольку создали все содержимое данной страницы,
используя JavaScript-код. Да, можно было бы просто Это отличный вопрос, поскольку мы используем
внести текст лирической песни прямо в элемент b o d y эти термины в широком смысле. Технически никакой
(и при этом нам бы пришлось долго печатать на клави разницы между двумя этими понятиями нет; другими
атуре), либо мы могли позволить коду выполнить всю словами, вам не нужно делать что-то особенное для
тяжелую работу за нас (что мы и сделали), а затем того, чтобы превратить страницу, написанную на HTML,
дать ему команду вставить текст песни на страницу JavaScript и/или CSS, в веб-приложение. Появление
посредством d o c u m e n t . w r i t e . различий — это скорее одна из возможных перспектив.
Имейте в виду, что здесь мы пока прощупываем поч Когда у нас имеется страница, ведущая себя скорее
ву, а по ходу книги будем тратить намного больше как приложение, нежели как статичный документ, мы
времени, рассматривая то, как можно динамически начинаем думать о ней больше как о веб-приложении
заполнять страницу содержимым с помощью кода. и меньше как о веб-странице. Приложение мы рассма
триваем как нечто такое, что обладает рядом особен
ных качеств, например способностью поддерживать
Я понял, что мы сгенерировали весь текст
множество состояний, управлять более комплексными
лирической песни, но что конкретно сделал метод
взаимодействиями с пользователем, отображать
document.write и как текст попал в документ?
динамические и постоянно обновляемые данные без
необходимости в обновлении всей страницы или даже
0 : Метод d o c u m e n t. w r i t e берет строку текста выполнять более сложные задачи либо вычисления.
и вставляет ее в документ; фактически, он помещает
ее точно туда, где располагается тег s c r i p t . Та Весь этот JavaScript, конечно, замечательная
ким образом, в данном случае d o c u m e n t . w r it e вещь, но как насчет CSS? Мне не терпится восполь
вставляет строку прямо в тело страницы. зоваться преимуществами CSSS-нововведений,
Вскоре вы познакомитесь с более тонкими способа чтобы улучшить внешний вид своих страниц.
ми изменения текста живого документа с помощью
JavaScript, а данный пример призван дать вам по 0 : Да, CSS прошел долгий путь, и мы с воодушев
чувствовать, как код способен динамически вносить лением смотрим на то, насколько хорошо он работает
изменения в страницу. с HTML5. Несмотря на то что эта книга не о CSS, мы
с вами обязательно воспользуемся преимуществами
некоторых новых возможностей этого языка. Как вы,
возможно, знаете, многие из трюков, к которым мы
прибегаем для добавления закругленных углов и
теней на изображениях при использовании HTML и
создания простых анимаций на JavaScript, теперь мо
гут быть с легкостью воспроизведены с помощью CSS.
Так что в этой книге мы воспользуемся мощью CSS
и обратим ваше внимание, когда это произойдет.
62 глава 1
знакомство с HTML5
^ HTMLS*
Язык разметки + д
API -интерфейсы JavaScript + CSS = Пум.уим .... Щ■г
дальше ► 63
ваш первый код на htm!5
]J°3A paBjlffeM , Б ы З а к о н ч и л и
f
и з д а т ь ГЛ аВ у Jи н а п и са Л и сВ о й
Г HTML5 I A P I -и н т е р ф е й с ы J a v a S c r i p t
JavaScript
CSS
XML ! Canvas I
R e d Vines M r . Pi b b
XHTML Forms
Язык
CSS3
I Geol o c a t i o n
I
<script>
64 глава 1
знакомство с HTML5
КЛЮЧЕВЫЕ
МОМЕНТЫ
■ HTML5 — это самая современная версия HTML. HTML5 включает элементы, которые привносят
Она включает новые упрощенные теги, а также новую семантику в станицы, открывая перед
семантические и медиаэлементы, полагается вами больше возможностей, связанных с соз
на набор JavaScript-библиотек, обеспечиваю данием структуры веб-страниц, чем было в
щих функционирование веб-приложений. HTML 4.01. Мы не будем рассматривать их в
книге, однако в приложении вы найдете не
■ XHTML больше не является стандартом для большое руководство по ним.
веб-страниц. Вместо него разработчики и W3C
решили продолжать расширять и совершен Для использования многих возможностей
ствовать HTML. HTML5 наилучшим образом вам потребуется
JavaScript.
■ Новое и более простое определение d o c ty p e
Применяя JavaScript, вы сможете взаимодей
в HTML5 поддерживается старыми версиями
ствовать с объектной моделью документа
браузеров: когда они сталкиваются с ним, то
(Document Object Model, DOM).
переходят в стандартный режим.
Объектная модель документа (DOM) — это
■ Атрибут ty p e больше не требуется в теге
браузерное внутреннее представление веб
< s c r i p t > или в ссылке на таблицу стилей
страницы. Используя JavaScript, вы сможете
CSS. JavaScript и CSS стали языками по умол получать доступ к элементам, изменять их,
чанию для HTML5. а также добавлять новые элементы в объект
■ Тег < m eta> , используемый для указания набо ную модель документа.
ра символов, был упрощен и теперь включает API-интерфейсы JavaScript (Application
только кодировку символов. Programming Interface — интерфейс приклад
ного программирования) позволяют управлять
■ UTF-8 сейчас является стандартной кодировкой
всеми аспектами HTML5 (20-рисованием, вос
символов, используемой в Интернете.
произведением видео и др.).
■ Изменения в d o c t y p e и теге < m e ta > не ска
JavaScript является одним из наиболее попу
жутся отрицательно на страницах, загружаемых
лярных языков в мире. Реализации JavaScript
в старые версии браузеров.
значительно усовершенствовались за послед
■ Совокупность новых элементов HTML5 пред ние годы.
ставляет собой расширенный набор элементов Вы можете выяснять, поддерживается ли та
HTML 4. Это означает, что старые страницы или иная новая функция браузером, и обе
смогут нормально функционировать в совре спечивать плавную деградацию веб-страниц в
менных браузерах. случае отсутствия такой поддержки.
■ Работы над стандартом HTML5 не будут офи CSS — это стандартный язык стилей для
циально завершены до 2014 года, однако HTML5; многие люди вкладывают CSS в по
большинство современных браузеров станет нятие «HTML5», когда используют его для опи
поддерживать его задолго до этого (а многие сания семейства технологий, применяемых для
поддерживают уже сейчас!). создания веб-приложений.
дальше ► 65
кроссворд
Ц Щ 5 - К Г 0С С В 0Г Д
По горизонтали По вертикали
3. __________ реклама, также называемая спамом. 1. Нам необходимо, чтобы деградация наших веб-страниц про
4. Ваша миссия заключалась в том, чтобы провести___________ исходила ___________ .
в стане браузеров. 2. Новейшие____________ HTML5 привносят новую семантику
5. Инструмент, позволяющий обновить старый код до HTML5 и открывают дополнительные возможности, связанные с соз
за три шага__________ . данием структуры веб-страниц.
9. Стандартный язык сценариев для HTML5. 6. Истинная мощь HTML5 заключается в __________ JavaScript.
10. Это определение теперь стало намного проще, чем было 7. Стандартный язык стилей для HTML5.
в версии HTML 4.01. 8. Тег <___________ > говорит браузеру, что все, что следует да
12. Этот язык получил «прощальное письмо» в 2009 году. лее, является JavaScript-кодом, а не HTML.
14. Используйте цикл___________ для генерирования вывода 10. ___________ — это внутреннее представление веб-страницы.
строк песни. 11. Данный атрибут тегов l i n k и s c r i p t больше не требует
15. JavaScript стал быстрее в раз, чем был 10 лет назад. ся, если вы используете HTML5.
13. Версия HTML, предшествующая HTML5.
66 глава 1
знакомство с HTML5
+
+
S f c e / * ! т?
Мы с вами говорили о «семействе технологий» столько раз, что уже кажется, что мы сами одна семья. Однако мы
по-настоящему так и не разобрались в том, что конкретно они собой представляют, поэтому, наконец, сделаем
это. Ниже представлен перечень большинства членов этого семейства, посмотрите, сможете ли вы разобраться,
кто есть кто. Не беспокойтесь, мы знаем, что это ваша первая встреча с членами семейства HTML5, поэтому
приводим решения задания.
дальше ► 67
I еэеиг gg
+ Немного кода*
<html>
<head>
<script>
</script>
<body>
0
<hl>My first JavaScript</hl>
< p x /p > | html"
<script>
X = X + 2;
</script>
| head~ body
</body>
</html> | title | script [ | hi ^ | h2 \| p [
\~errT\
Л
70 глава 2
javascript и dom
ф Д е л а т ь ч т о - т о дваЖды, неоднократно
О Принимать решения
П иш ите условный код, зависящий от состояния вашего приложения.
if (isReallyCool) {
invite = "You're invited!";
} else {
invite = "Sorry, we're at capacity.";
дальше ► 71
объявление переменных
Объявление переменной
П ерем енны е содерж ат данные. В случае с JavaScript они могут содержать
массу различны х вещей. Д авайте объявим несколько нерем енны х, содер
жащих данные. winners
Целочисленные значения .
var winners = 2 ; Или числовые значения с плаваю - boilingPt
var boilingPt = 212.0; точкой.
var name = "Dr. Evil"; 4 Или строки символов
(кратко «строки»).
var isEligible = false;
Или логические значения
(true или false).
name
Три шага по созданию переменной
isEligible
v a r sco o p s = 1 0 ; Переменные—
П ервы й шаг заклю чается в объявлении нерем енной, в данном слу
этоконтейнеры
чае s c o o p s . Следует отметить, что JavaScript, в отличие от неко
торы х других язы ков, не требует указания тина нерем енной, а нро-
длязначений.
сто создает кон тей н ер общего тина, в котором мож ет содерж аться JavaScript-
масса вещей:
иеременные
неимеютстрогих
scoops
типов, поэтому
Далее нам необходимо значение, которое будет размещ аться в не
любаяизних
рем енной. Указать значение можно несколькими снособами: можетсодержать
Значение может быть литеральным ,
например числом или строкой.
числовое,
var scoops = 10; Или значение может быть
результат ом оценки вы
строковое
var scoops = totalScoops / people;
var scoops = Math.random () * 10;
ражения. нлнлогическое
значение.
72 глава 2
javascript и dom
Каким будет значение моей переменной, если я просто 1Мне доводилось иметь дело с другими языками програм
дальше ► 73
присвоение имен переменным
( ^ ь е З Н о е п р о г р а м м и р о в а н и е 1
74 глава 2
javascript и dom
Я зык JavaScript вклю чает ряд зарезервированны х слов, нанрим ер i f , e ls e , w h ile , f o r (это
лиш ь часть из них), и не будет слишком лю безен, если вы ноны таетесь иснользовать их в качестве имен
для своих нерем енны х. П еречень зарезервированны х слов JavaScript нриведен ниже. Н е нужно сию же
минуту заноминать их, но ходу освоения JavaScript у вас вы работается нонимание, что же они собой
нредставляю т. Но если когда-либо JavaScript станет «ругаться» н а то, как вы объявили свои нерем енны е,
то вам следует мыслить следующим образом: «Хм, а может, слово, которое я нытаю сь иснользовать,
является зарезервированны м?».
дальше ► 75
присвоение имен переменным
Вебвилльское руководство
по вы бору оптим альны х имен
Вам предоставляется немалая свобода при выборе имен для своих переменных, поэтому
мы возьмем на себя смелость дать несколько советов, чтобы облегчить вам эту задачу.
Будьте осторожны
Проявляйте осторожность при присваивании имен переменным. Далее в книге мы дадим еще
ряд советов по этой теме, а пока знайте, что для переменных нужно выбирать понятные имена,
избегать зарезервированных слов и всегда указывать v a r при объявлении переменной.
76 глава 2
javascript и dom
ВыраЖения
Мы с вами уже видели, что представляют собой операторы JavaScript:
О п е р а т о р Ja v a S crip t
sc o o p s = sc o o p s - 1;
П еременная
—^ ]
^ '— 1/--------------
v
^
г ^ а а В ы раж ение
П рисваивание г
Однако давайте более пристально взглянем на выражения вроде того, которое приведено в дан
ном операторе. Оказывается, выражения повсеместно встречаются в JavaScript, поэтому важно
знать, какого рода вещи вы сможете выражать. Вот ряд примеров...
Вы м о ж е т е п и с а т ь в ы р а ж е н и я ,
р е з у л ь т а т о м оцен ки к о т о р ы х
б у д у т чис ло вы е значения... Вы м о ж е т е п и -
с а т ь вы раж ения, ^
результ ат ом Логические ВыраЖения
о цен ки к о т о р ы х
Числовые Выражения б у д ут логические
2 > з
s ta r tT :ime >
nov
(9/5) * tempC + 32
зн а ч е н и я t r u e tenqpF < 7 5
Math. random() * 10 но н а з ы в а ю т с я
логическим и вы
2.123 + 3.2 ра ж е н и ям и ).
...a т а к ж е п и с а т ь в ы р а ж е н и я , р е з у л ь т а
т о м о цен ки к о т о р ы х б у д у т с т р о к о в ы е
зн ачен и я.
♦ -2 1 - * - f P
phoneNumber. substring (0 , 3) Прочие выражения
function ()
Внимательно отнеситесь к выражениям, представленным
document.getElementByld("pink")
на нескольких следующих страницах (не говоря уже об
оставшейся части книги), и вы поймете, как они использу new Array (10)
ются для проведения вычислений, многократного повто
рения действий и принятия решений в вашем коде.
дальше ► 77
упражнение
Каким окажется результат, если значением te m p C будет 10? В приведенном ниже перечне об
ведите допустимые операторы.
va r s = "3 -8 ";
level >= 5 x = у ;
Подсказка: « / » va r le v e l_ = 11;
color != "pxnk"
% означает «не».
va r h ig h N o o n = fa ls e ;
Каким окажется результат, если значением color
будет blu e ? ______________ va r $ = 2 1 .3 0 ;
va r z = 2000;
(2 * Math.PI) * г
va r is B ig = у > z;
Каким окажется результат, если значением г будет 3?
z = z + 1;
z y ;
р а в н о 3 ,П4 ...)
x = z * t;
w h ile ( h ig h N o o n ) {
z— ;
78 глава 2
javascript и dom
m essage = 2 + м if by sea";
v a lu e = 2 * 3.1;
Ш ТУ РМ
Каков будет результат оценки следующих операторов со стороны
JavaScript?
numORStringl = 113 м + "4м
И почему?
дальше ► 79
javascript итерации
while (j u g g l i n g ) {
keepBallsInAir() ;
}
scoops = scoops - 1;
При каждом выполнении цикла while мы уведомляем
пользователя о том, что мороженое еще осталось
а затем удаляем одну ложку мороженого пут ем ее '
вычитания из общего числа ложек.
alert("life without ice cream isn't the same");
80 глава 2
javascript и dom
V
Таким образом, в нрим ере с циклом w h i 1 е мы инициализируем значение, в данном
случае —ноказатель количества оставш ихся лож ек м орож еного, которы й проверяет
ся циклом w h i l e , и если выдается t r u e , то мы выполняем блок кода. В результате
работы этого блока кода в определенны й момент нроисходит обновление вовлечен
ного в нр о верку условия ноказателя до такого уровня, нри котором значением условия
становится f a l s e и цикл заверш ается.
ИНИЦИАЛИЗИРОВАТЬ
JavaScript также предусматривает наличие цикла f o r , которы й еще больше формализует данную
структуру. Вот как будет выглядеть наш код из н рим ера с морож еным, нерен и сан н ы й с прим енени
ем цикла f o r :
ИНИЦИАЛИЗИРОВАТЬ
ОСУЩЕСТВЛЯТЬ ПРОВЕРКУ УСЛОВИЯ
I \ ^ ------ ОБНОВЛЯТЬ
В • Я не вижу никакой разницы между циклами while и for. Как понять, когда следует использовать каждый из них?
0 : В целом, вы сможете выполнять одни и те же задачи, используя либо цикл f o r , либо цикл w h i l e . Однако, как вы
могли убедиться в примере с мороженым, цикл f o r обеспечивает немного большую компактность, a w h i l e делает код
более удобочитаемым. Как правило, циклы f o r чаще используются для совершения итераций по фиксированному количеству
значений (например, по элементам, помещенным в электронную корзину в интернет-магазине), a w h i 1 е чаще применяются
для циклического выполнения чего-либо до тех пор, пока удовлетворяется соответствующее условие (например, заставлять
пользователя проходить тест до тех пор, пока он не сделает все правильно).
дальше ► 81
упражнения
СТАНЬ 6раумр«м
К а ж д ы й из п о в ед ен н ы х на эт< > й с т р а н и ц е J a V a ^ c I ip t- Фрагмент 1
с^раГменшоБ представляет со£ой ©цельный £лок
var count = 0;
Т С °Д а . ^ а Ш а задач а З а к л ю ч а ется В т °М , Ч т °# ы сы
for (var i = 0; i < 5; i++) {
г р а т ь р °Л ь бр аузер а и оД ен и т ь В се
count = count + i;
^ р а Щ е н т ы К °Д а д л я о щ В ет а н а В о
п росы ° р е з у л ь т а т а х . J J a n u H iu m e с В о й
alert (11count is 11 + count);
о щ В ет н а к а ж д ы й В опрос п о д с о о т в е т
var tops = 5;
while (tops > 0 ) {
for (var spins = 0; spins < 3; spins++) {
alert("Top is spinning!");
}
tops = tops - 1;
}
alert("life without ice cream isn't the same");
82 глава 2
javascript и dom
if (c a s h ln W a lle t > 5) {
o rd e r = “I'll tak e th e works: cheeseburger, frie s and a coke
} else {
o rd e r = "I'll ju s t have a glass o f water";
дальше ► 83
javascript условия
тся.
/
ш.
пражнение Возьмите приведенный выше код и вставьте его в цикл w h i l e внизу. Пройдитесь по цик
лу w h i l e и напишите сообщения диалоговых окон a l e r t в той последовательности,
в которой они будут выводиться. Проверить свои ответы вы сможете в конце главы.
v a r scoops = 1 0;
w h il e (s c o o p s > = 0 ) {
s c o o p s = s co o p s
T
Генерируемый вывод
напишите здесь.
a le r t( " lif e w it h o u t i c e c re a m i s n ' t th e s a m e " );
84 глава 2
javascript и dom
развлечения с м а гн и т а м и
Данный код отображает известный палиндром в диалоговом окне a l e r t . Проблема заключа
ется в том, что часть кода находилась на магнитных табличках, прикрепленных к холодильнику,
однако они упали на пол. Ваша задача заключается в том, чтобы восстановить целостность кода
и отобразить палиндром. Будьте внимательны, поскольку на полу уже лежало несколько табличек,
не имеющих отношения к данному коду, зато некоторые из табличек вам придется использовать
более одного раза! Проверьте свои ответы в конце данной главы, прежде чем двинетесь дальше.
) {
phrase = phrase + + word2 + wordl;
}
alert(phrase);
else if (i == 0) w ord5
i++ else if
J |^^Tord2
phrase
word4 i < 3 vro£ a i 1 < 4
ГШ Л I 1 [Т Т 7 Г ) C D Г 1- I i = 3
] [ word3
дальше ► 85
как добавлять javascript в веб-страницы
Мне сказали,
что мы будем добавлять
JavaScript в свои веб-страницы.
Когда мы, наконец, займемся этим?
Или так и будем ходить вокруг да око
ло, разбираясь в JavaScript?
86 глава 2
javascript и dom
дальше ► 87
взаимодействие со страницей
head body
| title | script || [ h2
О
Сокращенно мы также
называем ее просто РОМ .
2 Т Г 1 JavaScHpt мож^
веб- r ! М На.писания интеРактивных
-страниц/приложений. Из данной
книги вы узнаете, как это делается
88 глава 2
javascript и dom
1 html |
head body |
дальше ► 89
внедрение объектной модели документа
О бъект d o cu m en t — /
это словно корень
перевернутого с ног
на голову дерева.
L i= :
Z l rn d Z Цемент а.
Эти объекты подобны
^ вет вям дерева.
90 глава 2
javascript и dom
Forbidden Planet
Playingat5Л0рсп.9:00pm.
1 1 i
дальше ► 91
отношения между javascript и dom
92 глава 2
javascript и dom
Давайте иачием с DOM. Чуть пиж е приведеп п рим ер простой объектпой модели докумепта. Здесь
имеется песколько HTM L-параграфов (< р > ), каждый из которы х обладает i d со зпачепием соответ-
ствеппо g r e e n p l a n e t , r e d p l a n e t и b l u e p l a n e t . Все параграф ы также содерж ат текст. К опечпо,
здесь есть и элемепт < h e a d > , одпако мы отбросили детали в целях простоты .
Теиерь давайте задействуем JavaScript, чтобы стало ии тересиее. Допустим, пам пеобходимо изме-
пить текст п араграф а с i d в виде g r e e n p l a n e t с " A l l i s w e l l " па " R e d A l e r t : h i t b y p h a s e r
f i r e ! " . В будущем вам мож ет потребоваться печто подобпое, в зависимости от действий, п редпри н и
маемых пользователем, или от даппых веб-службы. Обо всем этом мы еще поговорим, а пока обповим
текст параграф а с i d в виде g r e e n p l a n e t . Вот код, которы й позволит пам это сделать:
d o c u m e n t .g e t E l e m e n t B y l d (" g r e e n p l a n e t " ) ;
•..после чего
g e tE le m e n tB y ld (‘'greenplanet") возвра
J a v a S crip t-код
сможет сде
щ ает элем ен т <р>> значение id к о т о
л а т ь с ним
рого с о о т в е т с т в у е т "greenplanet11...
много чего
интересного.
дальше ► 93
использование getelementbyid
Как только getE lem entB yld возвратит требуемы й элемент, вы см ож ете сделать с ним
что-нибудь (папример, измепить его текст па "R e d A l e r t : h i t b y p h a s e r f i r e ! " ) .
Для этого обы чпо требуется присвоить элем епт п ерем еппой, благодаря чему па пего мож-
по будет ссылаться повсюду в своем коде. Д авайте сделаем это, а затем измепим текст:
З д е сь м ы в ы з ы в а е м getElementByld,
Мы присваиваем элемент который отыщет и возвратит
переменной с именем planet. f элемент "greenplanet ''.
i
var planet = docume n t . g e t E l e m e n t B y l d ( " g r e e n p l a n e t " ) ;
I
Теперь мы можем использовать
в своем коде переменную planet
для ссылки на наш элемент.
>1,
p l a n e t .innerHTML = "Red Alert: hit b y phaser fire!";
_ /
Мы^можем использовать
свойство innerHTML на
7
Мы заменяем содержимое элемента greenplanet
шего элемента planet на наш новый текст... в результате чего объ
для изменения содержимо ектная модель документа (и веб-страница) будет
го требуемого элемента. обновлена с использованием этого нового текста.
О свойствах элементов мы
вскоре погорим подробнее...
| р id =^ re e n p la n e t^ j| | р id = V e d p la n e t“ ] | р id = “blueplanet
г
Любые изменения в объектной модели документа отражаются
на т о м j как браузер осуществляет рендеринг страницы , п о
этому вы увидите , что содержимое параграфа стало другим!
94 глава 2
Возьми в руку карандаш javascript и dom
document.getElementByld (11е7" )
document.getElementByld (11е8" )
document.getElementByld ("е1б")
document.getElementByld ("e9" )
document.getElementByld (Mel8")
document.getElementByld ("el3" )
document.getElementByld ("el2 ")
document.getElementByld ("e2" )
воз-
Hп и ш и т е , какой и м ен н о э л е м е н т
1ЛЛДК~
в р а щ а е т каждая из с т р о к кода а
тобы
же со д е р ж и м о е э т о г о э л е м е н т а ,
раскрыть т а й н о е с о о б щ е н и е .1
-(„Qwixvidg xw ? d g
QWlfiHdzgOVI X£QV?H он
f F )h viH V d \M V Q VZVH
-d?g?d?v i онж о]^}„)
q.ovi j.Yiq s'dSvd yvvq
vi л щ v\vo y)o\ „ :wi?gwiQ
дальше ► 95
тестирование кода dom
Tecm-драйб планет
Рапее вы уже видели, как использовать d o c u m e n t. g e tE le m e n tB y ld
для получепия доступа к элементу, a innerHTM L —для изм епепия его
содерж имого. Теперь давайте сделаем это по-пастоящему.
Н иж е приведепа HTM L-разметка веб-страпицы Planets; здесь у пас
имеется элем епт < s c r i p t > в <head>, куда мы будем помещ ать код,
и тр и п араграф а со зпачепиям и i d соответствеппо g r e e n p l a n e t ,
r e d p l a n e t и b l u e p l a n e t . Если вы еще этого пе сделали, то добавь
те HTM L и JavaScript для обповлепия объектпой модели докумепта
(DOM):
<! doctype html>
<html lang="en">
<head> Мы добавили JavaScript
<title>Planets</title> в <kead> страницы.
<meta charset="utf-8">
<script> Точно т ак же, как и раньше,
var planet = document.getElementByld("greenplanet") s r мы извлекаем элем ент <р>
planet.innerHTML = "Red Alert: hit by phaser fire!" с id в виде "greenplanet" и и з -
</script> ^ *меняем его содержимое.
</head>
<body>
<hl>Green Planet</hl>
Элемент <р>, содержимое
<p id="greenplanet">A11 is well</p>
которого мы изменяем
<hl>Red Planet</hl> с помощ ью JavaScript.
<p id="redplanet">Nothing to report</p>
<hl>Blue Planet</hl>
<p id="blueplanet">All systems A-OK</p>
</body>
</html> О оо ©Janets
*■ -> с л О localhost/~Beth/HTML.. |Г| ф Р , ^ ^
96 глава 2
javascript и dom
Я трижды перепроверил
[ свою разметку и код, но все равно
О V ничего не получается. Я не вижу ни
каких изменений на своей странице
дальше ► 97
ожидание загрузки страницы
. я --------------------------------------------------------------------------------
Здесь мы задаем значение
window.onload = init; свойства window.onload
в виде имени нашей функции.
< /s c rip t>
Здесь говорится: «когда
страница полност ью з а
Перезагрузите страницу грузится, выполнить код,
располагающийся в init».
Теперь перезагрузите страпицу и посм отрите, все ли встало па свои места:
ООО PEanets
I< |► 1|+ |0 http:f/localhosl/-BethyHead- (5 ](От Google ")»
Да! Теперь в элемент е <р> с id в виде
greenplanet отобразилось новое содер
G re e n P la n e t жимое. Здорово, не правда ли?
Red Alert: hit by phaser fire!
98 глава 2
javascript и dom
window.
</script>
</head>
<body>
<hl>My awesome playlist</hl>
<ul id="playlist"> Пустой список песен. Приведенный чут ь
<li id=" songl"X/li> выше код должен добавлять содержимое
<li id=" song2"X/li>
в каждый <li> плейлиста.
дальше ► 99
функциональность dom
100 глава 2
javascript и dom
Каждое значение
им е ет индексный Д ля каждого индекса
номер j при эт о м в массиве имеется
нумерация начи соот вет ст вую щ ее
нается с нуля. значение.
Ч тобы использовать массив, его спачала пужпо создать, а также п рисвоить этот массив пере-
меппой, чтобы у пас было печто такое, посредством чего мы будем ссылаться па пего в своем
коде. Д авайте создадим массив вроде того, которы й показап выше и содерж ит почасовы е
показатели температуры (по Ф арепгейту): ^
-создание нового пустого
Наша п ер е м е н - массива
ная для массива... ^ >t
^ Мы вернемся к эт о м у синтаксису
, _ __ .
var tempByHour = new Array () ; в главе 4, а пока просто
r з н а й т е J,
что он создает новый массив.
tempByHour [0 ] = 59.2;
tempByHour [1 ] 6 0 .1 ; Д ля добавления новых значений в массив мы
tempByHour [2 ] б3. просто ссылаемся на индексный номер э л е
м ент а массива и присваиваем ем у значение.
tempByHour [3 ] 65;
tempByHour [4 ] 62; 4- — Как и в случае с переменными JavaScript,
* вы можете присвоить любое значение
Индекс (или т и п значения) индексу массива.
дальше ► 101
использование массива
tempByHour[5] = 61 ;
Используя новый
порядковый индекс,
мы добавляем новый
элем ент в массив.
Д ля доступа к значению
т е м пер ат у р ы с индексом S
мы просто ссылаемся
на массив с индексом 5.
102 глава 2
javascript и dom
Возьми в руку карандаш
Внизу вы найдете веб-страницу со списком пустых элементов, готовых к тому, чтобы ваш JavaScript
заполнил их температурными показателями. Мы привели большую часть кода; вам необходимо
устранить имеющиеся в нем пробелы, чтобы он смог задать содержимое для каждого элемента
списка в виде соответствующего показателя температуры из массива (например, элемент списка
с id = "tempo" получит температурный показатель с индексом 0 в массиве и т. д.). Таким об
разом, элемент списка с id = "temp3" будет гласить: "The t e m p e r a t u r e at 3 w a s 65".
Попробуйте сделать так, чтобы элемент списка с i d = "tempo" гласил "The t e m p e r a t u r e
at n o o n w a s 59.2" вместо "The t e m p e r a t u r e at 0 w a s 59.2".
<! doctype html>
<h tml 1ang=11en11>
<head> 4r~ 3 mo HTML-
<title>Temperatures</title>
<meta charset="utf-8">
<script>
function showTemps() {
var tempByHour = new ____
tempByHour[0] = 59.2;
tempByHour[1] = 60.1;
tempByHour[2] = 63;
Здесь мы комбинируем
tempByHour[3] = 65; циклы и массивы. Видите,
tempByHour[4] = 62; как мы получаем доступ
for (var i = 0; i < _____ ) { к каждому элем ент у
var theTemp = _______ [i] ;
массива с использованием
var id = "__________ 11 + i ;
индекса переменной?
var li = document. (id) ;
if (i == ) {
li. = "The temperature at noon was " + theTemp;
else {
l i .innerHTML "The temperature at " + ______ + " was " + ___
}
}
window.onload = showTemps;
</script>
</head> К odj приведенный оОо
<body> выше, будет з а п о л
<hl>Temperatures</hl> нять каждый элем ент
<ul> списка содержимым Temperatures
<li id=" tempO"X/li> в виде фразы, вклю ча • The temperature at noon was 59 2
<li id=" tempi"X/li> ющей словосочетание • The temperature at 1 was 60.1
<li id=" temp2"X/li> • The temperature at 2 was 63
The tem p e ra tu re at... • The temperature at 3 was 65
<li id=" temp3"X/li>
• The temperature at 4 was 62
<li id=" temp4"X/li>
</ul>
</body>
</html>
дальше ► 103
пример приложения phrase-o-matic
window.onload = makePhrases;
</script>
</head>
<body>
<hl>Phrase-o-Matic says:</hl>
<p id=" phrase " X / p >
</body>
</html>
104 глава 2
javascript и dom
Phrase-O-Matic
Надеемся, вы догадались, что данны й код нредставляет собой отличны й инструмент для
генери рован ия маркетинговы х слоганов, отображ аемы х на веб-странице. В нрош лом он
уже генерировал такие удачные ф разы , как Win-win value-added solution («Беспроигры ш
ное эф ф екти вн ое реш ение») и 2 4 /7 em pow ered process («Процесс, идущий 24 часа в сутки,
7 дней в неделю»), и мы очень надеемся, что и будущие слоганы окажутся не хуже. Д авайте
но смотрим, как он работает.
дальше ► 105
как работает phrase-o-matic
( 3 ) И так, у нас есть три новы х массива, содержащ их красивы е звучные слова. Тенерь
мы будем осуществлять случайную выборку но слову из каждого массива, которы е
затем объединим в одну фразу.
Вот как п роизводится вы борка но одному слову из каждого массива:
Мы генерируем по одному случайному числу для каждого массива
и присваиваем его новой переменной ( r a n d l , r a n d z и rand3 с о о т
ветственно).
^ Тенерь сформируем отличны й м аркетинговы й слоган, для чего возьмем все слу
чайно вы бранны е слова и конкатенируем их друг с другом в одну фразу, разделив
нробелами для удобочитаемости:
Каждое случайное число мы исполь-
Мы определяем еще одну переменную зуе м как индекс в массивах слов...
для размещения фразы.
Мы но чти нодош ли к финалу: у нас есть фраза, которую тенерь необходимо ото-
бразить. Вы уже знаете, как мы будем действовать: нрим еним g e tE le m e n tB y ld
для ноиска нашего элем ента <р>, а затем иснользуем его свойство innerHTM L
для того, чтобы номестить в него новую фразу
106 глава 2
javascript и dom
Итак, напечатайте носледнюю строку кода, еще раз окиньте все взглядом и ощутите удов
л етворен и е от того, что вы довели дело до конца, нрежде чем нерейдете к загрузке стра
ницы в своем браузере. П роведите ее тест-драйв и нолюбуйтесь на генерируем ые фразы .
О О О Phrase-o-m atfc
д вот кдк [ МI If + 0 h ttp ://lo c a lh o 5 t/-B e th /H e a d F irs t-H T M L S /c h a p te r2 /p h rase.htm l б] 'Q,' Google
выглядит
наша фраза!
Phrase-o-Matic says:
B-to-B focused vision
дальше ► 107
Изучение языка является непро
стой задачей, и важно, чтобы ваш мозг
не только трудился, но и отдыхал. Поэтому,
закончив читать данную главу, устройте себе
передышку, перекусите немного и, прежде
чем перейти к следующей главе, ознакомь
тесь с рубрикой «Ключевые моменты» и ре
шите кроссворд, чтобы закрепить изучен
ный материал.
' о
'■ 3
Мы еще не научились
преобразовывать
цифровые изображе
ния с едой в нечто
вещественное, т ак
что вам самим п р и
дется позаботиться
о закусках.
108 глава 2
javascript и dom
кл ю ч евы е
МОМЕНТЫ
дальше ► 109
кроссворд
U IM L 5 -K f° < r B ° fA
Настало врем я заставить ноработать левое нолуш арие вашего
мозга нутем реш ения кроссворда. Удачи!
По горизонтали По вертикали
2. Если написать 3 + 11stooges11, то JavaScript осуществит_______ I. Объектная модель документа (DOM) — это внутреннее представление
3 в строку. веб-___________ .
4 . _________используется для извлечения значения из массива. 3. Браузер созд ает_______________________ документа при загрузке
5. 5 < 1 0 — э т о ____________ выражение. страницы.
7. Вы можете добавлять свой JavaScript-код в ____________ или body 6. Добавьте его в свои веб-страницы, чтобы сделать их интерактивными.
HTML-документа. 9. Значение id элемента <р>, содержащего текст 11Red Alert : hit
8. Количество элементов в массиве можно узнать с помощью свойства by phaser fire!11.
I I . Заключайте свой JavaScript-код в тег <___________ >, если помещае
10. Имена переменных могут начинаться с _________ , знака $ или те его в HTML-страницу.
символа подчеркивания. 14. Если вы почти закончили, то выпейте чаю, а если, как в условии
12. Выбирайте подходящие имена для переменных и используйте стиль ___________ , конец работы еще не близок, продолжайте дальше!
для указания имен, состоящих из нескольких слов. 15. Циклы while и for используют____________выражение в качестве
_
110 глава 2
javascript и dom
(^var х = 1138^
"Number" + " " + "2"
(^var у = 3/8 Г)
Какова будет результирующая строка? N u w b e ir 2
var s = "3-8
level >= 5
А каким окажется результат, если значением l e v e l будет ____ Технически данный оператор
является допустимым, однако
^ >= означает «больше получаемое в результате зна
либо равно» чение нельзя использовать.
color != "pink"
"one" + 11tw o j^
Каким окажется результат, если значением c o l o r будет b lu e ? (Svar t
С.Приблизительно!
с Math.Pi возвращает
значение пи (оно, как вы
зна е т е, равно 3,14...)
у ; недопустимый.
дальше ► 111
решение упражнения
СТАНЬ б р а у к р е м . Р еш ение
}(аж Д ы й u s ИриБеДенньхХ на э т о й ст р а н и ц е Фрагмент 1
J a V a ^ c r ip t—ф р а Щ е н т ° В п р е д с т а в л я е т собой о щ -
3-5*
112 глава 2
javascript и dom
Пражнение Возьмите приведенный выше код и вставьте его в цикл w h i l e внизу. Пройдитесь
решение по циклу w h i l e и напишите сообщения диалоговых окон a l e r t в той последова
тельности, в которой они будут выводиться. Вот наше решение этого задания.
дальше ► 113
решение упражнения
J else if i --
phrase J = phrase + wordl + word3;
else if l( I i == 3
phrase = phrase + + word2 + wordl;
}
alert(phrase);
114 глава 2
javascript и dom
Movie Showtimes
Plan 9 from Outer Space
Playing « 3:00pm . 7 0 0 p m . S p e d a l (bow ing tonight и midnigtul
Forbidden Planet
Playta* « 5:0Qpm. 9:00pm.
<! doctype html>
СТАНЬ браумром. <html lang=MenM>
Решение <head>
jjaiHa ЗаДаЧа З а к л ю ч а е т
<title>Movies</title>
</head>
ся Б т °М , Ч т °^ ы с ы Г р а т ь
<body>
роЛь браузера. ^аМ необхо
<hl>Movie Showtimes</hl>
димо о с у щ е с т в и т ь р азбор
<h2 id="moviel" >Plan 9 from Outer Space</h2>
ЩЩ-раЗМешКи и создать
<p>Playing at 3:0 0pm, 7:0 0pm.
на ее °сноВе сВок» собственную
<span>
объектную Модель документа
Special showing tonight at <em>midnight</em>!
ФОМ)- Поэвдому сначала про </span>
изведите разбор HTML’ к°щ о-
</p>
рый находится справа, а D0M
<h2 id=nmovie2M>Forbidden Planet</h2>
нарисуйте Внизу. ЦаЧаЛ©
<p>Playing at 5:00pm, 9:00pm.</p>
объектной м°дели документа
</body>
Мы уже нарисовали, а ВаМ
</html>
предстоит ее завершить.
дальше ► 115
решение упражнения
116 глава 2
javascript и dom
дальше ► 117
решение кроссворда
K M L 5 ” K F4><rBoP A’ f e ffleHue
5Л 0 г и ч Е С к
Юг
11с
13r 14г
U м N
17л
118 глава 2
3 собьипия, о б р а б о т ч и к и и Весь эггк>гп ДЖ аЗ
* -ф -
Немного взаимодействия
П у с т ь э т о будет м е н е д ж е р н л е й л и с т о в . М ы д а д и м ем у ка к о е -н и б у д ь
о р и ги н а л ь н о е н а з в а н и е , н а н р и м е р ... с ка ж е м , W e b v ille Tunes.
^ Приложение будет
Вот что мы будем создавать. V - полностью браузерным.
Код на стороне сервера
не потребуется.
Ш ТУ РМ
Если вам известно, для чего нужен этот код:
w in d o w .o n lo a d = i n i t ;
120 глава 3
события и обработчики
Приступаем...
Д л я н а ча л а н е т н е о б х о д и м о с т и созд авать б о л ьш у ю , к о м п л е к с н у ю в е б -стр а н иц у.
Н а сам ом деле м ы м о ж е м н а ч а ть о ч е н ь н р о с т о . Д а в а й те со зд а д им H T M L 5 -
д о к у м е н т с ф о р м о й и э л е м е н т о м с н и с ка , где будет с о д е р ж а т ь с я н л е й л и с т :
Проведите тест-д р ай в
Н а н е ч а т а й т е н р и в е д е н н ы й вы ш е ко д , за гр у зи т е е го в своем
л ю б и м о м браузере и н о л ю б у й те с ь н а результат, н р е ж д е че м non webviiie Tunes
н е р е й д е те к сл е д ую щ е й с т р а н и ц е . Г«Т»П [+ ie http://>ocaihOSt/~Beth/HTML5/javasc еП coogie ~)
[Song ^Add Song^
Вот что вы должны увидеть.
* Не забывайтеу что использованную в этом примере таблицу стилей (и весь код) вы можете
загрузить на свой компьютеру посетив страницу kttp.//wickedlysm art.com /kfktm l5.
дальше ► 121
о событиях нажатия кнопки
Н а са м ом деле в о н р о с за кл ю ч а е тс я в т о м , к а к за с т а в и ть к н о н к у делать ч т о -т о , к о гд а
в ы щ е л ка е те н а н е й . Т о ч н е е , в о н р о с с о с т о и т в т о м , к а к будет н р о и с х о д и т ь в ы зо в н е
о б х о д и м о го J a v a S c rip t-кода, к о гд а в ы н а ж и м а е те к н о н к у ?
122 глава 3
события и обработчики
ЭЙ, кнопка,
ты меня интересуешь...
Не могла ли бы ты дать
мне знать, если кто-нибудь
щелкнет на тебе?
Добавить песню
Ваша кнопка
Обработка событий
Далее в ы у зн а е те , ч т о в б раузере н р и о т о б р а ж е н и и веб-стра-
н и ц ы н р о и с х о д и т м н о ж е с т в о д е й с т в и й : п о л ь зо в а те л ь щ е л ка
е т н а к н о н к а х , н о с е т и м о гу т н о с т у н а т ь з а н р о ш е н н ы е в а ш и м
к о д о м д о п о л н и т е л ь н ы е д а н н ы е , з н а ч е н и я в р е м е н и та й м е р о в
м о гу т и с т е к а т ь (до э т о го м ы еще д о й д е м ). В се э т и в е щ и н р и в о -
д я т к и н и ц и и р о в а н и ю с о б ы т и й , с в и д е те л ь с тв у ю щ и х о т о м , ч т о
к н о н к а б ы ла н а ж а т а , ста л и д о с т у н н ы д о п о л н и т е л ь н ы е д а н н ы е ,
в р е м я и с т е к л о и т. д. (е сть ещ е м н о г о р а з н ы х с о б ы т и й ).
В с я к и й раз, к о гд а и н и ц и и р у е т с я с о б ы т и е , ваш ем у к о д у нр ед о -
ста в л яе тся в о з м о ж н о с т ь обработать е го ; то есть вам н е о б х о
д и м о п р е д у с м о тр е ть ко д , к о т о р ы й будет в ы зы в а т ь с я н р и и н и
Ваш код ц и и р о в а н и и о п р е д е л е н н о го с о б ы т и я . В ам н е н у ж н о с и ю ж е
м и н у т у о б е с н е ч и в а ть о б р а б о т к у к а к и х -л и б о с о б ы т и й , о д н а ко
э то н о т р е б у е т с я сделать, е сли в ы х о т и т е , ч т о б ы н р и и х и н и ц и
и р о в а н и и ч т о -т о н р о и с х о д и л о : н а н р и м е р , к о гд а и н и ц и и р у е т с я
с о б ы т и е н а ж а т и я к н о н к и , вам м о ж е т п о т р е б о в а т ь с я , ч т о б ы за
э т и м н о сл е д о в а л о д о б а в л е н и е н о в о й н е с н и в п л е й л и с т; ко гд а
н о с т у н а ю т д о п о л н и т е л ь н ы е д а н н ы е , в ы м о ж е т е за х о т е ть о б р а
б о та ть и х и о т о б р а з и т ь н а с в о е й с т р а н и ц е ; ко гд а за п у с ка е тся
т а й м е р , вам м о ж е т п о н а д о б и т ь с я с о о б щ и т ь п о л ь з о в а те л ю , ч т о
е го б р о н ь н а б и л е т ы в н е р в о м р я д у с к о р о и с т е ч е т, и т. д.
Т а к и м о б р а зо м , м ы зн а е м , ч т о н а м н е о б х о д и м о о б е с н е ч и т ь об
ра б о тку со б ы тия , и н и ц и и р у е м о го н р и н а ж а ти и к н о н к и , н о это
му н о с м о т р и м , к а к э то м о ж н о сделать.
дальше ► 123
код для обработчика кнопки
Составляем план...
Д а в а й те н е м н о го н р и т о р м о з и м , н р е ж д е ч е м угл у б и м с я в м и р о б р а б о т ч и к о в и с о б ы т и й . Н а ш а ц ель
се й ч а с — сделать т а к , ч т о б ы но сл е щ е л ч ка н а к н о н к е A d d S o n g (Д о б а в и т ь н е с н ю ) н р о и з о ш л о д о
бавлени е н е с н и в н л е й л и с т н а с т р а н и ц е . П о д о й д е м к р е ш е н и ю э т о й за д а чи н а о с н о в е с л е д у ю щ и х
э та н о в :
1 . Задание об р а б о тч и к а для о б р а б о тк и с о б ы т и й c lic k 6 о тн о ш е н и и кнопки A d d S on g ( Д о б а в и т ь п е с н ю ).
2 . Написание об р а б о тч и к а для извлечения названия песни, введ енного п ол ь з ов ател ем , после чего п о с л е д у е т ...
] К\ В есь к о д, к о т о р ы й д о л -
При в ы зове данной ф у н к ц и и жен в ы п о л н я т ь с я п р и
будет выводиться диалого- вы зове ф у н к ц и и , м ы з а -
вое окно a lert. к льо ча е м в скобки.
124 глава 3
1. Задание обработчика для обработки событий click
2. Написание обработчика для извлечения названия песни
3. Создание нового элемента для размещения новой песни
Задание обработчика событий click для кнопки 4 . Добавление нового элемента в D0M страницы
К а к в ы н о м н и т е , м ы делали н е ч т о н о д о б н о е , к о гд а и с н о л ь з о в а л и с в о й с т в о w in d o w .o n lo a d
для в ы зо в а ф у н к ц и и н о с л е о к о н ч а н и я з а гр у з к и о к н а . О д н а к о в д а н н о м случае м ы в ы зы в а е м
ф у н к ц и ю но сл е н а ж а т и я к н о н к и . Т е н е р ь с о е д и н и м все:
Проведение т е с т а .
Н а н е ч а т а й те н р и в е д е н н ы й в ы ш е ко д (в своем ф айле p l a y l i s t . j s ) , з а гр у зи те с тр а н иц у, а затем но -
щ е л ка й т е н а к н о н к е с т о л ь к о р аз, с к о л ь к о з а х о т и т е . П о с л е к а ж д о го щ е л ч ка в ы будете н а б л ю д а ть
н о я в л е н и е д и а л о го в о го о к н а a l e r t .
З а к о н ч и в т е с т и р о в а н и е с в о е го н о в о г о
о б р а бо тчика с о б ы ти й c l i c k в о тн о ш е н и и
к н о н к и , о т к и н ь т е с ь н а с н и н к у стула и и зу h Mp . y / f o c a l h o s t
ч и т е к о д , нро д ум а в т о , к а к о н раб о та е т. Button wa5 clicked!
К о г д а в ы н о й м е т е , ч т о все э то у ж е у вас
в го л о в е , н е р е в е р н и т е стр а н и ц у , и м ы с
в а м и н р о й д е м с я н о д е та л я м , ч т о б ы за-
к р е н и т ь м а те р и а л .
дальше ► 125
как работает кнопка add song
function handleButtonClick() {
alert("Button was clicked! ') ;
}
г 'и Обработчик
в вашем коде
126 глава 3
события и обработчики
Г Добавить песню
о
f u n c t i o n h a n d l e B u t t o n C l i c k () {
a l e r t ( " B u tton was c l i c k e d ! " )
}
Меня попросили
сообщить вам, что кноп
ка была нажата... Я знаю,
что для диалогового окна
http://localhost
ale rt это не слишком впечат
Button was clicked!
ляюще, но, как бы там ни было,
я просто делаю свою
( Q* )
работу.
дальше ► 127
извлечение названия песни из dom 1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick
2. Написание обработчика для извлечения названия песни
3. Создание нового элемента для размещения новой песни
извлечение названия песни 4 . Добавление нового элемента в D0M страницы
М ы готовы н е р е й т и к о в т о р о м у э та н у р е ш е н и я н а ш е й за д а ч и — и з в л е ч е н и ю н а з в а н и я н е с н и ,
в в е д е н н о го п о л ьзо в а те л е м . Сделав э т о , м ы с м о ж е м задум аться над те м , к а к н а ш н л е й л и с т будет
о т о б р а ж а т ь с я в браузере.
Д л я и з в л е ч е н и я т е к с т а и з т е к с т о в о го э л е м е н та ввода ф о р м ы н а м сна ча ла н о т р е б у е т с я и з в л е ч ь
э т о т э л е м е н т и з D O M , и в ы у ж е зн а е те , к а к о й и н с т р у м е н т для э т о го н у ж е н — g e t E l e m e n t B y l d .
Сделав э то , м ы см о ж е м в о с п о л ь зо в а ть с я с в о й с т в о м v a l u e т е к с т о в о го э л е м е нта ввода для п о л у ч е
н и я д о стун а к тексту, вве д е н н о м у в но л е ф о р м ы по л ьзо ва те л е м , и в о т к а к это все будет вы гл яд е ть:
\
input id^'songTextlnput” nput id="addButton" j
value="Blue Suede Strings, by Elvis Pagely"
З а т е м м ы и с п о л ь з у е м свойст во value
э л е м е н т а ввода для извлечения т е к с т а ,
С пом ощ ью мет ода набранного п о л ь з о в а т е л е м в п оле вчооа.
g e tE le m e n tB y l d м ы сможем
получит ь доступ к элем ент у
ввода s o n g T e x tln p u t в ф орм е.
f u n c t i o n h a n d l e B u t t o n C l i c k () {
v a r t e x t l n p u t = d o c u m e n t . g e t E l e m e n t B y l d ("
v a r songName = . v a lu e;
alert(" A d d in g " +
128 глава 3
события и обработчики
А вдруг вам потребуется провести проверку, чтобы убедиться в том, что пользо
ватель действительно ввел текст до того, как щелкнул на кнопке? Как это можно
будет сделать? (Решение данного задания вы также сможете отыскать на с. 130.)
Часш°
ЧаДаВаеМые
Вопросы
дальше ► 129
решение упражнения
f u n c t i o n h a n d l e B u t t o n C l i c k () { J
var t e x t I n p u t = docum ent. g e tE le m e n tB y ld (" so n g T ex tIn p u t"
v a r songName = t e x t I n p u t . v a l u e ;
a l e r t ( "Adding " + son gN am e);
Свойство value текстового
} элемента ввода содержит
все, что набирается в т е к -
стовом поле и представляет
Ь у д е т выводиться диалоговое окно собой строку. Здесь мы при -
alert, в к о т о р о м о т о б р а зи т с я сваиваем введенный текст
"Adding" и название песни. переменной songName.
f u n c t i o n h a n d l e B u t t o n C l i c k () {
v a r t e x t l n p u t = docum ent. g e tE le m e n tB y ld (" so n g T e x tln p u t" );
v a r songName = t e x t l n p u t . v a l u e ; M ы мож ем и с п о ль з о ва т ь о п е р а т о р
if (songName == "") { ^ — if и ср а в н и т ь с т р о к у so n g N a m e
с п у с т о й с т р о к о й , чтобы у б е
a l e r t ( " P lea se e n t e r a song"),
дит ься, ч т о п о л ь з о в а т е л ь д е й
} else { с т в и т е л ь н о ч т о - т о напечат ал.
a l e r t ( "Adding " + songName); Если п о л ь з о в а т е л ь ничего не н а п е
ч а т а л , т о мы выведем диалоговое
окно a le rt и п о п р о с и м его ввест и
название песни.
130 глава 3
1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick
2 . Нап и сан ие о б р а б о т ч и к а для и звлечения назВания песни
3. Создание нового элемента для размещения новой песни
Как добавить песню на страницу? 4-А»б»в».н«...вого«««м.»™вdom^«„цы
М ы с в а м и у ж е м н о г о ч е го сделали, и все р а б о та е т! В ы м о ж е т е в в е с ти назва
н и е н е с н и в ф орму, щ е л к н у т ь н а к н о н к е A d d S o n g (Д о б а в и т ь н е с н ю ) и и з в л е ч ь
т о , ч т о в в о д и л и в ф орму, — все в рамках вашего кода . Т е н е р ь м ы о т о б р а з и м п л е й
л и с т н а са м о й с т р а н и ц е . В о т к а к э то будет в ы гл я д е ть.
ООО W eb ville T u n e s
дальше ► 131
создание нового элемента
пражненке п По
соответствующие элементы на своих местах в DOM. 1Code the Line, by Johnny JavaScript
Один из них мы уже расположили в нужном месте,
That'll be the Data, by Buddy Bitly and the Variables
вам остается лишь сделать то же самое в отношении
остальных элементов. Посмотрите решение данного Your Random Heart, by Hank "Math" Williams
задания в конце главы, прежде чем двинетесь дальше.
Д о р и с у й т е зд е сь о с т а л ь н у ю
ч а с т ь РОМ д л я п л е й л и с т а ,
п р и в е д е н н о г о в в е р ху.
Придется ли вам строить какие-либо предположения насчет порядка,
в котором элементы < i i > добавляются в родительский элемент?
132 глава 3
события и обработчики
Д л я создания новых э л е м е н т о в и с п о л ь з уе т с я d o c u m e n t
c re a te E le m en t. В о звр а щ а е т с я ссылка на новый э л е м е н т .
var l i =
\
d o c u m e n t. c r e a t e E le m e n t ( " l i " ) ;
Передаем
Здесь м ы п р и с в а
c r e a te E le m e n t в виде
и ва ем новый э л е
с т р о к и т о , какой э л е
м е н т пер е м е н н о й И.
м е н т х о т и м создать.
С п о м о щ ь ю c r e a te E le m e n t создается совершенно
| li j новый э л е м е н т . С ледует о т м е т и т ь , ч т о он
Л пока не вс т а в л я е т с я в о б ъ е к т н у ю м о д е ль д о
ку м е н т а . На данный м о м е н т он п р е д с т а в л я е т
содой ли ш ь э л е м е н т , находящийся в свободном
п л а в а н и и , к о т о р о м у нужно п р и с т а н и щ е в РОМ.
И т а к , т е н е р ь у на с и м е е т с я э л е м е н т < l i > , в к о т о р о м н и ч е г о
н е т. В ы у ж е з н а е т е с н о с о б д о б а в и т ь т е к с т о в о е с о д е р ж и м о е
в эл е м е н т:
li.in n erH T M L = songN am e;
Наша п е р е м е н - ^ з а д а ш со д е р ^
ная I'- жимое в виде названия
песни для э л е м е н т а <h>.
Наш новый о б ъ е кт
э л е м е н т а li, готовы
р и н у т ь с я в бой. О д н а
ко он еще не явля е т с я
ч а с т ь ю РОМ!
дальше ► 133
добавление нового элемента 1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick
2 . Нап и сан ие о б р а б о т ч и к а для и звлечения назв ан и я песни
3 . С о здание нового э л е м е н т а для р а з м е щ е н и я новой песни
Ч т о б ы д о б а в и ть н о в ы й э л е м е н т в о б ъ е к т н у ю модель д о ку м е н та , вам
н е о б х о д и м о зн а ть , куда е го н о м е щ а ть . Ч т о ж , н а м э то у ж е и з в е с т н о :
м ы со б и р а е м ся н о м е с т и т ь э л е м е н т < l i > в э л е м е н т < u l> . Н о к а к э то
сделать? Д а в а й те еще ра з взгл я н е м н а D O M . П о м н и т е , к а к ра не е м ы
о т м е ч а л и , ч т о о н а с р о д н и дереву? М о ж е т е т а к ж е с ч и т а т ь ее че м -то
вр о д е родословного дерева.
к
м ейного рода и р а с п о л а г а е т с я б&нкоМ» (У V ...... р 0Эителелл
б да н но м п о ко л е ни и
на с а м о м верху дерева. р
document
У h t m l и м е ю т с я два
дочерних э л е м е н т а —
с html
i hea d и body. Р о дит е ле м
~ Г ~
body явля е т с я h tm l.
head | body j * '
v a r u l =
2
d o c u m e n t . g e t E l e m e n t B y l d ( " p l a y l i s t 11) ;
appendC hild новый
э л е м е н т <Ц> б удет
добавлят ься в э л е
u l .a p p e n d C h i l d ( li) ;
м е н т <ul> после
Здесь мы п р е д ла га е м э л е м е н т у <ul> добавить <h> в качест ве любых других э л е
дочернего э л е м е н т а . К ак т о л ь к о э т о будет сделано, в РОМ <(/> м е н т о в <li>j ко т оры е
с т а н е т дочерним э л е м е н т о м <ul>, и браузер обновит с т р а н и ц у , уже т а м б уд у т р а с
чтобы в ней о т р а зи л с я новый <h>. полага т ься.
134 глава 3
события и обработчики
f u n c t i o n h a n d l e B u t t o n C l i c k () {
v a r t e x t l n p u t = d o c u m e n t . g e t E l e m e n t B y l d ( " s o n g T e x t l n p u t " );
Сначала м ы создаем новый э л е м е н т <h>,
v a r songName = t e x t l n p u t . v a l u e ; ___ g к о т о р о м б удет р а з м е щ а т ь с я н а з в а -
tС ние новой п е с ни .
var l i = docum ent. c r ea teE le m e n t (" l i " );
З а т е м задаем содержимое в виде
li.in n erH T M L = songName; ^ названия песни для данного эл е м е н т а .
<ul> с id "playlist" я вля е т с я р о д и -
v a r u l = document . g e t E l e m e n t B y l d ( " p l a y l i s t " ) ; (г~т ельскиМ э л е м е н т о м no о т н о ш е н и ю
к н а ш е м у новом у <И>. П о эт ом у он
u l . a p p e n d C h ild ( l i ) ; -- ------------^ след у ю щ и й в очереди на извлечение.
дальше ► 135
обзор приложения playlist
136 глава 3
события и обработчики
В о зв р а щ а я с ь к п л е й л и с т у ... М ы х о т е л и б ы с т р о п р о
д е м о н с т р и р о в а т ь вам п р и м е р с о з д а н и я н е б о л ь ш о го
и н те р а кт и в н о го п р и л о ж е н и я , и п лейл ист о тл и чн о п о
до ш е л в д а н н о м случае. К р о м е т о г о , с о х р а н е н и е н е с е н
тр е б уе т A P I-и н те р ф е й с а W eb Storage и з в е р с и и H T M L 5 ,
до р а с с м о т р е н и я к о т о р о г о — еще н е с к о л ь к о глав.
С д р у го й с т о р о н ы , м ы д е й с тв и т е л ь н о н е х о т и м , ч т о б ы
здесь оставалась ка ка я -то н е д о с ка за н н о с ть ...
Переверните страницу
дальше ► 137
J o rD o B o
К y ilo r D j> eg j i eH U Io
М ы за р а н е е п р и г о т о в и л и для вас ко д , п о з в о л я
ю щ и й с о х р а н я ть п л е й л и с ты . Вам н у ж н о н р о с т о
н а п е ч а т а ть е го , а т а к ж е в н е с т и н а р у н е б о л ь ш и х
и з м е н е н и й в уж е и м е ю щ и й с я ко д , ч т о б ы в и т о ге
получился со хр а н е н н ы й пл ейл ист H T M L 5 .
О бо всех о со б е н н о стях со хр а н е н и я д ан ны х
л о ка л ь н о в браузере м ы п о г о в о р и м в главе, но -
с в я щ е н н о й A P I-и н те р ф е й с у W e b S torage, а н о к а
ч то вы научитесь со хр а нять н л ейлисты .
Е с т е с т в е н н о , н и к о г д а н е л и ш н и м б уд е т п р о
с м о тр е т ь п р и г о т о в л е н н ы й н а м и ко д . Вас м о ж е т
у д и в и т ь , н а с к о л ь к о м н о г о е в ы у ж е зн а е те , не
г о в о р я у ж е о то м , н а с ко л ь ко м н о го е в ы см о ж е те
п о н я т ь , д а ж е е сли ещ е н е зн а е те э т о го .
\Lm
Приготовленный код
не будет работать
J ДЫ НС | в некоторых браузе-
о о ц о р о Ж Н з» 1. рах, если вы загру
Приготовленный
ь код не будет ра жаете свои страни
цы из file://, а не с сервера (например,
б у д ь т е ботать в Internet localhost://) или онлайн-сервера.
оС Ш ороЖ Н ы Explorer 6 и 7.
В следующих главах мы поговорим об этой
Данные версии ситуации более подробно (она довольно
браузера Internet Explorer не поддержи часто возникает в случае с новыми функ
вают localStorage. Поэтому если вы циями HTML5). А пока, если вы не хотите
используете Internet Explorer, поза- запускать выполнение сервера или копиро
ботьтесь о том, чтобы его версия вать файлы на онлайн-сервер, используйте
была 8 или выше. браузер Safari или Chrome.
138 глава 3
события и обработчики
fu n c tio n sa v e(ite m ) {
v a r p l a y l i s t A r r a y = g e t S t o r e A r r a y ( " p l a y l i s t " );
p la y lis tA r r a y .p u s h (ite m );
l o c a l S t o r a g e . s e t I t e m ( " p l a y l i s t ", J S O N . s t r i n g i f y ( p l a y l i s t A r r a y )
}
f u n c t i o n l o a d P l a y l i s t () {
var p la y lis t A r r a y = g e tS a v ed S o n g s();
v a r u l = d o c u m e n t . g e t E l e m e n t B y l d ( " p l a y l i s t ");
i f ( p l a y l i s t A r r a y != n u l l ) {
f o r (var i = 0; i < p l a y l i s t A r r a y . l e n g t h ; i+ + )
v a r l i = d o c u m e n t . c r e a t e E l e m e n t ("l i " ) ;
li.in n e rH T M L = p l a y l i s t A r r a y [ i ] ;
u l . a p p e n d C h ild (li);
Перенесите Beet? этот код
} ® файл playlist_store.js
}
}
f u n c t i o n g e t S a v e d S o n g s () {
return g e t S t o r e A r r a y (" p l a y l i s t " ) ;
дальше ► 139
сохранение плейлиста
к употребл ение
Н ам необ ход им о в не сти нару неб о л ьш их и зм е н е н и й , ч т о б ы и н т е гр и
р о в а т ь к о д для с о х р а н е н и я н л е й л и с та . С на ча л а м ы д о б а в и м с с ы л ку
н а p l a y l i s t _ s t o r e . j s в э л е м е н т <head> в p l a y l i s t . h t m l :
Д об авьт е э т у с т р о к у , р а з -
< scr ip t s r c = " p la y lis t_ s to r e . j s " x / s c r i p t > / __ — ме с ти в ее прямо над ссылкой
„ П П у
< s c n p t s гс= " p l a y l i s t . j s " > < / s c r i p t >
^ на playlist.is.
л Она за груж а ет
приготовленный код.
Т е н е р ь н у ж н о д о б а в и ть две с т р о к и в у ж е и м е ю щ и й с я у вас ко д
в p l a y l i s t . j s , к о т о р ы е будут з а гр у ж а т ь и с о х р а н я т ь н л е й л и с т:
f u n c t i o n i n i t () {
v a r b u t t o n = d o c u m e n t . g e t E l e m e n t B y l d ( "addButton"
b u t t o n .o n c l ic k = h a n d leB u tto n C lic k ;
Д а н н а я с т р о к а загр уж а ет сохраненные
l o a d P l a y l i s t (); ^ __________
песни из localStorage, когда вы за груж ает е
} свою с т р а н и ц у , благодаря чем у они о т о
бразят ся на экране в п л е й л и с т е .
f u n c t i o n h a n d l e B u t t o n C l i c k () {
v a r t e x t l n p u t = d o c u m e n t . g e t E l e m e n t B y l d ( " s o n g T e x t l n p u t " );
v a r songName = t e x t l n p u t . v a l u e ;
var l i = docum ent. cr e a te E le m e n t (" l i " );
l i . innerHTML = songName;
var u l = docum ent. g e tE le m e n tB y ld (" l i s t " );
u l . a p p e n d C h i l d (l i ) А э т а ст р о к а сохр аняет каж
save(son gN am e); дую новую п е с н ю , к о т о р у ю Мы добавили
вы добавляете в п л е й л и с т . все э т и п е с
ни, закры ли
окно б раузера,
зат ем сно
ва о т к р ы л и
Тест-драйв сохраненного плейлиста его, з а г р у з и
° MfrbvUteTunes______ ли с т р а н и ц у ,
И т а к , п е р е з а гр у з и т е с т р а н и ц у и в в е д и те назва I * I I I M tpv/'lni ,|| 1ю'4/-КечhH«4ri Hr-.( HIMI Ч С
и перед нам и
н и я н е с к о л ь к и х н е се н . З а к р о й т е о к н о браузера. Song n a m e
( Add Sang-) предстал со
С н о в а о т к р о й т е е го и о н я т ь з а гр у з и т е с т р а н и Blue Suede Strings, by Elvis Pagely храненный
цу. П о с л е э т о го в ы д о л ж н ы у в и д е ть п л е й л и с т плейлист
Great Objecte on Fire, by Jarry JSON Lewis
со в се м и с в о и м и с о х р а н е н н ы м и н е с н я м и . с песнями.
I Code the Line, by Johnny JavaScript
140 глава 3
события и обработчики
Подходящее время.
М ы с тр е м и л и с ь п р о д е м о н с т р и р о в а т ь вам н о д р о б
н ы й п р и м е р т о г о , к а к H T M L -р а зм е тка и J a v a S c rip t
в с о ч е т а н и и д р у г с д р у го м п о з в о л я ю т с о зд а в а ть
и н т е р а к т и в н ы е в е б -п р и л о ж е н и я . Е сли вдум аться,
м ы с ва м и у ж е м н о го е делали:
1) в ста в л я л и к о д на с тр а н и ц у ;
2) п о з н а к о м и л и с ь с с о б ы т и я м и c lic k , и н и ц и и р у е
м ы м и п р и щ е л ч ке н а к н о п к е , и н а н и с а л и к о д для
п е р е х в а та и о б р а б о т к и д а н н ы х с о б ы т и й ;
3) и з в л е ка л и и н ф о р м а ц и ю и з о б ъ е к т н о й м о д е л и
д о кум е н та ;
4 ) созд авали и д о б а в л я л и н о в ы е э л е м е н т ы в D O M .
Н е п л о х о ! А те н е р ь , к о гд а у вас с л о ж и л о с ь н е к о т о
р о е и н т у и т и в н о е нре д ста вле н ие о то м , к а к действу
ет весь э т о т м е ха н и зм , давайте сделаем н е б о л ь ш о й
к р ю к н о а в е ню Ja va S crip t и н о с м о тр и м , к а к и м е н н о
р а б о т а ю т ф у н к ц и и и о б ъ е кты .
Н е т, э то н е будет за у р я д н а я н р о гу л к а , н о с к о л ь к у
м ы д а ж е за гл я н е м н о д к р ы ш к и л ю к о в н а д о р о ге
и ра зб е р е м ся в то м , к а к ф у н к ц и о н и р у е т В ебвилль.
З а и н те р е с о в а л и с ь ? Т огда п р и с о е д и н я й т е с ь к н а м
в главе 4...
дальше ► 141
обзор обработчиков событитй и dom
КЛЮЧЕВЫЕ
— МОМЕНТЫ
■ В браузере постоянно происходит масса со а затем добавить в качестве дочернего эле
бытий. Если вы хотите обеспечить реакцию мента по отношению к другому элементу.
на эти события, то вам потребуется обраба
Используйте d o c u m e n t . c r e a t e E l e m e n t
тывать их с помощью обработчиков событий.
для создания новых элементов. Передайте
■ Событие c l i c k инициируется при нажатии имя тега (например, " l i " ) в вызов функ
кнопки на странице. ции, чтобы указать, какой элемент вы хотите
создать.
■ Для обработки событий c l i c k необходимо
зарегистрировать функцию, которая и займет Для добавления элемента в качестве дочер
ся их обработкой. Для этого нужно сначала него по отношению к родительскому элементу
написать функцию, а затем присвоить ее имя в DOM необходимо извлечь ссылку на роди
свойству КНОПКИ o n c l i c k . тельский элемент и вызвать в отношении него
ap pend C h ild , передав при этом дочерний
■ Если обработчик событий c l i c k зарегистри
элемент, который требуется добавить.
рован, то данная функция будет вызываться,
когда пользователь щелкнет на кнопке с по При добавлении множественных дочерних
мощью мыши. элементов в родительский элемент с исполь
зованием a p p e n d C h ild КЭЖДЫЙ НОВЫЙ ДО-
■ Для реагирования на события c l i c k не
черний элемент будет добавляться после
обходимо написать соответствующий код
всех прочих уже имеющихся там дочерних
в функции обработчика. Можно выводить
элементов, в результате чего они окажутся
сообщения для пользователя в диалоговых
расположены позади или под дочерними
окнах a l e r t , обновлять страницу, а также
элементами, которые уже присутствовали на
выполнять другие действия.
странице (при условии, что вы не станете вно
■ Для извлечения данных, введенных пользова сить изменения в макет посредством CSS).
телем в текстовое поле формы, необходимо
Вы можете использовать API-интерфейс Web
использовать свойство v a l u e поля ввода.
Storage ( l o c a l S t o r a g e ) ДЛЯ Сохранения
■ Если пользователь ничего не ввел в текстовое данных в браузере пользователя.
поле формы, значением данного поля будет
Мы применяли localStorage для сохранения
пустая строка ("").
плейлиста с песнями, используя при этом
■ Вы можете проводить сравнение переменной заранее приготовленный код. Подробнее
с пустой строкой при помощи оператора i f о l o c a l S t o r a g e вы узнаете в главе 9.
и ==.
В следующей главе мы еще больше расска
■ Для добавления нового элемента в объектную жем о DOM и JavaScript-возможностях, таких
модель документа его сначала нужно создать, как функции и объекты.
142 глава 3
события и обработчики
Ц Щ 5 - К Г 0С СВ0Г Д
Д а й т е своем у м о з гу н е к о т о р о е в р е м я , ч т о б ы о н у с в о и л а с н е к т ы в за и м о
д е й с т в и я H T M L с J a v a S c rip t. П о р а з м ы с л и т е над те м , к а к о н и р а б о т а ю т
с о о б щ а . А н о к а в ы б удете д е л а ть э т о , р а з га д а й т е н р и в е д е н н ы й н и ж е
к р о с с в о р д для з а к р е н л е н и я м а те р и а л а . В се и с н о л ь з о в а н н ы е в н е м слова
в з я т ы и з д а н н о й гл авы .
По горизонтали По вертикали
2. Метод для создания новых элементов, внедряемых 1. Исполнитель, имя которого мы использовали в примере
в объектную модель документа (DOM). с песнями.
3. Метод для добавления новых элементов в DOM. 5. Код, который занимается обработкой событий_________ .
4. «Мать» дерева объектной модели документа. 6. В случае с кнопкой click — э т о ____________ ..
7. Объектная модель документа является чем-то вроде 7. Новый элемент добавляется в ка ч е с тв е ____________
родословного____________ . элемента.
8. Мы использовали его в заранее приготовленном коде, 10. Что мы будем рассматривать в следующей главе?
чтобы стало возможным сохранение плейлиста с пес Функции и ____________ .
нями.
9. В случае, если пользователь ничего не введет, значением
по умолчанию элемента ввода формы будет____________
строка.
11. Оно происходит, когда пользователь щелкает на кнопке.
дальше ► 143
решение упражнения
гр ш е н и е
решение ПОП
С html
| head | body |
А вот остальная
часть POM
144 глава 3
события и обработчики
Ц Щ § - к Г °с с Б о Г д . ^ ш е н и е
дальше ► 145
4 ^JJhkUuu и ойьетсщы jaVaScript
Серьезный JavaScript+
<script>
var guessInput = document.getElementByld(Mguess M);
С
var guess = guessInput.value;
Извлечение значения т е к
var answer = null;
стового поля ввода формы.
Использование браузерных
функций (например , alert).
А ч т о б ы вам э то д е й с т в и т е л ь н о удалось, м ы н е с та н е м н а ч и н а т ь с гл у б о к о го
ана л и за g e t E l e m e n t B y ld , а за й м е м ся ко е -ч е м более интересным: р а с ш и р и м ваш
с л о в а р н ы й занас в о б л а с ти J a v a S c rip t и н а у ч и м с я делать н о в ы е ве щ и .
148 глава 4
функции и объекты javascript
^ --
ЖеА| з а м е н и т ь на и з я и ш ,, ^ д, основного кода , м ы м о -
смож ем вы зы ват ь и M m ^ J ^ deTa^m Cke° kQuess‘ ко^ о р у н >
*мо же самое.
Создание функции checkGuess
Q Для создания функции необходимо воспользоваться ключевым словом
function, после которого следует указать ИМЯ, например checkGuess.
if (guess == answers[index]) {
answer = "You're right! I was thinking of " + answers[index];
} else {
answer = "Sorry, I was thinking of " + answers[index];
}
return answer; ' *)
Задайте тело своей функции, которое
Опционально можно воз следует заключить в фигурные скобки.
вращать значение в качестве Тело содержит весь код, который обе
результата вызова функции. спечивает выполнение работы функции.
Здесь мы возвращаем строку Здесь в теле мы повторно используем
с сообщением. код с предыдущей страницы.
дальше ► 149
как работают функции
В о т н а ш а удобная
ф у н к ц и я bark.
Д а в а й те в ы п о л п и м в ы зо в и п о с м о т р и м , к а к все
э то р а б о та е т:
При вы зо ве b a r k а р г у м е н т ы
function bark(dogName , dogWeight)
присваиваю т ся им енам п а
р а м е т р о в в ф у н к ц и и bark. if (dogWeight <= 10) {
return dogName + says Yip";
else {
return dogName + says Woof";
И каждый раз , когда
параметры встреча
ются в функцииj будут
использоваться пере
данные нами значения.
150 глава 4
функции и объекты javascript
О п е р а то р ы о ц е пи в а ю тся сверху в п и з, к а к и }
л ю б о й д р у г о й к о д , к о т о р ы й в ы п и ш е т е . Раз-
п и ц а з а кл ю ч а е тс я в т о м , ч т о м ы будем делать
э то в среде, где и м е п а п а р а м е тр о в d ogN am e и Здесь мы оцениваем весь код
d o g W e i g h t п р и с в а и в а ю т с я а р гу м е п та м , п ере- в теле функции.
даппы м в ф упкц ию .
дальше ► 151
важность функций и объектов
Т а к ч т о ж е я в л я е тс я э т о й о с п о в о й ? С ч и т а й т е , ч т о A P I-
и п т е р ф е й с ы J a v a S c rip t в H T M L 5 с о с т о я т и з о б ъ е кт о в , м е
т о д о в (т а к ж е п а зы в а е м ы х функциями) и с в о й с т в . Ч т о б ы
п о -п а с то я щ е м у овлад еть A P I-и п т е р ф е й с а м и J a v a S c rip t, вам
п е о б х о д и м о х о р о ш о р а зб и р а т ь с я в э т и х вещ ах. Е с те с тв е п -
п о , в ы м о ж е т е п о п ы т а т ь с я о б о й т и с ь и без з п а п и й о п и х , од
п а к о в т а к о м случае п р и и с п о л ь з о в а п и и А Р 1 -и п те р ф е й с о в
вам п р и д е т с я п о с т о я п п о с т р о и т ь д о га д к и , ч т о п е п о з в о л и т
вам п о л п о с т ь ю за д е й с тв о в а ть и х п о т е п ц и а л (п е го в о р я уж е
о т о м , ч т о в ы будете с о в е р ш а ть м ассу о ш и б о к и п и с а т ь пе-
к а ч е с т в е п п ы й к о д ).
М ы р е ш и л и о б р а т и т ь ваш е в п и м а п и е п а д а п п ы е а с п е к т ы ,
ч т о б ы в ы зп а л и , ч т о вас о ж и д а е т в п е р е д и . С ам ое замеча-
те л ь п о е за к л ю ч а е тс я в т о м , ч т о к к о п ц у гл а в ы в ы будете
р а зб и р а т ь с я в о б ъ е кта х , ф у п к ц и я х , м е то д а х и массе п р о ч и х
с в я з а п п ы х с п и м и в е щ е й л уч ш е , ч е м п р и м е р п о 98 % л ю д е й ,
за н и м а ю щ и х с я п а п и с а п и е м с ц е п а р и е в . И э то п е ш у тка .
152 глава 4
функции и объекты javascript
« р у н к ц и ю
Интервью недели:
Вещи, о которых вы не знали
Function: Д о п у с т и м , в а м п е о б х о д и м о с о о б щ а т ь Function: Д а , и м е п п о та к.
пользователям сто и м о сть то ва р о в, ко то р ы е о п и
п о м е с ти л и в св о ю э л е к т р о п н у ю к о р з и н у в и п т е р п е т -
Head First: Ч т о ж , а к а к п а с ч е т п р и с в а и в а н и я и м е п
с в о и м ф у п кц и я м , а то м п е д о в о д ил о сь слы ш а ть, ч т о
м а га з и п е , п о э т о м у в ы р е ш и л и п а п и с а т ь ф у п к ц и ю
э то делать п е о б я за те л ь п о , е сли п е х о ч е т с я .
com puteShoppingC a r t T o t a l . Сделав э то , в ы с м о ж е
те п е р е д а в а ть ф у п к ц и и р а з л и ч п ы е э л е к т р о п п ы е Function : Д а в а й те п е будем и з л и ш п е п у га ть ауди то
к о р з и п ы , п р и н а д л е ж а щ и е р а з п ы м п о л ь зо в а те л я м , р и ю . Д а в а й те в е р п е м с я к э т о й тем е, ко гд а ч и т а т е л и
и к а ж д ы й ра з п о л у ч а т ь с о о тв е т с тв у ю щ е е з п а ч е п и е у з п а ю т о б о м п е п е м п о г о больш е?
сто и м о сти товаров в ко п к р е т п о й ко р зи п е .
Head First: О б е щ а е те м п е д ать э к с к л ю з и в п о е и п -
...К с т а т и , в о з в р а щ а я с ь к В а ш е м у з а м е ч а п и ю па-
те р в ь ю ?
счет то го , ч то п о в и ч к и пе о чепь часто использу
ю т ф у п к ц и и ; п а с а м о м деле э то п е т а к , п о с к о л ь к у Function: М ы э то ещ е обсудим ...
дальше ► 153
параметры и аргументы
j
func t i o n coo k ( d e g r e e s , mode, duration) {
// здесь будет валя код
П р и в ы зо в е ф у н к ц и и в ы вызываете ее с и с п о л ь зо в а
н и е м аргументов:
\ т?
cook(425.0, "bake", 45);
Т а к и м о б р а зо м , с в о и п а р а м е т р ы в ы будете о п р е д е л я ть
т о л ь к о о д и п р аз, а в ы зы в а т ь с в о и ф у п к ц и и ста п е те с и с
п о л ь з о в а н и е м м а ссы р а з п ы х а р гу м е н то в .
3 ас удивит, насколько много людей путается в том, где исполь
зуются параметры, а где аргументы. 3 некоторых книгах даже
встречается неверное толкование, поэтому если вы где-то увидите,
^ что утверждается обратное, то будете знать, где правда...
Днапк>Мия «^нкДии
Т е п е р ь , ко гд а в ы зп а е те , к а к о п р е д е л я ть п в ы зы в а т ь ф у п к ц и и , давай те
уб е д и м ся , ч т о в ы х о р о ш о р а зб и р а е те с ь в с и п т а к с и с е . В о т к а к в ы гл я д я т
с о с та в п ы е ч а с т и а п а т о м и и ф у п к ц и и :
г Даже если у вашей ф унк-
Затем идут з а - ции нет параметров, вам
После ключевого слова ключенные в круглые по-прежнему необходимо
Вначале всегда function следует имя скобки и разделенные указать открывающую
должно идти ключе вашей функции. запятой параметры, и закрывающую скобки,
вое слово function. которых может быть
ноль и более.
Часш°
зад аваем ы е .........
B o T L j= > o tb l
Почему перед именами параметров ] ) • Я передаю переменную своей функ Смогу ли я изм енять значен и я
не ставится var? Параметр — это же но ции; если я изменю значение соответ в функции?
вая переменная, ведь так? ствующего параметра в моей функции,
то приведет ли это также к изменению
0 : Вы сможете изменять только значения
0 : Да, так и есть. Функция сделает за вас моей исходной переменной?
глобальных переменных (они определяются
всю работу по созданию экземпляра пере
вне функций) или переменных, которые вы
менной, поэтому вам не нужно указывать 0 : Нет. Когда вы передаете примитивное явно определили в своей функции. Вскоре
ключевое слово v a r перед именами своих значение, оно копируется в параметр. Мы
мы чуть подробнее затронем эту тему.
параметров. называем это «передача по значению».
Таким образом, если вы измените значение
^ 3 * Каковы правила присваивания имен параметра в теле своей функции, то это Котсутствует
- - оператор
— , *return?
™ . -
функциям? никак не повлияет на оригинальное значе
ние вашего аргумента. Исключением здесь
0 : Они аналогичны правилам присваива является передача массива или объекта, но 0 : Функция без оператора r e t u r n воз
ния имен переменным. об этом мы поговорим чуть позже. вращает значение u n d e f in e d .
дальше ► 155
упражнение
function dogsAge(age) {
return age * 7;
}
function addUp(numArray) {
var total = 0;
for (var i = 0; i < numArray.length; i++) {
total += numArray[i];
}
return total;
}
function getAvatar(points) {
var avatar;
Напишите
здесь, какое
if (points < 100) {
значение б у
avatar = "Mouse"; дет и м ет ь
} else if (points > 100 && points < 1000) { каждая из
avatar = "Cat";
} else {
avatar = "Ape";
С
myDogsAge = .............
}
rectArea = .............
return avatar;
} theTotal = .............
var myAvatar = getAvatar(335); myAvatar = .............
156 глава 4
функции и объекты javascript
В ы у ж е зп а е те , ч т о м о ж е т е о б ъ я в л я ть п е р е м е п п ы е с и с п о л ь зо в а
н и е м к л ю ч е в о го слова v a r и и м е п и где у го д п о в св о е м J a v a S c rip t-
Еслииеремеииая
ко д е :
var avatar;
Это гл о б а л ь н ы е п е р е м е н н ы е j
\ С ~ они п о в с е м е с т н о д о с т у п н ы
объявлена
var levelThreshold = 1000; в в а ш е м J a v a S c r i p t -коде.
внефункции,
В ам т а к ж е и з в е с т п о , ч т о п е р е м е п п ы е
м о ж п о о б ъ я в л я ть и в п у т р и ф у п к ц и и : тооиаявляется
function getScore(points)
var score; ^
{
Переменные points>
score и i объявляются ГЛОБАЛЬНОЙ.
внутри функции.
дальше ► 157
локальная и глобальная область видимости
8 u p d a te P o in ts у нас и м е е т с я л о к а л ь
function updatePoints(bonus , newPoints) ная п ер е м е н н а я L Д а н н а я п ер е м е н н а я
for (var i = 0; i < bonus; i++) { видима для всего кода в updatePoints.
newPoints += skill * bonus; bonus и n e w P o in ts также я в л я
} ю т с я л о к а ль н ы м и по о т н о ш е
return newPoints + userPoints; нию к u p d a te P o in ts , в т о вр е м я как
userPoints я вля е т с я глобальной п е р е
менной.
158 глава 4
функции и объекты javascript
Готов поклясться,
что переменная была прямо
у меня за спиной, но когда
я обернулся, она уже исчезла.
Т а к ч т о ж е , п о л у ч а е тс я , «сбеж ать» о т с т р а п и ц ы
п и к а к Н Е Л Ь З Я ? Е сл и в ы — л о ка л ь п а я п е р е м е п -
п а я, т о ваш а ж и з п ь п р о л е т а е т б ы с т р о . Н о если
Присоединяйтесь к нам в главе,
вам п о в е зл о р о д и т ь с я гл о б а л ь п о й п е р е м е п п о й ,
т о в ы будете зд р а в с тв о в а ть , п о к а п о л ь зо в а те л ь посвященной A P I -инт ерф ейсу Web
п е п е р е з а гр у з и т с т р а п и ц у в б раузере. Storage, где мы помож ем ваш им
_ данным избежать «уж асаю щ их»
О д п а к о в с е -та ки должен с у щ е ств о в а ть с п о с о б
для н и х последствий перезагрузки
«сбежать» о т с т р а п и ц ы ! М ы м о ж е м е го п а й т и !
веб-странии,ы!
К а к в ы считаете?
дальше ► 159
переменные в тени
Интересно, что
будет, если я присвою
локальной переменной то же
имя, которое имеет уже суще
ствующая глобальная пере
ев V менная?
var beanCounter = 1 0 ;
Здесь у нас
имеются
function getNumberOf Items (ordertype) { и глобальная
var beanCounter = 0; Чг и локальная
if (ordertype == "order”) { переменные!
/ / сделать что-то с помощью beanCounter...
}
return beanCounter;
}
К о гд а в ы сделаете э т о , л ю б ы е с с ы л к и п а b e a n C o u n t e r
в н у т р и ф у н к ц и и будут в е с т и к л о к а л ь п о й п е р е м е п п о й ,
а не к гл о б а л ь н о й . Т а к и м о б р а зо м , м ы го в о р и м , ч т о гл о
бальная п е р е м е н н а я будет п а х о д и т ь с я «в те п и » л о ка л ь
н о й п е р е м е н н о й (д р у ги м и сл о в а м и , м ы п е с м о ж е м ее
ув и д е ть , п о с к о л ь к у па м п о м е ш а е т э то сделать л о ка л ь п а я
п е р е м е п п а я ).
б е д у е т от метит ь , что ло -
кальная и глобальная переменные
не влияют друг на друга: если и з
менить одну из них , то это никак
не скажется на другой. Они явля
ются независимыми переменными.
160 глава 4
функции и объекты javascript
Част°
ЧаДаВаеМые
В опросы
дальше ► 161
функции как значения
ч
После выполнения
plusOne присваивается функции , поэтому
мы сможем вызывать ее с использованием
Целочисленного аргумента в виде г
данного вызова result
будет равен 2.
Ч т о ж е , р а п е е м ы п е т о л ь к о за б ы л и у п о м я п у т ь об э т о й п е б о л ы н о й де та л и , к а с а ю щ е й
ся ф у п к ц и й , п о т а к ж е п е со все м б ы л и ч е с т п ы , к о гд а р а с с ка зы в а л и вам об а п а т о м и и
ф у п к ц и и , — о ка зы в а е тс я , вам даж е п е п у ж п о п р и с в а и в а т ь и м я с в о е й ф у п к ц и и . Все
в е р п о : ваш а ф у п к ц и я м о ж е т б ы ть анонимной. Ч т о ж е все э то з п а ч и т и за ч е м вам м о
ж е т п о т р е б о в а т ь с я п о с т у п и т ь так? Д а в а й те сп а ча л а п о с м о т р и м , к а к созд ать ф у п к ц и ю
без и м е п и :
var f = f u n c t io n (n u m ) {
r e t u r n num + 1 ; А затем мы сможем
•» ^ использовать нашу
* L переменную_ для
. - вызова
п .-.~
v a r r e s u lt = f (1);
функции
a le r t(r e s u lt); ^
162 глава 4
функции и объекты javascript
М 9 *Г 9 ? 9 Й
Ш ТУРМ Все это должно быть
для вас немного более
Взгляните на данный код: как вы думаете, что он делает? понятным, учит ы
вая то, что мы сейчас
var element = document.getElementByld ("button" ) ; с вами рассмотрели...
element.onclick = function () {
alert("clicked!"); к Не беспокойтесь, если вы так и не с м о -
} жете на ZOO % во всем здесь разобраться,
поскольку мы еще дойдем до этого...
Л и б о м ы м о ж е м п о с т у п и т ь ещ е и п т е р е с п е е :
ству window.onload.
Не беспокойтесь, если
window.onload = function() {
window.onload кажется
alert("you rule!"); вам несколько непонятным,
} ^ Красота! Разве это поскольку позже мы под-
не проще и удобнее < Q Q н ш поговорим,
для чтения?
К а к в ы уж е п а ч а л и п о п и м а т ь , ф у п к ц и и п о з в о л я ю т делать к о е -ч т о п о л е зп о е п о м и м о п р о с т о й « у п а ко в ки »
ко д а для п о в т о р п о г о и с п о л ь з о в а п и я . Ч т о б ы л у ч ш е р а з о б р а ть с я в т о м , к а к п о л п о с т ь ю за д е й с тв о в а ть все
п р е и м у щ е с тв а ф у п к ц и й , д а в а й те в згл я п е м п а о б ъ е к т ы и п о с м о т р и м , к а к о п и в п и с ы в а ю т с я в J a v a S crip t,
п о с л е ч е го о б ъ е д и п и м и х в е д и п ы й м е х а п и зм .
дальше ► 163
зажигательная речь
Так ч то п о те р п и те — ф а кти ч е с ки , вы уж е
п р о ш л и п о л о в и н у п у т и ! И не за б ы в а й те , ч т о
в д а п н о й главе в ы п р е в р а т и т е с ь и з п и с а те л я
с ц е п а р и е в в п р о гр а м м и с т а , и з H T M L /C S S -
п а е з д н и к а в т о г о , к т о с п о с о б е н создавать
с е р ь е зн ы е п р и л о ж е н и я .
L А мы уже упоминали о т о м ,
что все это также может
позволить вам заработать
намного больше денег?
164 глава 4
функции и объекты javascript
Благодаря объектам N
будущие перспективы выглядят
настолько яркими, что нам действи
тельно НЕ ОБОЙТИСЬ без солнцеза
щитных очков...
дальше ► 165
объекты и свойства
Размышления о свойствах...
Е с те с тв е н н о , н а ш не с F id o , е сли б ы м о г го в о р и т ь , сразу ж е о т м е т и л б ы , ч т о у н е го
и м е е т с я н а м н о го б о льш е с в о й с т в , ч е м м ы н е р е ч и с л и л и в ы ш е , о д н а ко в д а н н о м
н р и м е р е и м е н н о и х м ы и о т р а з и м в н р о г р а м м н о м ко д е . Д а в а й те в згл я н е м н а э т и
с в о й с т в а с т о ч к и з р е н и я т и н о в д а н н ы х Ja v a S c rip t:
166 глава 4
функции и объекты javascript
h ------------ И с п о л ь з у й т е т о ч ку (.)
if (fido.weight > 25)
alert ("WOOF") ;
И спользуйт е объект н а
I
ряду с т очко й и и м е н е м £ id o .w e ig h t ^
} else { свойст ва для п о л у ч е ... а в о т и м я
ния д о с т у п а к значению В о т объект.. свойства.
alert ("yip") ;
эт ого свойства.
}
На э т о т р а з з а к л ю
Обращение к свойствам с использованием строки
ч и т е и м я свойст ва
и скобочной нотации: в квадрат ны е скобки.
дальше ► 167
что могут объекты
168 глава 4
функции и объекты javascript
по сл е ч е го у fid o п о я в и т с я н о в о е с в о й с т в о : аде.
А ч т о б ы удал ить с в о й с т в о , н у ж н о в о с п о л ь з о в а ть с я к л ю
ч е в ы м сл о в о м delete:
d e le te f i d o . a g e ;
П р и уд а л е н и и с в о й с т в а в ы удаляете н е н р о с т о е го зн а ч е
н и е , а само э то с в о й с т в о . Ф а к т и ч е с к и , если в ы з а х о т и т е
в о с п о л ь з о в а ть с я f i d o . аде но сл е т о г о , к а к уд а л ил и е го ,
то о н о будет о ц е н е н о к а к u n d e fin e d .
В ы р а ж е н и е d e le t e в о зв р а щ а е т t r u e , е сли с в о й с т в о
б ы л о у с н е ш н о удалено (л и б о е сли в ы удаляете с в о й с т в о ,
к о т о р о е н е сущ ествует, л и б о если т о , ч т о в ы н ы т а е те с ь
уда л ить, н е я в л я е тс я с в о й с т в о м о б ъ е кта ).
дальше ► 169
объекты как аргументы
К о гд а о б ъ е к т н р и с в а и в а е т с я н е р е м е н н о й , о н а будет с о д е р ж а т ь н е сам
э т о т о б ъ е кт, а ссылку н а н е го . С ч и т а й т е с с ы л ку у ка за те л е м н а о б ъ е кт.
weight: 40
Т а к и м о б р а зо м , н р и в ы зо в е ф у н к ц и и и пе р ед а че е й о б ъ е кта в ы будете
н ер е д а ва ть с с ы л ку н а о б ъ е к т — не сам о б ъ е кт, а т о л ь к о ука за те л ь на не го ,
К о н и я с с ы л к и п е р е д а е тс я в н а р а м е т р , п р и э т о м у ка зы в а т ь о н а будет на
о р и г и н а л ь н ы й о б ъ е кт.
170 глава 4
функции и объекты javascript
— breed: "Mixed"
function loseWeight(dog) {
dog.weight = dog.weight 10; e Такимобразом , при вычитании
НО фунтов* из dog.weight мы
изменяем значение fido.weight.
10 ф у н то в ® 4,5 4 кг.
дальше ► 171
приложение webville cinema
Рейтинг в звездочках: 2.
Рейтинг в звездочках: 5.
172 глава 4
функции и объекты javascript
m o v i e l обладает ч е т ы р ь м я с в о й с т в а м и :
M bi создали два
о б ъ е кт а с и м е title , g e n r e , ra tin g и show tim es.
нам и moviel-
и m o vieZ для var moviel = { Значения title и g e n r e явля-
двух ф и льм ов. title: "Plan 9 from Outer Space"
ю т е я строками.
свои -
у m o v i e z тоже и м е ю т с я ч е т ы р е
var тоvie2 = { ства: title, g e n re , rating и sho w tim es.
Мы использовали т е ж е самые
им ена с в о й с т в , как и в случае
с m o v i e l , но значения с во йст в
на э т о т раз б уд у т уже другие.
дальше ► 173
внедрение следующего сеанса
к уно^е^леншо
function getTimeFromString( time String) {
var theTime = new D a t e ();
В о т п р и го т о вл е н н ы й
var time = timeString.match(/(\d+)(?:: (\d\d))?\s*(p?) /);
нам и кодj ко т о р ы й п р о
theTime.setHours( parselnt(time[1]) + (time[3] ? 12 : 0) )
ст о б е р е т с т р о к у ф о р
theTime.setMinutes( parseInt(time[2]) II 0 ) ; м а т а , например l a m
return theTime.getTime() ; или Ърт> и п р е о б р а з у е т
} ее в значение вр ем ени
в м и ллисекунда х.
He беспокойт есь насчет данного кода; в нем и с п о л ь з у ю т с я
р е гу ля р н ы е выражения , о ко т о р ы х вы у з н а е т е по ходу и з у ч е
ния Ja vaS cript. А пока п р о с т о в зг л я н и т е на них!
174 глава 4
функции и объекты javascript
В ы о б р а т и л и в н и м а н и е н а д а н н у ю с т р о к у в н р е д ы д у щ е м коде?
movie.showtimes.length
Э та с т р о к а н е н о х о ж а н и н а ч т о и з т о г о , ч т о н а м д о в о д и л о с ь в и д е ть р а н ь ш е .
О н а нр е д с та в л я е т с о б о й с о к р а щ е н н ы й в а р и а н т с е р и и ш а го в , к о т о р ы е н а м п о
тр е б о в а л о с ь б ы в ы н о л н и т ь , ч т о б ы и з в л е ч ь д л и н у м а сси в а s h o w tim e s и з об ъ
е к т а m o v ie . В м е сто нее н а м н р и ш л о с ь б ы н а н и с а т ь следую щ ее:
— Сначала мы извлекаем
ллассив showtim es.
var showtimes Array = movie.showtimes; ^
var len = show timesArray, length; ^ ____ Затем МЫ используем его
для доступа к свойству length.
О д н а к о м ы м о ж е м делать все э то за о д и н н о д х о д н у т е м о б ъ е д и н е
н и я в ы р а ж е н и й в ц е н о ч к у . Д а в а й те н о с м о т р и м , к а к э то р а б о та е т:
movie.showtimes.length
А ^ t ^
ЧЭОценива - ...который и м е - ...который
ется как ет свойство имеет свой -
объект showtimes , что яв - ство с им е -
movie... ляется массивом... нем length.
Tecm-драйб
Н а н е ч а т а й т е к о д с н р е д ы д у щ е й с т р а н и ц ы и н р о в е д и т е е го те ст-д р а й в . В ы у в и д и те , ч т о ф у н к ц и я
g e tN e x tS h o w in g н р и н и м а е т о б ъ е к т m o v ie и в о зв р а щ а е т с т р о к у со з н а ч е н и е м с л е д ую щ е го сеанса
с о о т в е т с т в у ю щ е го ф ильм а. В ы т а к ж е м о ж е т е с в о б о д н о созд авать с о б с т в е н н ы е н о в ы е о б ъ е к т ы
и н р о в о д и т ь те ст-д р а й в с и х уч а с ти е м . М ы т а к и н о с т у н и л и , н р и э т о м м е с тн о е в р е м я б ы л о 12:30.
var banzaiMovie = {
h« PV/focalhost
title: "Buckaroo Banzai",
Next showing of Buckaroo в а л а ! is j
■00pm
genre: "Cult classic",
rating: 5,
showtimes: ["1:0 0pm" , "5:0 0pm" , "7:0 0pm" ]
'jV
С
Примечание: качество нашего кода явля
J ется не совсем т а к и м , как у « производ -
var next Showing = getNextShowing (banzaiMovie) ; ственного кода»; если вы выполните его
alert (nextshowing); после наступления времени последнего
киносеанса , то получите значение null.
Повторите попытку на следующий день>.\&
дальше ► 175
объекты и методы
}; i К
объект, как показано здесь. объект
Вместо того чтобы гово- Обратите внимание , что
ритъ, что это «функция “ с™ л»зуем анонимную включает
в объекте » , мы просто гово- и присваиваем ее
рым , ч т о это метод. М ежду
ними нет никакой разницы,
^ о и с ^ в у bark объекта,
в себя метод.
однако функции в объектах
все называют методами.
f i d o .b a r k () ;
Мы говорим объекту сделать
чт о-т о, вызывая его методы.
3 данном случае мы вызываем
метод bark объекта fido.
176 глава 4
функции и объекты javascript
var moviel = {
title: "Plan 9 from Outer Space",
M ы взяли наш код и пом ест и
genre: "Cult Classic",
ли его в метод объекта m o v ie l
rating: 5, с использованием имени свойст\
showtimes: ["3:0 0pm" , "7:0 0pm" , "11:0 0pm" ] getNextShowing.
дальше ► 177
переработка функции как метода
} } 1
А вот и еще одно
return null; свойство - title.
}
};
U что теперь?
И т а к , в о т в ч е м з а кл ю ч а е тс я го л о в о л о м к а : у нас и м е ю т с я с с ы л к и н а с в о й с т в а showtimes и title. О б ы ч
н о в ф у н к ц и и м ы ссы лаем ся н а л о к а л ь н у ю н е р е м е н н у ю , н а гл о б а л ьн у ю н е р е м е н н у ю и л и н а н а р а м е т р
ф у н к ц и и , о д н а ко showtimes и title я в л я ю т с я с в о й с т в а м и о б ъ е кта moviel. В н р о ч е м , м о ж е т все и ср а б о
тает... ведь Ja v a S c rip t, к а ж е т с я , д о с т а т о ч н о у м е н для т о г о , ч т о б ы с а м о с то я те л ь н о во всем р а зо б р а ться?
Д е л о в о т в че м : э т и н е р е м е н н ы е я в л я ю т с я с в о й с т в а м и о б ъ е кта , о д н а ко м ы н е с ка за л и J a v a S c rip t, к а к о г о
и м е н н о о б ъ е кта . В ы м о ж е т е н о д ум а ть: «Ведь о ч е в и д н о ж е , ч т о м ы и м е е м в ви д у Д А Н Н Ы Й о б ъ е кт, в о т
э то т, к о т о р ы й н а х о д и т с я н р я м о здесь! Ч т о т у т м о ж е т б ы т ь н е н о н я т н о го ? » . И , да, м ы п о д р а зум е ваем
св о й с т в а и м е н н о э т о го о б ъ е кта . В J a v a S c rip t п р и с у т с т в у е т к л ю ч е в о е сл о во this, к о т о р о е н о з в о л я е т т о ч
н о дать н о н я т ь , ч т о в ы и м е е те в в и д у данный конкретный объект.
178 глава 4
функции и объекты javascript
var moviel = {
title: "Plan 9 from Outer Space",
genre: "Cult Classic",
rating: 5,
showtimes: ["3:00pm", "7:00pm", "11:00pm11], 3dect> МЫ д о бавили к л ю ч е в о е слово
th is п е р е д каж ды м с в о й с т в о м ,
обо зна чив т е м с а м ы м , ч т о и м е е м
getNextShowing: function() {
w T 6 6 иду с с ы л к у на о б ъ е к т m o v i e l .
var now = new Date().getTime();
httP'/Zfocalhost
Next showing of Plan 9 from Outer Space is 3:00pm
V О б р а т и т е в н и м а н и е , ч т о т е п е р ь м ы в ы з ы в а е м 3 etNe^ ho^ 3
В О Т Н О Ш Е Н И И о б ъ е к т а . Т а к более п о н я т н о , н е п р а в д а ли.
дальше ► 179
повт орное использование кода и м ет оды
Похоже, что мы
дублируем один и тот же
код всеми этими копированиями
и вставками /метода getNextShowing.
Разве нет более оптимального
пути?
Верно подмечено.
У вас отличная интуиция, если вы догада
лись, что код дублируется, когда мы копиру
ем g e tN e x tS h o w in g в более чем одип объект
m o vie. Одна из целей объектпо-ориептиро-
ванного програм м ирования заклю чается в
максимизации повторпого использования
кода — здесь мы не используем повторпо
код, а ф актически создаем каждый объект
как уникальный, а наши объекты movie по
соглашению (и из-за копировапия и встав
ки!) в итоге долж ны получаться одинако
выми. Такой подход пе только является
излиш ней тратой ресурсов, по и мож ет соз
давать благодатную почву для ошибок.
Существует лучш ий способ сделать это, ис
пользуя конструктор. Ч то такое копструк-
тор? Это специальпая фупкция, которую
мы с вами папиш ем и которая сможет
создавать объекты и делать их все одина
ковыми. М ожете считать ее своего рода
пеболы ной ф абрикой, которая припим ает
зпачепия свойств, которы е вы хотите за
дать в своем объекте, и возвращ ает повы й
объект со всеми пужпыми вам свойствами
и методами.
Д авайте создадим копструктор...
180 глава 4
ф ункции и объект ы ja v a s c rip t
ф у н к ц и я - к о н с т р у к т о р во м н о г о м
Параметры конст рукт ора п р и н и
схожа с обычной ф у н к ц и е й . О д н а к о м а ю т значения свойств, которыми
по с о г л а ш е н и ю ее и м я должно н а должен обладать наш объект.
ч и н а т ь с я с п р о п и с н о й буквы.
fu n c tio n
Л D o g (п а ш е , b r e e d , w e ig h t) {
Здесь мы инициализируем
свойства объекта значениями,
t h i s , nam e = пате; ~ переданными к о н ст р ук т о р у.
t h is , b re e d = b re e d ;
П ройдем ся по коду еще раз, чтобы убедиться в том, что вы во всем разобра
лись. D og —это фупкция-копструктор, припимаю щ ая пабор аргумептов, ко
торы е являю тся пачальпы ми зпачепиям и пеобходимых пам свойств: nam e,
b r e e d и w e i g h t . Получив эти зпачепия, копструктор п рисваивает свойства,
используя клю чевое слово t h i s . O n также определяет паш метод b a r k .
И каков же результат всего этого? К опструктор D og возвращ ает повы й объ
ект. Д авайте посмотрим, как ф актически использовать копструктор.
дальш е ► 181
использование конст рукт ора
182 глава 4
ф ункции и объект ы ja v a s c rip t
th is th is th is
дальш е ► 183
конструктор movie
184 глава 4
ф ункции и объект ы ja v a s c rip t
Часш°
ЧаДаБаеМые
В опросы
В чем заключается истинная разница между функцией Q l Да, в теле объекта this всегда будет указывать на сам
и методом? В конце концов, если они являются одним и тем объект. Нов некоторых особых ситуациях это может быть не так;
же, почему называются по-разному? например, все окажется несколько сложнее, когда объекты будут
находиться внутри объектов, и если вы решите предпринять дан
Q i По соглашению, если объект включает функцию, мы называем ное действие, то вам придется принимать во внимание семантику,
ее методом. Функция и метод работают одинаково, за исключени поскольку таково общее правило.
ем того, что вызов метода объекта осуществляется с применением
оператора «точка», при этом метод может использовать this для Мне доводилось слышать о том, что при объектно-ориен-
доступа к объекту, в отношении которого был вызван. Считайте тированном программировании у меня могут иметься классы
функцию отдельным блоком кода, который можно вызывать, а ме объектов, которые способны наследовать свойства и методы
тод — поведением, привязанным к определенному объекту. друг от друга по цепочке. Например, у меня мог бы быть класс
mammals, от которого наследуют свойства и методы dog и cat.
Если я с помощью конструктора создам объекты, вклю Возможно ли это на JavaScript?
чающие метод, то в случае со всеми этими объектами будет
совместно использоваться один и тот же код данного метода? Q i Да, возможно. В случае с JavaScript используется так назы
ваемое прототипное наследование, которое представляет
Q i Да, все верно, причем в этом заключается одно из преиму собой даже более мощную модель, чем модели, основанные строго
ществ объектно-ориентированного программирования: вы можете на классах. Рассмотрение прототипного наследования немного
создать код для класса объектов (например, для всех своих объ выходит за рамки данной книги, хотя, может, нам и стоило бы
ектов dog) в одном месте, и он будет совместно использоваться в написать больше о нем в сфере JavaScript.
случае со всеми объектами dog. Чтобы сделать его специфичным
для каждого из объектов dog, необходимо обратиться к их свой
ствам, для доступа к которым вам потребуется использовать this. тор, не так ли?
Могу ли я задавать для this значения по своему выбору, 0 : Да, абсолютно верно! Date — это встроенный JavaScript-
и если да, не приведет ли это к тем или иным отрицательным конструктор. Когда вы указываете new Date () в коде, то полу
последствиям? чаете в свое распоряжение объект Date с набором полезных
методов, которые можно использовать для работы с датами.
0 : Нет, вы не сможете задать для this какие-либо значения.
Помните, что this — это ключевое слово, а не переменная! Оно В чем разница между объектами, которые мы пишем сами
выглядит и ведет себя отчасти как переменная, но не является ею. и которые создаем с помощью конструктора?
Есть ли у this значение вне метода объекта? 0 : Основное различие заключается в том, как вы их создаете.
& Объекты, которые вы пишете сами, используя фигурные скобки
0 : Нет, если вы не вызываете метод объекта, то this будет и разделенные запятыми свойства, называются литералами
undefined. объектов. Вы символ за символом вносите их в свой код! Если
вам потребуется еще один такой объект, то придется самим напи
сать его и позаботиться о том, чтобы он располагал аналогичными
Насколько я понимаю, когда я вызываю метод в отно
свойствами. Объекты, генерируемые конструктором, создаются с
шении объекта, этот объект задается как значение this на все
использованием new и функции-конструктора, возвращающей объ
время, пока будет идти оценка метода. Так ли это?
ект. Вы можете использовать функцию-конструктор для создания
множества объектов с одинаковыми свойствами, но с разными
значениями свойств, если пожелаете.
дальш е ► 185
реш ение упражнения
развлечения с м а гн и т а м и , ^ е^ ен и е
Это к о н ст р ук т о р , в качестве
имени которого мы используем
Movie.
r a tin g , s h o w t im e s ) {
va r now = n e w D a t e ( ) . g e t T i m e ()
fo r (v a r i = 0; i < t h i s . s h o w t im e s
va r s h o w t im e = g e tT im e F r o m S tr in g ( th is . [i]) ;
i f ( ( s h o w tim e - now) > 0 ) {
186 глава 4
ф ункции и объект ы ja v a s c rip t
в вызов функции.
var plan9Movie = new Movie ("Plan 9 from Outer Space",
5,
["5:00pm", "9:00pm"]);
http://iocalliost
Next Showing o f Forbidden Planet is 5:0flpm
http://Jocalhost
Next showing o f Plan 9 from Outer Space is 3:00pm
h ttp ://lo c a lh o s t
дальш е ► 187
тур по объектам
Объекты, с к о document
торы ми мы уже domain
1
сталкивались. title
movie
URL
А вот наш
объект movie. title
genre getElementByld
N— 7 rating getElementsByTagName
showtimes
188 глава 4
ф ункции и объект ы ja v a s c rip t
па пего. 7
@ hnp:/ localhosi/mavle.htm l Google
и м е т о д а м и >о которых вам нужно знать. Next showing of Butkaroo Banzai is i:00pm
Помимо нихj есть еще множество других...
focation содержит
U R L -аЭ р е с с т р а н и ц , : .
Е сли и з м е н и т е е г о ,
L " f « Г Г
новмй URL -адрес.
Вы, несомненно, уже сталкивались с ним
ранее, onload — это свойство, содержа
status содержит стро
щее функцию, которая вызывается после
Ку, которая отобра полной загрузки страницы.
жается в ст атусной
строке браузера. С в о й с т в о d o c u m e n t с о д е Р * “ ™ ° 6*у
ек т н ую модель документа (РОМ).
Вы уже знакомы
с мет одом a lert,
который выводит v r o m . p t подобен a l e r t , за т е м и с к л ю
О т к р ы в а е т новое^
окно браузера.
В ы з ы в а е т о б р а б о т ч и к по и с т е ч е н и и
З акр ы ва ет окно , заданного и н т ер в а л а врем ен и.
s e tT im e o u t
s e tln te rv a l
Многократно вызывает обработчик
через заданный инт ервал времени.
дальше ► 189
как работает w indow .onload
Вот наш глобальный onload является свой - Это анонимная функция, которая
объект window ст вом объекта window. f присваивается свойству onload.
L ^ *
^ w in d o w . o n l o a d = f u n c t i o n ( ) {
// code h e re
} ;
И, конечно же, тело функции будет выполняться
как.только window полностью загрузит страницу
и вызовет нашу анонимную функцию!
190 глава 4
ф ункции и объект ы ja v a s c rip t
r
ЮЩее’ э т о объект document, который является в с т р о
енным JavaScript-объектом, обеспечивающим
доступ к объектной модели документа (РОМ).
var div = document.getElementByld("myDiv");
дальше ► 191
объект элемента
Част°
ЧаДаБаеМ ы е
В опросы
192 глава 4
ф ункции и объект ы ja v a s c rip t
• Какой из двух способов создания обработчика window, J y * В чем разница между встроенными объектами вроде
onload лучше: с указанием имени функции или посредством window и document и теми, которые создаем мы?
использования анонимной функции?
0 : Первое различие заключается в том, что встроенные объекты
Q l Один не является лучше другого, поскольку при использовании отвечают принципам, определяемым спецификациями, и вы можете
любого из этих способов вы, по сути, будете делать одно и то же — обраться к спецификациям W3C, чтобы разобраться во всех их
задавать значение w in d o w , o n lo a d в виде функции, которая свойствах и методах. Во-вторых, многие встроенные объекты (на
станет выполняться после полной загрузки страницы. Если вам по пример, s t r i n g ) обладают свойствами, которые не могут быть
какой-то причине потребуется вызывать i n i t из другой функции изменены. Кроме того, объекты есть объекты. Замечательная
позже в своей программе, то придется определить функцию i n i t . вещь, касающаяся встроенных объектов, состоит в том, что они
В противном случае не будет важно, какой способ вы предпочтете. уже созданы и готовы к использованию вами.
Поздравляем! Вы завершили
свое путешествие по объектам и преодолели
несколько глав учебного курса по Ja va S crip t.
Настало время применить эти знания и заняться
программированием с использованием H TM L5
и всех новы х A P I-интерсрейсов J a v a S c rip t
начиная со следую щ ей главы!
Вы завершаете эту главу, зная об объек
тах и ф ункциях больше, чем м ногие дру
гие л ю д и. Естественно, вы всегда можете
научиться чем у-то еще, и м ы призываем вас
именно так и поступить (после то го , как
закончите читать данную книгу)!
дальш е ► 193
обзор ф ункций и объектов
КЛЮЧЕВЫЕ
МОМЕНТЫ
■ Для создания функции необходимо использовать ■ Если присвоить новую переменную, не используя
ключевое слово fu n c tio n в сочетании с круглы ключевое слово v a r, эта переменная будет гло
ми скобками, в которые будут заключаться пара бальной, даже если вы впервые присваиваете ее
метры при наличии таковых. функции.
■ Функции могут быть именованными либо аноним- ■ Функции — это значения, которые могут присваи
ными. ваться переменным, передаваться другим функ
■ Правила присваивания имен функциям являются циям, сохраняться в массивах и присваиваться
теми же самыми, как и в случае с переменными. свойствам объектов.
■ Тело функции заключается в фигурные скобки и со- " Объекты — это коллекции свойств.
держит операторы, выполняющие работу функции. ■ Обращаться к свойствам объектов можно с ис
■ Функция может возвращать значение посредст пользованием точечной или скобочной нотации.
вом оператора re tu rn . ■ При использовании скобочной нотации имя свой
■ Для вызова функции необходимо указать ее имя ства следует заключать в кавычки, как строку, на
и передать все необходимые аргументы. пример: myObj e c t [ "имя"].
■ В JavaScript используется передача параметров " Вы можете изменять значения свойств, удалять
по значению. свойства и добавлять новые свойства в объекты.
194 глава 4
ф ункции и объект ы ja v a s c rip t
U I M L 5 - K f ° CCB ° r A
По горизонтали По вертикали
2. Функция без имени. I. По соглашению, имена конструкторов должны начинаться
6. Эти переменные доступны только внутри функций. с __________ буквы.
8. Функции без операторов return возвращают это. 3. Связывание свойств и вызовов функций посредством оператора
9. Функция в объекте. «точка».
12. Объект__________ представляет собой объектную модель до 4. То, что указывается в вызове функции.
кумента (DOM). 5. Функция данного рода создает объекты.
13. Аргументы передаются по__________. 7. Свойство в window, которое мы присваиваем функции обработ
15. Данное ключевое слово необходимо использовать в начале чика.
определения функции. 10. Оператор «________ » позволяет получить доступ к свой
17. Настоящий глобальный объект. ствам и методам объекта.
18. То, что указывается в объявлении функции. II. Функции могут включать, а могут и не включать данный оператор.
14. Область видимости переменной, которая доступна повсеместно.
16. Указывает на текущий объект в методе объекта.
дальш е ► 195
решение упражнения
г ^ о зь м и в руку карандаш
Решение Воспользуйтесь своими знаниями о функциях и передаче аргументов
параметрам для оценки приведенного ниже кода. Сделав это, напишите
внизу, какое значение будет иметь каждая из переменных. Вот наше ре
шение этого задания.
fu n c tio n d o g s A g e (a g e ) {
re tu rn age * 7;
va r m yD ogsA ge = d o g s A g e (4 ) ;
fu n c tio n r e c t a n g le A r e a ( w id t h , h e ig h t ) {
va r a re a = w id th * h e ig h t ;
re tu rn a re a ;
va r re c tA re a = r e c t a n g le A r e a ( 3 , 4) ;
fu n c tio n a d d U p (n u m A rra y ) {
va r to ta l = 0;
fo r (v a r i = 0; i < n u m A r r a y . le n g t h ; i+ + ) {
to ta l += n u m A r r a y [ i] ;
}
re tu rn to t a l;
}
va r th e T o ta l = addU p([1 , 5, 3, 9 ]) ;
fu n c tio n g e tA v a ta r ( p o in ts ) {
va r a v a ta r;
Hanuvuume
i f ( p o in ts < 100) { ^
^ здесьj какое
a v a ta r = "M o u s e " ; значение будет
} e ls e i f ( p o in ts > 100 && p o i n t s < 1000) { и м е т ь каждая
a v a ta r = "C a t" ; [ из переменных.
} e ls e {
a v a ta r = "A p e "; О О
m yD ogsA ge = . .......................
re tu rn a v a ta r;
re c tA re a = . . . Ш . .......................
} th e T o ta l = ...% Z ............................
va r m y A v a ta r = g e t A v a t a r (3 3 5 ) ; m y A v a ta r = . ...C & t. ...................
196 глава 4
ф ункции и объект ы ja v a s c rip t
K M L 5 ” K F4><rBoP A* Г еШ ение
дальш е ► 197
g создание 1 П Ж -ст р а н и ц с поддержкой
определения м есто п о л о ж ен и я ^ _ф _
Местоположение, местоположение...
Знание того, где находятся ваши пользователи, дает возможность обеспечи
вать для них более качественное взаимодействие: вы мож ете указывать им
направление; советовать, куда бы они могли отправиться; дать им знать о том,
кто еще, находящ ийся поблизости, интересуется, наприм ер, теми же м еро
приятиям и, что и они. Существует бесчисленное множество путей использо
вания и нф орм ации о местополож ении.
С помощью HTML5 (и API-интерф ейса G eolocation на основе JavaScript) вы
можете легко получать доступ к инф орм ации о м естополож ении на своих
страницах. Однако есть вещи, о которы х вам необходимо знать, прежде чем
мы приступим к работе. Д авайте рассмотрим их.
Часто
Задаваем ы е
BolJpocTbl
0 :
Geolocation не считается полноценным членом семейства
существующего стандарта HTML5, однако следует отметить, что
О , Спецификации API-интерфейса Geolocation определяют, что
любой браузер должен получить от пользователя специальное
он является стандартом W3C, который широко поддерживается, разрешение на использование данных о его местоположе
и многие относят Geolocation к числу важных API-интерфейсов нии. Таким образом, если ваш код задействует API-интерфейс
в HTML5. И его наверняка можно назвать настоящим API-
Geolocation, то первое, что сделает браузер, — это удостове
интерфейсом JavaScript!
рится в том, что пользователь согласен раскрыть информацию
о своем местонахождении.
f t API-интерфейс Geolocation и API-интерфейс Google
Maps
Maps — это не одно и то же?
5 =Насколько хорошо поддерживается API-интерфейс
Geolocation?
Geoh
0: Нет. Это абсолютно разные API-интерфейсы. Geolocation
сосредоточен исключительно на получении информации о ме
стоположении человека на поверхности Земли. API-интерфейс
Google Maps — это JavaScript-библиотека от компании Google,
0 :Очень хорошо. Фактически, он доступен почти в любом
современном браузере, включая настольный и мобильный
которая обеспечивает доступ ко всей функциональности Google сегменты. Только необходимо убедиться, что вы используете
Maps. Если вам необходимо отображать местоположение своих последнюю версию браузера. Если это так, скорее всего, ни
пользователей на карте, то API-интерфейс от Google станет каких проблем с поддержкой API-интерфейса Geolocation у вас
удобным инструментом. не возникнет.
200 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
Широта и долгота...
Ч тобы узнать, где вы находитесь, нотребуется система координат на новерхности Земли. К сча
стью, у нас им еется такая штука, которая задействует ш ироту и долготу в качестве системы коор
динат. Ш ирота онределяет северную /ю ж ную точку на новерхности Земли, а долгота — восточ
ную / занадную точку. Ш ирота изм еряется от экватора, а и зм ерение долготы ведется от Гринвича, _
Англия. Задача API-интерф ейса G eolocation заклю чается в том, чтобы дать нам координаты на- *\
шего м естонолож ения в лю бой момент времени, иснользуя следующие координаты:
О т Королевской
Ш ирота — это расстояние обсерват ории
Координаты Си на север или на юг от экватора. в Г р и н в и ч е , ес ли
ликоновой долины: быть точными.
3737, - г г г я г Координат ы Гринвича,
Англия: 5 1 .4 7 , О
Координаты
Н ью -Й орка:
4 0 .7 7 , - 7 3 Я 2 Долгот а — это рас
стояние на восток
или на запад от
Гринвича , Англия .
Координаты
П о р т о -Ново,
Тренин: (о.4Я, 2-.(о1
Координаты Л и м ы ,
Перу: - 1 2 . 0 5 , - 7 7 . 0 4
/> П о д л е е ° ш и ^ о т а е /т я г о т е
Вам, вероятно, доводилось видеть, что широта и долгота указываются как в градусах/минутах/секундах,
например (47°38'34", 122°32|32"), так и в десятичных значениях, например (47.64, -122.54). В случае
с API-интерфейсом Geolocation мы всегда будем использовать десятичные значения. Если вам по
требуется преобразовать градусы/минуты/секунды в десятичные значения, это можно будет сделать
с помощью следующей функции: *■
Следуем о т м е т и т ь ,
function degreesToDecimal (degrees , minutes , seconds) { ито западная долгота
return degrees + (minutes / 60.0) + (seconds / 3600.0) ; w южная ш и р о к а пред
ставляются отрица-
) т е л ь н ы м и зн а ч е н и я м и .
дальше ► 201
определение мест оположения
Я выиграла новейший
смартфон со встроенной под
держкой GPS и теперь могу с вы 1Р-адресс
сокой точностью определять свои
координаты!
Для получения информации
о местоположении пользова
теля по его IP-адресу исполь
зуется внешняя база данных,
посредством которой 1Р-адрес
соотносится с физическим ме
стоположением пользователя.
Преимущество данного под
хода заключается в том, что он
может работать везде; однако
зачастую оказывается, что IP-
адреса принадлежат, напри
мер, местному офису интернет-
провайдера, обслуживающего
пользователей. Данный способ
можно считать надежным,
если речь идет о городе
ЫуЛ или его окрестностях.
ш
GPS
Глобальная система определения координат (Global
Positioning System), поддерживаемая многими со
временными мобильными устройствами, позволяет
очень точно определять местоположение благода
ря спутникам. Информация о местоположении мо
жет включать данные о высоте, скорости и направ
лении. Однако для того, чтобы пользоваться этой
системой, вашему устройству необходимо «видеть»
небо, при этом получение данных о местоположе
нии иногда занимает много времени. GPS также
может ускорить разрядку аккумуляторной батареи
вашего устройства.
202 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
Мобильный
телефон
Триангуляция с использованием
вышек сотовой связи и мобиль
ного телефона позволяет опре
делить местоположение, взяв за
Я перемещаюсь из одного кафе
основу расстояние, на котором
в другое с ноутбуком и беспроводным
его обладатель находится от од
подключением. Определить мое место
ной или более вышек (очевидно,
положение можно посредством триангу
что чем больше будет вышек, тем
ляции с использованием точек беспро
точнее окажется информация о местоположении).
водного доступа. Данный способ должен
Данный способ может давать довольно точный ре
довольно хорошо работать.
зультат и работает в помещениях (в отличие от GPS);
кроме того, иногда он позволяет намного быстрее
получить итоговые данные, чем GPS. Однако если
пользователь окажется в какой-нибудь глухомани,
где есть только одна вышка сотовой связи, точность
определения его местоположения будет невысокой.
дальш е ► 203
мет од определения м ест оположения
Никак.
К раткий ответ на ваш вонрос —«никак»,
поскольку подход к онределению ме
стополож ения зависит от реализации
браузера. Однако есть и хорош ая но
вость: браузер мож ет иснользовать лю
бой из упоминавш ихся выше снособов
определения местополож ения. Ф акти
чески, если браузер достаточно умен,
он сначала мож ет задействовать три ан
гуляцию с использованием вышек сото
вой связи, если таковая достунна, для
грубой оценки м естополож ения, а за
тем выдать вам более точны й результат
посредством WiFi или GPS.
П озже вы увидите, что не стоит бесно-
коиться о том, как именно определяет
ся м естонолож ение. Вместо этого мы
сосредоточимся на точности опреде
лен и я м естонолож ения. Исходя из точ
ности результатов вы сможете реш ить,
насколько нолезны ми окажутся для вас
но лученные данные. Мы вернем ся к во-
нросу точности чуть нозже.
204 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
□ ........................................................................................
□ ........................................................................................
□ ........................................................................................
□ ........................................................................................
дальш е ► 205
использование ар1-интерфейса geolocation
} e ls e { функция displayLocation —
— это обработчик, которому
a l e r t (" O ops , n o g e o lo c a tio n s u p p o r t " ) ; будет передаваться объект
у с данными о местоположении.
Если браузер НЕ поддерживает A P I-инт ерф ейс Geolocation,
} то просто выводим диалоговое окно alert с с о о т в е т с т в у ю
щ им сообщением для пользователя.
206 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
Обработчику getCurrentPosition п е р е
Обработчик, который будет вы дается объект position, содержащий
зываться, когда браузер получит ш иро т у и долготу вашего м е с т о п о л о
данные о м ест ополож ении.^ жения (наряду с данными, касающимися
точност и, о которых мы поговорим
fu n c tio n d is p la y L o c a tio n ( p o s itio n ) {
немного позже).
va r la titu d e = p o s it io n . c o o r d s . l a t it u d e ; П
va r 1 o n g i tu d e = p o s i t i o n . c o o rd s .1 o n g i tu d e ; \
Извлекаем ш и рот у и долготу
вашего местоположения из объ
екта position.coords.
va r d iv = d o c u m e n t . g e t E le m e n t B y ld ( " l o c a t i o n " ) ;
х
З а т е м извлекаем наш X
<div> из HTML * 4 ваше
... и задаем * местоположение
в качестве содержимого элем ент а
<div> с использованием innerHTML.
Tecm-драйб местоположения
Н аберите нриведенны й выше код и нроведите тест-драйв сво
ей новой страницы.
□ Request P erm ission o n ly once
e v e ry 2 4 h o u rs
П ри нервом вы нолнении геолокационного веб-нрилож ения
вы увидите в браузере окно с занросом на разреш ение исноль-
зовать данны е о вашем м естонолож ении. Это нроверка систе
мы защ иты браузера, и вы мож ете отказать браузеру в данном Запрос на разрешение может
занросе. Поскольку нреднолагается, что вы хотите протести
ровать свое веб-нриложение, нужно будет нажать кнонку Allow
(Разреш ить) или Yes (Да). П осле этого н рилож ение выдаст ко
t выглядеть п о-ра зн ом у в зависи
м о ст и о т используемого вами
браузера, но будет приб лизи
ординаты вашего м естонолож ения, как но казано ниже. тельно таким.
& О О J Q W h e r e a m [?
с
ей , которая вызывается, если ч т о - т о
если браузер способен успешно определить ваше
пойдет не т ак и браузер не сможет
местоположение.
\ определить ваше местоположение.
getcurrentPosition (successHandler, errorHandler, options)
] 'ft ^ Параметр options
Эти два пара м ет р а являются опциональ позволяет сконф и
ными, что объясняет, почему они не т р е гурировать работу
бовались нам ранее. API -инт ерф ейса
Qeolocation.
208 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
n a v ig a t o r . g e o lo c a t io n . g e t c u r r e n t P o s it io n ( d is p la y L
ции? К
здесь ак передаем
мы отмечалось
одну
Вызываем м ет од getcurrentP osition в главе 4, другой
функции
Когда АР [ - и н т е р ф е й с ' функцию ф унк-
объекта geolocation с использованием являются значениями,
определит ваше м е
одного аргум ент а — обработчика по эт ом у мы можем
стоположение, он вы
успешного исполнения.
зовет displayLocation. это делать.
Теперь взглянем на обработчик успешного исполнения d i s p l a y L o c a t i o n .
При вызове d i s p l a y L o c a t i o n API-интерсрейс Geolocation передает ему объ
ект p o s i t i o n , включающий информацию о местоположении браузера, в том
числе объект c o o r d i n a t e s , в котором содержатся широта и долгота (а также
прочие значения, о которых мы поговорим позже).
position — это объект, который A P I-
интерфейс Geolocation передает вашему
обработчику успешного исполнения.
Объект position обладает свойством
coords, которое содержит ссылку
на объект coordinates...
fu n c tio n d is p la y L o c a tio n ( p o s itio n ) {
va r la titu d e = p o s it io n . с о o r d s T la t it u d e ;
va r 1 o n g i tu d e = p o s i t i o n . со o r d s .1 o n g i tu d e ; .объект coordinates,
свою очередь, содержит
ваши ш ирот у и долготу.
va r d iv = d o c u m e n t. g e tE le m e n t B y ld ( " l o c a t i o n " ) ;
t
А эт а часть к настоящему м о м ен т у должна быть вам
абсолютна ясна: мы просто берем информацию о коор
динатах и отображаем ее в элемент е <div> страницы.
дальш е ► 209
как работает получение т екущ ей позиции
Затем API-интерфейс
6eolocation запраши
вает у пользователя
разрешение.
The w ebsite ,£http ://lo c a lh o s t" would like to
use your current location.
Если пользователь дает разреше
ние, то API-интерфейс Seolocation
□ Request p erm iss io n o n ly once every 2 4 hours прикладывает максимум усилий
D o n ’t A llo w 3 (_ A llo w )
для извлечения информации о ме
стоположении браузера (посред
Браузер ством GPS, триангуляции и т. д.).
С ( i [С И м аДНвц М а Ь /Н ... О ☆ К ** *
p o s i t i o n .c o o r d s .l a t i t u d e
210 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
si
-Диагностический тест-драйв
Когда дело касается API-интерфейса Geolocation, не каждый тест-драйв оказывается удачным; даже
если в случае с первым тестом все пройдет успешно, в дальнейш ем все равно что-то может пойти
не так. Поэтому мы создали небольшой диагностический тест, который вы можете добавить в свой
код. Таким образом, если у вас возникнут проблемы, вы сможете выяснить их причины; и даже если
они обойдут вас стороной, кто-то из ваших пользователей все равно может столкнуться с той или
иной проблемой, и вам будет необходимо знать, как решить ее в своем коде. Поэтому добавьте
приведенный ниже код, и если вы обнаружите неполадки, заполните диагностическую форму в
конце данной секции, указав в ней проблему, которую вам удалось диагностировать:
Для создания диагностического теста мы добавим обработчик ошибок в вызов метода
g e t c u r r e n t P o s i t i o n . Данный обработчик будет вызываться всякий раз, когда API-интерфейс
Geolocation сталкивается с рудностями определения вашего местоположения. Вот как будет осу
ществляться его добавление:
Д о б а в ь т е в т о р о й а р г у м е н т в с вой вы зов getcurrentPosition с и м е н е м
d l T u Z o r . Э т о ф у н к ц и я , к о т о р а я б у д е т в ш и в а т ь с я , к о гд а А Р -
инт ересу Geolocation не у д а е т с я о п р е д е л и т ь м е с т о п о л о ж е н и е .
Теперь необходимо написать код обработчика ошибок. Для этого вам нужно знать, что API-интерфейс
Geolocation передает вашему обработчику объект e r r o r , содержащий числовой код с описанием при
чины, по которой он не смог определить местоположение вашего браузера. В зависимости от кода
также может выводиться сообщение с дополнительной информацией о возникшей ошибке. Вот как
мы можем использовать объект e r r o r в обработчике:
Вот нам новый обработчик, кот ором у API -
f f ' интерфейс deolocation передает объект error.
f u n c tio n (@jrjrojr) { О бъект error содержит своиамво error.code, Koimo —
_ рое им еет числовое значение от О до 3. Бот о т -
va r e rro rT y p e s личный способ ассоциировать сообщение об ошибке
0: "U n k n o w n e rro r", с соо т вет ст в ую щ и м кодом JavaScript:
" P e r m is s io n d e n ie d by u s e r" — Создаем объект с несколькими свойст вами,
" P o s itio n is no t a v a ila b le " , им ею щ им и имена О, И, 2 и 3 соот вет ст венно.
Эти свойства пр едст авляю т собой строки
"R e q u e s t tim e d o u t" с соо§ще,ниями об ошибке, которые мы х о т и м
}; ассоциировать с со о т вет ст вую щ и м кодом.
va r e rro rM e s s a g e = e rro rT y p e s [e r r o r . co d e ] ; ________ Используя свойство error.
i f (e rro r, code == 0 | | e r ro r, code = 2) { code} М Ы присваиваем
одни из этих ст рок новой
e rro rM e s s a g e = e rro rM e s s a g e + 11 " + e rro r .m e s s a g e ; и Г
^ переменной errorMessage.
3 случае с ошибками О и 2 иногда
va r d iv = d o c u m e n t. g e tE le m e n t B y ld ( " l o c a t i o n " ) ;
в свойстве error.message п р и с у т -
d i v . in n e r H T M L = e rro rM e s s a g e ; РЧ с т в у е т дополнительная инфор
А за т е м добавляем сообщение к с т р а - ' м ация, поэт ом у мы добавляем его
нице для уведомления пользователя. в нашу ст року error.Message.
дальше ► 211
П р е ж д е чем вы полнить тест, более пристально взглянем на типы о ш и б о к ,
ко то р ы е м о гу т вы водиться на экр ан .
Это общая ошибка, которая выводится в с и т у а
циях, когда ни одна из остальных ошибок не под-
ходит. О брат ит есь к свойству error message
va r e rro rT y p e s = { J для получения дополнительной информации.
"U n k n o w n e rro r" , — Это означает, что пользователь от ка-
" P e r m is s io n d e n ie d by u s e r" , ^ запросе на разрешение использовать
" P o s itio n is no t a v a ila b le
информацию о местоположении.
А это означает, что браузер попытался,
"R e q u e s t tim e d o u t"
но не смог определить ваше м ест ополо-
У' \ жение. О пят ь-т аки, для получения до-
И наконец, A P I -интерфейс Geolocation полнительной информации обратитесь
предусматривает такую внутреннюю к свойству error.message,
настройку, как время ожидания (timeout), г- . Л Л Л
и если оно истекает до того, как будет Позже 6 этой главе вы Узнает е>как изменять
определено местоположение, выводится значение tim eout, задаваемое по умолчанию
данная ошибка. в случае API-интерфейса Geolocation.
а
буд ьте
Для тестирования своего геолокаци-
онного кода на мобильном устройстве
Част°
ЧаДаВаеМые
B oD poC fci
вам потребуется сервер.
o O H o j= > o JK H bi
Если у вас нет средств загрузки своих
HTML-, JavaScript- и CSS-файлов напря
5 =Значения широты и долготы моего
местоположения,
мест возвращаемые прило
мую на мобильное устройство, то их жени
жением, не совсем точны. В чем же дело?
Координаты ш т а б -
<body> квартиры Wickedly Sm art.
< d iv id = " lo c a tio n " > 4 7 .6 Я 4 8 5 ,
Your lo c a t io n w ill go h e re .
< /d iv >
< d iv id = " d is t a n c e " >
D is ta n c e fro m W i c k e d l y S m a r t HQ w i l l go h e re .
< /d iv >
< /b o d y > ^
< /h tm l> Добавьте э т о т новый элем ент <div> в свой HTML
дальш е ► 213
пригот овленны й код для вы числения расст ояния
у-1ojpoBo х у п о т р е б л е н и е ; вы чи сл я е м р а с с т о я н и е _________________________
fu n c tio n c o m p u te D is ta n c e ( s ta r tC o o r d s , d e s tC o o rd s ) {
va r s ta rtL a tR a d s = d e g r e e s T o R a d ia n s ( s ta r tC o o r d s . l a t i t u d e ) ;
va r s ta rtL o n g R a d s = d e g r e e s T o R a d ia n s ( s ta r tC o o r d s . l o n g i t u d e ) ;
va r d e s tL a tR a d s = d e g r e e s T o R a d ia n s ( d e s tC o o r d s . l a t i t u d e ) ;
va r d e s tL o n g R a d s = d e g re e s T o R a d i a n s (d e s tC o o r d s . 1 o n g i t u d e ) ;
va r d is ta n c e = M a th , a c o s (M a th , s i n ( s t a r t L a t R a d s ) * M a th , s i n (d e s tL a tR a d s ) +
M a th .c o s ( s ta rtL a tR a d s ) * M a th .c o s (d e s tL a tR a d s ) *
M a th .c o s (s ta rtL o n g R a d s - d e s tL o n g R a d s ) ) * R a d iu s ;
re tu rn d is ta n c e ;
fu n c tio n d e g r e e s T o R a d ia n s ( d e g r e e s ) { 3w y ф ун кц и ю МЫ ещ е у в и д и м в г л а в е ,
va r r a d ia n s = (d e g re e s * M a th .P I)/1 8 0 ; посвященной элем ент у canvas.
re tu rn r a d ia n s ;
214 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
М ы хоидиМ вь1Иислиидь
Написание кода для определения расстояния р а с с т о я н и е оил б а с
до н а с то п р я м о й
Теперь, когда у пас имеется фупкция для вы числепия расстояпия между дву
мя точками коордипат, определим паше (то есть пас, авторов) местополо
ж ение —коордипаты ш таб-квартиры Wickedly Sm art (паберите и этот код)::
С
Определяем литеральный объект
var ourCoords = { у для координат местоположения
latitude: 47.624851, нашей ш т аб-кварт иры Wickedly
longitude: -122.52099 S m art. Добавьт е его как глобаль
ную переменную в верхнюю часть
};
своего файла myLoc.js.
А теп ерь папиш ем код: все, что пам потребуется сделать, — это передать
коордипаты вашего и паш его местополож епия фупкции com puteD istance:
f u n c t io n d is p la y L o c a tio n ( p o s itio n ) {
v a r la titu d e = p o s itio n .c o o r d s . la t it u d e ;
v a r lo n g it u d e = p o s i t i o n . c o o r d s . l o n g i t u d e ;
v a r d i v = d o c u m e n t .g e t E le m e n t B y ld ( " l o c a t i o n " ) ;
d iv .in n e r H T M L = "Y o u a r e a t L a t i t u d e : " + la titu d e + ", L o n g it u d e : " + lo n g it u d e ;
Передаем координаты ваш е
го и нашего местоположения
v a r km = c o m p u t e D is t a n c e ( p o s it io n . c o o r d s , o u r C o o r d s ) ;
функции computeDistance.
v a r d is t a n c e = d o c u m e n t. g e tE le m e n tB y ld ( " d is t a n c e " ) ;
d is ta n c e .in n e r H T M L = "Y ou a r e " + km + " km fr o m th e W ic k e d ly S m a rt HQ";
Локационный тест-драйв
П роведем тест-драйв пашего пового кода. Заверш ите добав
ление кода в myLoc.js, а затем перезагрузите myLoc.html
в своем браузере. П осле этого вы долж пы увидеть коордипа
ты вашего местополож епия, а также расстояпие, па котором
You are at Let,tude: 4 7 .6 2 4 6 5 ,. Longitude: -12 2.5 20 99
паходитесь от пас. You are 0 km from the W ickedlySm art HQ
дальш е ► 215
добавление google maps
216 глава 5
Ж^Отклоняемю
Как добаВить карту к странице от маршрута
Теперь, когда вы указали ссылку па API-иптерф ейс Google Maps, все его возмож пости будут доступпы
вам посредством JavaScript. Одпако пам потребуется место для разм ещ епия карты Google, для чего пе
обходимо определить элемепт, которы й будет ее содержать.
<body>
< d iv id = " lo c a tio n " >
Your lo c a t io n w ill go h e re .
< /d iv >
< d iv id = " d is t a n c e " >
D is ta n c e fro m W ic k e d ly S m a r t HQ w i l l go h e re .
< /d iv >
< d iv id = "m ap "> , В о т н а ш <div>. С л е д у е т о т м е т и т ь , ч т о м ы о п р е д е л и л и
с т и л ь в m y L o c . j s , к о т о р ы й з а д а е т для э л е м е н т а <div> с id
1V й gu de т а р р а з м е р 4 0 0 на 4 0 0 п и к с е л о в и ч е р н у ю р а м к у .
< /b o d y >
< /h tm l>
дальш е ► 217
код для от ображения карт ы Отклоняемся
от маршрута
Отображение карты
Соберем все воедипо в п овой фупкции с имепем showMap, которая при-
п им ает пабор коордипат и отображ ает карту па веб-страпице:
Объявляем глобальную переменную т а р >которая будет со-
va r ш ар; держать нашу к арт у Google после т ого, как мы ее создадим.
Ч ут ь позже вы увидит е, как она используется.
va r la titu d e = p o s it io n . c o o r d s . la t it u d e ;
va r 1 o n g i tu d e = po s i t i o n . c o o rd s .1 o n g i tu d e ;
va r d iv = d o c u m e n t . g e t E le m e n t B y ld ( " l o c a t i o n " ) ;
va r km = c o m p u te D is ta n c e ( p o s i t i o n , c o o r d s , o u rC o o rd s ) ;
va r d iv = d o c u m e n t . g e t E le m e n t B y ld ( " d i s t a n c e " ) ;
show M ap ( p o s i t i o n . c o o r d s ) ;
Ъудем вызывать showMap из displayLocation после
т ого, как обновим остальные <div> на странице.
218 глава 5
Tecm-gpauB нашей новой карты
У б ед и тесь, ч то вы д о б а в и л и весь А вот и наша
повы й код с предыдущей страницы , новая карта
а также элемент < d iv > с i d в виде тар V/
Google
в свой HTM L. Затем п ерезагрузите
веб-страницу, и если браузеру удастся
о п р ед ел и ть ваш е м естоп олож ен и е,
вы увидите карту.
Здорово! А есть ли
способ увидеть мое точное
местоположение на карте?
Отмеченное, например,
булавкой?
3t?i действительно
х о т и т е , чтобы эта
штука валялась рядом
с вашим велосипедом?
дальш е ► 219
добавление маркера google
Отклоняемся
от маршрута
ПрикалыВаем булаВку на карту...
Будет пампого лучше, если вы сможете увидеть па карте
свое точпое м естополож епие. Если вам доводилось поль
Space Needle ;J
зоваться Google Maps, то вы, вероятпо, видели, что там ме 219 4th Avenue North
стополож епие искомых ф изических объектов отмечается Seattle, WA 98109
(206) 9Q&-21&Q
spaceneedlB.com
с помощью своего рода булавок. Н априм ер, если вы ищ е **** 28reviews
те башпю Space N eedle («Космический шпиль») в Сиэтле,
Directions Search nearby Save to
ш тат Вашипгтоп, то система поиска выдаст вам карту, где map more Y
va r m a r k e r O p tio n s = {
t it le : t it le ,
...задаем для clickable значение true, поскольку к от и м ,
c lic k a b le : tru e гчтобы пользователь мог щелчком на маркере выво-
FZ ' дить информационное окно.
>;
va r m a rk e r = new g o o g l e .m a p s . M a r k e r ( m a r k e r O p t i o n s )
^ З а т е м создаем объект m arker, используя еще один конст рукт ор из API -ин т ер-
фейса Google Maps, ко т ором у передаем ранее созданный объект markerOptions.
220 глава 5
Отклоняемся
0 П»р«ру»
p o sitio n : la tlo n g ^ ^
------------ ...а т акж е ш и р о т а и долгот а.
>;
va r in fo W in d o w = new g o o g l e . m a p s . I n f o W i n d o w ( i n f o W in d o w O p t i o n s ) ;
С п о м о щ ь ю эт о го м ы создаем
и н ф о р м а ц и о н н о е окно.
g o o g le .m a p s . e v e n t . a d d L i s t e n e r ( m a r k e r , " c lic k " , f u n c t i o n () { ^
i n f o W i n d o w . o p e n (m a p ) ; ^ f ^
/к П е редае м с л у ш а т е л я З а т е м мы и с п о л ь з у е м м е т о д
}>; / Ф ункции, к о т о р а я a d d U ste n e r A PI-инт ерф ейса
1 вы зы вае т ся, когда G o o g l e M a p s для добавления с л у -
} Когда пользоват ель щ е л - пользоват ель щ е л к а - ш а т е л я с о б ы т и и click. С л у ш а т е л ь
к а е т на м а р к е р е , п р о и с к о - е т на м а р к е р е . подобен о б р а б о т ч и к у со б ы т и и
д и т вы зо в д а н н о й ф у н к ц и и , ( н а п р и м е р , o n lo a d или on chck),
и на к а р т е о т к р ы в а е т с я с к о т о р ы м вы с т а л к и в а л и с ь р а не е.
и н ф о р м а ц и о н н о е окн о.
a d d M a rk e r(m a p , g o o g le L a tA n d L o n g , t it le , c o n te n t);
r ? < ,
П ередаем объ ект ы m a p
и g o o g le L a tA n d L o n g, создан- a такж е c m P 0KU t i t , e u c o n t e n t Здя м а р к е р а ,
ные с и с п о л ь з о в а н и е м A P I -
и н т е р ф е й с а Google Maps...
дальш е ► 221
больше google maps
Отклоняемся
от маршрута
Tecm-драйВ маркера
Щ « ► « CO ft
Добавьте весь код, касаю щ ийся addM arker, обповите showMap
для вы зова addM arker и перезагрузите страпицу. П осле этого вы I
увидите карту с маркером, указывающ им ваше местополож епие. 1 —
•
Элементы управления: ваша карта Google по умолчанию будет включать несколько элементов управле
ния, позволяющих, например, изменять масштаб, осуществлять панорамирование, переключаться между
представлениями Мар (Карта) и Satellite (Спутник) и даже просматривать улицы (позволяющий делать это
элемент управления выглядит как маленький оранжевый человечек над кнопками масштабирования). Вы
можете обращаться к этим элементам управления программно из JavaScript, чтобы использовать их в своих
приложениях.
Службы: вам когда-нибудь доводилось искать маршруты с помощью Google Maps? Если да, то вы пользо
вались при этом службой Directions (Направления). Для обращения к этой и другим службам, позволяющим,
например, узнавать расстояние и просматривать улицы, вам потребуется прибегнуть к API-интерфейсам
Google Maps для работы со службами.
Слои: они позволяют размещать дополнительное представление поверх карты Google (например, карту по
годы). Если вы собираетесь в поездку, то сможете проверить загруженность дорог транспортом с помощью
слоя трафика. Используя API-интерфейсы Google Maps, позволяющие работать со слоями, вы получаете
возможность создавать пользовательские слои (например, пользовательские маркеры, применять в слоях
свои фотографии) и делать массу всего другого, что только сможете себе представить.
Все это доступно посредством API-интерфейса JavaScript Google Maps. Если у вас возникнет желание пойти
еще дальше в своих экспериментах, изучите документацию по адресу:
h t t p : / / c o d e . g o o g l e . c o m /a p is /m a p s /d o c u m e n t a t i o n /j a v a s c r ip t /
222 глава 5
в с т р к Ч Л к М
Л Р 1 ~ И Ш ,Ё Р <Р Е р 1 .С
Интервью недели:
Разговор с тем, кто хочет стать
API-интерфейсом HTML5...
Head First: Добро пожаловать, API-интерфейс чина, по которой я стал первым API-интерфейсом,
Geolocation. Сразу хочу отметить, что немного удив которому была отведена отдельная глава?
лен видеть Вас здесь.
Head First: Давайте поговорим о поддержке.
Geolocation: Почему же?
Geolocation: Тут не о чем особо говорить, посколь
Head First: Вы даже не являетесь «официальной» ча ку меня поддерживают почти все браузеры как в на
стью спецификации HTML5, однако стали первым стольном, так и в мобильном сегменте.
API-интерфейсом, которому была отведена целая
глава в данной книге! Чем это объясняется? Head First: Какая от Вас польза на устройствах, кото
рые не поддерживают GPS?
Geolocation: Что ж, Вы правы в том, что я опреде
лен в спецификации, отдельной от HTML5, однако Geolocation: Это заблуждение, что я как-то зависим
являюсь официальным стандартом W3C. Оглянитесь от GPS. На сегодняшний день существует масса дру
вокруг: я уже реализован в браузерах, устанавливае гих способов определять местоположение, напри
мых на любом стоящем мобильном устройстве. Под мер посредством триангуляции с использованием
этим я подразумеваю следующее: будет ли много вышек сотовой связи и мобильного телефона, по
пользы от мобильного веб-приложения, если оно не средством IP-адресов и т. д. Если в Вашем устройстве
поддерживает меня? есть GPS, то это здорово, поскольку в этом случае я
смогу быть для Вас еще более полезным; если же GPS
Head First: Какие приложения задействуют Вас?
отсутствует, то Вы всегда можете прибегнуть к массе
Geolocation: К их числу относится большинство других способов определения местоположения.
приложений, которыми люди пользуются в дороге:
Head First: Быть еще более полезным?
начиная с приложений, позволяющих обновлять
свой статус и включать геолокационную информа Geolocation: Если у Вас достаточно хорошее мо
цию, и заканчивая приложениями для фотокамер, бильное устройство, то я смогу сообщить Вам еще и
фиксирующими то, где были сделаны снимки, а так высоту, направление, скорость, то есть все возмож
же социальными приложениями, дающими возмож ные показатели.
ность отыскать местных друзей или отметиться в
разных местах. Люди используют меня даже для фик Head First: Допустим, что ни один из этих способов
сации того, где они ездили на велосипеде, бегали не сработал —ни GPS, ни IP-адрес, ни триангуляция.
или останавливались перекусить, а также для того, Какой тогда от Вас толк?
чтобы добраться до нужного пункта назначения. Geolocation: Что ж, я не всегда могу ручаться, что
Head First: Вы как API-интерфейс выглядите просто Вам обязательно удастся определить местоположе
вато, то есть я хочу сказать, что у Вас в сумме имеется ние, однако есть и положительный момент — я даю
лишь несколько методов и свойств, ведь так? возможность выяснить причину проблемы. Все, что
Вам нужно сделать, —это дать мне обработчик оши
Geolocation: В компактности и простоте заключена
бок, и я буду вызывать его в случае возникновения
мощь. Разве многие жалуются на меня? Нет. У меня проблем.
есть то, что нужно всем разработчикам, которые каж
дый день создают массу приложений с поддержкой Head First: И это хорошо. Что ж, наше время истек
определения местоположения. Кроме того, моя ком ло. Благодарю Вас, API-интерфейс Geolocation, за то,
пактность означает, что меня можно быстро и легко что посетили нас. И поздравляю с обретением стату
освоить, не так ли? Может, в этом и заключается при са настоящего стандарта W3C!
дальш е ► 223
детали geolocation api
224 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
va r la titu d e = p o s it io n . c o o r d s . l a t i t u d e ;
va r 1 o n g i tu d e = p o s i t i o n . coo r d s .1 o n g i tu d e ;
va r d iv = d o c u m e n t. g e tE le m e n tB y ld ( " l o c a t i o n " ) ;
s h o w M a p ( p o s itio n .c o o r d s ) ;
Проверка точности
Убедитесь, что вы добавили приведепную выше выделепную строку
ко д ак своей страпице, после чего загрузите ее. В результате вы увидите,
пасколько точпо было определепо ваше местополож епие. Не забудьте
провести даппы й тест па имеющемся у вас мобильпом устройстве.
Тест онлайн: W ttp://wickedlys m a r t . c o m / k f k t m l 5 / chapters/accuracy/m yLoc.i
дальш е ► 225
от слеживание перемещ ения
Вы уже зпаете, что API-иптерф ейс G eolocation вклю чает метод w a t c h P o s it io n . Д аппы й метод делает
то, что подразумевает его имя: оп следит за вашим перем ещ ением и докладывает о вашем м естополо
ж ении по мере того, как опо измепяется. М етод w a t c h P o s i t io n п а самом деле очепь схож с методом
g e t c u r r e n t P o s i t i o n , по ведет себя пемпого по-другому: оп повторпо вы зы вает обработчик успешпого
исполпепия каждый раз, когда изм епяется ваше м естополож епие. Д авайте посмотрим, как оп работает.
Браузер p o s i t i o n .c o o r d s .l a t i t u d e
p o s i t i o n .c o o r d s .l o n g i t u d e
226 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
< /h e a d >
Мы добавляем э л е
<body> м е н т form с двумя
< fo r m > кнопками, одна из
которы х, имеющая id
< in p u t ty p e = " b u tto n " id = " w a tc h " v a lu e = "W a tc h m e ">
в виде "watch", будет
< in p u t ty p e = "b u tto n " id = " c le a r W a tc h " v a lu e = " C le a r w a tc h " >
использоваться для
< /fo rm > запуска отслеживания,
< d iv id = " lo c a tio n " > а вт орая, с id в виде
Your lo c a t io n w ill go h e re .
"clearWatch", — для его
остановки.
< /d iv > ^
< /b o d y >
дальш е ► 227
использование w atchposition
w a tc h B u tto n . o n c lic k = w a t c h L o c a t io n ;
c le a r W a tc h B u tto n .o n c lic k = c le a r W a tc h ;
w a tc h ld = n a v ig a t o r . g e o lo c a t io n . w a t c h P o s it io n (d is p la y L o c a t io n ,
d is p la y E r r o r ) ;
В ы з ы в а е м м е т о д w a t c h p o s i t i o n , п е р е д а в а я е м у уже н а п и с а н н ы й о б р а б о т ч и к у с п е ш н о г о
и с п о л н е н и я d i s p l a y L o c a ti o n , а т а к ж е и м е ю щ и й с я у нас о б р а б о т ч и к о ш и б о к d isp la y E rro r.
228 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
n a v ig a t o r . g e o lo c a t io n . c le a r W a tc h ( w a tc h ld ) ; ^ ^ ...вызываем м ет од geolocation.
clearWatch, передав ему
w a tc h ld = n u ll;
watchld. Это приведет
} к остановке отслеживания.
va r la titu d e = p o s it io n . c o o r d s . l a t it u d e ;
va r 1 o n g i tu d e = po s i t i o n . c o o rd s .1 o n g i tu d e ;
va r d iv = d o c u m e n t. g e tE le m e n t B y ld ( " l o c a t i o n " ) ;
va r km = c o m p u te D is ta n c e ( p o s itio n .c o o r d s , o u rC o o rd s );
va r d is ta n c e = d o c u m e n t. g e tE le m e n tB y ld ( " d is t a n c e " ) ;
i f (m a p = = n u ll) {
s h o w M a p ( p o s itio n .c o o r d s ) ;
Если функция showMap еще не вызывалась, следует
} вызвать ее; в прот ивном случае ее не нужно будет
вызывать при каждом вызове displayLocation.
дальш е ► 229
т ест ирование от слеживания пользоват еля
В о т наш т е с т о в * .« лрогон...
Следует о т м е т и т ь , что на
данный м о м е н т в центре карты
будет отображаться ваше н а
чальное местоположение...
230 глава 5
Часш°
ЧаДаВаеМые
В опросы
Как я могу регулировать частоту обновления браузером 0 : Нет гарантий, что эти свойства обязательно будут поддержи
моего местоположения при использовании watchPosition? ваться (и, очевидно, их поддержка будет обеспечиваться только на
мобильных устройствах высшего класса), поэтому вам потребуется
Q j Никак. Браузер сам определяет оптимальную частоту обнов удостовериться в том, что ваш код сможет справиться с отсутствием
местоположения.
Что такое heading и speed?
В
Почему показатели моего местоположения изменяются
по нескольку раз при первой загрузке страницы, даже несмотря 0 : h e a d in g — это направление, в котором вы двигаетесь,
на то что я сижу на месте не перемещаясь? a s p e e d — скорость, показывающая, насколько быстро вы это
делаете. Представьте, что вы едете в автомобиле на север по ав
0 : Помните, мы говорили, что браузер может применять разные томагистрали, а спидометр показывает 90 км/ч. Ваше направление
методики для определения вашего местоположения? В зависимости в данном случае — на север, а скорость равна 90 км/ч. Если же вы
от методики (или методик), используемой браузером для выяснения сидите в машине, стоящей на парковке, то ваша скорость равна О,
того, где вы находитесь, точность определения вашего местопо а направления у вас нет (поскольку вы не двигаетесь).
ложения со временем может изменяться. Как правило, точность
улучшается, но иногда (например, если вы заехали в сельскую Когда я проверяю по карте расстояние от своего место
местность, где есть только одна вышка сотовой связи) может положения до вашего, у меня получается намного больший
ухудшаться. Кроме того, вы всегда можете задействовать свойство результат, чем рапортует приложение. В чем причина?
accuracy в объекте position.coords, чтобы следить за точностью.
}
}
p re v K m = km ;
д е л а е т в есь э т о т код. ^
дальш е ► 231
обзор объектов geolocation
Параметр positionOptions...
До пастоящ его момепта мы пе затрагивали трети й парам етр g e t c u r r e n t P o s i t i o n (и w a t c h p o s it io n ) —
p o s it io n O p t io n s . С помощью даппого парам етра мы можем контролировать, как API-иптерф ейс
G eolocation вы числяет соответствующ ие показатели. Д авайте взгляпем па три парам етра вместе с их
зпачепиям и по умолчапию.
Сначала идет свойство, которое а к т и в и р ует высо
кую точность; что именно под э т и м подРаз^ ев
ется, м ьi поговорим через несколько мгновений...
var positionOptions = {
Параметр tim e o u t позволяет конт роли ро ва т ь,
enableHighAccuracy: false, как долго браузер сможет определять м е с т о
положение пользователя. По умолчанию для
timeout: Infinity, данного п ар ам ет ра задается значение Infinity,
то есть браузер получит столько времени,
сколько ему потребуется.
maximumAge: 0
Д л я данного пара м ет р а также можно задать
} значение в миллисекундах (например, ю ООО),
И наконец, с помощ ью п а ра м ет ра m a xim um A ge то есть браузер по луч ит Ю секунд на о п р е
устанавливаем максимальный « во зр а ст » данных деление местоположения, в прот ивном случае
о местоположении, который они м о гу т и м е т ь будет вызван обработчик ошибок.
до того, как браузеру пот ребует ся заново опре
делит ь местоположение. По ум олчанию данный
па р а м е т р и м е ет значение О, которое подраз
ум евает , что браузеру придется всегда зано
во определять местоположение пользователя
(при каждом вызове getcurrentPosition).
Вы уже видели, что все даппы е о м естополож епии, возвращ аемы е пам API-
иптерф ей сом G eolocation, включают свойство a c c u r a c y . Одпако мы также мо
жем сказать API-иптерфейсу G eolocation, что хотим получать только паиболее
точпы е результаты, которы е оп способеп выдать. Но это будет лиш ь памек брау
зеру, а различпы е реализации в действительности могут по-разпому отпоситься
к такому памеку. Н есм отря п а то что даппы й вариапт мож ет показаться мало-
важпым, оп песет в себе массу подтекста. Н априм ер, если вас пе иптересует
суперточпость результатов определепия м естополож епия — вам мож ет быть вполпе достаточпо зпать,
что ваш пользователь паходится в Балтиморе, —то API-иптерф ейс G eolocation сможет очепь быстро и
дешево (в плапе эпергопотреблепия) сообщ ить вам эти сведепия. С другой сторопы , если вы захоти
те узпать улицу, па которой паходится ваш пользователь, то пет проблем, одпако в таком случае API-
иптерф ейсу G eolocation придется задействовать GPS и использовать массу электроэпергии для извле
чен ия даппой ипф орм ации. П осредством парам етра en a b le H ig h A c c u r a c y вы говорите API-иптерфейсу
G eolocation, что вам пеобходимы паиболее точпы е результаты определепия м естополож епия, какие оп
только способеп дать, нусть даже и вы сокой цепой. И м ейте в виду: использование даппого п арам етра
пе гараптирует того, что браузеру обязательпо удастся выдать вам более точпое местополож епие.
232 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
дальш е ► 233
упражнение на использование парамет ров geolocation
+КТ 9 И Н Т^»Б Л а
т
1т ? _____
Ниже приведены параметры, касающиеся API-интерфейса Geolocation.
Ваша задача заключается в том, чтобы подобрать каждому параметру
пару в виде соответствующего ему поведения.
234 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
o p tio n s ) ; КГ <
литерального o o v -
И ли мы могли бы просто добавить соответствую щ ий объект как встроеппы й: екта прямо в вызов
n a v ig a t o r . g e o lo c a t io n . g e t C u r r e n t P o s it io n < Вы б у д е т е ч а с т о с т а л - функции! Н е к о т о р ы е
киваться с использова- с ч и т а ю т , что так
d is p la y L o c a tio n , / нием т акой методики будет прощ е, п о -
d is p la y E r r o r , в Ja vaS cript-коде. ц^~скольку код п о л у -
{e n a b l e H i g h A c c u r a c y : t r u e , m a x im u m A g e : 6 0 0 0 0 } ) ; ЧитСЯ более удобо
читаемым.
Теперь, когда вы зпаете, что представляю т собой даппы е парам етры , что опи делают и как их задавать,
можпо переходить к их использованию . Этим мы и займемся далее, одпако пе забы вайте, что опи пред-
пазпачепы для пастройки вашего прилож епия, которое мож ет предъявлять свои специф ические тр е
бования. Н а эти п арам етры также влияет используемое вами устройство, реализация браузера и сеть,
поэтому полпы м их исследованием вам придется запяться самостоятельпо.
— Диагностический тест-драйв ^
Ранее, при выполнении диагностических тест-драйвов, сталкивались ли вы с ситуациями, когда вы все ждали
и ждали, но ничего не происходило? Причина, скорее всего, заключалась в том, что для t i m e o u t было задано
значение I n f i n i t y . Другими словами, браузер будет бесконечно долго пытаться определить местоположение,
пока не столкнется с условием возникновения ошибок. Что ж, теперь вы знаете, как исправить это, поскольку
можете заставить API-интерфейс Geolocation вести себя более рационально в подобных ситуациях, задав соот
ветствующее значение для t i m e o u t . Вот как это делается:
fu n c tio n w a t c h L o c a t io n () {
w a tc h ld = n a v ig a t o r . g e o lo c a t io n . w a t c h P o s it io n (
d is p la y L o c a tio n , З ад ав для t i m e o u t значение SOOO м и л л и с е
кунд ( S секунд), вы с д е л а е т е т а к , ч т о д р а у -
d is p la y E r r o r , ^ ^ ^ S y d e m бесконечно долго п ы т а т ь с я
определит ь местополож ение.
{ t im e o u t : 5 0 0 0 }) ;
} J
Проведите т ест ирование, подставляя сюда разные значения.
дальш е ► 235
г И С П Ы Т А Й Т Е С Ь с д е л а т ь э т о д о м а
(КА К ЗАСТАВИТЬ GEOLOCATION РАБОТАТЬ
НА ПРЕДЕЛЕ ВОЗМОЖНОСТЕЙ)
Разве не интересно узнать, как быстро браузер сможет определить ваше местопо
ложение? Мы усложним для него задачу, насколько это представляется возможным:
■ ограничим его по времени, задав для tim e o u t значение 100, которое будем
увеличивать после каждой неудачной попытки браузера определить местополо
жение в течение заданного времени.
^ и т ак далее...
Теперь ознакомьтесь с кодом, приведенным на следующей странице, — он покажется вам довольно
интересным. Наберите его (можете добавить его в свой JavaScript-файл m yLoc. j s ). Протестируйте
данный код на различных устройствах, которые у вас имеются, а результаты запишите здесь:
236 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
238 глава 5
создание HTML-ст раниц с поддерж кой определения мест оположения
U еще раз... о®
П ерезагрузите свою страпицу и пачпите движепие...
г *
/\орожка из м а р к е
Ну как, вы черчивается па карте ваш нуть? Вы долж- ров, показывающая
пы увидеть дорожку из маркеров, добавляемы х па наш недавний п у т ь
карту по мере вашего передвиж епия (если, копеч- от ш т аб-кварт иры
по, вы пе сидите за пастольпым компью тером!). Wickedly S m a r t до
Таким образом, даппое прилож епие мы представля тайного подземно
ем как твердое доказательство того, что «куда бы ты го логова... Ой, зря
пи шел —ты имеппо там» (в паш ем случае под этой мы проболтались
ф илософ ской ф разой попимается, что вас можпо об этом...
будет пайти).
дальш е ► 239
оптимизация использования маркеров
лечения с магнитами
Завершая эту главу, мы предполагаем, что вы можете захотеть
еще больше отшлифовать рассмотренное выше приложение. Вы
обратили внимание (в силу тех или иных обстоятельств) на то, что
на карту добавляется слишком много маркеров, когда ведется от
слеживание вашего местоположения?
Это происходит потому, что w a t c h P o s i t i o n слишком часто детек
тирует перемещение, что приводит к вызову обработчика успешно
го исполнения d i s p l a y L o c a t i o n каждый раз, когда вы успеваете
сделать лишь несколько шагов. Один из способов исправить это
заключается в добавлении кода, благодаря которому новый маркер
будет создаваться только после того, как вы пройдете более значи
тельное расстояние (например, 20 метров в целях тестирования).
У нас уже имеется функция, которая вычисляет расстояние между З а м не к а ж е т с я ,
двумя точками ( c o m p u t e D i s t a n c e ) , поэтому нам останется лишь
ч т о зд е сь ч р е з м е р
сделать так, чтобы ваше местоположение сохранялось при каж
но м н о г о м а р к е р о в ?
дом вызове d i s p l a y L o c a t i o n и проводилась проверка того,
является ли расстояние между вашим предыдущим местоположе
нием и новым больше 20 метров, прежде чем произойдет вызов
s c r o l l M a p T o P o s i t i o n . Необходимый для этого код приведен
ниже; ваша задача заключается в том, чтобы заполнить имеющиеся в
нем пробелы. Будьте внимательны, поскольку некоторые магнитные
таблички нужно использовать более одного раза!
function displayLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var div = document.getElementByld(Mlocation");
div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: 11 + longitude;
div.innerHTML += " (with " + po s i t i o n .coords.accuracy + 11 meters accuracy) " ;
var km = computeDistance(position.c oords, ourCoords);
var distance = document.getElementByld("distance");
distance.innerHTML = "You are " + km + " km from the Wickedly Smart HQ";
if (map = null) {
showMap(position.coords);
prevCoords = _________________ ;
} else {
var meters = _________________ (position, c oords, prevCoords) * 1000;
if ( > ) {
scrollMapToPosition(position.coords);
240 глава 5
создание HTML-страниц с поддержкой определения местоположения
КЛЮЧЕВЫЕ
— МОМЕНТЫ
Я
■ Можно использовать разные методики определения ■ w atc h P o sitio n — ЭТО МвТОД объекта geo l o c a t i o n ,
своего местоположения в зависимости от устройства, который отслеживает ваше местоположение и вызыва
которое у вас имеется. ет обработчик успешного исполнения при изменении
вашего местоположения.
■ GPS позволяет получать более точные данные о ме
стоположении, чем триангуляция с использованием ■ Как И у g e t C u r r e n t P o s i t i o n , у w a t c h P o s i t i o n
вышек сотовой связи и мобильного телефона или имеется один обязательный параметр — обработчик
дальше ► 241
кроссворд
1 Л Щ , 5 - К Г °ссК°Г Д
Вы проделали довольпо длиппы й путь в этой
главе, используя свой п ервы й API-иптерф ейс
JavaScript. Закреп и те изучеппы й материал,
реш ив даппы й кроссворд.
По горизонтали По вертикали
3. Измерение долготы ведется о т _______________, Англия. 1. В случае применения устройств без поддержки GPS опре
4. Точность определения местоположения имеет опреде делить ваше местоположение можно будет посредством
ленный подтекст в случае с веб-приложениями, который _______________ с использованием вышек сотовой связи.
заключается в том, что она может сказываться на уровне 2. Для вычисления расстояния между двумя точками ко
заряда аккумуляторной_______________ устройства. ординат можно использовать формулу_______________.
7. Не давайте кому-либо рекомендаций насчет направления 5. Вы никогда не получите кэшированных данных о место
движения, если ваши координаты не будут обладать до положении, если для параметра_______________ задано
статочной _______________. значение 0.
9. Фраза «Куда бы ты ни шел — ты уже там» упоминалась 6. Центрирование карты заново осуществляется с исполь
в ф ильме__________________________ . зованием м етод а_______________.
10. Если вы откажете браузеру в его запросе на разреше 8. Место, где располагается город_____________ , имеет
ние использовать данные о вашем местоположении, широту и долготу соответственно 40.77, -73 .9 8.
это приведет к вызову обработчика ошибок с кодом
_______________ в виде 1.
11. Тайное местоположение штаб-квартиры______________
имеет координаты 47.62485, -12 2.52099.
242 глава 5
создание HTML-страниц с поддержкой определения местоположения
p re v C o o rd s = n u l l ;
function displayLocation(position) {
div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
if (map == null) {
showMap(position.coords);
}
else {
> -L i° I <
scrollMapToPosition (position, coords) ;
prevCoords p o s i t i o n .c o o r d s ^ j ;
r *
Так намного лучше!
дальше ► 243
решение упражнения
244 глава 5
создание HTML-страниц с поддержкой определения местоположения
+
+
КТ9 И
дальше ► 245
решение упражнения
Д Н г Ш М Ь 5 _ к Г оссБоР л - f e ffleHue
246 глава 5
6 оё>1Ц 0Н ие с В0ё>— с л у ж б а м и
Приложения-экстраверты
— Ес л и бы я только
знала, что обращение к веб
службам и взаимодействие
с ними м ожет быть настолько
увлекательным...
Б л а г о д а р и м , ч т о с о г л а с и л и с ь п о м о ч ь ! В о т к а к , на на ш в з г л я д , долж ен
р а б о т а т ь и н с т р у м е н т д л я о т с л е ж и в а н и я продаж ж е в а т е л ь н о й р е з и н к и
и з а в т о м а т о в , и м ы н а д е е м с я , ч т о вы см о ж е т е его д ля нас р е а л и з о в а т ь !
Miehty Gumball Inc. О б р а щ а й т е с ь , ес ли у вас в о з н и к н у т к а к и е - л и б о в о п р о сы !
Там, где автомат для
продажи жевательной
К р о м е т о г о , м ы в с к о р е в ы ш л е м в а м сп е ц и ф и к а ц и и , к а с а ю щ и е с я в е б
резинки никогда не пуст
наполовину служ бы. — —к о м п а н и и M ig h ty C jum ball
И нж енеры
М о б и ль н ы е
и наст оль
ны е у с т р о й
ст ва будут кг
получат ь
св е д ен и я
Н аш и н т е р н е т -
о продаж ах
о т сервера
'я сервер
Н а м н е о б х о д и м о , чт о б ы
Все наши а вт ом ат ы для п р о
реально дажи жевательной резинки
вы н а п и с а л и э т у ч а с т ь ,
го в р е м е н и будут о т п равлят ь отчеты
ест ест вен н о , используя
с пом ощ ью на центральный сервер.
веб -служ б ы . HTMLSH
248 глава 6
общение с веб-службами
дальше ► 249
обзор системы mighty gumball
250 глава 6
общение с веб-службами
/Ж 1 М Т Т \0
V
Приложение возвраща
Браузер обновляет страницу
на основе DOM, в результа
те чего пользователи могут
увидеть результаты.
ется к шагу 3 и постоян
но запрашивает новые
данные. В результате
этого страница обнов
ляется почти в режиме
реального времени.
дальше ► 251
подготовка разметки
И сп о льзуем ст а н д а р т
<! d o cty p e h tm l> ны е H T M L S - э л е м е н т ы
<html lang="en"> <head> и <body>.
<head>
Заранее размещаем ссылку
< title > M ig h ty G u m b a ll (J S O N )< /title > на JavaScript-ф айл , зная , что
< m e ta c h a r se t= " u tf-8 " > вскоре напишем соответству
< s c r ip t sr c = " m ig h ty g u m b a ll. j s " X / s c r i p t >
ющий JavaScript-код!
< lin k r e l= " s ty le s h e e t" h r e f = nm i g h t y g u i n b a l l . c s s " >
252 глава 6
общение с веб-службами
Начнем с URL. Ведь, в конце концов, нужно же нам как-то ска "js<m" о зн а ч а е т ф о р
зать браузеру, где искать данные, которые нас интересуют: м а т о б м ен а д а н н ы м и
Вот наш URL -адрес (к н е м у м ы в е р н е м с я
someserver.com н е м н о го позж е).
V
var url = "http://someserver.com/data.j son11
T
Сохраним URL-адрес в переменной u rl,
кот орую будем использовать далее.
254 глава 6
общение с веб-службами
- — ■ ь
Запрос Данные
Веб-служба
дальше ► 255
как получить доступ к http-omeemy
Мы можем извлечь о т в ет
„ 1 1
из свойства respc
responseText
объекта request.
П отерни те немного, носко льку мы но чти но до
шли к моменту нанисания реального кода, в кото
ром задействуется r equest.responseText.
256 глава 6
общение с веб-службами
развлечения с магнитами
г\
Новая веб-служба http://wickedlysmart.com/ifeelluckytoday возвращает u n l u c k y либо l u c k y при каж
дом обращении к ней. Логика в данном случае базируется на тайном и древнем алгоритме, о котором
мы не можем вам рассказать, однако эта служба дает возможность пользователям узнать, повезет им
(lu c k y ) или нет (u n lu c k y ) в определенный день.
Нам требуется ваша помощь в создании показательной реализации, чтобы продемонстрировать дру
гим, как они могут включить ее в свои сайты. Ниже приведен скелет кода; помогите нам заполнить
пробелы в нем, используя магнитные таблички. Будьте внимательны, поскольку здесь есть лишние
таблички. Одну из табличек мы уже разместили в нужном месте.
w in d o w . o n lo a d = f u n c t i o n () {
v a r u r l = " h t t p : / / w ic k e d ly s m a r t . c o m / i f e e ll u c k y t o d a y " ;
v a r r e q u e s t = __________________________
{
if (_________________________ ) {
d i s p l a y L u c k (_ );
P in n e rH T M L = "T o d a y y o u a r e " + l u c k ;
}
У-
request.onload = function() |
new XMLHttpRequest()
m yLuckyText^^""^^"*"^™ "*™ ^"™ "^^
g e tE le m e n tB y ld
r e q u e s t . s t a t u s == 200
дальше ► 257
решение упражнения
window.onload = function () {
n e w X M L H t t p R e q u e s t ();
var request =
1
r e q u e s t . o n l o a d = f u n c t i o n () [{
r e q u e s t .status == 200 1) {
if (_
di s p 1 a y L u c k ( r e q u e s t .responseText );
function displayLuck(luck) {
Лишние таблички
request.create("GET", url)
myLuckyText
258 глава 6
общение с веб-службами
Интервью недели:
Признания объекта XMLHttpRequest
Head First: Д обро ножаловать, X M LH ttpR equest, ционны е данны е о том, что раснолож ено но бли
мы рады, что вы смогли вы кроить для нас время зости... П очти любые данные, которы е вы только
в своем нлотном граф ике. Расскажите, как Вы вни- можете себе нредставить, нонадают во Всемирную
сываетесь в нроцесс создания веб-нриложений. наутину в форме, с которой я могу работать.
XMLHttpRequest: Я нолож ил начало целому Head First: Это же ведь все исклю чительно XML-
тренду но нривнесению внеш них данны х в веб данны е, не так ли? Я имею в виду, что в Вашем име
страницы. Слышали о Google Maps? О GMail? Это ни присутствует часть XML.
все я. Без меня все это было бы невозможным. XMLHttpRequest: Неужели? П озвольте ответить
Head First: В каком смысле? нрямо. Н есомненно, было время, когда я, главным
образом, занимался извлечением XML-данных, од
XMLHttpRequest: До моего ноявления люди гене нако мир не стоит на месте. В настоящ ее врем я я
рировали веб-страницы на стороне сервера, нри могу извлекать всевозмож ны е данные. Естествен
этом в них закладывались сразу все данные. Я же но, н екоторы е из них являю тся XML-данными,
нозволяю нолучать данны е после того, как страни однако я нолучаю все больше занросов на извлече
ца сгенерирована. Всномните Google Maps: дан ние JSO N -данных.
ная служба обновляет то, что им еется на страни
це, каждый раз, когда нроисходит корректи ровка Head First: В самом деле? А что такое JSON и н е
вашего м естонолож ения на карте, без необходи чему он набирает такую нонулярность?
мости перезагрузки страницы целиком. XMLHttpRequest: JSO N — это сокращ ение от
Head First: Вы нользуетесь уснехом. В чем ваш се JavaScript O bject N otation (нотация JavaScript-
крет? объектов). У этого ф орм ата им еется ряд преиму
ществ: разм ер, удобочитаемость, а также тот факт,
XMLHttpRequest: В моей ненритязательности и что он является «родным» для наиболее нонуляр-
нростоте. Д айте мне URL-адрес, и я отнравлю сь ного язы ка програм м ирования, иснользуемого
но нему и извлеку необходимы е вам данные. Н е нри создании веб-нрилож ений, которы м, конечно
более того. же, выстунает м ой друг JavaScript.
Head First: И этим все ограничивается? Head First: А нравда, что на самом деле ф орм ат
XMLHttpRequest: Ч то ж, вам нотребуется сказать не долж ен иметь для Вас значения? П ользовате
мне, что дальше делать с данны ми носле того, как ли долж ны быть снособны занраш ивать данны е в
я их извлеку. Вы мож ете нросто дать мне функцию ф орм ате XML, JSO N , а также телетайнное тексто
обработчика — функцию обратного вызова, — вое содерж имое с Вашей номощью. И ли нет?
и когда я добуду данны е, я нередам их этому обра XMLHttpRequest: < s i l e n c e >
ботчику, которы й сможет сделать с ними все, что
Head First: Ч то ж, судя но вашему молчанию , я за
ему нотребуется.
тронул болезненную тему. Ладно, н ора сделать
Head First: О какого рода данны х мы говорим нереры в... Послушайте, X M LH ttpR equest, ведь у
в данном случае? нас же еще будет врем я для общ ения с Вами нозже
в этой главе?
XMLHttpRequest: С оврем енны й И н терн ет нолон
всевозмож ны х данных; нрогнозы ногоды, карты , XMLHttpRequest: Да, хоть здесь и нет ничего ра
социальны е сведения о разны х людях, геолока- достного, но я вижу это в своем раснисании...
дальше ► 259
знакомство с json
ляОТЯ. s tr : ingifY<®ovie)
string)
JSO N.parse (jso n!
260 глава 6
общение с веб-службами
У меня новость !
Т
Спецификации сервера Mighty Gumball
Спасибо, что согласились помочь!
Minify Gumball, Inc.
О т ч е т ы об уровне продаж, п ост уп аю щ ие от а в т о м а т о в
Там, где автомат для
продажи жевательной
для продажи жевательной резинки, собираются вм ест е
резинки никогда не пуст и доступны на нашем цент ральном сервере по адресу
наполовину
h t t p : //g u m b a ll. w ic k e d ly s m a r t. с о т /
В качестве ф о р м а т а для наших данных мы выбрали JSO N , и если
воспользоваться приведенным выше URL-адресом , то обратно
можно получит ь массив JSON -объ ект ов, кот орые выглядят так:
Название города; на данный м о м е н т
[ { "пате" :" C A M P B E L L " ^ ы т е с т и р у е м свои т орговы е а в -
"time": 1302212903099, т о м а т ы в Калифорнии-
" s a l e s " : 3} ,
В ремя поступления данного
от чет а в Миллисекундах .
{" n a m e " : " F R E S N O "
" time" : 1 3 0 2 2 1 2 9 0 3 1 0 0 , Количество проданной жвачки
" sales" : 2 } с м о м е н т а последнего от чет а.
262 глава 6
общение с веб-службами
Пора за работу!
И так, мы нолучили специф икации от и нж енеров, а также
ноговорили с вами о X M L H ttpR equ est и JSON. Вы долж ны
быть уже готовы к тому, чтобы нереходить к нанисанию
кода и нерв о му зануску н рилож ения Mighty Gum ball.
Ранее мы с вами нанисали HTM L-разметку, но л ожив нача
ло нашему веб-нриложению , и предусмотрели в н ей ссылку
на файл m i g h t y g u m b a l l . j s. Сейчас займемся нанисанием
кода, которы й будет в нем размещ аться. Н аномним, что
мы также оставили в HTM L-разметке место, где будем раз
мещать данны е об уровне нродаж нрямо в < d iv > с i d в виде
« s a l e s » . Соединим все и наниш ем код.
Ь
б уд ьте
Е с л и в ы используете Opera либо Internet Explorer 8
(или ниже), рекомендуем вам проводить тестиро
вание с применением другого браузера. Об особен
ностях поддержки Opera и старых версий Internet
o O H o j= > oJK H bi Explorer мы поговорим позже.
дальше ► 263
как проводить тестирование локально
h t t p : / / l o c a l h o s t / m i g h t y g u m b a l l . h tm l
264 глава 6
общение с веб-службами
Mac OS X Windows
ф а и а т с к и о дистрибутивы Linux
Взглянем в лицо фактам: вы уже знаете, что делать в данном случае. Мы угадали?
Apache обычно устанавливается по умолчанию, поэтому читайте документацию
к используемому вами дистрибутиву Linux.
дальше ► 265
установка собственного веб-сервера
зоваться удаленным сервером, однако вам придется разм естить свои HTML-, JavaScript- и
CSS-файлы, а также JSO N -файл на одном сервере (о том, почему это так важно, поговорим
позже), следуя приведенному здесь примеру.
Больш инство хостинговы х сервисов обеспечат вам FTP-доступ к папке, в которую вы смо
ж ете поместить все свои файлы. Если у вас есть доступ к подобному серверу, то выгрузите
туда все файлы и подставьте имя данного сервера вместо lo c a l h o s t везде, где увидите его.
_________________ гхэ Г Т Т П f D h f h t m iS 5 3
Q chapterl
Q chapt*f2
п chapter3
Р~1 chapter4 Вы можете прибегнуть
D chapters
r~| Chapters к Т Р -п р о гр а м м е (н а п р и
р-i chapter7 м е р j Transit, Cyberduck
f~ | chapters
p i chapter9 или VJinSCP), для вы груз
p~| chapter10 ки своих ф айлов, если не
х о т и т е использовать
FTP командной строки.
their stuff. (10 items)
your Stuff. (1 3 item s)
Мы составили список поставщ иков услуг хостинга на случай, если вам потребуется под
сказка, однако их и так можно отыскать без особого труда; просто введите в поисковик
«веб-хостинг», и он выдаст вам массу вариантов. С оставленный нами список доступен по
адресу h ttp :/ / wickedlysm art.com /h fh tm l5 /h o s tin g /h o s tin g .h tm l. И дайте нам знать, если у
вас появится собственны й веб-сайт HTML5 в И нтернете, поскольку нам будет лю бопы тно
взглянуть на него!
---------------------------------------------------------------------------------------------------------------------------------
266 глава 6
общение с веб-службами
Возвращаемся к коду
Н а данны й момент мы нреднолагаем, что вы уже установили собственны й сервер, — это мож ет быть
сервер, вы полняю щ ийся на вашем локальном ком нью тере (как в наш ем случае), либо сервер, распола
гаю щ ийся где-то в другом месте, и у вас есть к нему достун. И в том и в другом случае вы будете разм е
щать свои HTML- и JavaScript-файлы на этом сервере, а затем укажете браузеру нуть к соответствующ е
му HTM L-файлу. Вам также но требуется тестовы й ф айл с данны ми об уровне нродаж Mighty Gum ball,
ноэтому мы нредоставим вам нростой ф айл с такими данными, которы й вы сможете номестить н а свой
сервер. Д ля вашего н рилож ения он будет выглядеть так, будто ностунает с центрального сервера Mighty
Gum ball, обеснечиваю щ его обновление данны х ночти в реж им е реального времени, что даст вам воз
мож ность протестировать свой код, не задействуя производственны й сервер Mighty Gum ball. Далее
но казано, как будет выглядеть данны й файл; он назы вается s a l e s . j son и вклю чен в код, иснользуемый
в этой книге и достунный в И н терн ете (вы мож ете и самостоятельно набрать его, если вам нравится
этот нроцесс):
h t t p : / / l o c a l h o s t / g u m b a l l / s a l e s . j so n:
URL в сво-
Полезно сначала пр от ест ир оват ь э т о т
V ем браузере, чтобы убедиться, что он работает. ('■«■**,‘SACRAXEJJTO* 111*40**9' ‘«W »5>,
window.onload = function() {
var url = "http://localhost/gumball/sales.json" ;
var request = new XMLHttpRequest () ; fib*
request.open ("GET" , u rl ) ; V_ Убедитесь, что здесь
request.onload = function() { указан правильный
URL-adpec.
if (request.status == 200) {
updateSales(request.responseText);
}
};
reques t .s e n d (nul1);
дальше ► 267
тестирование приложения mighty gumball версии 1
268 глава 6
общение с веб-службами
т
Пока мы просто сбрасываем J S O N -массив п р я
мо в браузер. В некоторой степени э ф ф е к т и в
С Здесь мы использовали JSON -массив
и преврат или его в красиво от обра
но, но р е з у л ь т а т получается не очень красивым. жаемые данные.
Какая жалость, ведь есть целая с т р у к т у р а
данных, которая только и ждет более э ф ф е к
тивного подхода к ее использованию!
дальше ► 269
добавление поддержки json
function updateSales(responseText) {
}
Здесь мы б ерем о т в е т и и с п о л ь з у е м JSO N .p arse для
преобразования его в J a v a S c r i p t -о б ъ е к т (в данном случае
э т о б удет м ассив) и п р и с ва и ва е м его п е р е м е н н о й sales.
270 глава 6
общение с веб-службами
дальше ► 271
проблема с mighty gumball
Хьюстон, у нас
проблема! Идите скорее сюда,
мы вообще не можем получить
какие-либо данные об уровне продаж Это еще что?!
после того, как перешли к исполь Мь/ не видим вообще
зованию действующего сервера никаких данных!
Mighty Gumball!
Ой!
А все вы гл яд ело т а к х о р о ш о ; м ы уж е
п р е д с та в л я л и себе, к а к будем п о т я
ги в а ть м и н е р а л ьн ую воду « P e rrie r» и
о тм е ч а ть у с п е ш н о е за в е р ш е н и е еще л
о д н о г о п р о е к т а с M ig h ty G u m b a ll. Примечание для редактора:
А т е п е р ь все м о ж е т п о й т и н а с м а р вообще-то мы представляли
ку. Л а д н о , н е б уде м и з л и ш н е д р а себеj как будем обналичивать
м а ти зи р о в а ть си туа ц и ю , но в чем Жирный чек и от пр а в л ят ь вам
ж е в с е -т а ки дело? Ведь все д о л ж н о э т у книгу! А вм ест о этого
р а б о та ть ! нам т еперь придется допи
сывать ее, рассказывая о т о м ,
С делайте гл у б о к и й вдох. Т ом у есть
л о г и ч е с к о е о б ъ я с н е н и е ...
как найти выход из очередной
непростой ситуации!
272 глава 6
с веб-службами
КЛЮЧЕВЫЕ
МОМЕНТЫ
■ Для извлечения HTML-файлов или данных с сервера XMLHttpRequest может применяться для извлечения
браузер отправляет НТТР-запрос. всевозможного текстового содержимого (например,
XML, JS0N и др.).
■ HTTP-ответ включает код ответа, который позволяет
узнать, произошли ли какие-либо ошибки при выпол XMLHttpRequest Level 2 является самой последней
нении запроса. версией X M L H ttpR equest, однако данный стандарт
все еще находится в разработке.
■ Код 2 0 0 в HTTP-ответе означает, что при выполнении
запроса не произошло никаких ошибок. Чтобы использовать XMLH ttpRequest, СООТВвТСТВу-
ющие файлы необходимо разместить на сервере,
■ Для отправки HTTP-запроса из JavaScript используется
с которого и будут запрашиваться данные. Вы можете
Объект X M LH ttpR equest.
установить локальный сервер на своем компьютере
■ Обработчик событий o n l o a d объекта XMLHttpRequest для проведения тестирования либо воспользоваться
обрабатывает получение ответа от сервера. хостинговыми сервисами.
дальше ► 273
З ф И М И та р в & е Э Д й & г» ч а с т ь г
Интервью недели:
Internet Explorer и «Вы сказали JSO N ?»?
Head First: Д обро нож аловать вновь на наше интервью , X M LH ttpR equest. Я хотел снросить у Вас на
счет браузеров —Вы ноддерж иваетесь только их новейш им и версиями?
XMLHttpRequest: М еня не зря назы ваю т старожилом; браузеры ноддерж иваю т м еня с 2004 года.
Head First: Ч то ж, а как насчет м орального устаревания, Вас это не беснокоит?
XMLHttpRequest: Я объект, новая версия которого выходит каждые 10 лет или около того. В настоя
щ ий момент нолны м ходом идет работа над м оей второй версией, назы ваемой X M LH ttpR equest Level 2.
Ф актически, больш инство соврем енны х браузеров уже ноддерж иваю т данную версию.
Head First: Это внечатляет. А в чем заклю чаю тся особенности версии Level 2?
XMLHttpRequest: П реж де всего в ноддерж ке большего количества тинов собы тий, благодаря чему вы
сможете, нанрим ер, отслеж ивать ход вы нолнения занроса и нисать более элегантны й код.
Head First: Говоря насчет браузерной ноддержки...
XMLHttpRequest: До этого мы сейчас дойдем... не торонитесь...
Head First: По слухам, вы и In tern et Explorer на самом деле не ладите друг с другом...
XMLHttpRequest: Вы что, шутите? Вся и стори я X M LH ttpR equest началась с In te rn e t Explorer.
Head First: А как насчет ActiveXObject и X D om ainRequest? Вам доводилось слышать эти имена?
XMLHttpRequest: Это мои нрозвища! Так меня назы ваю т в Microsoft! Да, я согласен, что наличие у меня
разны х им ен — не очень хорош о, однако нод ними подразумеваю тся инструменты , которы е реш аю т
одну и ту же задачу. Для улаживания данной ситуации Вам нотребуется лиш ь небольш ое количество
дополнительного кода, а с точки зрен и я носледних верси й браузера In tern et E xplorer от M icrosoft начи
ная с версии 9 и выше все и так будет в норядке. Если это новость для Ваших читателей, то я с радостью
задержусь носле интервью , чтобы нозаботиться о том, чтобы их код был совместим с более старыми
версиям и In tern et Explorer.
Head First: М ило с Вашей стороны , но мы займемся этим вонросом как-нибудь нозж е в данной главе.
XMLHttpRequest: Эй, я хорош ий нарень и не стану бросать ваших читателей наедине с нроблемой.
Head First: Л овим Вас на слове. И еще один вонрос: В ы у н о м и н ал и ^ С Ж и говорили, что являетесь его
большим ноклонником. А что, JSO N P Вас вообщ е никак не беснокоит? По слухам, многие люди исноль-
зуют его вместо Вас.
XMLHttpRequest: Да, с номощью JSO N P вы, конечно же, сможете извлекать данны е, однако это всего
лиш ь ловкий халтурны й нрием. Я хочу сказать: задумайтесь о том витиеватом коде, которы й вам нри-
дется нанисать. И как насчет безонасности?
Head First: Я не слишком технически нодкован и знаю лишь, что люди говорят, будто он дает им воз
мож ность обойти нроблемы, которы е Вы не нозволяете реш ить. Внрочем, наше время истекло.
XMLHttpRequest: Ч то ж, ну хотя бы в части «не слиш ком технически нодкован» Вы не ошиблись.
274 глава 6
общение с веб-службами
request.onreadystatechange = function() {
updateSales(request.responseText); З а т е м проверьте
readyState, чтобы
убедиться, что з а
грузка данных за в ер
};
шилась. Если значением
request.o p e n ("GET", url) readyState является 4,
то вы будете знат ь,
request.send(null); Вы также можете что загрузка закончена.
проводить проверку
f на предм ет других зн а
See остальное, no большей чений readyState и status
част и, является т аким же,
с и,елы-о выявления р а з
как и раньше.
личных ошибок.
дальше ► 275
выяснение, что пошло не так
В о т как в итоге выглядит наша страница А вот как в итоге выглядит наш а стра
но еле того, как мы вы нолнили код и из ниц а но еле того, как мы вы нолнили код
влекли данны е об уровне нродаж со сво и извлекли данны е об уровне нродаж с
его локального сервера, иснользуя адрес сервера Mighty Gum ball, используя адрес
http: / /lo c a lh o st / gum ball / sales.json. http: / / gum ball.wickedlysm art.com .
276 глава 6
общение с веб-службами
Джуды
дальше ► 277
обзор браузерной политики безопасности
Сервер
успешно
Ваш браузер о т возвращает
правляет запрос запраш ива
страницы из ем ую вами
doodD om ain.com . страницу.
Браузер GoodDomain.com
Браузер GoodDomain.com
278 глава 6
общение с веб-службами
Сервер
Ваш браузер о т успешно
правляет запрос возвращает
страницы из запраш ива
QoodDomain.com. ем ую вами
страницу.
Браузер GoodDomain.com
Однако на этот раз у нас имеется код, которому требуются данные из другого источника, то есть
из BadDomain.com. Посмотрим, что произойдет, когда страница запросит эти данные с использо
ванием XMLHttpRequest::
Браузер видит, что
Ваша с т р а н и это запрос в домен,
ца использует отличный от т ого ,
XMLHttpRequest в кот ором р асп о
для попытки лагается ст раница,
запроса данных, и п р е п я т с т в у е т его
располагающихся совершению. То есть
в BadPomain.com в запросе будет о т
казано.
Браузер GoodDomain.com
Сервер BadPomain.com т ак и не
увидит запрос; полит ика безопас
ности вашего браузера во с п р еп ят
с т ву е т его совершению прежде, BadDomain.com
чем это могло бы случиться.
дальше ► 279
обзор имеющихся вариантов
X M L H ttp R e q u est является отличным инструментом для извлечения данны х в ваши нрилож ения,
если эти данны е располагаю тся в том же домене, что и нрилож ения. Но вдруг вам нотребуется
извлечь данны е из стороннего источника? Ч то делать, если вам нонадобятся данны е, которы е
мож ет дать, нанрим ер, Google или Twitter? В нодобных ситуациях неред нами встает нроблема,
которую нужно реш ить путем ноиска иного нодхода к извлечению данных.
О казы вается, есть другой нодход, которы й основан на JSON и известен как JSO N P (JSON with
P adding —JSO N P с нодкладкой; согласны, звучит странно, однако ноговорим об этом чуть ноз-
же). Н адевайте свой реактивны й ранец, носкольку снособ его работы немного «с другой нлане-
ты», если вы нонимаете, что мы имеем в виду.
дальше ► 281
знакомство с jsonp
282 глава 6
общение с веб-службами
Присаживайся,
Кузнечик. Зачастую то,
чему я учу, ты уже, в сущ
ности, знаешь...
Гуру HTML5: ...и этот как раз один из таких случаев. Кузнечик,
взгляни на этот код:
Что он делает?
Данным
Веб-разработчик: Если произвести код ра спо
его оценку, предполагая при этом, лагается
что он выполняется в браузере, то данный код выведет диа по э т о
логовое ОКНО a l e r t С ТеКС ТО М "woof". м у URL-
Гуру: Да, верно. Создай свой собственный простой HTML- адресу.
файл и помести в него < s c r i p t > , расположив данный элемент
в <body>, как показано далее:
дальше ► 283
гуру дает урок по jsonp
Веб-разработчик: Он схож с кодом из файла d o g . j s , однако в данном случае вызову будет под
вергаться функция a n i m a ls a y s . Кроме того, функция обладает не одним, а двумя аргументами: тип
животного и звук, который оно издает.
Гуру: Напиши функцию a n i m a ls a y s и добавь ее в элемент < s c r i p t > в < h e a d > твоего HTML-файла
над элементом < s c r i p t > , указывающим на wickedlysmart.com.
Веб-разработчик: Вот так?
f u n c t i o n a n i m a l S a y s ( t y p e , so u n d ) {
a l e r t ( t y p e + " says " + s o u n d );
}
Гуру: Очень хорошо, ты делаешь успехи. А теперь измени ссылку своего другого < s c r i p t > , того,
который указывает на d o g . j s , чтобы он стал указывать на d o g 2 . j s , и перезагрузи страницу в браузере.
Веб-разработчик: У меня на экране появилось диалоговое окно a l e r t с сообщением " d o g s a y s w o o f" .
Гуру: Теперь переключись на http://wickedlysmart.com/hfhtml6/chapter5/cat2.js, измени ссылку
своего < s c r i p t > , чтобы он стал указывать на c a t 2 . j s , и посмотри, что будет.
284 глава 6
общение с веб-службами
v a r s a l e s = [ { " n a m e " : "A R T E S IA " , " t i m e " : 130 8 774240 6 69, " s a l e s 8} ,
{"name":"LOS ANGELES", "time":1308 774240669,"sales":2}];
u p d ateS ale s (sales) ;
Гуру: Да. Однако ты должен уметь видеть главное за массой второстепенных деталей. Разве при
этом их извлечение осуществляется не из другого домена? А это X M L H t t p R e q u e s t запрещает.
Веб-разработчик: Кажется, так оно и есть. Действительно похоже на какое-то волшебство.
Гуру: Здесь нет никакого волшебства, поскольку элемент <script> всегда так работал. Ответ все вре
мя был рядом. Теперь поразмышляй над тем, как все это функционирует, чтобы закрепить материал.
Веб-разработчик: Да, учитель. «Закрепить материал»... знаете, эта фраза звучит для меня так зна
комо, но в то же время как-то непривычно.
Использование JavaScript для извлечения данных является тем, с чем вам необхо
димо слиться воедино. Возьмите лист бумаги или используйте внутреннюю сторо
ну обложки этой книги. Нарисуйте сервер, на котором располагаются ваши HTML- и
JavaScript-фэйлы. Также изобразите сервер в другом домене, где размещаются фай
лы dog3 .js и cat3 .js. Затем проделайте все шаги, которые браузер предприни
мает для извлечения и использования объекта в каждом из файлов. После того как
вы во всем разберетесь, мы снова проделаем эти шаги вместе.
дальше ► 285
обзор jsonp
Знакомство с JSONP
Вы, вероятно, уже ноняли, что JSO N P нредетавляет собой еноеоб извлечения JSON-
объектов с использованием тега < s c r i p t > . Это также еноеоб и звлечения данны х (онять-
таки, в ф орм е JSO N -объектов), нозволяю щ ий избеж ать нроблем безонасности, связан
ны х с н олитикой одного источника, которы е мы видели в случае с X M L H ttpR equest.
Н а н ротяж ени и следующих нескольких страниц мы с вами ношагово нройдем ся но тому,
как работает JSONP:
г Браузер
/^p\ Мы включили
элемент < s c r i p t >
в свою H TM L-разметку.
Источником для этого
<body>
оау^ элемента выступает
< h l > M i g h t y Gumball Sales</ URL веб-службы, кото
< d i v id*" sales ••>
рая будет обеспечивать
для нас J S O N -данные
</diV> ,/ V, U Wickedlysmart.com/" X / script об уровне продаж жева
<script src="h t t p ://gumball.wicke
тельной резинки.
</body>
</html> _____ ____
Когда браузер
сталкивается
с элементом <script>
на странице, он отправ
( Т \ ТJ S O N -ответ посту ляет HTTP-запрос по
пает в форме строки, URL-адресу источника.
которую браузер разбирает
и интерпретирует. Л ю
бые типы данных преоб
разуются в подлинный
JavaScript-объект и значе
ния, а любой код подвер
гается выполнению.
286 глава 6
общение с веб-службами
На э т о т раз J S O N -
данные будут обернуты Л/
в вызов функции.
updateSales
f o \ Как и ранее, сервер воспринимает данный
запрос как обычный запрос и отправляет
в ответ на него J S O N -строку, о дн ако ... здесь
имеется небольшое отличие.
дальше ► 287
разбираемся с функциями обратного вызова
ШТУРМ
Введите данные URL-адреса: что вы видите в ответ?
http://search.twitter.сот/search.j son?q=hfhtml5&callback=myCallback
h t t p ://search.twitter.com/search.j son?q=hfhtml5&callback=justDoIt
288 глава 6
общение с веб-службами
Д ж им : Ч то ж, почти.
Д ж о: Думаю, это дает нам возмож ность избавиться от части кода.
Ф рэнк: Я готов придать веб-нриложению красивы й внеш ний вид,
когда вы закончите.
Д ж им : Д ж о, а что ты думаешь?
Д ж о: В случае с X M L H ttpR e quest мы извлекали строку. Но нри ис
пользовании JSO N P тег < s c r i p t > обеснечивает разбор и оценку
возвращ аемого кода, поэтому когда мы нолучим данны е, они уже
будут представлять собой JavaScript-объект.
Д ж им : Да, все верно, а в случае с X M L H ttpR eq uest мы иснользова-
ли J S O N . p a r s e для преобразования строки в объект. Получается,
что теперь мы можем избавиться от этого кода?
Д ж о: Да. Это мое мнение, которого я нридерж иваю сь.
Джим: Ч то еще?
Джо: Ч то ж, очевидно, что нам нотребуется вставить элемент
< scrip t> .
дальше ► 289
план повторной реализации
window.onload = function() {
v a r u r l = "h t t p : / /g u m b a ll. wi c k e d ly s m a r t. com " т g данный МОЛЛент бяМ HCofixo-
var request = new XMLIIttpRequest () ; димо просто удалит ь весь код,
имеющийся в этой функции.
reque st.open (ивВФм , url);
reque st.onload = function ()— f-
if— (reque st.status == 200)— {-
updateflales(request.responseText);
t
290 глава 6
общение с веб-службами
Удаляем responseText и п е р е
function up date Oale s(resp onseText) писываем ст року с использо
function updateSales(sales) { ванием парам ет ра sales.
var salesDiv = document.getElementByld("sales")
var sale s = JOON.p arse (re sp onseTex t ) ; ^ ------
К роме т ого, мы можем
for (var i = 0; i < s a les.length; i++) { удалит ь вызов JSON.parse.
var sale = sales[i];
var div = document.createElement ("div") ;
div. setAttribute ("class" , "saleltem") ;
div.innerHTML = sale.name + " sold " + sale.sales + gumballs";
salesDiv. appendChiId (div) ;
< !d o c ty p e h tm l>
< h tm l la n g = " e n " >
<head>
< t itle > M ig h tY G u m b a ll< /title > Это ссылка на веб-службу
<m eta c h a r s e t = " u t f - 8 "> Mighty Gumball. Мы исп оль
< s c r i p t s rc = " m ig h ty g u m b a ll.j s " X / s c r i p t > зуем п а рам ет р callback и
< l i n k r e l = " s t y l e s h e e t " h r e f= " m ig h ty g u m b a ll. c s s " >
указываем имя нашей ф у н к
ции updateSales, в силу чего
< /h e a d >
веб-служба будет оберт ы
<body> вать J S O N -данные в вызов
< h l> M ig h ty G um ball S a le s < /h l> функции updateSales
< d iv i d = " s a l e s ">
</div>
< script src="http:/ /gumball.wickedly smart.com/?callback=updateS ales" X / scrip t>
</body>
</html>
дальше ► 291
тестирование кода с jsonp
292 глава 6
А мне кажется, что JSONP
является одной большой бре
шью в безопасности!
294 глава 6
общение с веб-службами
H E A D F IR S T :
Благодарю , ребята! Боюсь, наше врем я истекло!
дальше ► 295
jsonp-упражнение для ума
М 9 *Г 9 *9 Й
ШТУРМ
Он прав, нам необходимо подкорректировать приложение, чтобы оно обновляло
отображаемые данные, используя новые сведения об уровне продаж, через регу
лярные интервалы времени (например, каждые 10 секунд). На данный момент у
нас в странице имеется элемент <script>, который инициирует отправку запроса
на сервер только один раз. Вы можете придумать какой-нибудь способ так исполь
зовать JSON, чтобы обеспечивалось непрерывное извлечение отчетов с новыми
данными об уровне продаж?
296 глава 6
общение с веб-службами
Ребята, как я только что узнала,
исполнительный директор Mighty Gumball
не совсем доволен вашей первой версией
приложения?
дальше ► 297
делаем jso np динамическим
298 глава 6
общение с веб-службами
М етод s e tln te r v a l
приним ает одра-
Наила функция обра
ботчика, кот орую мы
г
Наше значение интервала вр е м е
ни, выраженное в миллисекундах.
б о т ч и к и зн а ч е н и е определим чут ь позже. 3 ООО миллисекунд = 3 секунды.
и нт ер ва ла врем ени.
Таким образом, каждые 3000 миллисекунд JavaScript будет вызы вать обработчик —в данном
случае функцию h a n d l e R e f r e s h . Д авайте наниш ем нростой обработчик и протестируем его:
Тенерь нам нотребуется код для задания вы зова s e t l n t e r v a l , которы й мы добавим в функ
цию o n l o a d , чтобы он нроисходил сразу но еле того, как страница нолностью загрузится:
П роведем тест-драйв, а затем, когда убедимся, что все работает (то есть когда мы увидим,
что обработчик вы зы вается каждые 3 секунды), реализуем JSO N P-код.
дальше ► 299
тестирование интервального таймера
Tecm-драйб таймера
Э т о будет весело. Убедитесь, что вы набрали функцию h andleRef resh, а также внес
ли изм енения в обработчик onload. С охраните все, а затем загрузите код в своем
браузере. В результате вы долж ны увидеть ноток откры ваю щ ихся диалоговы х окон
alert, остановить которы й сможете, лиш ь закрыв окно браузера!
------------------------------------------------------------------ 1
h ttp ://lo c a lh o s t
Cm alive
С OK 3
Л
4 Вот что мы получим!
Возьми в руку карандаш
300 глава 6
общение с веб-службами
function handleRefresh () {
var url = "http://gumball.wickedly smart.com? callback=updateS ales " ;
Сначала мы создаем но
вый элем ент <scnpt>...
var newScriptElement = document.createElenient (" script")
newScriptElement.setAttribute (" src" , url) ;
...а за т е м присваиваем его
а т р иб ут у scr значение
newScriptElement.setAt tribute ("id" , "jsonp") ; виде URL-адреса JSONP.
r Мы также присвоим
Метод setA ttrib u te может показаться вам ч е м -т о данному элем ент у <script>
новым (мы лишь мимоходом упоминали его ранее), иден т и ф и ка т ор , чтобы
однако несложно понять, что он делает . Данный его можно было без труда
м ет од позволяет задавать значения для ат рибут ов найти позже, что, как вы
HTML-элем ент ов (например, для scr и id), а также увидите, нам и п о т р е б у
для множества других, включая class, href и m. д. ется сделать.
дальше ► 301
вставка jsonp в dom
П осле того как мы вставим <script>, браузер увидит этот новы й элемент в объектной модели до
кумента (DOM) и отнравится извлекать то, что раснолож ено но URL-адресу, которы й задан в каче
стве зн ачен ия атрибута scr. Однако у нас также имеется второй вариант иснользования. Взглянем
на него.
/Cpv Теперь, за исключением време-
данном случае мы снова будем из
ни, когда происходит первый
влекать ссылку на элемент <head>.
вызов handleRefresh, у нас уже будет
иметься элемент <script> с id
в виде "jsonp" в DОМ.
302 глава 6
общение с веб-службами
Итак, взглянем на код для замены элемента <script> в случае, если вы
ясняется, что таковой уже существует. Мы рассмотрим только условный
оператор if, в котором сосредоточен весь новый код:
if (oldScriptElement == null) {
head.appendChiId(newS criptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
\ Если в <head> уже имеет ся элем ент <scnpt>, мы просто заменяем его.
Мы используем м ет од replaceChild в отношении <head> и передаем ему
new ScriptE lem ent и oldScriptElement для выполнения данной процедуры.
Через несколько мгновений мы подробнее поговорим об эт ом методе.
дальше ► 303
подробнее о дополнительных методах для работы с dom
g e t^e in e n b ^y X a g ^a K ie п о д у в е л и ч и те л ь н ы м с т е к л ° м ________________
Это было ваше нервое знакомство с методом g e tE le m e n tsB yT a g N a m e , ноэтому быстро ис
следуем его нодробнее. О н нодобен методу g e tD o c u m e n tB y ld за исклю чением того, что
возвращ ает массив элементов, соответствующ их определенному имени тега.
\
var arrayOfHeadElements = document.getElementsByTagName ("head" ) ;
Гер1асе(Ти1с1 по д у в е л и ч и те л ь н ы м с т е к л ° м ____________________________
Взглянем также на метод r e p la c e C h i I d , носко льку вы не встречали его раньш е. Д анны й ме
тод следует вызы вать но отнош ению к элементу, в котором вы хотите зам енить дочерни й
элемент, нередав ему ссылки на н овы й и стары й дочерние элементы. М етод r e p la c e C h ild
нросто зам еняет стары й д очерни й элем ент новым.
head.replaceChild(newScriptElement, oldScriptElement) ;
304 глава 6
общение с веб-службами
Часш°
Задаваем ы е
В сЩ роСъх
0 : Если вы лишь замените значение атрибута s c r элемента 0 : В случае большинства веб-служб публикуется общий API-
< s c r ip t > новым URL-адресом, браузер не будет рассматривать интерфейс, который включает способы доступа к конкретной службе,
его как новый элемент < s c r i p t > и, следовательно, не станет а также описание всего того, что можно сделать с ее помощью.
совершать запрос для извлечения JSONP. Чтобы заставить бра Если вы используете коммерческий API-интерфейс, то вам может
узер выполнить запрос, необходимо создать абсолютно новый потребоваться получить соответствующую документацию напрямую
элемент < s c r ip t > . Данная методика называется скриптовой от поставщика. Информацию относительно большей части общих
инъекцией. API-интерфейсов вам, скорее всего, удастся найти в Интернете,
используя поисковик либо зайдя в раздел для разработчиков на
^ 3 * Что происходит со старым дочерним элементом, когда я сайте соответствующей организации. Вы также можете посетить,
заменяю его новым? например, сайт programtheweb.com, где документируются API-
интерфейсы, список которых постоянно увеличивается.
прежнему имеется ссылка на него, сохраненная в находящейся JSON и JSONP? Являются ли они частью HTML5? Нужен ли мне
где-то переменной, то вы сможете продолжить использовать его HTML5, чтобы использовать их?
(любым путем, который будет иметь смысл). Если же у вас ее нет, то
среда выполнения JavaScript в конце концов регенерирует (освобо 0 : Мы бы назвали JSON и JSONP современниками HTML5.
дит) память, которую занимает данный элемент в вашем браузере. Ни один из них пока не определен спецификацией HTML5, од
нако они активно используются HTML5-пpилoжeниями и играют
А что, если в HTML-файле будет более одного элемента важнейшую роль в процессе создания веб-приложений. Таким
<head>? В случае с вашим кодом, по-видимому, предполага образом, несмотря на то что мы говорим HTML = Язык разметки +
ется, что там будет только один элемент <head>, поскольку API-интерфейсы JavaScript + CSS, JSON и JSONP также являются
вы используете индекс 0 в массиве, возвращаемом методом весомой частью данной картины (равно как и запросы с использо
getElementsByTag? ванием HTTP И X M LH ttpR e q u e s t).
0 : По определению HTML-файл включает только один элемент ^ J Продолжают ли люди использовать XML? Или в настоящее
<head>. Следует отметить, что, конечно же, кто-то может включить время везде уже господствует JSON?
и два таких элемента в HTML-файл. В этом случае получаемые ре
зультаты могут варьироваться (так и будет, если вы не произведете 0 : В компьютерной индустрии существует одна прописная истина,
валидацию своего HTML!), но браузер, как обычно, постарается согласно которой ничто никогда не умирает. При этом также следует
приложить максимум усилий, чтобы сделать все правильно (а что отметить, что JSON в настоящее время набирает обороты, в силу
именно считается правильным, зависит от браузера). чего создание многих новых веб-служб осуществлялся именно с
его помощью. Вы часто будете сталкиваться с тем, что многие
Можно ли остановить интервальный таймер после его веб-службы поддерживают разнообразные форматы, включая
запуска? XML, JSON и массу других (например, RSS). Преимуществом JSON
является то, что он основан непосредственно на JavaScript, a JSONP
позволяет избежать междоменных проблем.
0 : Конечно, можно. Метод s e t l n t e r v a l возвращает значение
id , которое идентифицирует таймер. Сохранив данное значение
i d в переменной, вы сможете в любой момент передать его методу
c l e a r i n t e r v a l для остановки таймера. Закрытие браузера
также останавливает таймер.
дальше ► 305
разбираемся с кэшем браузера
Благодаря этому новому коду сгенерированны й URL-адрес будет выглядеть нрим ерно так:
http://gumball.wickedlysmart.com?callback=updateSales&random=1309217501707
У *
Эта часть будет каждый раз изменяться
для предотвращения кэширования.
Зам ените объявление н ерем ен ной url в своей функции handleRefresh нредставленны м
здесь кодом, но еле чего вы будете готовы к нроведению тест-драйва!
306 глава 6
общение с веб-службами
Просто у к а -
Вы также можете добавить п а р а м е т р lastreporttim e в к о - время
н е ц U R L -адреса, чтобы извлечь только от чет ы , которые в миллисекундах,
по ст упили начиная с указанного времени. Например: oQnj f QQ
h t t p : / / gUnba 1 1 . Wic3cedly sma r t .conl/ ?1a s t r e p o J:t t i Iae=1302212903099
Это, конечно, здорово, но как узнать врем я ностунления носледнего отчета, которы й
мы извлекали? Д авайте еще раз взглянем на ф орм ат вывода отчетов об уровне нродаж:
[{"name":"LOS ANGELES","time":1309208126092,"sales":2},
{"name":"PASADENA","time":1309208128219,"sales":8}, У каждого от чет а об уровне
{"name":"DAVIS CREEK","time":1309214414505,"sales":8} продаж имеет ся время его
. . .] поступления.
дальше ► 307
использование параметра веб-службы
}
Нам необходимо убедиться
Если вы взглянете на массив sales, то у в и в Н АЛ И Ч И И массива; в случае
дите, что самый свежий о т ч ет о прода о т с ут ст ви я новых отчетов
жах является последним в эт о м массиве. о продажах будет возвращен
Поэтому здесь мы присваиваем его нашей пустой массив и наш код сгене
переменной lastReportTime. р и р у е т исключение.
308 глава 6
общение с веб-службами
Тест-драйв lastReportTime
П роведем тестирование нарам етра занроса last reporttime и посмо
трим, реш ает ли он нашу нроблему с дубликатами отчетов об уровне про
даж. Убедитесь, что вы набрали весь нриведенны й чуть выше новы й код
перезагрузите страницу и щ елкните на кнонке Refresh (О бновить).
А О О _ ИЦМуСииМ»__________ | у
ГлИЗС+З
Mighty Gumball Sales
LOS ANGELES sold 3 gumballs
Отлично! Теперь мы
LOS ANGELES sold 9 gumballs
ATWATER sold 8 gumballs
будем получат ь т о л ь
FARMINGTON sold 1 gumboils
ко новые отчеты о
F A R M IN G T O N sold 1 gumballs продажах, то есть все
GARDEN GROVE sold 3 gumballs дубликаты исчезнут!
дальше ► 309
Вы превзошли самих себя! Приложение
работает замечательно — теперь я могу
быть в курсе уровня продаж как сидя за своим рабочим
столом, так и находясь в пути. Я начинаю думать, что в
подобных веб-приложениях действительно что-то есть.
Только представьте, сколько всего мы сможем сделать,
используя автоматы для продажи жевательной резинки
в сочетании с J S O N и всеми этими
A P I-интерсрейсами HTML5!!
общение с веб-службами
КЛЮЧЕВЫЕ
"МОМЕНТЫ
■ Используйте JSONP, если вам требуется доступ ■ Добавляйте случайное число в конец своего URL-
к данным, имеющимся у веб-службы на удаленном адреса JSONP-запроса, если многократно исполь
сервере (при этом предполагается, что эта веб зуете этот URL для совершения запросов, чтобы
служба будет поддерживать JSON Р). Веб-служба — браузер не кэшировал ответ.
это веб-интерфейс API, доступ к которому осущест
■ Метод replaceChild заменяет один элемент
вляется по протоколу HTTP.
другим в DOM.
■ JSONP представляет собой способ извлечения
■ set Interval — это таймер, который вызывает
данных с использованием элемента <script>.
функции через заданный интервал времени. Вы мо
■ JSONP — это JSON-данные, обернутые в JavaScript; жете использовать setlnterval для отправки
обычно JSON-данные обертываются в вызов функ повторяющихся JSONP-запросов на сервер с целью
ции. извлечения новых данных.
дальше ► 311
U I M L 5 - K f ° CCBopA
Здорово, в этой главе вы научили свое веб-нриложение общ аться с веб-службами!
П ора заставить ноработать левое нолуш арие мозга для закрепления материала.
По горизонтали По вертикали
4. Шаблон использования XMLHttpRequest для извлечения данных 1. В середине данной главы нас подстерегал один из них.
ссерверов иногда называют . 2. JSONP означает JSON with__________ .
7. Гуру учила Кузнечика тому, что аргументы функций также являются 3. JSONP использует__________ .
5.Формат, который, как мы все полагали, «спасет» мир.
8.__________ представляет собой новейшую модель автомата 6.__________ ,работающий контролером качества, был расстроен,
для продажи жевательной резинки Mighty Gumball с поддержкой под когда запрос, отправленный на производственный сервер Mighty
ключения кИнтернету. Gumball, потерпел неудачу.
10. Одно из прозвищ XMLHttpRequest в Microsoft. 8. Локальный сервер легко установить в операционной системе
13. Мы допустили_________ ,сначала углубившись на 25 страниц
в главу и только затем рассказав вам о браузерной политике безо 9. У _________ имеется веб-служба JSONP.
пасности. 11. Используемые JSONP типы объектов.
15. XMLHttpRequest высмеял слово_______ в названии JSONP. 12. Компания Mighty Gumball проводит тестирование модели торгового
автомата MG2200 в__________ .
14. напомнила Фрэнку,Джиму иДжо о междоменных проблемах,
возникающих В случае С XMLHttpRequest.
312 глава 6
общение с веб-службами
Специальное сообщение
из главы 7 ...
Мы работаем с АР1-интерсреисом
JSONP T w itte r и создаем службу, ко
торая дает пользователям возможность
размещать на футболках любые твиты.
Оснобятел&ница
Tw/eetS^i rt.com
дальш е ► 313
решение кроссворда
314 глава 6
7 р аскр ы в аем б се^е х у д о ж н и к а
% т
Элемент canvas *
Да, разметка — это, конечно,
здорово, но ничто не сравнится
с тем, когда собственными руками
раскрашиваешь что-либо свежими,
аккуратными пикселами.
t
Вероятно, вы подумали: « А зна е т е, это неплохая идея». Что ж , в т аком случае мы
с вами успешно положим начало данному с т а р т а п у , создав к концу главы полност ью
готовое к работе веб-приложение. А если вы р еш ит е использовать его для зараба
тывания денег, мы не ст анем заявлять права на и нт е л ле к т уа л ь н ую собственность,
но хот я бы вышлите нам бесплатную футболку!
Мы любим говорить:
«Если вы поклонник Твит
тера, закажите футболку
с отпечатанным твитом».
Основательница
Т\л/ е et S Кir t ’-со w
316 глава 7
раскрываем в себе художника
Взгляд на «оригинал-макет»
П роведя исчерпывающ ую итеративную разработку и обш ирпое тестирование с участием
фокус-группы, мы создали оригипал-макет (процесс его создапия по-другому пазы вается
пачальпы м визуальпым проектированием ), па которы й сейчас и взгляпем.
Это наш ст арт ап. Сначала мы
все нарисовали на са лф ет ке, сидя
болки в Starbuzz Coffee.
Д изайн
Наше веб-приложение
должно по возмож
ности выглядеть,
как данная с т р а н и
ца! Д р у ги м и словами,
мы х о т и м показывать
дизайн ф утболки и
предоставлять п о л ь
зоват елю возмож
ность интерактивно
изменят ь его с п о
мощ ью элемент ов
управления.
А вот как v
должен вы гля- \
деть интерфейс \
пользователя.
S elect background c o lo r JVK/teJ* ]
дальше ► 317
обзор требований
М 9 * Г 9 * 9 Й _____________________________________________________________________________________________________________________________________________________________________________________
Ш ТУРМ
Взгляните еще раз на требования, приведенные на предыдущей странице. Как вы считаете,
можно ли их выполнить, используя HTML5? А помните, что одно из требований заключает
ся в обеспечении работоспособности вашего сайта на как можно на большем количестве
устройств различного формата и размера?
Ознакомьтесь с приведенными ниже возможностями (а затем выберите наилучший ответ).
Часш°
ЧаДаВаеМые
В опросы
А серьезно, почему бы в данной ситуации не использо Мне нравится идея генерирования изображений на сторо
вать Flash или не прибегнуть к написанию пользовательского не сервера. Таким образом, я смогу написать один блок кода,
приложения? который вместе с генерируемыми изображениями сможет
работать на всех устройствах. Я немного знаю РНР, так что
0 : Flash является замечательной технологией и вы, несомненно, эта задача должна быть мне по плечу.
можете использовать именно ее. Однако в настоящее время инду
стрия движется по направлению к HTML5, и на момент написания
0 : Это еще один путь, по которому вы можете пойти, однако
данной книги у вас могли бы возникнуть проблемы с выполнением
его недостаток заключается в том, что если у вас будет огромное
Flash-приложений на всех устройствах, включая очень популярные.
множество пользователей, вам придется беспокоиться о масштаби
Написание пользовательского приложения является отличным
ровании используемых для генерирования изображений серверов,
выходом, если вам требуется обеспечить для пользователей вза
чтобы они смогли удовлетворить предъявляемые требования
имодействие, полностью заточенное под конкретное устройство.
(в противопоставлении с тем, когда клиент каждого из пользовате
Имейте в виду, что разработка пользовательского приложения для
множества разных устройств — дело затратное. лей сам будет генерировать предварительный просмотр футболки).
Вы также сможете обеспечить более интерактивное и цельное
В случае с HTML5 вы получаете отличную поддержку со стороны
взаимодействие, если предпочтете написать соответствующий
браузеров как для мобильных, так и для настольных устройств
код для браузера.
и зачастую можете создавать приложения, используя всего одно
технологическое решение. Как? Что ж, мы рады, что вы об этом спросили...
318 глава 7
раскрываем в себе художника
LiuV
Вы уже ознакомились с требованиями, а также с базовым проектировани
ем взаимодействия пользователя с приложением. Пришло время перейти
к сложной части — реализации всего этого на практике. Давайте прислуша
емся к разговору и узнаем, как обстоят дела...
Джо: Я думал, что все будет просто, пока пе увидел эти ф оповы е круги.
Фрэнк: Ч то ты хочеш ь этим сказать? Ведь это всего лиш ь изображ епие...
Джудн: Нет, пет, осповательпица TweetShirt хочет, чтобы разм ещ епие кру- Я -ч
гов происходило случайпым образом, благодаря чему располож ение кругов, ^ фрэнк> Л
к примеру, па м оей футболке будут отличаться от располож ения кругов па w А* 0
твоей. То же самое и с квадратами.
Фрэнк: Все пормальпо, поскольку рапы не мы делали это, геперируя изобра
ж епие п а сторопе сервера.
Джо: Да, я зпаю, по такой подход был пе очепь разумпым; помпите, как пам
приходилось платить ком папии Am azon за пользовапие серверами?
Фрэнк: Да. Но это пе беда.
Джо: В лю бом случае, пам пеобходимо, чтобы все работало очепь быстро,
то есть пе было пикаких долгих «рейсов» обратпо па сервер. Поэтому давай
те будем делать все па сторопе клиепта, если это возможпо.
Джудн: Ребята, я думаю, что это возможпо, я тут смотрю па canvas в HTML5.
Фрэнк: Я всего лиш ь дизайпер, поэтому разъяспи мпе, что это такое.
Джудн: Ф рэпк, ты, должпо быть, уже слышал о canvas —это повы й элемепт
в HTM L5, которы й п озволяет создавать поддерживающую рисовапие об
ласть для 2 Б-фигур, текста и растровы х изображ епий.
Фрэнк: Все это похож е па тег <img>. Мы просто помещ аем его в страпицу
с указапием ш ирипы и высоты, а браузер делает все остальпое.
Джудн: Н еплохое сравпепие, мы действительно определяем ш ирину и вы
соту для canvas, одпако в даппом случае все рисуемое в canvas будет зави
сеть от JavaScript-кода.
Джо: А где здесь в дело вступает разметка? М ожпо ли сказать canvas
па JavaScript: «Даппый элемепт <hl> пеобходимо разм естить вот здесь».
Джудн: Нет, после того как ты помещ аеш ь canvas в страпицу, ты оставляеш ь
мир разм етки позади; па JavaScript мы размещ аем точки, липии, коптуры,
и зображ епия и текст. Это пизкоуровпевы й API-иптерфейс.
Джо: Ч то ж, если оп сможет справиться со всеми этим и размещ аемы ми слу
чайпы м образом кругами, то оп мепя устраивает. Ладпо, хватит разговоров,
давайте взгляпем па пего!
дальше ► 319
добавление canvas к странице
v. I I
Мь/ добавили id для иден Здесь для w idth
Закрывающий тег
тификации canvasj а как мы задали значе
его использовать, вы ние (оОО пикселов.
увидите чут ь позже...
320 глава 7
раскрываем в себе художника
< ! d o c ty p e h tm l>
< h tm l la n g = " e n " >
<head> Напечатайте данный код
< t i t l e > L o o k W hat I D r e w < / t i t l e > и п р о т е с т и р у й т е его.
< m eta c h a r s e t = " u t f - 8 ">
< /h e a d >
<body>
< ca n va s id = " lo o k w h a t I d r e w " w id t h = " 6 0 0 " h e i g h t = " 2 0 0 " > < /c a n v a s >
< /b o d y >
< / h tm l>
...вероятно, то же са
мое увидите и вы!
Мы нарисовали эти
линии, чтобы объяс
нить, как именно canvas
вставляется в с т р а н и
цу, и сделали это лишь
в целях иллюстрирования.
На самом деле их т а м не
будет (если только вы их
\л
сами не нарисуете).
Переверните страницу,
чтобы узн ат ь больше...
дальше ► 321
добавление css для canvas
322 глава 7
раскрываем в себе художника
Часш°
^адаВ аеМ ы е
В опросы
На каждую страницу может приходиться только один Можно ли использовать CSS для задания ширины и высо
canvas? ты canvas вместо атрибутов width и height в случае с данным
элементом?
Ш ТУРМ
Возможно, вы обратили внимание на то, что наш элемент canvas
не включал никакого содержимого. Если поместить текст между тега
ми, то что, по вашему мнению, будет делать браузер, когда страница
загрузится?
° #) < / canvas> I
дальше ► 323
рисование в canvas
324 глава 7
раскрываем в себе художника
В паш ей разм етке мы определили canvas и присвоили ему идентиф икатор, используя
тег <canvas>. П ервое, что пам пеобходимо сделать, чтобы пачать рисовать в даппом
canvas, —это извлечь ссылку п а объект canvas в объектпой модели докумепта (DOM).
Как обычпо, мы делаем это с помощью метода getElementByld:
дальше ► 325
обзор работы кода canvas
j
context.fillRect(10, 10, 100, 100);
Ш ТУРМ
Можете ли вы придумать способ использовать элемент canvas,
если ваш браузер поддерживает его, а при отсутствии поддерж
ки просто выводить сообщение, например: Hey, you, yes
you, upgrade your browser! ! (Эй, вы, да, вы, обно
вите свой браузер! !)?
326 глава 7
4acm< раскрываем в себе художника
^аД аВ аеМ ы е
BoTLj=>otbl
I ) ; Откуда c a n va s знает, что к прямоугольнику
Ж Л Т1ля- любознательных ---------------
следует применять именно черную заливку?
А если мне потребуется нарисовать контур Это, конечно же, можно сделать, однако отметим, что все
прямоугольника, а не фигуру с заливкой? это время предполагалось, что наш браузер поддерживает
canvas. Но в любом производственном коде вам будет необ
0 : Чтобы нарисовать только контур прямоуголь ходимо позаботиться о проведении проверки, чтобы убедиться
ника, вместо f i l l R e c t следует воспользоваться в наличии такой поддержки.
функцией s tr o k e R e c t . Подробнее об обводке
Все, что вам потребуется сделать, — это проверить, при
мы поговорим позже в этой главе.
су тс тв у е т ли метод getContext в с о о тв е т с тв у ю
щем объекте canvas (который возвращается методом
Что такое контекст 2d и почему нельзя рисо
getElementByld):
вать сразу в canvas?
Сначала мы извлекаем ссылку
I canvas представляет собой графическую об на элем ент canvas в ст ранице.
0
ласть, отображаемую на веб-странице, c o n te x t — v a r canvas = ^
это объект, ассоциированный с c a n va s, который d o c u m e n t .g e t E l e m e n t B y l d ("tshirtCanvas") ;
определяет набор свойств и методов, используемых if (canvas.getContext) {
для рисования в can va s. Вы можете даже сохра // под д е р ж к а canvas имеется
нять состояние c o n te x t, а затем восстанавливать } else {
его позже, что иногда бывает кстати. В оставшейся // и з в и н и т е , A P I -интерфейс canvas
части этой главы вы познакомитесь с множеством не поддер ж и в а е т с я
свойств и методов объекта c o n te x t. }
Элемент canvas создавался с расчетом на поддерж З а т е м проверяем п р и сут ст вие метода
ку более одного интерфейса — 2d, 3d и пр., о ко getContext. О б р ат и т е внимание: мы не вызываем
торых мы даже еще не задумывались. Используя егоj а просто см о т р и м , есть ли у него значение.
c o n te x t , можно работать с разными интерфей
сами в пределах одного элемента canvas. Нельзя
рисовать сразу в can va s, поскольку необходимо Если вы захотите проводить проверку на предмет поддержки
будет указать, какой интерфейс вы используете, canvas без необходимости заранее иметь canvas в своей
выбрав c o n t e x t . разметке, то можете создавать элемент c a n v a s «на лету»,
используя все методики, которые вам уже известны. Например:
Означает ли это, что существует также кон var canvas =
текст 3d?
d o c u m e n t .c r e a t e E l e m e n t ("canvas") ;
Q : Пока еще нет. Существует ряд конкурирую He забудьте заглянуть в приложение (в конце книги), где име
щих перспективных стандартов, но не похоже, что ется информация о библиотеке с открытым исходным кодом,
какому-либо из них уже удалось стать лидером. которую вы сможете использовать для проведения последова
Не упускайте из виду данный момент; между тем тельного тестирования на предмет поддержки всевозможной
взгляните на библиотеку WebGL, а также на библи функциональности в HTML5.
отеки, которые ее используют, например SpiderGL,
SceneJS и three.js.
дальше ► 327
canvas и internet explorer
328 глава 7
раскрываем в себе художника
Как вы уже зпаете, другой способ выхода из ситуации, когда браузеры пе поддерж ива
ю т canvas, заклю чается в использовапии JavaScript с целью вы яспепия того, зпаком ли
браузеру даппы й элемепт. Такой подход обеспечивает пемпого большую гибкость в обе
спечении для пользователей ипого взаимодействия в случае, если их браузеры пе будут
поддерж ивать canvas; паприм ер, вы сможете перенаправить их па другую страпицу или
взамеп вы вести па экрап какое-то изображ епие.
дальше ► 329
обзор плана реализации
330 глава 7
раскрываем в себе художника
JS
Это canvas
чдля дизайна
4г
фмтболки.
Peek, a tw e e t:
Щелчок на кнопке Preview
интерф ейс п о л ь -^
(Предварительный п р о
зователя, который
см от р) будет вызывать
n 0 cyvnu явл яется
JavaScript для выполне
э л е м е н т о м form.
ния со от вет ст вую щ их
действий и генерирования
предварительного п р о
В определенный м о м е н т нам пот ребует ся под
см от ра футболки.
держка со стороны сервера для торговли ф у т б о л
ками через И н т ер не т , но мы реш или ост авит ь
э т у часть работы вам (ее придется выполнить,
когда вы будете организовывать собственный
ст артап). Не забудьте присла т ь нам бесплатную
футболку. А если вы, как основатели ст а р т а п а ,
возьмете нас в долю, то это будет еще лучиле!
дальше ► 331
СТАНЬ браузером
332 глава 7
раскрываем в себе художника
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " b a c k g r o u n d C o lo r " ) ;
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r b g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ;
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " s h a p e " ) ;
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r shape = s e l e c t O b j [ i n d e x ] . v a l u e ;
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " f o r e g r o u n d C o lo r " ) ;
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r f g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ;
дальше ► 333
написание html
<head> О б ра т ит е внимание,
что мы изменили з а
<title>TweetS h i r t < / t i t l e >
головок на T weetshirt.
<meta c h a r s e t = " u t f - 8 " />
<style>
WTVPM
Что еще вам необходимо знать для того, чтобы заменить CSS-рамку в сво
ем canvas рамкой, нарисованной в canvas с помощью JavaScript? Какую
методику вы предпочли бы (CSS или JavaScript) и почему?
334 глава 7
раскрываем в себе художника
< s e le c t i d - tw e e ts " > ) ^ ^ B o m где будут размещ ат ься все твиты. А почему здесь пусто?
< / s e le c t > А х да, мы же будем заполнят ь данный элем ент позже (подсказка:
</ р > нам необходимо, чтобы т вит ы извлекались непосредственно из
<р> Т ви т т ер а , ведь это же веб-приложение, не т ак ли?!).
< in p u t t y p e = " b u t t o n " id = " p r e v ie w B u t t o n " v a lu e = " P r e v ie w " >
< /fo r m > &CAU @ам доводилось ст алкиват ься с элем ент ам и g конце добавляем кнопку
fo r m , то вы, вероятно, обратили внимание, что дАЯ предварительного п р о -
здесь form не им еет ат ри б ут а action (а это озна- см от ра футболки,
ч ает , что при щелчке на кнопке Preview (Предвари
тельный просм от р) ничего не произойдет). Со всем
э т и м мы разберемся через несколько мгновений...
дальше ► 335
добавление javascript
Таким образом, когда кпопка Preview (П редварительны й просм отр) будет пажата, п роизой дет вызов
фупкции previewHandler. И здесь самое врем я обповить canvas с целью представить футболку, пад ди-
зайпом которой трудится пользователь. Приступим к паписапию p r e v i e w H a n d l e r :
Сначала извлекаем элем ент
function prev i e w H a n d l e r () { ^ запрашиваем его
c a n v a s
и
336 глава 7
раскрываем в себе художника
Часш°
^адаВ аеМ ы е
В о Ц р о С ьх
• Как именно работает selected Index?
0 : Свойство selectedlndex элемента управления формы начинается с 0). Вероятно, вам потребуется не только индекс,
select возвращает номер параметра, выбранного пользовате но и значение параметра с этим индексом (в нашем случае —
лем в раскрывающемся списке. Каждый список параметров преоб "doughnut"). Чтобы извлечь данное значение, сначала нужно
разуется в массив, при этом все объекты в массиве располагаются воспользоваться индексом для извлечения элемента массива; в
по порядку. Допустим, у вас имеется список выбора, включающий результате обратно вы получите объект параметра. Чтобы из
следующие варианты: "pizza", "doughnut" и "granola влечь значение этого объекта, необходимо прибегнуть к свойству
bar". Если вы выберете «doughnut», то selectedlndex value, которое возвращает строку в атрибуте value параметра.
вернет 1 (не забывайте, что нумерация в JavaScript-MaccnBe
развлечения с магнитами
Воспользуйтесь своими псевдомагическими способностями программиста для размещения в нуж
ной последовательности приведенных ниже табличек. Вам нужно написать псевдокод для функции
drawSquare. Данная функция принимает canvas и context и рисует в canvas один квадрат про
извольного размера. Проверьте свои ответы в конце главы, прежде чем двинетесь дальше.
Расположите здесь
таблички с псевдоко
дом в нужной после
довательности!
в ы ч ислить п р о и з в о л ь н у ю п о з и ц и ю У
для к в а д р а т а в н у т р и canvas задать для fillstyle значение " l i g h t b lU ie j
в ы ч ислить п р о и з в о л ь н у ю по з и ц и ю X
для к в а д р а т а в н у т р и c a n v a s
дальше ► 337
реализация квадратов
Ширина canvas
Ширина и высота
л
Координаты X и у квадрата (не забы
предназначены для вайте, что в с л у В ы со ка
левого верхнего чае с квадратом canvas
угла квадрата. эти значения будут
одинаковыми).
J
338 глава 7
раскрываем в себе художника
Qiwctcliwt * V-
С # I S>lo cs.lho s«/~ B *th,H e ad.Fir*t.W T V L... jJ ☆ | B j И -$г Л
Г^
Он прав, у нас воз
никла небольшая
проблема. Щ елкнит е Scloct background co lo r f w »№н»|
на кнопке Preview
Circles or squares? j i: j
(Предварительный
Sclotl LCXt colon ' BLfclc
просм от р) несколько
раз подряд — и вы Fick a tweet; [ Щ
увидите нечто п о
добное.
дальше ► 339
корректировка кода для квадратов
fu n c t io n f illB a c k g r o u n d C o lo r ( c a n v a s , c o n t e x t ) {
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " ____
Подсказка: т о, ч т о вы no
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ; черпнете из выбранного
параметра, будет строкой
v a r b g C o lo r = s e l e c t O b j . o p t i o n s [ i n d e x ] . v a l u e ;
со значением цвета, кот орую
вы сможете использовать
c o n te x t. f i l l S t y l e = _________________ ;
т о чно т а к же, как "И д Ш и е
c o n t e x t . f i l i R e c t (0 , 0 , _______________ , ________ для заливки квадратов.
, Подсказка: мы х о т и м за ли т ь ВЕСЬ
canvas соо т вет ст в ую щ и м ц в е т о м .1
340 глава 7
раскрываем в себе художника
f u n c t i o n p r e v ie w H a n d le r () {
v a r c a n va s = d o c u m e n t. g e tE le m e n tB y ld ( " t s h i r t C a n v a s '
v a r c o n te x t = c a n v a s . g e tC o n te x t( " 2 d " ) ; Добавляем вызов fillBackgroundColor
fillBackgroundColor(canvas, context); до создания квадратов, поэт ом у
то, что было нарисовано ранее,
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " s h a p e " ) ; окажется скры ты м под слоем з а
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ; ливки, и мы получим чистый фон
v a r shape = s e l e c t O b j [ i n d e x ] . v a l u e ; для рисования новых квадратов.
дальше ► 341
обзор свойства fill style
J a V a ^c iij4 —с в о й с т в о у в е л и ч и те л ь н ы м о п е к л °м
л > Б олее приетальпо взгляпем па свойство fillStyle, поскольку вы впервы е с пим столкпу-
лись. О по является свойством context, которое содерж ит определеппое зпачепие цвета
для того, что вы рисуете в canvas. л
£ 3йЭйем мы значение цвета.
ы сможете использовать т е же ф о р
Но в отличие от filiRect, fillStyle
К ак и fi'HRect^ м а т ы цвет ов, что и в CS5. У вас будет
является свойством, а не м е
с б о й с т б о л л f illS ty le
тодом. Поэтому мы задаем для как иТ ЛЬ30вать ™ ена,
мы управляем п о - hghtblue, либо значения вроде #ccccff
него значение , а не вызываем его. или п
средством c o n t e xt . •gb(o 173, 231). Попробуйте!
J.
^ c o n te x t.f illS t y le = " lig h tb lu e " ;
t
О б ра т ит е внимание, ч т о , в о т
личие о т CSS >значение необходи
мо заклю чат ь в кавычки , если вы
не используете переменную.
Часш°
^адаВ аеМ ы е
В сЩ роСъх
Я ожидал, что мы будем задавать Почему значение цвета следует за Ладно, я сдаюсь. Почему мы иногда
f t
цвет фона квадратов и canvas путем ключать в кавычки, в то время как в CSS наблюдаем менее 20 квадратов?
передачи значения цвета методу filiRect. со значениями свойств так поступать не
Я не могу понять, как работает свойство нужно? 0:
\J * Позиция х, у и ширина квадратов яв-
ляются произвольными. Одни квадраты
fillStyle. Как оно влияет на то, что делает
filiRect?
все немного по-другому, чем вы привыкли значение цвета в кавычки, то JavaScript ре- из-за чего вы сможете увидеть только один
думать. Как вы помните, c o n t e x t пред шит, что имя этого цвета является перемен- его пиксел (поскольку остальная часть этого
ставляет собой объект, управляющий до ной, а не строкой, и попытается использовать квадрата будет лежать вне canvas). Одни
ступом к canvas. Используя fillStyle значение переменной вместо имени цвета, квадраты могут иметь ширину 1 пиксел,
и filiRect, вы сначала задаете свойство, Допустим, у вас имеется переменная а другие - даже 0 пикселов, так как метод
которое говорит элементу canvas следую fgColor = " b l a c k ”. Вы могли бы напи- M ath, r a n d o m может возвращать значе-
щее: «Все, что будет нарисовано в сать context.fillStyle = fgColor, ние 0. Либо вы можете сгенерировать два
тебе далее, должно иметь данный и это сработало бы, поскольку значением квадрата с абсолютно одинаковыми раз-
цвет». Таким образом, все, к чему вы ста f gcolor является “b l a c k ”. меРами и местоположением.
нете применять заливку цветом (например, Однако в случае с нашим приложением все
Однако c o n t e x t .fillStyle = black
с помощью filiRect) после задания свой ” это является произвольным, поэтому мы и
не сработает, так как black не является пе-
ства fillStyle, будет иметь данный цвет, считаем, что все в порядке. А в ином случае
ременной (если только вы не определите его
пока вы снова не измените цвет, присвоив нам, возможно, пришлось бы позаботиться
как переменную, что может внести неболь
fillStyle другое значение цвета. о том, чтобы такого не случалось.
шую путаницу). Вы узнаете, что допустили
эту ошибку, поскольку будет сгенерирована
JavaScript-ошибка и выведено сообщение
вроде Can't find variable: black
(He могу найти переменную: black)
(но не стоит беспокоиться, так как все мы
хотя бы раз допускали эту ошибку).
342 глава 7
раскрываем в себе художника
дальше ► 343
знакомство с контурами и дугами
344 глава 7
раскрываем в себе художника
Черчение контуров
П реж де чем п ерей ти к кругам, пеобходимо п оговорить о коп-
турах и дугах. Д авайте пачпем с коптуров и парисуем пе
сколысо треугольпиков. Если вам потребуется парисовать
треугольпик в c a n v a s , то зпайте, что метода f i l l T r i a n g l e пе
существует. Одпако треугольпик все же можпо парисовать,
спачала пачертив его контур, которы й затем нужпо будет обве
сти, чтобы парисовать треугольпик в c a n v a s .
Ч то все это озпачает? Донустим, вы хотите очепь аккуратпо
парисовать что-то па холсте, для чего мож ете взять карапдаш
и пабросать едва зам етпы е очертап и я нужпой вам фигуры
(будем пазы вать их коптуром). Вы п ачертите их так легопько,
что едва сможете разглядеть эти липии. Затем, когда коптур
вас устроит, вы возьмете ручку (с толщ ипой стерж пя и цветом
ч ерп ил по своему выбору) и обведете коптур, чтобы все смог
ли увидеть ваш треугольпик (или любую другую фигуру, кото
рую вы пачерти ли карапдаш ом).
И меппо так осущ ествляется рисовапие произвольны х фигур
с помощью л ип и й в элемепте c a n v a s . Д авайте н а р и с у е м тр е
угольпик и посмотрим, как это работает. \Сарандаш, с
которого Mbi ЬудеМ
Используем метод begmPatW, ч е р т м то к о н т у р -
чтобы сказать canvas о т о м , что
£ начинаем чертить новый контур.
c o n t e x t . b e g in P a t h ( ) ;
c o n te x t.m o v e T o (1 0 0 , 150
Здесь мы о п у
/ скаем кончик
Используем метод moveTo карандаша в
для перемещения «карандаша т о ч к у с к оорди-
в определенную точку в canvas. на1ЛЛами X = Ю О
М о ж е т е счит ат ь, что мы и у = 150. Это
как бы опускаем кончик каран- 5 у Э е т первая
даила в данную точку. точка контура
Кончик
J
карандаша находился в точке с ко ^
ки с координатами
X = 2SO, у = 15.
ординатами х = Ю О и у = IS O , от которой
мы чертим конт ур , двигая инст румент
к т о ч к е с координатами х = 2-50, у - 7 5.
дальше ► 345
как рисовать с помощью контуров
У Начертите вт орую
c o n t e x t . l in e T o (1 2 5 , 30) л и н и ю j двигая к а
рандаш от преды
Ч ерт им линию от т екущ ей позиции дущей точки к н о
кончика карандаша ( z s o , 7 s), двигая его вой с координатами
к новой точке с координатами х = i Z s К = 125, у = за
У ~ 30. 8 р е зу л ь т а т е у нас получит ся
вторая сторона треугольника.
c o n te x t.b e g in P a th ( ) ;
c o n te x t.m o v e T o (1 0 0 , 1 5 0 ); Вот код, приводившийся ранее.
c o n t e x t . l i n e T o (2 5 0 , 7 5 );
c o n t e x t . l i n e T o (125 , 3 0 ) ;
c o n t e x t . c lo s e P a t h ( ) ;
c o n t e x t . l in e W id t h = 5 ;
c o n t e x t . s t r o k e () ;
c o n te x t. f i l l S t y l e = "re d ";
c o n t e x t . f i l l () ;
А здесь приведен новый код. О п и ш и т е , что делает каждая
из этик ст р ок . Загрузит е страницу. Ваши ответы оказа-
лись правильными? Решение упражнения - в конце главы.
346 глава 7
раскрываем в себе художника
c o n te x t.b e g in P a th ();
дальше ► 347
взгляд на метод arc
Суть метода a rc заклю чается в том, что оп позволяет определять, как будет
ч ерти ться требуемый коптур вдоль окружпости. П осмотрим , как имеппо каж
ды й из его парам етров содействует этому.
c o n te x t. a r c (х , у , r a d iu s ,
348 глава 7
раскрываем в себе художника
false
s ta r tA n g le , e n d A n g le , d ir e c tio n )
Ниже приведен важный момент!
startAngle, Если зпачепием d irection Н е п р о п у скай те это. Углы могут изм еряться в от-
endAngle является true, дуга будет рицательпы х величипах (в паправлепии против
черти ться п ротив часовой часовой стрелки от оси X) либо в полож итель-
стрелки, ас* если j_*
false — пы х величипах (по часовой стрелке от оси X).
Конечная точка по часовой стрелке Это пе то же самое, что парам етр direction в
нашей дуги — случае с дугой! (Вы убедитесь в этом па следую
щ ей страпице.)
Д у га , к о - Угол, от меряем ый в направлении
т о р у ю мы Ось X прот ив часовой ст релки от оси X,
это
х о т и м на Начальный угол будет и м ет ь о т рицат ельную
чер т и т ь между осью Х и н а - величину (н а при м ер, -35°).
угол
чальнои мочкой дуги
Конечный угол -
это угол между Начальная точка
осью X и конечной нашей дуги
точкой дуги.
дальше ► 349
практикуемся в использовании метода arc
цеп тр которого им еет позицию х = 1 0 0 , у = 1 0 0 . П ри этом вам нужпо, чтобы ш ирипа круга
была 150 пикселов (то есть оп имел радиус 75 пикселов). А дуга, которую вы хотите пачертить,
будет составлять лиш ь 1 / 4 круга.
Ч ерт им дугу в направлении
прот ив часовой с т р ел к и .
Центр: х = Ю О ,
Начальный угол равен <9 °, а конеч-
у = гоо
Г ный составляет 270°.
К V— Следует о т м е т и т ь ,
что мы от м ер яем конеч
ный угол в направлении
по часовой стрелке от
Н я м -н я м j радиус равен оси ™ э^ о м у величина
яблочный пирог! 7 5 пикселам. конечного угла будет п о -
ложительной.
А что с паш ими пачальпы м и копечпы м углами? Н ачальпы й угол будет равеп
0° отпосительпо оси X. К опечпы й угол —это угол между осью X и копечпой
точкой паш ей дуги. Поскольку паша дуга является 90-градуспой, копечпы й К э т о й функции
угол будет равеп 270° (90° + 270° = 360°) (если бы мы изм еряли его в отрица- мы вернемся
тельпы х величипах, то есть в паправлепии против часовой стрелки, то ко- через несколько
п ечпы й угол был бы в итоге равеп -90°). ----------------------- мгновений. Она
просто преоб-
context, arc (100, 100, 75, 0, degree sToRadians (270) , ____ ) ; р азует градусы
тт ^ » (которые нам
О
Н акопец, поскольку дуга будет черти ться в паправлепии против часовой л ^ ^
стрелки, указываем зпачепие true. пРи Ра
дианы (которые
предпочит ает
context.arc (100 , 100, 75, 0, degr ее sToRadians (270) , true); context).
350 глава 7
раскрываем в себе художника
Классный разворот
Я говорю «градус», вы говорите «радиан» на 360 градусов! То есть
я хотел сказать, классный
Все мы каждый депь говорим об углах, связаппы х с
разворот на 2п радиан!
кругами: «Класспый разворот па 360 градусов», или
«Я паправился по этому нути и развернулся па целых
180 градусов», или... ну, в общем, вы попяли. Одпако
проблем а заклю чается в том, что мы думаем в граду
сах, a c o n t e x t в случае с c a n va s —в радиапах. у __ Радиан -
еще одна единица и з м е
Сейчас мы могли бы сказать вам, что: рения углов. Один радиан
360 г р а д у с о в = 2 P i р а д и а н равен 120/Ъ,14-15Ч2<Ь5...
( то есть числу IS O , р а з
и после этого вы были бы готовы посчитать в уме
деленному на п).
градусы в радиапах в случае необходимости. Если по
какой-то причи пе вы пе захотели бы делать это в уме,
то зпайте, что существует удобпая фупкция, которая И с п о л ь з у й ^ э т у функцию
вы полпит дапную работу за вас: когда захот ит е дум ат ь
f u n c t i o n d e g re e s T o R a d ia n s (d e g re e s ) { в градусах, но будете о п е
рировать радианами при
re tu rn (d e g re e s * M a th . P I ) / 1 8 0;
рисовании дуги.
^ 1
Как пом н ит е, с этой ф у н к -
t Чтобы перевести
На с. 3 4 7 вы видели, как мы и сп о л ь
цией м ы м и м о л е т о м с т а л - г р а д у сы в р а д и а н ы ,
зовали 2 * Matk.PI для определения
кивались в гла ве, посвящ енной нуж но у м н о ж и т ь
конечного угла дуги на круге. Бы могли
A P I - и н т е р ф е й с у G eolocation. их на п и р а з д е л и т ь
бы п о с т у п и т ь т ак же... либо прост о
на 1 2 0 .
использовать degreesToRadians(3(,0).
(ТА Н Ь браум ром ---------------
I I н т е ] ^ р е т и р у й т е п о в е д е н н ы й н и ж е в ы зо в м е т о д а аГс и н а п и ш и т е все
со ощ В ещ ещ ^^Щ и е значения, к о т о р ы е б у д у т х а р а т с т е ^ ^ о В а т ь круг,
а т а к ж е и з о б р а з и т е ДУ^)» со зд а в а ем у ю в р е з у л ь т а т а э т ° Г о ВыЗоВа.
дальше ► 351
/ еэеи г ZSZ
ojOHLfou
bHHeaoond but/ я±еаоея1_гоиэи eietfAg н а н ш Л шяньэном и шяняиеьен иоме>]
W d M fD
‘S ? J V Y ) b S M V J l'p Y)dY\V)
H6&6J16VN
-у н б ф v gvbfivv д owie
Y)VVV9Q сэ ж >iVW I
YlYlh>iH(ncf? 1 X 9 1 V I 0 V Y)
s v a v iv v W d v g z d d jj
{
.' (q.xsq.uoo ;spaupo) эхоттэм^тр
онжВн д а в и CHfidov*
(+ + sax o iio .'OS > s s p i i o .'0 = 2 0 x 0 1 1 0 лгл) joj
-m ) nrihylHFi(r } („ se p iT O y == scteqs) j t ss x s {
(oHPVnowovI 0 go?fid>t Ot w ? {
\evndvH k»w ' ( i w v d e m 0 .' (q.xsq.uoo ;spaupo) si^nbsM^ip
sw nbs ™ v 4 " * ^ (++saienbs .'os > saienbs .'0 = saienbs л г л ) joj
vvdpwg « v w » 9° w ° ' A"У*
■<:,cwvdevg* v)VY) Yi?fidyI) } („ sei^ n b su == scteqs) j t
ssijvnbs ло s« jw p 9
} () згэ-[рит?да-этлэz d uopounj
эогЛсй/ эпнэиэедод
раскрываем в себе художника
дальше ► 353
b iB
П е г е г
354 глава 7
раскрываем в себе художника
= гоо> Я.so
радиус - 2-5 *> У = 4 0 0 , 2SO
Справа изображено улыбающееся лицо (или печенье с кусочками шоко
лада в форме улыбающегося лица, если вам так больше нравится). При
веденный внизу код для рисования улыбающегося лица почти завершен;
нам нужна ваша помощь, чтобы устранить имеющиеся в нем пробелы.
После работы, проделанной в этой главе, у вас есть все необходимое для длийа
того, чтобы справиться с данной задачей. Закончив, вы сможете сверить носа = SO]
свои ответы с решением этого упражнения в конце главы.
угол)- 2.0°
у = з о о , 3SO
радиус = 7 5
f u n c t i o n d ra w S m ile y F a c e () {
v a r ca n va s = d o c u m e n t. g e tE le m e n tB y ld ( " s m i l e y " ) Bom что нам требуемся. По ходу дела
v a r c o n te x t = c a n v a s . g e tC o n te x t( " 2 d " ) ; у вас может возникнуть желание испечь
настоящее печенье с кусочками ш окола
да в ф орме улыбающейся рожицы...
c o n t e x t . b e g i n P a t h () ;
c o n t e x t . a r c (3 0 0 , 300, 200, 0, d e g re e s T o R a d ia n s (3 6 0 ) , tru e К руг лица. Здесь мы
c o n te x t. f i l l S t y l e = " # ffffc c ";
уже уст ранили за
вас один из пробелов.
c o n t e x t . f ill();
О б рат ит е enuManuej
c o n t e x t . s t r o k e () ; что мы применили
к кругу заливку жел
c o n t e x t . b e g i n P a t h () ;
т ы м цветом.
c o n t e x t . a r c (_____, 25, tr u e ) Левый глаз
c o n t e x t . s t r o k e () ;
c o n t e x t . b e g i n P a t h () ;
c o n t e x t . a r c ( 4 0 0 , _____, Правый глаз
c o n te x t. s tr o k e () ;
c o n t e x t . b e g i n P a t h () ;
c o n t e x t . _________(____ , Нос
c o n t e x t . _________(____ ,
c o n t e x t . __________ () ;
Рот. Самый мудреный
аспект!
c o n t e x t . b e g i n P a t h () ;
c o n te x t. (3 0 0 , 350, _, d e g re e s T o R a d ia n s (_ ) , d e g re e s T o R a d ia n s (_
c o n t e x t . s t r o k e () ;
дальше ► 355
добавление jsonp для твиттера
flo6aBHTb<script>BHH)KHK)K)4acTb4>aimatweetshirt.
html для вызова API-интерфейса JSONP Twitter. Мы бу
дем запрашивать самые последние статусные обновле
ния определенного пользователя.
< /s c r ip t>
356 глава 7
раскрываем в себе художника
извлечение твитов
Мы уже п о к о п ч и л и со слож пой работой, заключавш ейся в извлече
нии твитов из Твиттера. Теперь пеобходимо добавить их в элем епт
<select>, используемый для вы бора твитов, в элемепте <f orm> па
ш ей страпицы. Еще раз повторим: когда происходит вызов фупк Ответ Твиттера пред
ции обратпого вы зова (в паш ем случае — update Tweets), Твиттер ставляет содой массив
передает ей ответ, содерж ащ ий твиты в ф орм ате JSON. твитов. Каждый твит
включает в себя массу
О тредактируйте файл tweetshirt.j s и добавьте фупкцию
данных; мы будем использо
update Tweets в его пижпюю часть:
вать текст т вит а.
function updateTweets(tweets) {
var tweetsSelection = document.getElementByld("tweets'
8 случае с каждым т вит ом в массиве
твитов мы сделаем следующее.
for (var i = 0; i < t weets.length; i++) {
— ■* Извлекаем твит из массива.
tweet = tweets[i]; ^
var option = document.createElement("option’ ) ; ^ — Создаем новый элемент option.
option.text = tweet.text; < ------------- Задаем
для его te x t
option.value = t w eet.t e x t .replace ("\"", "'") значение tweet.
дальше ► 357
тестирование tweetshirt с твиттером
TwectShlrt
Tecm-драйб TweetShirt L t j ^ r o ■'■»:ca Kxo-Bcn/HTHLS^c-jhin^indcxJhD С ] (QlS£*4£_J_ _ g;^
Планшетный к о м п ь ю
т ер Фрэнка
358 глава 7
раскрываем в себе художника
Джпм: Помпиш ь метод arc? С его помощью пам и придется рисовать весь текст.
Фрэпк: Ты что, шутишь? Похоже, теп ерь мы провозим ся весь уикепд.
Джпм: Как я тебя подловил! Если серьезпо, то существует метод fillText, которы й п рипим ает текст
для рисовапия в canvas паряду с п озиц и ей х, у, где оп будет рисоваться.
Джо: Звучит довольпо просто. А как пасчет разли чи й в стиле? Н асколько я помпю оригипал-макет,
ш ри ф т текста твита в пем был курсивпый, а остальпого текста —полужирпый.
Джпм: Н ам нужпо еще пемпого покопаться, поскольку существуют разпообразпы е методы для за-
дапия вы равпивапия, ш риф тов и стилей, по я пе очепь хорош о зпаю, как их использовать.
Фрэпк: Если подумать, то я, возможпо, мог бы помочь, по как это сделать без CSS?
Джпм: П рости, по как сказал Джо, это API-иптерф ейс для рисовапия в canvas, и оп пе использует
HTM L или CSS.
Джо: Тогда давайте остаповимся па даппом API-иптерфейсе, после чего можем попробовать па-
рисовать текст «Я повелся па этот твит...» в canvas. Фрэпк, присоединяйся к пам, все пе так уж и
плохо, и я увереп, что пам пригодятся твои зпапия в области ш риф тов, стилей и тому подобпого.
Фрэнк: К онечно, я к вашим услугам!
Ч Я -------------------------------------------
повелся на этот твит...
Тбит алы будем рисо А за т е м мы нари су
‘ ват* зЫсъ, посередине. ем «...а в р е зу л ь т а т е
получил э т у паршивую
м айку!» справа внизу,
под т е кс т о м твита.
...ав результате получил эту паршивую майку!
Мы извлечем выбранное
Select background color. (wbtej
значение цвета переднего
Circles o r Squares? fg'Vdes] t ) плана для использования его
в качестве цвета текста.
Select text c o lo r
дальш е ► 359
обсуждение структуры и представления
360 глава 7
раскрываем в себе художника
развлечения с магнитами
Пришло время вашего первого эксперимента с текстом в ca n v a s . Ниже приведен начатый нами код для
метода d ra w T e x t, который мы будем вызывать, чтобы нарисовать весь текст в c a n v a s для предвари
тельного просмотра. Посмотрите, сможете ли вы завершить данный код, чтобы нарисовать Я п о в е л ся
на э т о т т в и т . . . и . . . а в р е з у л ь т а т е п о л учи л э т у паршивую м а й к у ! в c a n v a s , а рисование
реального твита пользователя мы оставим на потом. Проверьте свои ответы в конце главы, прежде чем
идти дальше.
f u n c t i o n d r a w T e x t( c a n v a s , c o n t e x t ) {
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r f g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ;
c o n t e x t . _________________= f g C o lo r ;
J Q
canvas.height-40
дальше ► 361
более пристальный взгляд на текст в canvas
textj^ign
Свойство t e x t A i i g n определяет, где будет находиться
якорная точка для текста. Значением по умолчанию явля
ется " s t a r t " .
c o n te x t. t e x t A iig n = " le f t" ;
filfjext u s1joW]ext
Текст с заливкой
Как и в случае с прямоугольниками, мы можем обводить
текст и прим енять к нему заливку. Мы указываем текст
для рисования, позицию х, у и опциональны й парам етр
Dog1 ^
m a x wi d t h , что обеспечит масш табирование текста, если
он окажется ш ире, чем значение ma xw i d t h. m
362 глава 7
раскрываем в себе художника
follt
П ри задании значений для свойства fo n t вы мож ете прим енять тот же
формат, что и в CSS, - это удобно. Если вы будете задавать все значения
для данного свойства, то среди них будут следующие: стиль ш риф та, его
толщ ина, разм ер, семейство —именно в таком порядке.
c o n t e x t . f o n t = "2em L u c id a G ra n d e ";
textj}as e W
c o n t e x t . s t r o k e () A lp h a b e t ^ m iddle
c o n t e x t . t e x t B a s e li n e = " m id d le " ; ' -
c o n t e x t .f illT e x t ( " A lp h a b e t" , 100, 100); Alphabet ^ top
Возможные значения данного свойства: " t o p " , " h a n g in g " , " m i d d le " , " a l p h a b e t i c " ,
" id e o g r a p h ic " и " b o tto m " . Значением по умолчанию является " a lp h a b e t ic " . П о
экспериментируйте с разны ми значениями, чтобы выяснить, какое именно из
них вам требуется (а также загляните в специф икацию для получения дополни
тельных сведений).
оальше ► 363
рисование текста
Применение drawText
Теперь, когда вы узпали еще об одпом API-иптерф ейсе, паберите код, пад которы м вы работали в п р е
дыдущем упраж пепии «Развлечепия с магпитами». Вот как оп будет выглядеть после того, как таблички
с кодом окажутся па своих местах:
fu n c t io n d r a w T e x t( c a n v a s , c o n t e x t ) {
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " f o r e g r o u n d C o lo r " ) ;
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r f g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ;
c o n te x t. f i l l S t y l e = f g C o lo r ;
c o n t e x t . f o n t = " b o ld le m s a n s - s e r i f " ;
c o n te x t. t e x t A lig n = " le f t" ;
c o n t e x t . f i l l T e x t ( "Я п о в е л с я на э т о т т в и т " , 20, 40)
c o n t e x t . f o n t = " b o ld le m s a n s - s e r i f " ;
c o n te x t. t e x t A lig n = " r ig h t" ;
c o n t e x t . f i l l T e x t ( "а в р е з у л ь т а т е п о л у чи л э т у паршивую м а й ку !
c a n v a s .w id t h - 2 0 , c a n v a s . h e i g h t - 4 0 ) ;
}
364 глава 7
раскрываем в себе художника
дальше ► 365
запуск tweetshirt
Надеемся, что вы видите то же самое, На футболке Если вы поклонник Твиттера, носите футболки Tweetshirt
г Да!
Все работает!
Мы готовы к за
пуску стартапа!
Т
Помните основательницу
TweetSkirt.com ?
366 глава 7
раскрываем в себе художника
Давайте сей
час вместе прой
демся по нему...
Следующий шаг уже долж еп показаться вам вполпе естествеппым. Н ам пужпо парисовать
изображ епие в c a n v a s , используя метод объекта c o n t e x t с имепем, как вы уже догадались,
d ra w lm a g e .
^ 3 от наш ^
Используем метод drawlm age. объект Кром е того, указываем значения координат
местоположения х, у, ширины и высоты.
Image.
Об изображ епиях вам пужпо зпать еще одпу вещь: опи пе всегда загружаются мгповеппо, по
этому вам будет пеобходимо удостовериться в том, что изображ епие полпостью загрузилось,
преж де чем вы приступите к его рисовапию . Как мы ждем, пока что-то загрузится, перед тем
как п редприпять действие? Мы реализуем для этого обработчик o n lo a d :
Здесь мы говорим: «Когда изо -
бражение загрузится, выполнить
twitterBird.onload = function () { данную функцию».
дальше ► 367
добавление изображения
f u n c t io n d r a w B ir d ( c a n v a s , c o n te x t) {
v a r tw itte r B ir d = new Im a g e ( ) ;
Свой код
напишите
здесь.
368 глава 7
4acm° раскрываем в себе художника
ЧаДаБаеМые
В опросы
0 : Сначала нужно выяснить количество символов, содержащих А будет ли все создаваемое в ca n va s работать и на моем
ся в твите, и если оно будет превышать определенное число, то мобильном устройстве или мне придется переписывать его для
разбить данный твит на несколько строк и рисовать каждую из них мобильных пользователей?
отдельно в c a n v a s . Мы включили соответствующую функцию
s p l i t in t o L in e s в код, доступный по адресу wickedlysmart.com. 0 : Если на вашем мобильном устройстве установлен современ
ный браузер (на всех устройствах вроде Android, iPhone и iPad
Я также заметил, что в некоторых твитах имеются HTML- как раз имеются такие браузеры), то все будет отлично работать
сущности вроде " и &атр;. Что все это значит? (масштабирование страницы может быть отключено, однако функ
циональность сохранится). Замечательная особенность ca n va s
0 : API-интерфейс Twitter, используемый нами для извлечения заключается в том, что, поскольку вы рисуете «сырые» пикселы,
твитов в виде JSON-данных, преобразует символы, которые поль все создаваемое вами будет везде отображаться одинаково (то есть
зователи печатают в своих твитах, в HTML-сущности. Вообще-то во всех браузерах, которые поддерживают canvas).
дальше ► 369
Для этого придется еще потрудиться.
Н а самом деле ca n v a s призван быть простой поверхностью
для рисования. Когда вы создаете фигуру, ca n v a s видит ее как
группу пикселов. О н ничего не знает об особеппостях того,
что вы рисуете, и не отслеж ивает никаких фигур, а просто соз
дает пикселы, которы е вы говорите ему создать (если вам зпа-
комы такие терм ины из области граф ики, как «растровое р и
сование» и «векторное рисование», то вы пойм ете, что ca n va s
осущ ествляет растровое рисование).
Если вам захочется обходиться с прямоугольпиками в своем
ca n v a s как с набором объектов, которы й можпо будет сохра
нить (или, возможно, вы захотите перемещ ать его или мани
пулировать им), то вам потребуется сохрапять ипф орм ацию о
фигурах и контурах по ходу рисования их в canvas. Вы сможе
те сохранить эти данны е в JavaScript-объектах. Н априм ер, если
вы захотите отследить произвольны е круги, парисоваппы е
вами в ca n va s при работе над TweetShirt, вам потребуется со
хранить координаты м естополож ения х, у, зпачепия радиуса и
цвета каждого конкретного круга, чтобы вы смогли воссоздать
его позже.
П охоже, что это и есть плап действий, которы й вам п уж еп ...;)
раскрываем в себе художника
дальше ► 371
обзор canvas
КЛЮЧЕВЫЕ «
МОМЕНТЫ J O ' -------------------
■ canvas — это элемент, который вы размещаете в сво ■ Метода f i l l C i r c l e не существует. Чтобы нарисо
ей странице с целью создания области для рисования. вать круг в c a n v a s , вам потребуется начертить дугу.
■ ca n va s не будет иметь стиля по умолчанию или со ■ Для рисования произвольных фигур или дуг сначала
держимого, пока вы не снабдите его им (таким образом, необходимо начертить контур.
вы не увидите c a n v a s на веб-странице до тех пор,
■ Контур — это невидимая линия или фигура, которую
пока не нарисуете что-нибудь в нем или не добавите
вы чертите для определения линии или области в
рамку для него с помощью CSS).
canvas. Контур нельзя будет увидеть до тех пор, пока
■ У вас на странице может иметься более одного вы не обведете его или не примените к нему заливку.
canvas. Вам, конечно же, потребуется присвоить каж ■ Для создания треугольника необходимо начать контур
дому из них уникальный идентификатор, чтобы к ним с ПОМОЩЬЮ b e g in P a th , а ЗЭТвМ ИСПОЛЬЗОВЭТЬ moveTo
можно было обращаться с использованием JavaScript. и lin e T o для рисования контура. Для соединения двух
■ Для задания размеров элемента c a n va s следует ис точек контура используйте c lo s e P a th .
пользовать его атрибуты w id t h И h e ig h t . ■ Чтобы нарисовать круг, начертите 360-градусную дугу.
■ Все, что вы захотите поместить в c a n v a s , будет Начальный угол будет 0°, а конечный — 360°.
рисоваться с применением JavaScript. ■ Углы задаются в canvas с использованием радианов,
■ Для рисования в c a n v a s вам сначала нужно будет а не градусов, поэтому нужно преобразовать градусы
создать контекст. В настоящее время вашим един в радианы, чтобы задать начальный и конечный углы.
ственным выбором является контекст 2d, однако в бу ■ 360 градусов = 2% радианов.
дущем возможно появление и других типов контекста.
■ Чтобы нарисовать текст в canvas, используйте метод
■ Контекст необходим ДЛЯ рисования В ca n va s потому, fiiiT e x t.
что он обеспечивает специфический тип интерфейса
■ При рисовании текста в c a n v a s вам будет нужно
(например, 2d и 3d). Вы сможете выбирать нужный
указывать позицию, стиль и пр., используя свойства
ТИП Интерфейса ДЛЯ рИСОВаНИЯ В ca n va s.
Объекта c o n te x t .
■ Обращаться к c a n v a s следует с использованием
■ Когда вы задаете значение для свойства объекта
свойств и методов объекта c o n te x t .
c o n t e x t , оно применяется на протяжении всего про
■ Чтобы нарисовать в c a n v a s прямоугольник, нуж цесса рисования, пока вы не присвоите этому свойству
но воспользоваться методом c o n t e x t . f i l l R e c t . другое значение. Например, изменение значения свой
Он создает прямоугольник с заливкой цветом. ства f i l i s t y l e повлияет на цвет фигур и текста,
■ Чтобы нарисовать контур прямоугольника, вместо создаваемых вами после присваивания этому свойству
нового значения.
f i l l R e c t используйте МвТОД s tr o k e R e c t.
■ Добавление изображений в c a n v a s осуществляется
■ Используйте f i l l S t y l e И s t r o k e S t y l e ДЛЯ ИЗ-
с ПОМОЩЬЮ метода d ra w lm a g e .
менения задаваемого по умолчанию цвета заливки
и обводки, которым является черный. ■ Чтобы добавить изображение в ca n va s, вам сначала
потребуется создать объект Im age и убедиться, что
■ Вы можете задавать цвета, используя тот же са
соответствующее изображение полностью загрузилось.
мый формат, что и в CSS (например, " b l a c k " ,
" # 0 0 0 0 0 0 ", " r g b ( о , о, 0) " ) . Не забывайте за ■ Рисование в c a n va s сродни растровому рисованию
ключать значение f i l i s t y l e в кавычки. в программах для работы с графикой.
372 глава 7
раскрываем в себе художника
Трой А рм строн г
Ш Т А Т Н Ы Й А В Т О Р « В Е Б В И Л Л Ь С К О Г О КУР ЬЕР А »
оальше ► 373
кроссворд
U I M L 5 - it occ B t a
Мы с п етерп еп и ем ждем следующей главы, где сможем подробпее погово
рить о сепсациоппой повости, касаю щ ейся < c a n v a s > и < v id e o > . А вы тем
врем епем закрепите свои повы е зпапия о c a n v a s , разгадав пеболы ной кросс
ворд (возможпо, за чаш кой чая).
По горизонтали По вертикали
2. Свойство, для которого мы задавали значение с целью заливки 1. Данный метод объекта c o n t e x t создает прямоугольник.
фигуры цветом. 3. < c a n v a s > и ____________ хорошо сочетаются друг с другом.
5. Несуществующий метод, который Джим пытался использовать 4. Объект, включающий методы и свойства для рисования
для рисования кругов.
В ca n va s.
6. Сообщить о завершении загрузки чего-либо можно с помощью
5. Используйте данный метод для рисования текста в canvas.
обработчика____________ .
8. Для рисования кругов следует применять метод____________ . 6. Наилучшее место для размещения хорошего твита.
9. Мы осуществляем ее для того, чтобы сделать контур фигуры 7. Чтобы переместить карандаш при черчении контура в точку с
видимым. координатами 100,100, используйте____________ (100,100).
10. Хотите узнать, какой параметр был выбран? Тогда вам может 12. Мы думаем в градусах, a c a n v a s — в __________ .
потребоваться данное свойство.
11. Невидимая линия, которую вы чертите с целью нарисовать
фигуру.
13. Мы выравнивали текст . . . а в р е з у л ь т а т е п о л учи л
э т у паршивую м а й к у ! по_____________краю.
14. В круге 360____________ .
15. Все в c a n va s является____________ .
374 глава 7
раскрываем в себе художника
(Т А Н Ь браузером. Решение
] е п е р ь , к ° г д а у Бас е с т ь и н т е р
ф ей с, В ы полните п о в ед е н н ы е
Представьте, что вы используете
этот интерфейс для выбора зна Здесь JaVa^cript—о п е ^ а т ^ ы
чений в случае со своей футболкой. и н а п и Ш и т е Значение
д л я к а ж д о г о эл ем ен
т а и н терф ей са.
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " b a c k g r o u n d C o lo r " ) ;
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r b g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ; white
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " s h a p e " )
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r shape = s e l e c t O b j [ i n d e x ] . v a l u e ; circles
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld ( " f o r e g r o u n d C o lo r ”
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r f g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ; b la c k
Обратите внимание, что в случае Не забывайте, что значение^ парам е
с каждым значением меню мы и з тра может отличаться от текста,
влекаем элемент select, в кот ором который вы видите в элементах
содержится соответствующий управления; в нашем случае это как
парам ет р , находим выбранный раз касается первых букв текста.
парамет р с помощью свойства
selectedlndex и извлекаем значение
этого параметра. При необходимости
Select background color: [ White t ] еще раз взгляните
на H T M L , чтобы
Circles ОГ squares? [ Neither t j увидеть значения
Во ^ ^ м ’ коглТ ' ^
параметров.
Select text color: [ Black 11 ]
Pick a tweet: [ ■; ]
( Preview)
дальше ► 375
решение упражнения
вычислить
произвольную ширину
для квадрата
Р а з м е с т и т е здесь
Задать для fillstyle значение
таблички с п с е в д о
" lig h tb lu e "
кодом в нужной п о
с л е д о в а т ел ь н о с т и !
нарисовать квадрат, имеющий
позицию х г у и ширину w
fu n c t io n f illB a c k g r o u n d C o lo r ( c a n v a s , c o n te x t) {
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld (" b a c k g r o u n d C o t o r - ) t
var in d e x = s e le c tO b j . s e le c t e d ln d e x ; д дя заливки ф он а ц в е т о м МЫ р и с у е м
var b g c o lo r = s e le c t O b j . o p t io n s [ in d e x ] . v a l u e ; п р я м о у г о л ь н и к , к о т о р ы й за п о л н я е т
I ^ i ц в е т о м п о л н о с т ь ю весь canvas.
c o n te x t. f i l l S t y l e = и ^ С 0 \ 0 \ Г ;
376 глава 7
раскрываем в себе художника
Начальный угол = 2 7 0 °
c o n te x t . b e g in P a t h ( ) ;
c o n te x t .m o v e T o (1 0 0 , 1 5 0 ); Вот код} приводившийся ранее
c o n te x t . l i n e T o (2 5 0 , 7 5 ) ;
c o n te x t . l i n e T o (1 2 5 , 3 0 ) ;
c o n te x t . c lo s e P a t h ( ) ;
дальше ► 377
решение упражнения
Перерыв, решение
il * )
X> У = 'Z-OO) 2 5 0
радиус = ZS *> у = 4 0 0 , 2.s o
Пора применить на практике ваши новые знания о дугах
и контурах для создания улыбающейся рожицы. Устра
ните пробелы в приведенном ниже коде, который позво
лит нарисовать улыбающееся лицо. Мы предусмотрели
для вас подсказки относительно того, где на диаграмме
должны располагаться глаза, нос и рот.
ЪОО, 3 0 0 | угол = 2 0 °
Вот наше решение этого упражнения: длина носа
fu n c t io n d ra w S m ile y F a c e () {
v a r c a n va s = d o c u m e n t. g e tE le m e n tB y ld ( " s m i l e y " ) ;
v a r c o n te x t = c a n v a s . g e tC o n te x t( " 2 d " ) ; у = зоо, з so
радиус = 7 s
c o n t e x t . b e g in P a t h ( ) ;
c o n t e x t .a r c ( 3 0 0 , 300, 200, 0, d e g re e s T o R a d ia n s (360 tr u e
c o n te x t . f i l l S t y l e = " # ffffc c "; К р' уг ......
лица. мы Здесь
уже устранили за вас
ооин из пробелов. ' Обратите
" ~I внимание , М Ы
^ми/нипиЬ;
c o n te x t •f i l l ( ) ;
применили к кругу заливку желт ым цветом.
c o n te x t . S tro k e ( ) ; Левый глаз. Центр
Левый глаз. Центр круга имеет координаты х = 2 0 0 , и = 2SO оади-
2 5 , начальный цгол О. конечный Mn-f-u р I *- о э х J
c o n t e x t b e g in P a th о Р 5вод“ м конт ур , чтобы получить очертания круга ( н о ^ е з з а л и в к и у ^ '
c o n te x t a r с ( 2 0 0 , 2 5 0 , 2 5 , О, dcgrCCS~ToRacliaiAS(3G?0), t r u e ) ;
c o n te x t S tro k e о ; Правый глаз. Такой Же, как
и левый, но с координатой
c o n t e x t b e g in P a th () ; & X = 40 0 . Мы используем
378 глава 7
раскрываем в себе художника
Развлечения с магнитами
Пришло время вашего первого эксперимента с текстом в c a n va s. Ниже приведен начатый нами код для
метода d ra w T e x t, который мы будем вызывать, чтобы нарисовать весь текст в c a n v a s для предвари
тельного просмотра. Посмотрите, сможете ли вы завершить данный код, чтобы нарисовать Я п о в е л ся
на э т о т т в и т . . . и . . . а в р е з у л ь т а т е п о л у чи л э т у паршивую м а й ку ! в c a n v a s , а рисование
реального твита пользователя мы оставим на потом. Вот наше реш ение этого упражнения.
f u n c t i o n d r a w T e x t( c a n v a s , c o n t e x t ) {
v a r s e le c tO b j = d o c u m e n t. g e tE le m e n tB y ld (" fo r e g r o u n d e d or
v a r in d e x = s e l e c t O b j . s e le c t e d ln d e x ;
v a r f g C o lo r = s e l e c t O b j [ i n d e x ] . v a l u e ;
f i l l S t y l e | = f g C o lo r ;
fillCircle fillRect
дальше ► 379
решение упражнения
пражнение Посмотрите, сможете ли вы собрать функцию d r a w B ir d из всех тех кусочков, которые нам предоста
решение вила Джуди. Функция d r a w B ir d Принимает ca n va s И c o n te x t И рисует изображение ПТИЦЫ В canvas.
Исходите ИЗ ТОГО, ЧТО С ПОМОЩЬЮ данной функции МЫ ДОЛЖНЫ разместить " t w i t t e r B i r d . p n g " вместе
с координатами х = 20, у = 12 0, при этом ширина и высота будут равны 70 пикселам. Мы уже на
писали за вас объявление метода и первую строку. Вот наше решение этого упражнения.
Не забудьте доба
f u n c t i o n d r a w B ir d ( c a n v a s , c o n t e x t ) { вить вызов d ra w B ird
Свой код на п и v a r t w i t t e r B i r d = new Im a g e ( ) ; в свою функцию
шите здесь tw itte r B ir d s r c = (ft w i t t e r 8 i i r d . p n g n; preview Handler!
tw itte r B ir d .o n lo a d = fu n c tio n Q {
1;
U r M L § - K r occ® T A - Г еШение
380 глава 7
раскрываем в себе художника
дальше ► 381
8 телевидение для нового поколения
♦
* Элемент video...
...и наш особый гость—элемент canvas
Знакомство с Webville TV
Webville TV —это содерж имое, которого вы жда
ли, нанрим ер: «Пункт назначения - планета Зем
ля» (D estination Earth), «Нападение 50-футовой
женщины» (The Attack of the 50’ W om an), «Нечто»
(The T hing), «Капля» (The Blob), и не будет лиш
ним вклю чить сюда образовательны е фильмы
1950-х годов. Однако это всего лишь содерж и
мое, а что касается технологий, то ож идаете ли
вы здесь чего-то меньш его, чем НТМЬ5-видео?
Это, конечно же, лиш ь наше видение нроблемы,
и если мы хотим трансф орм ировать его в нечто
реальное, то нам но требуется создать Webville
TV. Н а нескольких следующих страницах мы бу
дем заниматься созданием Webville TV «с нуля»,
иснользуя НТМЬ5-разметку, элемент video и не
много JavaScript.
Webville T V , на Ю О %
созданное с применением
технологии HTML5.
Скоро в вашем
браузере!
384 глава 8
телевидение для нового поколения
s r c = " v i d e o / p r e r o l l . ogv"
\ Попробуйте
А если вы работаете с In te rn e t Explorer версии 8 сделать так для
или ниж е, вам не новезло, —но стойте-ка, это же гла качала, а чуть
ва 8! Как вы до сих нор мож ете пользоваться браузе позже мы вер
ром In tern et Explorer 8 (или ниже)? О бновите его! немся к этому.
Н о если вам необходимо узнать, как обеснечить р е
зервное содерж имое для пользователей, у которы х
установлен In tern et Explorer 8, нотерните, но сколь
ку мы еще дойдем до этого.
386 глава 8
телевидение для нового поколения
дальше ► 387
обзор атрибутов элемента video
Элементы управле
ния в каждом браузере выглядят
по-разному; хотя при использова
нии решений вроде Flash в их внеш
нем виде, по крайней мере, наблюда
лась согласованность.
дальше ► 389
обзор форматов видео
Претенденты
Если вы собираетесь ноставлять содерж имое для ш ирокого круга пользователей, то вам нри-
дется предусмотреть наличие видеоф айлов более чем одного формата. С другой стороны , если
вы нацеливаетесь, нанрим ер, только на пользователей A pple iPad, возможно, вам удастся обой
тись лиш ь одним ф орм атом видео. В настоящ ее врем я существуют три основны х нретендента.
Я64
T h e o ra — это ко д е к с о ткр ы ты м нативное решение
ИСХОДНЫМ КОДОМ. н _ ^Ь им ец с от крыт ым исход
В и д е о , з а к о д и р о в а н н о е с его п о м о щ ь ю , индустрии, но не ным кодом.
о б ы ч н о с о д е р ж и т с я в O g g -ф а й л е , правящий чемпион ...
ко то ры й и м е ет р асш и р е н и е O G V.
O g g /T h e o r a п о д д е р ж и в а е т с я б р а у з е р а м и
F ir e fo x , C h r o m e и O p e r a .
г
VPS — претендент , за спи-
ной которого стоит Google,
при эт ом поддерживается
браузерами других разра
ботчиков и набирает силу...
дальше ► 391
управление форматами видео
Обратите внимание, что мы удаляем ■■■и добавляем мри тега <source>, каж
ат рибут src из тега <video> ... дый из которых имеет собственный Л
атрибут src, указывающий путь к ви
деофайлу в отличающемся формате.
I г
< v id e o s r c = " v i d e o / p r e r o l l .m p4" id = " v id e o "
p o s te r = " v id e o / p r e r o llp o s t e r . jp g " c o n t r o ls
w id t h = " 4 8 0 " h e i g h t = " 3 6 0 ">
< s o u rc e s r c = " v id e o / p r e r o l l. m p 4 " >
< s o u rc e s r c = " v id e o / p r e r o ll. w e b m " >
< s o u rc e s r c = " v i d e o / p r e r o l l . o g v ">
< p > S o rry , y o u r b ro w s e r d o e s n 't s u p p o r t th e v id e o e le m e n t< /p >
< / v id e o > горюхи и двигается
г x ‘
браузер натИ^ Ы[Л, Ст файл в форма
Сообщение, которое выведет вниз, пока не о воспроизвести.
браузерл если он не поддер
живает элемент video. \
3 случае с каждым <source> браузер загружа
ет метаданные видеофайла, чтобы проверить,
сможет ли он его воспроизвести (этот процесс
бывает длительным, однако его можно облегчить
КЛЮЧЕВЫЕ ^ЛЯ
йраУзеРа " слЛ' бедующ ую страницу)
МОМЕНТЫ
Я
Контейнер — это формат файлов, используемый для «упаковки» видео-, аудио- и ме
таданных. Среди распространенных контейнерных форматов можно назвать MP4, WebM,
Ogg и Flash Video.
Браузер сам решает, какое видео он сможет декодировать. При этом среди разработчиков
браузеров нет согласия относительно единого формата видео, поэтому если вы хотите
обеспечить поддержку для каждого пользователя, вам придется позаботиться о наличии
видеофайлов в нескольких форматах.
392 глава 8
телевидение для нового поколения
J
type является опциональным Это тип MIME видео- Обратите внимание на двойные
атрибутом , который вы файла Он определяет кавычки вокруг значения параметра
ступает в роли подсказки контейнерный формат, codecs. Они подразумевают , что
для браузера , помогающей ему значение атрибута type нам следует
понять , сможет ли он воспро заключить в одинарные кавычки.
извести данный тип файла.
Мы можем обновить наш и элементы <source> с целью вклю чения в них и нф орм ации о тине
для каждого из трех тинов видеоф айлов, которы е у нас имею тся, как но казано далее:
Когда вы будете разбираться с кодированием видеоф айлов, вам нридется узнать подроб
ности о разнообразны х вариантах нарам етров ty p e для иснользования в вашем элементе
< s o u rc e > . Д ополнительную инф орм ацию о данны х нарам етрах вы сможете найти но адресу
h t t p : / / w ik i. w h a t w g . o r g / w i k i/ V i d e o _ t y p e _ p a r a m e t e r s .
дальше ► 393
вопросы о кодировании и воспроизведении видео
Ч а с т°
Задаваем ы е
B o llp o C b l
Следите за этой темой, если видео имеет для вас большое элемента управления для проигрывания видео во весь
значение; за ней, несомненно, будет интересно наблюдать экран (например, на планшетных компьютерах), который
ближайшие несколько лет, пока специалисты будут со всем наделяет данной возможностью элемент v id e o . Однако
этим разбираться. И, как всегда, принимайте во внимание после того, как вы найдете способ воспроизводить видео
потребности своей целевой аудитории и обязательно в полноэкранном режиме, список того, что с ним можно
делайте все возможное, чтобы обеспечить для них соот будет сделать помимо простого проигрывания, может
ветствующую поддержку. оказаться ограниченным по соображениям безопасности
(как это бывает с видеоплагинами).
394 глава 8
телевМ е н и ед л я н о ап
° п°коления
* 4 .
Щь
ВАША СЛЕДУЮЩАЯ МИССИ Я: c o b e p iu e h u o
РАЗВЕДКА ПОДДЕРЖКИ ВИДЕО С ЕК РЕТН О
ВАМ ПОРУЧАЕТСЯ ОПРЕДЕЛИТЬ Т Е К У Щ И М У Р О В Е Н Ь ПОДДЕРЖКИ ВИДЕО
В КАЖДОМ ИЗ ПРИВЕДЕННЫХ НИЖЕ Б Р А У З Е Р О В (ПРИМЕЧАНИЕ: НУЖНУЮ ИНФОРМАЦИЮ
ВЫ СМОЖЕТЕ О Т Я С К А Т Ь ПО АДРЕСАМ HTTP: //E N .W IK IP E D IA .O R G /W IK I/H T M L 5 _
V ID E O , HTTP://CANIUSE.COM/#SEARCH=VIDEO)
ПРИНИМАЙТЕ ВО ВНИМАНИЕ НОВЕЙШИЕ В Е Р С И И БРАУЗЕРОВ. ПО КАЖДОМУ Б Р А У З Е Р У ,
ПРИВЕДЕННОМУ В С Т О Л Б Ц Е «ВИДЕО/БРАУЗЕР», ОТМЕТЬТЕ ВИДЕОПАРАМЕТРЫ, К О Т О Р Я Е
ОН ПОДДЕРЖИВАЕТ. ПО ВОЗВРАЩЕНИИ ПРЕДСТАВЬТЕ ОТЧЕТ ДЛЯ П О Л У Ч Е Н И Я Н О В О Г О
ЗАДАНИ Я!
дальше ►
Нет проблем.
Существует ряд методик для п ереклю чения на другой
проигры ватель видео, если тот, которы й вы нредно-
читаете (будь то проигры ватель видео HTML5, или
Flash, или другой), не поддерж ивается.
Н иж е вы найдете прим ер того, как можно вставить
свое Flash-видео в качестве резервного содерж имо
го, заменяю щего НТМЬБ-видео в ситуациях, когда
браузер не знает, как воспроизвести НТМЬб-видео.
Ясно, что данная область быстро меняется, ноэтому
заглядывайте в И н терн ет (в котором разм ещ ается
более свежая инф орм ация, чем нриводим ая в кни
гах), чтобы использовать новейш ие и наилучшие
методики. Вы также сможете найти снособы сделать
резервны м не Flash-видео, а НТМЬБ-видео, если
п редпочтете отдавать п ри ори тет Flash-видео.
videoHeight muted
currentTime paused
duration readyState
¥
ended seeking
&
г error volume
Это свойства объекта эле
мента <video>. Одним из них ^П ер ехв аты вай те эти события
вьч можете присваивать зна
чения (например, loop и muted),
другие же предназначены play abort
только для чтения (например,
currentTime и error). pause waiting
progress loadeddata
Это события, которые вы сможете
обрабатывать, если захотите, до error loadedmetadata
бавив обработчики событий, вызов
которых будет происходить при timeupdate volumechange
наступлении события, прослушива
ние которого вы ведете. ended
дальше ► 397
как работает плейлист
7 /и h i m l’ cf Ouulilij
398 глава 8
телевидение для нового поколения
в о з ь м и в руку карандаш
Решение У вас может возникнуть соблазн взглянуть на спецификации разметки
< v id e o > , чтобы узнать, как определить плейлист. Что ж, для этого вам потре
При загрузке страницы мы буется код, поскольку элемент < v id e o > позволяет определять только одно
генерируем массив playlist, видео. Если бы вы находились на необитаемом острове и вам требовалось
запускаем воспроизведение реализовать плейлист исключительное использованием браузера, элемента
первого видео и задаем обра < v id e o > , свойства src, методов lo a d и p la y , а также свойства ended, то как
ботчик событий, иницииру бы вы сделали это (у вас есть возможность использовать любые типы данных
JavaScript, какие пожелаете)? Вот наше решение этого задания:
емых, когда воспроизведение
видео завершается. ^
*
£
&
Создать переменную p o s i t i o n = о. /Qj ft
Задать в качестве источника видео &
ПОЗИЦИЮ О В p l a y l i s t .
Массив playlist
Воспроизвести видео.
Псевдокод обработчика
...что приводит
со бы ти й ended
к вызову обработчи Увеличить значение p o s i t i o n на 1.
ка событий ended.
Задать в качестве источника видео Дойдя до конца плей
следующую ПОЗИЦИЮ В p l a y l i s t листа, мы можем
Воспроизвести следующее видео либо остановиться,
либо снова вернуться
к первому видео.
дальше ► 399
реализация плейлиста
А тенерь создайте новы й файл с именем webvilletv. js. К роме того, давайте
онределим ряд глобальных нерем енны х и функцию, которая будет вы зы ваться
носле нолн ой загрузки страницы:
v i d e o . p l a y () ; И з а г р у Ж а е м э т о
400 глава 8
телевидение для нового поколения
дальше ► 401
тестирование плейлиста
Хороший вопрос.
Когда мы использовали множ ественны е теги < s o u rc e > , мы мог
ли рассчиты вать, что браузер пройдется но одному или более
форматам видео и решит, сможет ли он воснроизвести какой-
либо из них. Теперь при использовании кода мы нросто даем
элементу v id e o единственны й вариант выбора. Так как же нам
проверить и узнать, какие ф орм аты видео ноддерж ивает брау
зер, чтобы убедиться в том, что мы обеснечили наиболее нод-
ходящ ий из них?
Для этого мы можем воспользоваться методом c a n P la y T y p e объ
екта v id e o . Он приним ает ф орм ат видео и возвращ ает строку,
которая дает понять, насколько браузер уверен в том, что он смо
ж ет воспроизвести данны й тип видео. Существуют три стенени
уверенности: вероятно, может быть, уверенности нет. Д авайте бо
лее пристально взглянем на canPlayType, а затем доработаем код
нашего плейлиста, чтобы задействовать в нем данны й метод.
ТВы почесываете затылок , произнося:
«Вероятно? Может быть?
А почему этот метод не возвращает true или false»? С нами было
то же самое! Через несколько мгновений вы узнаете , что под всем
эт им понимается...
402 глава 8
телевидение для нового поколения
Тенерь нам необходимо внести ряд изм енений в функции w in d o w .o n lo a d и n e x t v id e o с целью задей
ствовать g e tF o r m a tE x te n s io n . Сначала мы удалим расш ирения файлов из ф айловы х имен в плейлисте
(носкольку вместо этого мы будем нрим енять g e tF o r m a tE x te n s io n для их вы яснения), а затем вызовем
g e tF o r m a tE x te n s io n там, где мы задали свойство v i d e o . s r c :
И нроделайте то же самое в n e x tv id e o :
f u n c t io n n e x t v i d e o () {
p o s itio n + + ;
if ( p o s i t i o n >= p l a y l i s t . le n g t h ) {
p o s itio n = 0; Здесь мы делаем то
} же самое — конка
тенируем результат
v id e o .s r c = p l a y li s t [ p o s i t i o n ] + g e tF o r m a tE x te n s io n ()
getForm atExtension
v id e o . lo a d ( ) ;
с файловым именем
v id e o .p la y ( ) ; источника видео.
U проведение mecm-драйва...
Добавьте функцию c a n P la y T y p e и внесите п родем онстриро
ванны е чуть выше изм енения, носле чего перезагрузите свой
файл w e b v i l l e t v . h t m l . Ну как, работает? Тенерь ваш код сно- h ttp ://(o c a lh
a l e r t ( " P la y in g " + v id e o . c u r r e n tS r c ) ;
404 глава 8
телевидение для нового поколения
_ Часщо
^адаБ аеМ ы е
Б о Ц р о сьх
:ь
чтобы перехватывать соответствующую ошибку и предоставлять посредством кода, а не разметки.
объекту v id e o другой источник (о перехвате ошибок мы поговорим
в конце главы). Второй заключается в использовании объектной
модели документа (DOM) для написания сразу нескольких тегов
^ V epG ° ° g /e Chrome
Вам может пот ребо
ват ься уст ановит ь
Ii ] ) У Д ь т е c Целью обеспечен ^ ” ия
Quicktime для воспроиз
ведения видеоф айлов °С 2 Ц о р о ^ Н ы ! ПаСНОСти- °'
с расширением MP4 Данные ограничения не пп
дыне
в браузере Safari. торые операции vid e o + T ™ ™ * * * °овеРШать не'ко
Программа Quicktime Ч ^ у и и Цу какфТс°(тТ ^ Г Г ' * * * £ ?
дет выглядеть как ?,) ваш и ^ - а д р ес бу-
зачастую устанавливается по умолчанию,
но если она все же не была инсталлирована, главы Кр К МЫ 6удвМ ПостУпать Т о с ^ ’ //)з Подоб"о
вы можете загрузить ее отсюда: http://www.
apple, com/quicktim e/do wnload/.
5 3 г = 3 5 £ Й £ г
Убедитесь, что с вашего сервера загружаю т ся видеоф айлы, имеющ ие
коррект ны й т ип MIME .
О
Независимо от того, используете вы свой собственный локальный сервер или
^ Д ь ш е выполняете приложение, задействуя видео с онлайн-сервера, нужно удосто
вериться в том, что с сервера поступают видеофайлы с корректным типом
MIME. В противном случае они не смогут работать должным образом.
Если вы работаете в операционной системе Mac OS или Linux, то, скорее всего, используете Apache.
Вы можете модифицировать файл h t t p d . c o n f (если у вас имеется корневой доступ) либо создать
файл .h ta c c e s s в каталоге, где располагаются ваши видеофайлы, и добавить в него следующие
строки:
A ddType v id e o / o g g . ogv
A ddType v id e o /m p 4 . mp4
A ddType v id e o /w e b m . webm
Этот код сообщит серверу, как подходить к загрузке файлов с данными расширениями.
Вы можете установить Apache в операционной системе Windows и произвести аналогичные манипу
ляции. В случае с серверами IIS рекомендуем заглянуть в онлайн-документацию Microsoft и найти там
«Конфигурирование типов MIME в IIS» (Configuring MIME types in IIS).
дальше ► 405
наше послание вам
В какой-то момент нам уже придется относиться к вам как к настоящим разработчикам.
В этой книге мы (надеемся) номогаем вам делать каждый шаг —мы находимся рядом, чтобы
нодхватить вас, нреж де чем вы унадете, и убедиться в том, что в вашем коде были расставле
ны все точки над i. Однако быть настоящ им разработчиком номимо всего остального означа
ет нонимать код, нанисанны й другими людьми, уметь увидеть главное за массой второстеп ен
ных деталей и разбираться в запутанности того, как все объединяется в одно целое.
В оставш ейся части главы мы нредоставим вам возмож ность сделать все это. Далее нриведен
нрим ер, которы й наиболее близок к реальному веб-нриложению из всего того, что нам до
водилось видеть до настоящ его момента, нри этом он вклю чает массу составны х частей, ак
тивное иснользование API-интерф ейсов и большое количество кода, которы й обеснечивает
обработку множ ества реальны х деталей. Тенерь мы не можем разбирать каждую часть, разъ
ясняя вам каждый нюанс, как обычно это делали (иначе книга разрослась бы до 1200 стра
ниц); мы и не хотим этого делать, но скольку вам необходимо н риобретать навы ки объедине
н и я всех кусочков «мозаики» без нас.
Н е беснокойтесь, носкольку мы но-нрежнему будем рядом и расскажем, что именно делать,
однако вы долж ны учиться восприним ать код, читать его, разбираться в нем, а затем донол-
нять и изменять его для того, чтобы он делал то, что вам необходимо. Таким образом, на про
тяж ении следующих трех глав мы хотим, чтобы вы ногрузились в нриводим ы е нрим еры ,
изучили их и «вбили» код себе в голову. Да... вы к этому готовы!
406 глава 8
телевидение для нового поколения
дальше ► 407
исследуем видеокабинку starring you video
408 глава 8
телевидение для нового поколения
РаспакоВка демоблока
Н а следующий день наш демоблок был доставлен самолетом, и настало врем я
раснаковать его. П охоже, что мы нолучили функциональны й блок с уже нани
санной нростой HTM L-разметкой и JavaScript-кодом. Д авайте сначала взглянем
на HTM L ( v id e o b o o t h . h tm l) . Внереди вас ждут несколько страниц «заводского»
кода, нросм отром которого мы займемся, а затем нерейдем к настоящему коду.
J T HTMLS ■ конечно же ^ оме м о г^ вся стилизация
<! doctype html> ОЫЛа сделана 3(Х H a d Вот СО -
<html lang=Mе п п> ответствующий CSS -файл.
<head> J д вот Ja va S crip t-файл, который нам
<title>Starring YOU Video Booth</title> потребуется для размещения большей
<meta charset="utf-8"> части написанного кода. Чуть позже мы
Clink rel=Mstylesheet" href = пvideobooth, c s s 11> /"взглянем на него более подробно, и, п о -
<script src= "videobooth. j s nx / s c r i p t > ^ хоже, что они уже написали здесь код для
-
</head> контроля над кнопками в интерфейсе.
<body> Вот главный интерфейс, где у нас имеется сама консоль,
<div id= "booth”> которая разделена на область отображения видео и панель
<div id="console"> Управления с тремя наборами кнопок, сгруппированных
<div id="videoDiv"> Y- в "effects", "controls" и "videoSelection".
<video id="video" w idth=n720" height=" 480мX / video>
</div>
*ч _ Они уже установили видеопроигры
<div id=" dashboard" > ватель. это хорошо, поскольку он
<div id="effects"> нам понадобится.
<a class="effect" i d = " n o r m a l " X / a >
<a class="effect" i d = " w e s t e r n " X / a >
<a class="effect" i d = " n o i r " X / a >
\ Вот все эффекты
Это всего лишь H TM L-якоря.
<a class="effect" id=" scifi" X / a >
О привязке к ним мы пого
</div> J ворим чуть позже...
<div id="controls">
<a class="control id="play"X/a>
<a class="control id=" pause" Х / а >
И элементы управления
<a class="control id="loop"X/a>
проигрывателем
<a class="control id="mute"X/a>
</div>
<div i d = "videoSelection">
<a class="videoSelection" id="videol"></a> И два демовидео для
<a class="videoSelection" id="video2"></a> тестирования
</div>
</div>
</div>
</body>
</html>
дальше ► 409
рассмотрение имеющегося кода
410 глава 8
телевидение для нового поколения
Все это, конечно, здорово, однако где будет располагаться наш код? Д авайте нодумаем: когда пользова
тель нажмет кнонку, нанрим ер Play (В оснроизведение), нам не только пужно будет обеснечить обнов
ление и н терф ей са (для чего у нас уже им еется код), но и предусмотреть вы нолнение дополнительного
кода, которы й действительно что-то делает, нанрим ер запускает воснроизведение видео. Д винемся
дальше и взглянем на два других обработчика (для задания видеоэф ф ектов и тестового видео), и вам
станет внолне ясно (если уже не стало), где именно будет располагаться наш код...
дальше ► 411
задание обработчиков кнопок
} e ls e i f ( i d == " n o i r " ) {
p u s h U n p u s h B u tto n s ( " n o i r " , [ " n o r m a l" , "w e s te rn ", " s c if i" ] ) ;
} e ls e i f ( i d == " s c i f i " ) {
p u s h U n p u s h B u tto n s ( " s c i f i " , [ " n o r m a l" , "w e s te rn ", " n o ir " ] ) ;
}
3 каждом случае мы добавим код для об
работки реализации соответствующего
фильтра, обеспечивающего спецэффекты.
412 глава 8
телевидение для нового поколения
И не забывайте, что если вы не хотите
набирать приводимый в книге код, може-
А Bom U 8 СП0 М 02 <1ГП6 ЛЬНЫ6 функции те целиком загрузить его, посетив адрес
h ttp ://w ic k e d ly sm a rt.c o m /h fh tm ls.
И для нолноты (либо если вы соверш аете 11-часовой н ерелет на Фиджи, не имея н ри
этом достуна в И нтернет, и у вас возникло ж елание заняться набором всего этого кода):
pushUnpushButtons забот и т ся о состояниях кнопок. Он п рини
м а е т ар гум ен т ы в виде значения id кнопки, кот орая будет в ы
глядет ь нажатой, а также значения id одной или более кнопок Сначала мы убеж даем ся в т о м ,
в массиве, которые б уд ут выглядеть ненажатыми. ч т о значение id кнопки для н а -
f u n c t i o n p u sh U n p u sh B u tto n s (id T o P u sh, idA rrayT oU npush) { , Ж ат ия не я вляет ся п у с т ы м .
if ( id T o P u s h != " " ) { < п .
И з в л е к а е м э л е м е н т a n c h o r с ис~
v a r a n c h o r = d o c u m e n t . g e t E l e m e n t B y l d ( id T o P u s h ) ; п о л ь з о в а н и е м данного значения id...
v a r t h e C l a s s = a n c h o r . g e t A t t r i b u t e ( " c l a s s ") ; 4---------- ...и и зв л е к а е м а т р и б у т class.
if (! t h e C l a s s . i n d e x O f ( " s e l e c t e d " ) > = 0 ) { Мы « н а ж и м а е м » кн опку n y -
^ ^ „ lff „ ___________ т е м добавления класса "s e l e c t e d "
th e C la ss = th e C la ss + " s e le c te d " ; c r ----------✓-
л / & a n c h o r и...
a n c h o r . s e t A t t r i b u t e (" c l a s s ", th e C la ss);
v a r n ew lm age = " u r l ( i m a g e s / " + i d T o P u s h + " p r e s s e d . p n g ) " ;
a n c h o r . s t y l e . b a c k g ro u n d lm a g e = n e w lm a g e ; бы OHO пбрбКрЫЛО
} . .. о * « > в л « м ф о н о во е oSpa.WM. « “ У
’ 9 c P1
“ ИНГ „ 3
"° е" % Э е « С о д “ » в < .~ е .« С р а ж е н u t ■ p a ^ p r e s s e «
Чтобы кнопки выглядели нена-
■
a n c h o r . s ty le .b a c k g r o u n d lm a g e = " " ;
^ ...а также удаляем фоновое изо-
} бражение, чтобы мы смогли
} увидеть ненажатую кнопку.
isButtonPushed п р о с т о п р о в е р я е т ,
наж ат а ли кнопка. О н п р и н и м а е т
fj=u n c .t i •o n • т > 4- 4-
is B u t to n PI-»u s 1h e dл/('idл)\ {г id э л е м е н т а anchor...
...извлекает anchor...
v a r a n c h o r = d o c u m e n t. g e tE le m e n tB y ld ( id ) ;
_ _ , I, , ... i
v a r th e C la s s = a n c h o r . g e t A t t r i b u t e ( " c l a s s " ) ;
ff4 ,
^ —
...извлекает class данного anchor . . .
Кажется, я что-то
пропустила... Как вы проводили из
влечение из элементов <div> с использо
ванием якорных тегов <а>, чтобы в интер
фейсе были кнопки?
Элемент <video>
располагается
в <diV>j который пс
зиционируется о т
носительно консоли
Кром е того , мы
производим абсо
лютное позициони
рование элемента
<video>j чтобы он
оказался в центре
консоли.
дальше ► 415
решение упражнения
416 глава 8
телевидение для нового поколения
Подготовка
v
демоВидео...
v v l^ bl создадим этот
П реж де чем мы реализуем элементы унравления button, нам нотребуется видео °^ьект &ля разме
для их тестирования, и, как можно судить но кнонкам, сотрудники S tarring You
щения
*
двух
и демо-
Video нрислали нам два демовидео. Создадим объект для разм ещ ения двух видео,
видео. Вскоре мы
вернемся к этому
а затем добавим код для нашего обработчика onload, чтобы задать источник объ
и объясним вам все
екта video (точно так же, как мы делали в случае с Webville TV).
подробнее.
var videos = {videol: пvideo/demovideolп , video 2 : "video/demovideo 2
п е р в о е ви д ео в м а с с и в е , и м е ю -
v a r v id e o = d o c u m e n t. g e tE le m e n tB y ld ( " v i d e o " ) ; \щ е р а с ш и р е н и е , к о т о р о е М ОЖ -
v i d e o . s r c = v i d e o s . v i d e o l + g e tF o r m a tE x te n s io n () ; КО б у д е т в о с п р о и зв е с т и .
дальше ► 417
поддержка пользовательских элементов управления видео
f u n c t i o n h a n d le C o n t r o l (е) {
v a r id = е . ta r g e t. g e tA ttr ib u te (" id " ) ;
Нам необходима ссылка
v a r v id e o = d o c u m e n t. g e tE le m e n tB y ld ( " v i d e o " ) ;
на объект video.
if ( i d == " p la y " ) {
p u s h U n p u s h B u tto n s ( " p la y " , [" p a u s e " ]) ; Это должно быть довольно просто
i f ( v i d e o . ended) { для вас. Если пользователь щелкнет
v id e o . lo a d () ; \ на кнопке Play ( Воспроизведение),
} то произойдет вызов метода play
v i d e o . p l a y () ; в отношении объекта video.
} e ls e i f ( i d == "p a u s e " ) {
p u s h U n p u s h B u tto n s (" p a u s e " , [" p la y " ]);
Но хот им предупредить, что
здесь имеется один сложный м о
} e ls e i f ( i d == " lo o p " ) {
мент , который может оказаться
if ( is B u tto n P u s h e d ( " l o o p " )) {
хлопотным: если бы мы воспроиз
p u s h U n p u s h B u tto n s ( " " , [ " l o o p " ] ) ;
водили видео и позволили ему п р о
} e ls e {
играться до конца, то для того,
p u s h U n p u s h B u tto n s ( " lo o p " , [ ] ) ;
чтобы опять запуст ит ь его, нам
}
сначала пришлось бы снова его
} e ls e i f ( i d == "m u te ") {
загрузить. Мы проверяем, что
if ( is B u tto n P u s h e d ( " m u t e " )) {
видео проигралось до конца (а не
p u s h U n p u s h B u tto n s ( " " , [ " m u t e " ] ) ;
было просто поставлено на паузу),
} e ls e {
поскольку в данном случае нам п о
p u s h U n p u s h B u tto n s (" m u te " , [ ] ) ;
требуется лишь снова загрузить
}
его. Если оно было поставлено на
паузу, мы сможем воспроизвести
его, не прибегая к загрузке.
418 глава 8
телевидение для нового поколения
f u n c t i o n h a n d le C o n t r o l (е) {
v a r id = е . ta r g e t. g e tA ttr ib u te (" id " ) ;
v a r v id e o = d o c u m e n t. g e tE le m e n tB y ld ( " v i d e o " )
if ( i d == " p la y " ) {
p u s h U n p u s h B u tto n s ( " p la y " , [ " p a u s e " ] ) ; Если пользователь пост а
v id e o . lo a d ( ) ; вит видео на паузу, то бу
v id e o .p la y ( ) ; дет задействован метод
} e ls e i f ( i d == " p a u s e " ) { pause объекта video.
p u s h U n p u s h B u tto n s (" p a u s e " , [ " p l a y " ] ) ;
v id e o . p a u s e ( ) ; Для воспроизведения видео в за
цикленном режиме у нас в объекте
} e ls e i f ( i d == " lo o p " ) { video имеется логическое свойство
if ( is B u tto n P u s h e d ( " l o o p " )) { loop. Мы просто присваиваем ему
p u s h U n p u s h B u tto n s ( " " , [ " l o o p " ] ) ; соответствующее значение...
} e ls e {
p u s h U n p u s h B u tto n s ( " lo o p " , [ ] ) ; ...для чего, чтобы было еще
} интереснее , используем ло
v id e o .lo o p = ! v id e o .lo o p ; гический оператор ! («не»),
который просто меняет
} e ls e i f ( i d == " m u te ") { за нас логическое значение.
if ( is B u tto n P u s h e d ( " m u t e " )) {
p u s h U n p u s h B u tto n s ( " " , [ " m u te " ] ) ;
з случае с m ute все происходит
} e ls e {
аналогичным образом'- мы п р о
p u s h U n p u s h B u tto n s (" m u te " , [ ] ) ;
сто меняем текущее значение
}
свойства m ute , когда пользо
v id e o .m u te d = ! v id e o .m u t e d ;
ватель нажимает кнопку Mute
(О т клю чит ь звук).
}
дальше ► 419
разбираемся с событием ended объекта video
420 глава 8
телевидение для нового поколения
J
део и даже раснолагаем двумя кнонками для вы бора между ними.
Каждой кнонке нрисвоен обработчик setVideo. Д авайте взглянем
на код, которы й нозволит нереклю чаться между этими видео: 4 1 ,
Д1<М 0Ш ЦШ ) \ 1
Вот наш объект с двумя видео, который мы приводим снова
в качестве напоминания, чтобы вы смогли по нят ь, как мы IV 1
if (id == "videol”) {
З а т е м мы обновляем кнопки
pushUnpushButtons("videol" , ["v i d e o 2 "]);
т е м же п у т е м , что и раньше,
} else if (id == "video2") { никаких изменений здесь нет.
pushUnpushButtons("video2" , ["videol"]);
Д а л ее мы используем id кнопки
(а т р и б ут id элем ент а anchor)
video.src = videos[id] + getFormatExtension();
для извлечения со от вет ст вуй
к - ющего имени видеофайла и
video, load () ; прибавляем расширение, под
video .pi ay () ; держиваемое нашим браузером.
О бр ат и т е внимание, что мы
применяем скобочную нотацию
pushUnpushButtons("play", ["pause"]); в случае с объектом videos, и с
пользуя ст року id в качестве
Мы удостоверяемся, что кнопка Play имени свойства.
(Воспроизведение) нажата, поскольку Имея корректный п у т ь
за п у с т и м проигрывание видео, когда к видео и его файловое
пользователь щ елкнет на кнопке для имя, мы загружаем и
выбора нового видео. воспроизводим данный
видеофайл.
дальше ► 421
интервью с элементом video
Интервью недели:
Признания элемента video
Head First: Д обро ножаловать, Video. Сра Head First: Все это звучит здорово, однако
зу нерейду к вонросу, которы й всех и н тере видео требует больших вы числительны х
сует, и заклю чаться он будет в отнош ениях ресурсов для обработки. Я имею в виду, что
между Вами и элементом canvas. н ри этом нроходит огром ны й н оток дан
Элемент Video: Ч то Вы имеете в виду? ных. Как JavaScript, язы к сценариев, смо
ж ет сделать здесь что-либо реальное? На-
Head First: Вы якобы кутите ночи н анролет нисание JavaScript-кода — не то же самое,
в вихре удовольствий, завтракаете вместе
что програм м ирование на нативном языке.
но утрам. Нужно ли еще что-то говорить?
Video: О, для вас это будет сю рнризом...
Video: Здесь следует отметить, что у нас с
Вы см отрели носледние тесты производи
Canvas сложились нрекрасны е взаим оотно
ш ения. Canvas отображ ает свое содерж и тельности JavaScript? Он уже является бы
мое в весьма п ривлекательной в визуаль стрым, и его скорость с каждым днем повы
ном плане манере, а я являю сь «рабочей шается. Самые блестящ ие снециалисты но
видеолош адкой». Я разбираю сь с кодеками виртуальным машинам в индустрии уснеш-
и доставляю видеосодерж имое в браузер. но работаю т над этой нроблемой.
Head First: Ч то ж, это не совсем тот от Head First: Да, но что с видео? Д ействи
вет, на которы й я рассчиты вал, но он тельно ли с ним все обстоит так?
меня устраивает. Ладно, элемент canvas
Video: Д ействительно.
нрекрасно снравляется с отображ ением
2Б-граф ики, а Вы —с отображ ением видео. Head First: Н е могли бы Вы нривести нри-
И что? В чем здесь и стинная связь? меры того, что можно сделать с номощью
Video: Как и в любых взаимоотнош ениях, JavaScript, canvas и video?
когда вы объединяете две вещ и и имеете Video: Конечно. Вы мож ете обрабаты вать
на выходе нечто большее, чем сумма двух видео в реж им е реального времени, ин
частей, то вы нолучаете нечто особенное.
спектировать характеристики видео, из
Head First: Ч то ж, а не могли бы Вы вы ра влекать данны е из видеокадров, модиф и
зиться более конкретно? ц ировать видеоданные путем, нанример...
Video: Это нростая конценция. Если вы вращ ения, м асш табирования видео или
хотите делать что-то еще номимо обы чно даже и зм енения никселов.
го воснроизведения видео (нанример, осу Head First: Н е могли бы Вы нам нов едать,
щ ествлять обработку своего видео, либо как это можно сделать в коде?
задействовать пользовательские оверлеи,
либо одноврем енно выводить несколько Video: Я еще верпусь к Вам, чтобы обсу
видеоизображ ений), то вам нотребуется дить данны й вонрос, мне тут нросто носту-
иснользовать canvas. нил звонок от Canvas... Нужно бежать...
422 глава 8
телевидение для нового поколения
Время спецэффектов
Н е н ора ли нам добавить видеоэффекты ? Мы хотим нрим енять
эф ф екты к нашему оригинальному видео, такие как Film noir, Old-
tim e w estern и даже Sci-fi. Н о если вы взглянете на API-интерф ейс
Video, то не найдете там каких-либо методов для н рим енения эф
фектов либо снособов добавить их нанрямую. Так как же мы будем
добавлять эти эффекты ? Мы х о т и м прим енят ь к на
Н емного но думайте над тем, как мы могли бы добавить эф ф екты ш ему оригинальному видео
в наше видео. Не беснокойтесь, если вы нока еще не знаете, как такие эф ф ек т ы , как Film
обрабаты вать видео, нросто обдумайте вы сокоуровневы й дизайн. noirj O ld -tim e w estern и Sci-fi.
Добравшись до пикселов,
К ак вы сможете до
как вы будете обрабаты
браться до пикселов,
образующих каждый вать их с целью применения
определенного эф ф екта?
кадр видео?
\
идеи напиш ите здесь.
дальше ► 423
план реализации спецэффектов
Временный буфер,
Мы немного изучим особенности видеообра-
который и н т е
ботки и познакомимся с методикой на основе
ресно выглядит...
применения временного буфера для добавле
ния наших эффектов.
Мы реализуем
Мы реализуем временный буфер, который даст временный буфер,
нам возможность увидеть совместно в дей используя canvas
ствии video И canvas. (хо т ит е —
верьте, х о т и
т е — нет)!
К ''
Измененные п и к
И наконец, мы соединим все воедино и прове
селы мы будем
дем тестирование! отображать,
как вы уже дога
дались, в canvas.
lO T W T V P M
424 глава 8
телевидение для нового поколения
Мы станем нрисваивать этой функции соответствующ ее значение каждый раз, когда пользователь бу
дет щелкать н а кнонке для н рим ен ен ия эф ф екта. Сейчас мы воспользуемся такими именами функций,
как western, noir и scifi, а сами эти функции наниш ем немного нозже.
8 от снова наш обработчик setEffect. Как вы по м нит е При каждом нажатии кнопки
его вызов происходит всякий р а з>когда пользователь пользоват елем мы будем присва
щ елкает на кнопке для применения эффекта. ивать переменной effect Function
значение в виде соот вет ст вую щ ей
f unction setEffect (е) { функции (все эти функции нам
var id = е .t a r g e t .g e t A t t r i b u t e ("id" / еще предст оит написать).
Если пользователь
if (id == "normal") { ре ш и т не п р и
менят ь э ф ф ек т ы j
pushUnpushButtons("normal", ["western",
то есть выберет
effectFunction = null;
"normal", мы присво
} else if (id == "western") { им значение null.
p u s h U n p u s h B u t t o n s (" w e s t e r n " , ["normal", "noir", "scifi"])
у
*■— 8 иных случа -
effectFunction = western;
ях мы будем
} else if (id == "noir") { >/ присваивать
p u s h U n p u s h B u t t o n s (" n o i r " , ["normal", "western", "scifi"]) eff ectFunction
effectFunction = noir; значение в виде
имени с о о т
} else if (id == "scifi") {
вет ст вую щ ей
p u s h U n p u s h B u t t o n s (" s c i f i " , ["normal", "western", "noir"])
ф ункциил которая
effectFunction = scifi; займ ет ся п р и
менением опреде
Нам по-преж нему нужно написать все эти функции ленного эффекта.
* для применения эффектов. Д авай т е п о см от рим
как осуществляется обработка видео, чтобы мы
смогли п р им енит ь к нему эффекты!
Итак, мы можем нереходить к изучению врем енного буфера, носле чего вернемся и носмотрим, как дан
ные функции внисы ваю тся в общую картипу и как осущ ествляется их нанисание!
дальше ► 425
обзор процесса обработки видео
/ З а т е м мы копируем обра
ботанный кадр из б уф ер
ного canvas в canvas о т о
бражения.
' Если говорить кратко,
то мы берем каждый
кадр видео и преоб
р азуем из цветного в
черно-белый, после чего
отображаем его.
426 глава 8
телевидение для нового поколения
дальше ► 427
использование временного буфера
428 глава 8
телевидение для нового поколения
<div id="videoDiv">
</div>
430 глава 8
телевидение для нового поколения
}
З а т е м мы вызываем effectFunction (если т о л ь
} ко значением соот вет ст вую щ ей переменной
display.putImageData(frame, 0, 0) не окажется null, что бывает, когда пользова
На данном эт апе обработка frame.data уже т ель нажимает кнопку "normal"), передавая ей
проведена, поэт ом у мы используем мет од позицию пиксела, значения RQB и массив frame,
putlm a geP ata объекта context для размещения data, функция effectFunction обновит массив
данных в canvas отображения. Данный мет од fram e.data, используя новые значения пикселов,
при ним ает данные в fram e и записывает их обработанные в соот вет ст вии с т е м , какая
в canvas в указанную позицию х, у. функция для применения ф и л ьт р а была п р и
своена effectFunction.
Мы обработали один кадр, что дальше?
Да, мы т о л ь к о что обработали один-единственны й кадр и хотим нродолж ать об- setT im eout анало-
работку всех кадров, нока будет идти нроцесс воснроизведения видео. Мы можем гичен setlnterval,
иснользовать метод setT im eo u t и нередать ему значение 0 миллисекунд, чтобы дать о>а исключением
указание JavaScript снова вы нолнить processF ram e так быстро, как это будет воз- того, что вы -
можно. Вообще-то JavaScript не станет вы нолнять функцию через 0 миллисекунд, полняется т о л ь -
однако обеснечит для нас самое бы строе следующее врем енное окно. Д ля этого вам ко один раз через
пужно нросто добавить данны й код в нижню ю часть функции processFram e: заданное время
Э т им мы даем иказание JavaScript в миллисекундах.
s e tT im e o u t(p ro c e s s F ra m e f 0 ) ; „ .
снова выполнить processFrame т ак
быстро, как это будет возможно!
дальше ► 431
частота кадров и таймеры
432 глава 8
телевидение для нового поколения
>>> является
m
function n o i r ( p o s, r , g , b, data) {
Таким образом, первое,
что мы делаем, — это
вычисляем значение
brightness для данного
поразрядным
—^ var brightness = (3*r + 4*g + b) » > 3; пиксела, взяв за осно
операт ором,
который сдви if (brightness < 0 ) brightness = 0 ; ву все его компоненты
гает биты в (г, b и д).
data[pos 0 ] = brigh t n e s s ;
числовом з н а А за т е м присваиваем
data[pos 1 ] = brightness ;
чении с цельно каждому компонент у
его м одиф и data[pos 2 ] = brightness ; в изображении canvas дан
кации. Ъолее ное значение brightness.
подробно о \
нем вы с м о
жете узнат ь
7 Это будет и м е т ь эф ф ект задания
для пикселя значения, обеспечивающего
из справочника Помните, что эта от т енки серого, которые с о о т в е т
по JavaScript. функция будет
с т в у ю т общей яркости пиксела.
вызываться по од
ному разу в случае
с каждым пикселом
в видеокадре!
Т
Вели задуматься, получается в неко
т ором роде удивительная вещь.
дальше ► 433
упражнение по реализации видеоэффектов
data[pos * 4 + 0] = brightness+40;
data[pos * 4 + 1 ] = brightness+20;
data[pos * 4 + 2 ] = brightness-20;
data[offset+1] = M a t h . r o u n d (255 - g) ;
data[offset+2] = M a t h . r o u n d (255 - b) ;
outputData[offset] = 80;
outputData[++offset] = 80;
outputData[++offset] = 80;
} else {
outputData[offset] = 255;
outputData[++offset] = 255;
outputData[++offset] = 255;
}
outputData[++offset] = 255;
++offse t ;
434 глава 8
телевидение для нового поколения
Реж им S C I-F I
Реж им W E S T E R N
Р еж и м FILM N O IR
дальше ► 435
В ЛАБОРАТОРИИ
Мы лишь поверхностно затронули тему обработки видео. Увере
ны, что вы сможете придумать более креативные эффекты, чем
те, которые были продемонстрированы. Придумайте несколько
таких эффектов, реализуйте и задокументируйте их здесь.
Удалось ли вам изобрести и реализовать что-то по-настоящему
классное? Расскажите нам об этом, посетив wickedlysmart.com,
и мы продемонстрируем плоды вашего труда другим читателям!
436 глава 8
телевидение для нового поколения
дальше ► 437
video streaming
А существует ли
стандарт для потокового
видео в случае HTM L5?
438 глава 8
телевидение для нового поколения
Ошибки
MEDIA ERR ABORTED= 1
MEDIA_ERR_NETW/0RK= 2 MEDIA_ERRJ)EC0DE = 3
MEDIA_ERR_SRC_N0T_SUPP0RTED = 4
дальше ► 439
обработка ошибок видео
Тенерь нам нужно нанисать функцию e rro rH a n d le r, Когда произойдет ошибка, будет
которая будет нроводить нроверку на нредмет
ошибок. Если она обнаружит ошибку, то разм естит
наше изображ ение с наднисью p le a s e s ta n d by
(не меняйте настройки) в области отображ ения
V nbllfirtHrt
вызвана Antiuwuua trirnirf-l /ил 10 ir
функция 0errorHandler.
if (video.error) {
alert(video.e r r o r .c o d e ) ;
Вы можете опционально добавить дан
ную ст року, чтобы и м е т ь возможность
увидеть код ошибки (см. предыдущую
страницу, где рассказывается о цело
Kpaui-mecm! численных значениях, которые р асполага
ю тся в свойстве code).
Существует много нричин, но которы м воснроизведение видео мож ет ока
заться неудачным, а для тестирован и я данного кода вы снециально сделае
те так, чтобы это нроизош ло. Вот ряд советов о том, как это можно сделать:
■ нонробуйте отклю чать свою сеть в разны е моменты воснроизведения
видео;
■ введите в нроигры вателе неправильны й URL-адрес;
■ нонробуйте воспроизвести в нроигры вателе видео, которое, как вам
будет известно заранее, он не сможет декодировать;
■ иснользуйте нрограм м ное обеснечение для сниж ения нропускной
снособности своего канала (оно существует, нужно лиш ь ноискать).
440 глава 8
телевидение для нового поколения
Используйте веб
Создавайте основанное службы для обеспечения
на времени содержимое, соответствующей
которое отображается контексту информации
только в определенные для своего видео.
промежутки времени Создавайте
при воспроизведении собственные
видео. экранные элементы
управления или
Используйте программные
JSONP для указатели.
добавления
интерактив
ности!
Обеспечи Применяй
вайте режим те все API-
просмотра интерфейсы
«картинка в для работы
картинке». с графикой
и текстом,
которыми вы
Используйте
умеете поль
свои стра
зоваться, на
ницы для
чиная с Canvas,
размещения
и наклады
соответству
вайте изобра
ющей рекламы.
жения прямо
поверх видео.
дальше ► 441
обзор api-интерфейсэ video
КЛЮЧЕВЫЕ ff
"МОМЕНТЫ » ---
Вы можете воспроизводить видео путем использования Вы можете программно спрашивать у объекта video,
элемента < v i d e o > в сочетании с несколькими про сумеет ли он воспроизвести видео в том или ином
стыми атрибутами. формате, используя canPlayType.
Атрибут a utoplay обеспечивает запуск воспроизве Метод canPlayType возвращает пустую строку (под
дения видео по окончании загрузки страницы, однако держка формата отсутствует), "maybe " (если ему, воз
его следует использовать, только когда он уместен. можно, удастся воспроизвести видео в определенном
Благодаря наличию атрибута controls браузер пре формате) и "probably" (если он будет уверен в том,
доставит пользователю набор элементов управления что не сможет воспроизвести видео в определенном
воспроизведением видео. формате).
Внешний вид элементов управления различается canvas может использоваться в качестве поверхности
в разных браузерах. отображения для video с целью реализации пользо
вательских элементов управления и прочих эффектов
Посредством атрибута poster вы можете предусмо
в случае с видео.
треть наличие своего собственного постерного изо
бражения. Вы можете использовать временный буфер для об
работки видео, прежде чем оно будет скопировано
Атрибут s г с содержит URL-адрес видео для воспро
В displayCanvas.
изведения.
Вы можете задать обработчик setTimeout для видео
Для форматов видео и аудио существует множество
кадров; несмотря на то что он не привязывается на
«стандартов».
прямую к каждому кадру видео, это наилучший метод,
Широко применяются три формата: WebM, МР4/Н.264
который имеется на данный момент.
и Ogg/Theora.
Вы можете использовать URL-адрес как источник видео
Изучайте свою аудиторию, чтобы понять, какие фор
для воспроизведения видеофайлов, размещаемых
маты видео вам потребуется обеспечить.
в Сети.
Используйте тег <source> для определения альтер
Некоторые браузеры задействуют политику одного
нативных форматов видео.
источника в случае с видео, так что вам придется
Используйте полностью определенные типы в сво загружать свое видео из того же источника, откуда
ем теге <source>, чтобы сэкономить силы и время исходит ваша соответствующая страница.
браузера.
В случае с видео возникновение ошибок возможно
Вы сможете сохранить поддержку других видео- всегда, особенно когда задействуется Сеть.
фреймворков, например Flash, добавив резервный
Событие error может использоваться для уведомле
тег <ob j ect> в элемент video.
ния обработчика, когда при извлечении, декодировании
Элемент v i d e o предусматривает богатый набор или воспроизведении случаются ошибки.
свойств, методов и событий.
Элемент video полагается на прогрессивно загружа
video поддерживает методы И свойства play, pause, емое видео. В настоящее время нет НТ1\/^5-стандарта
load, loop И mut e ДЛЯ ПрЯМОГО КОНТРОЛЯ НЭД BOC- для потоковой передачи видео, однако комитет стан
произведением видео. дартов начинает обращать внимание на решения для
Событие ended может использоваться для того, чтобы передачи потокового видео на основе HTTP.
дать знать, когда воспроизведение видео закончится На текущий момент не существует стандартного спо
(например, для реализации плейлиста). соба защиты видео, доставляемого посредством эле
мента video.
442 глава 8
телевидение для нового поколения
Щ Щ -К ^ С С В о р д
По горизонтали По вертикали
I. Для обеспечения набора видео в форматах, из которых 2. Мы смотрели____________ фильмы 1950-х годов.
можно будет выбрать подходящий, используйте сразу 5. Внешний вид элементов управления_____________
_____________ элементов s o u r c e . в разных браузерах.
3. Используется для отображения обработанного видео. 6. Задействуйте атрибут_____________ , если вам требу
4. Тип буфера, который мы использовали в случае ются встроенные средства управления видео.
С can vas. 8. Что следует делать, если астероид собирается врезаться
7. Тип доставки, который элемент v i d e o использует в Землю?
в случае с видео. 12. Клинту Иствуду понравился бы тип видеоэффекта, ко
9. Когда воспроизведение видео заканчивается, иницииру торый обеспечивается нажатием данной кнопки.
ется данное событие. 14. То, что мы обрабатывали при каждом вызове
10. Свойство для воспроизведения видео в зацикленном setTimeout.
режиме.
II. Запускает воспроизведение видео так быстро, как это
только будет возможно.
13. Аудиокодек с открытым исходным кодом.
15. Я могу воспроизвести данный тип видео, а ты?
дальше ► 443
решение упражнения
outputData[++offset] = 255;
}
outputData[++offset] = 255;
++offset;
444 глава 8
id
И
В w
M ro
X H
S to
И я
>
\ Safari
a
s S о
I 2 to
to
\ Chrome ^ c< и
o' I Tl
N
я Firefox > ?
SX.cc DO
i.- l s
S M obile Webkit Ob to
м
-s I о
N я Opera
• !
о 5
£ ^3
X Si
Internet Explorer JE
и выше s
0
1
I
<T
X
Internet Explorer
Э
I
Internet Explorer
сохран яем Д ан н ы е Л ^каЛ ьН с
1 2
С Браузер
Браузер сохраняем
Веб-сервер
'
Содержимое файлов
cookie.
файлы cookie локально. Cookie: pet=dog; age=5; color=black
Он отправим их об
ратно на сервер, когда Г
Пары «клю ч — значение». У нас имеется
будет совершать запрос ключ p e t со значением dog, а также ключ
о следующий раз.
аде со значением 5 и т. д.
448 глава 9
сохраняем данные локально
Сервер затем сможет использовать эти файлы cookie для персонализации взаимо-
действия. В данном случае это будет выражаться в продвижении соответствующих
элементов, касающихся определенного пользователя, но существует и масса дру
гих способов использования файлов cookie.
Ш Т У Р М
Файлы cookie уже давно у нас под рукой, однако вам, возможно, удастся придумать способ
усовершенствовать их.
Отметьте флажками те пункты из приведенных ниже, которые, по вашему мнению, делают ис
пользование файлов cookie проблематичным.
□ Похоже, что они являются удобным способом передачи вирусов и прочего вредо
носного программного обеспечения в мой браузер.
| | Мне доводилось слышать, что способ, посредством которого пары «ключ — значе
ние» включаются в HTTP-запрос, сложно реализовать в коде.
Я надеюсь, что H TM L5
предусматривает простой A P I-
интерсрейс клиентской стороны для
сохранения данны х, которы й обеспечивает и х
хранение на постоянной основе в браузере, пред
лагает больш ий объем хранилищ а и передачу
данны х на сервер только в том случае, если
я этого захочу.
450 глава 9
сохраняем данные локально
HTM L5 предусматривает изящ пы й и простой API-иптерф ейс JavaScript в браузере для сохрапепия
устойчивы х пар «ключ —зпачепие». К роме того, вы пе будете ограпичепы скудпыми 4 Кбайтами храпи-
лища; в пастоящ ее врем я все браузеры готовы предоставить вам храпилищ е разм ером от 5 до 10 Мбайт,
причем в браузере каждого пользователя. Н ТМ Ьб-техпология localStorage также создавалась с учетом
веб-прилож епий (и мобильпых прилож епий!); опа озпачает, что ваше п рилож епие сможет сохрапять
даппы е в браузере, чтобы спизить объем «общепия» с сервером. Д авайте посмотрим, как все это рабо
тает (а затем пы рпем в даппы й API-иптерф ейс с головой).
Страница может сохранить одну или бо- 0 ^ Позднее можно будет использовать
лее пар «ключ — значение» в локаль ключ для извлечения соответству
ном хранилище (localStorage) браузера. ющего значения.
Используя С0° Г р ,_
бетстбук^ ^
значение»
Имея ключ»
л .н о е х р а н и л и щ е .
MW сможем т а к *
1л з 6лече> значение
и 3 локального
xpa HwAWiMa -
Браузер
Пара «клю ч — Браузер
значение»
Конечно можно,
этим значением
будет dog.
Каждый современ-
у / ный браузер обе
спечивает локальное ПРИМЕЧАНИЕ: сервер
хранилище раз будет продолжать за
мером 5 Мбайт гружать ваши страни
цы, а вы при этом даже
(“ ^оле-е!) для каждо- сможете отправить на
го домена.
него немного данных, рас
полагающихся в вашем
localStorage локальном хранилище, для
проведения вычислений
localStorage Как и в случае с файла на стороне сервера. Одна
Хранилище обеспечива ми cookies, ваша ст ра ко с деталями локального
ет сохранение данных на ница сможет сохранять Хранилища будет р а з
постоянной основе, даже и извлекать лишь те бираться клиент, а не
элементы, которые были сервер (как это обычно
если вы закроете окно
сгенерированы страница бывает в случае с файла
браузера или вообще з а
ми, исходящими из того ми cookie).
верш ите его р аб от у. же домена. Подробно об
этом поговорим позже.
дальше ► 451
использование web storage
Не будем валять дурака, а сразу приступим к использованию локального хранилища. Для этого
вам потребуется создать простую HTML-страницу с базовыми элементами: <head>, <body> и
нение <script> (либо ВЫ можете просто воспользоваться файлом no t e t o s e l f . h t m l в примерах
кода). Следуйте за нами и наберите в своем элементе <script> приведенный далее код (ввод
кода способствует запоминанию материала):
Мы начина
На клейкой заметке присутствует лишь текст, который вы напи ем с простого,
сали, не так ли? Поэтому давайте сначала сохраним эту заметку однако прежде,
(sticky) ДЛЯ "Pick up dry cleaning" ("Забрать вещи из чем вы осознаете
химчистки"): fs" это, у нас уЖе
будет целое р а
ботающее п р и
A P I - ин терф ей с Web Storage Метод set Item принима ложение Stickies.
будет доступен посредством ет две строки в каче
обьекта localStorage. Вы увидите, Вы сможете сохранять
стве а р гум ент ов, кото
что браузер уже определил его за рые играю т роль пары только элементы т ипа
вас. Применяя его, вы используе «клю ч — значение». string. Напрямую сохра
нять числа или объекты
/ \
т е основную сист ему локального
хранения, ^ нельзя (однако мы вскоре
найдем способ обойти
это ограничение).
localStorage. set Item ("sticky_0 ’’ Pick up dry c l e a n i n g " ) ;
452 глава 9
сохраняем данные локально
Предыдущее действие было довольно простым. Давайте добавим второй элемент в локальное
О хранилище:
l o c a l s t o r a g e . s e t I t e m (" sticky_l", "Cancel cable tv, who needs it now?");
Рше один «Люч. К ак м ь I уже говорили, у вас есть Значение, которое будет
Кпъллпжность использовать для ключа любое и м я , соот вет ст воват ь нашему
^ с к о л ь к у он является ст рока*. ^ ^
сохранять только одно значение на каждый ка
4 ^ Теперь, когда у нас есть два значения, надежно сохраненные в локальном хранилище браузе-
ра, вы можете воспользоваться одним из ключей для извлечения соответствующего значения
из localStorage. Например:
J a v a S c rip t
Здорово, что данное значение было сохранено
Pick up dry cleaning и извлечено из localStorage браузера! Вы можете
заверш ит ь работу своего браузера, о т п р а
виться в от пуск на фиджи, за т е м вернуться
( )
а оно по-преж нему будет дожидаться вас там.
дальше ► 453
как работает ар 'ьинтерфейс localStorage
Это бы ло здорово,
но не м о гл и бы м ы с вами О о
пройтись по коду подробно?
Я не уверена, что разобралась
в происшедшем на 100 %.
Каждый современный
^ ^ д р а у з е р располагает
локальным хранилищ ем
«за кулисам и» , г о т о
вым к использованию
вами для сохранения пар
«клю ч — значение».
localStorage
Браузер
454 глава 9
сохраняем данные локально
дальше ► 455
вопросы о локальном хранилище
Част°
Задаваем ы е
Боцрось!
ft «Web Storage» и локальное хранилище — это одно и то же? 0 : В других технологиях, позволяющих сохранять данные в
браузере, нет ничего плохого, однако локальное хранилище HTML5
0 : Веб-стандарт называется Web Storage, однако большинство сейчас является стандартом (Google, Apple, Microsoft и прочие
компании считают Web Storage стандартным инструментом для
людей просто называют его локальным хранилищем (фактически,
сохранения содержимого локально в браузере).
браузеры как раз и предоставляют данный API-интерфейс посред
ством объекта localStorage). Web Storage — не самое удачное
название для стандарта (поскольку элементы сохраняются в вашем
браузере, а не в Интернете). Тем не менее мы придерживаемся
& Что произойдет, если я вызову setltem в отношении од
ного и того же ключа несколько раз? Скажем, дважды вызову
setltem в отношении «sticky_1». В итоге в локальном хранилище
его. Вы увидите, что мы будем использовать термин «локальное
у меня окажутся два ключа «sticky_1»?
хранилище» чаще, чем название стандарта Web Storage.
S "
Здесь ключ выглядит как индекс
\\ А вот наше значение, р а сп о л а -
для массива хранения. ™ " Р * 6 у " сторону
0 г от оператора присваивания.
Н еплохо, правда? Таким образом, вы мож ете прим епять лю бой сиптаксис, поскольку опи оба допусти
мы. А если вы привы кли использовать ассоциативпы е массивы па JavaScript, то даппы й сиптаксис мо
ж ет показаться вам более компактпым и удобочитаемым.
458 глава 9
сохраняем данные локально
Чаапо
Задаваем ы е
B olIpoC bX
ч нилище?
И г р а в скорлупки
на какой-то определенный порядок в коде. Фактически
разные браузеры могут предусматривать различный
порядок для одного и того же кода и элементов.
Готовы испытать удачу (или, скорее, сноровку)? Данная игра позволит проверить, насколько хорошо
вы знаете localStorage, однако вам потребуется проявить решительность, Используйте свои
знания об извлечении и сохранении пар «ключ — значение» в localStorage, чтобы уследить за
горошиной, когда она будет перемещаться от одной скорлупки к другой.
Можете использовать
это прост ранст во для
function shellGame() {
отслеживания сост оя
l o c a l S t o r a g e .s e t l t e m (" s h e l l l " , " p e a " ) ;
ния localStorage.
l o c a l S t o r a g e .s e t l t e m (" s h e l l 2 ", "empty");
l o c a l S t o r a g e .s e t l t e m (" s h e l l 3 ", "empty");
localStorage["shelll"] = "empty";
localStorage["shell2"] = "pea";
localStorage["shell3"] = "empty";
var value = l o c a l S t o r a g e .g e t I t e m (" s h e l l 2 ");
l o c a l S t o r a g e .s e t l t e m (" s h e l l l " , v a l u e ) ;
value = l o c a l S t o r a g e .g e t l t e m (" s h e l l 3 ");
l o c a l S t o r a g e [" s h e l l 2 "] = value;
var key = "shell2";
localStorage[key] = "pea";
key = "shelll"; Под какой скорлупкой
localStorage[key] = "empty"; находится горошина
key = "s h e l l 3";
(«реа»)? Свой о т в е т
напиш ите здесь•
localStorage[key] = "empty";
дальше ► 459
беседа технологий хранения данных
460 глава 9
сохраняем данные локально
дальше ► 461
приложение для работы с клейкими заметками
462 глава 9
сохраняем данные локально
Создание интерфейса
Для пачала пам пеобходимо пайти способ вводить текст клей
ких заметок. И было бы здорово, если бы мы могли видеть
их па страпице, поэтому пам потребуется элемепт, в котором
будут содерж аться все заметки, отображ аемы е па страпице.
Н апиш ем соответствующ ий код, пачав с HTM L-разметки. О т
кройте свой HTM L-файл и добавьте элем епт <form>, элем епт
<ul> и CSS-ссылку п а пего, как показало пиже:
/
< ! doctype html>
Mw добавили небольшое количество
CSSj чтобы наши электронные з а
<html> м е т к и выглядели более похожими
на настоящие листочки. Эта книга
<head>
не посвящена C SS, но вы можете з а
<title>Note to Self</title> глянут ь для справки в данный файл!
Cmeta c h a r s e t = " u t f -8">
<body>
Мы добавили ф о р м у в качестве интерфейса
<f orm> пользователя для ввода новых заметок.
< input type="text" i d = " n o t e _ t e x t ">
дальше ► 463
написание javascript-кода для заметок
Г
щ ест влят ь итерации по всем
function i n i t () { элем ент а м в хранилище.
for (var i = 0; i < l o c a l S t o r a g e .length; i++ Извлекаем каждый ключ.
var key = l o c a l S t o r a g e .k e y (i ) ;
А за т е м убеждаемся, что
if (key.s u b s t r i n g (0, 6) == "sticky") { данный элем ент является
var value = l o c a l S t o r a g e .getltem(key)
за м е т к о й , п у т е м проверки,
начинается ли его ключ со
addStickyToDOM(value);
"sticky". Зачем мы это делаем?
Что Ж, в localStorage м о г у т
' V находиться и другие э л ем е н
}
Если это клейкая за м е т к а , ты помим о наших клейких
то мы извлекаем ее значение зам ет о к (подробнее об эт о м
и добавляем на нашу страницу мы поговорим позже).
(посредством РОМ).
s t i c k i e s .a p p e n d C h i l d ( s t i c k y ) ;
И добавляем span в элем ент списка
"sticky"j который, в свою очередь, добав
ляем в элем ент <ul> с id в виде "stickies".
464 глава 9
сохраняем данные локально
И добавим обра
/ / f o r lo o p goes h e re ботчик., который
Остальная часть кода будет вызываться
в init будет такой же, при ее нажатии.
как раньш е, мы просто Д а нном у об
экономим м ест о, не п р и работчику мы
водя ее здесь повторно. присвоим имя
createSticky.
дальше ► 465
создание заметок с помощью кода
466 глава 9
сохраняем данные локально
4acm°
^адаВ аеМ ы е
B o llp o C b l
Т5
JJ *-
Зачем нам проводить проверку для того, чтобы узнать, Т5-
y j • Я всего лишь перезагрузил страницу, и теперь мои заметки
начинается ли ключ каждого из элементов со строки "sticky"? располагаются в другом порядке!
0 : Как вы помните, все страницы из одного домена (например, 0 : Когда вы добавляете новую заметку, ее элемент добавляется
apple.com) смогут «увидеть» любой элемент, сохраненный другими путем внедрения его в список заметок, поэтому такой листок всегда
страницами в этом домене. Это означает, что если мы не будем будет оказываться в конце списка. Когда вы перезагружаете стра
внимательно подходить к присваиванию имен нашим ключам, то ницу, заметки добавляются в том порядке, в котором они обнару
можем вступить в конфликт с другой страницей, которая использует живаются в l o calStorage (а как вы помните, определенный
аналогичные ключи иным путем. Таким образом, это наш способ порядок расположения элементов здесь не гарантируется). Вы
убедиться в том, что элемент является заметкой (а не, к примеру, могли бы подумать, что порядок будет таким же, в каком элементы
порядковым номером или игровым уровнем), прежде чем мы ис добавлялись в хранилище, либо они окажутся в каком-то другом
пользуем его значение для своей заметки. обоснованном порядке, однако рассчитывать на это нельзя. По
чему? Причина заключается в том, что соответствующая специ
Т5
JJ *-
А что, если в localStorage окажется большое количество фикация не определяет порядок, в силу чего разные браузеры
элементов, включая те, которые не являются клейкими замет могут реализовывать его по-своему. Если окажется так, что ваш
ками? Разве будет эффективным осуществление итераций по браузер будет возвращать элементы в порядке, который имеет
всему этому набору элементов? для вас смысл, можете считать, что вам повезло, но не стоит рас
считывать на данный порядок, поскольку браузер пользователя
0 : Что ж, если речь не идет об очень большом количестве эле может упорядочивать ваши элементы по-другому.
ментов, то мы сомневаемся, что вы заметите разницу. Вместе с
тем вы правы, это будет неэффективным, и, возможно, существуют Т5
J; •-
Я часто использую форму for in цикла for. А здесь он
более оптимальные подходы к управлению нашими ключами (о не сработает?
которых из них мы вскоре поговорим).
дальше ► 467
диагностика браузерного хранилища
Источник хранилища. Здесь мы и споль Для активации или доступа к ипструмептарию раз
зуе м локальные файлы , загружаемые работчика, как мы уже говорили, в разпы х браузерах
из http ://lo c a lh o st, однако это может п ридется поступать по-разпому. П осетите страпицу
быть и доменное и м я, если вы проводи h ttp :/ /w ickedlysm art.com /h fh tm l5 / devtools.htm l, что
т е тестирование на онлайн-сервере. бы узпать, как это сделать имеппо в вашем браузере.
468 глава 9
сохраняем данные локально
</body>
</html>
</form>
Г
А вот наша кнопка. Используйт е
файл m aintenance.htm l всякий р а з,
когда вам понадобится ст ерет ь
все содержимое localStorage (хо р о Данный код уда
шо подходит для тестирования). лит все элемен
|Аыпе ты в вашем до
оаг*ороЖ Н Ь 1
мене!
Н абрав даппы й код, загрузите его в своем браузере.
Теперь у вас есть возмож пость безопаспо (в случае с Если у вас име-
паш им прилож ением для работы с электроппы м и за ется сверхценное локальное хранилище
метками N ote to Self) очистить localStorage, поэто °гЛ 3аИТ е ° другим проектом в том же
самом домене, то выпишитесь всех своих
му попробуйте это сделать! Н о спачала убедитесь в
элементов, если выполните данный код.
том, что вы разобрались в своем ипструмептарии раз просто имейте это в виду...
работчика, чтобы увидеть измепепия.
дальше ► 469
проблема с приложением note to self
Прежде всего наши клей кие заметки нумеруются от нуля до числа, которое
обозначает общее и х количество (минус один):
ооооо
Ms tic k y _ 0 " "s tic k y _ 1 " "s tic k y _ 2 " "s tic k y _ 3 " "s tic k y _ 4 "
Пять за м ет о к с м е т ка м и от О до 4.
Чтобы добавить новую заметку, м ы подсчиты ваем количество элементов
в локальном хранилищ е и создаем новый кл ю ч исходя из получивш егося
количества:
^ ^ ^ ^ ^ ^
"s tic k y _ 0 " "s tic k y _ 1 " ,,s tic k y _ 2 " "sticky_Z" ,,s tic k y _ 4 ” " s tic k y .S ”
ч * 4 2
Значением length на данный м о м е н т является
поэт ом у мы осуществляем ит ерацию от О до 5,
отображая зам ет ки от "sticky_0" до "sticky_S".
470 глава 9
сохраняем данные локально
—
var key = "sticky_n + localStorage.length; - ' о
"sticky_9”
При создании новой за м ет ки значением length локального
хранилища будет <?, поэт ом у мы создаем за м е т к у с именем
sticky_я". Х м , не похоже, что это будет правильным.
Когда нам потребуется совершить итерацию по заметкам для того, чтобы
отобразить их, у нас возникнет проблема:
QQ Q Q Q Q
"sticky_0” "sticky_1" "sticky_2" ”sticky_3" ”sticky_4" “sticky_5” — ’ ------- ^ — J '— v— '
Q
“sticky_9”
4 Я 3 Ч -Л
Теперь значением length является НО (мы только что
добавили новую за м е т к у ), поэт ом у итерация будет \■ # T
осуществляться от О до Я с отображением каждой О >" s t ic k y ^ , s ic у_
зам ет ки от "sticky_0" до "sticky_4". WAU "st'C^yS У нас Иет'
j [ Клейкая заметка может быть перезаписана методом setltem, если объем localStorage
уменьшится, несмотря на то что другое приложение удалит все свои элементы.
Сложно быстро сказать, сколько имеется клейких заметок; вам придется осуществлять
итерацию по каждому элементу в localStorage, чтобы извлечь все заметки.
дальше ► 471
сохранение массивов
472 глава 9
сохраняем данные локально
Вернемся немного назад и представим, что у нас имеется шесть клейких за
меток В localStorage:
И зам ет ки , и массив
Шесть клейких зам ет ок с м е т к а м и от О до 5 "stickiesArray" располагаются
localStorage.
дальше ► 473
переписываем приложение с использованием массива
474 глава 9
сохраняем данные локально
function i n i t () {
sticki e s A r r a y = [];
l o c a l S t o r a g e .s e t l t e m (" s t i c k i e s A r r a y " , __________ ,(stickiesArray)) ;
} else {
s ticki e s A r r a y = ____________ (stickiesArray) ; Me?/ добавили данное предложе
} ние else, поскольку вам п о т р е
буется кое-чт о п редпринят ь,
for (var i = 0; i < s t i c k i e s A r r a y .length; i++) {
если вы извлечете массив из
var key = s t i c k i e s A r r a y [ i ] ; localStorage (поскольку это
var value = l o c a l S t o r a g e [ k e y ] ; будет строка, а не массив).
addStickyToDOM(value);
addStickyToDOM(value);
) блем) нам пот ребует ся соз
дать более уникальный клю ч.
дальше ► 475
добавление уникального идентификатора Часто
ЧаДаВаеМые
В опросы
Ч то именно необходимо изменить?
Что это за значение в виде количества
f t
Есть две вещи, которы е пеобходимо изм епить в createSticky. мил;
миллисекунд, прошедших с 1970 года?
Во-первых, пам потребуется п овы й способ геп ери ровап ия упи-
кальпого клю ча для каждой клейкой заметки. Во-вторых, пам
будет пужпо изм епить код, чтобы оп сохрапял определеппую
О:' Вы, возможно, уже знаете, что миллисекун
да представляет собой тысячную долю секунды,
а метод getTime возвращает значение, ко
заметку в stickiesArray в localStorage.
торое является общим количеством миллисе
ф Создание уникального ключа для клейкой заметки. кунд, прошедших с 1970 года. Почему именно с
1970 года? Данное поведение унаследовано от
Существует масса способов создапия упикальпых клю операционной системы Unix, которая определя
чей. Мы могли бы использовать зп ачеп ия даты и време- ла время таким способом. Несмотря на то что
пи, либо геперировать причудливые случайпые 64-бит- такой подход неидеален (например, значения
пые числа, либо задействовать в сочетапии с пашим времени до 1970 года представляются в виде
п рилож епием API-иптерфейс, связаппы й с атомпы ми отрицательны х чисел), он окажется кстати,
часами. И спользование зп ачеп ий даты и врем епи пред когда вам потребуется уникальное число или
ставляется хорош им и легким реш епием. JavaScript под возникнет необходимость отслеживать время
в JavaScript-коде.
держ ивает объект Date, которы й возвращ ает зпачепие в
виде количества миллисекупд, прош едш их с 1970 года;
даппое зпачепие должпо оказаться достаточпо упикаль- Разве применение методов parse и
пым (если только вы пе собираетесь создавать свои за stringify в случае с JSON-типами не явля
ется довольно неэффективным с точки
метки с очень высокой скоростью):
зрения производительности? А если мой
— Создаем объект P a te, а за т е м извлекаем массив сильно разрастется, то не окажется
^ значение текущего времени в миллисекундах. ли так, что и сохранение будет осущест
var currentDate = new Date() ; ^ л w _ вляться неэффективно?
Наш новый код для
var time = currentDate .getTime () ; > генерирования уни -
„ ^. . „ , ^.
var key = "sticky_" + time; J\ кального клю ча. 0 : Теоретически, да, по обоим упомянутым
вами пунктам. Однако в случае с типичными за
Теперь, когда у пас имеется способ геп ери ровап ия упи- но сохранения данных, то можете столкнуться
с проблемами, используя JSON для преобразо
кальпого ключа, пам пеобходимо сохрапить текст заметки
вания элементов в строки и обратно.
с этим клю чом и добавить даппы й ключ в stickiesArray.
П осмотрим , как это можпо сделать, а потом объедипим
весь код. Вместо того чтобы повт орят ь весь код
Сначала извлечем массив stickiesArray. для извлечения и проверки stickiesArray,
как мы это делали в функции init (на п р е
var stickiesArray = getStickiesArray(); дыдущей странице), мы создадим новую
функцию. Д о этого мы дойдем позже.
localStorage.setltem(key, value)
З а т е м сохраняем ключ с его значением,
stickiesArray.push(key);
как делали раньше (только речь здесь
localStorage.set l t e m ("stickiesArray" идет о нашем новом ключе).
Сначала мы и з
влекаем э лем е нт
"stickiesArray" из
localStorage.
function getStickiesArray() {
Г
var stickiesArray = localStorage.ge t l t e m ("stickiesArray" И если все-т аки массив
Если это будет первая наша будет о т с у т с т в о в а т ь ,
if (!stickiesArray) загрузка данного приложения, то мы создадим пустой
то элем ент "stickiesArray" массивj а за т е м сохраним
stickiesArray = []
может от сут ст воват ь. его в localStorage.
localStorage.set l t e m ("stickiesArray" JSON.stringify(stickiesArray)
Не забудьте сперва п р е
} else {
образовать его с п о м о
щью метода stringify!
stickiesArray = JSON.parse(stickiesArray);.
3 прот ивном случае мы все же
находим в localStorage массив,
в отношении которого нам п о
return stickiesArray; т ребует ся прим ени т ь мет од
3 любом случае parse, чтобы преобразовать его
в итоге у нас 6ydev в JavaScript-Maccu6.
массив, который
мы возвратим.
дальше ► 477
интеграция всего кода
Начинаем с извлечения
function createSticky () { массива stickiesArray.
var stickiesArray = getStickiesArray () ; Л а л е ес о з д а д и м уникальныи
-X к л ю ч для нашей новой заметки.
var currentDate = new Date() ;
addstickyToDOM(value); с А за т е м применяем м ет од
j stringify для преобразования
Наконец, обновляем страницу массива и записываем его
с использованием новой за м ет ки обратно в localStorage.
п у т е м ее добавления в РОМ.
478 глава 9
сохраняем данны е локально
Тест-драйв!
(Aaatdcfcyncaiataf-,
Н а б е р и т е весь и р и в е д е и п ы й в ы ш е к о д , о ч и с т и т е
у себя l o c a l S t o r a g e , ч т о б ы п а ч а т ь с ч и с т о г о л и ста . Pick up dry Cancel Buy another
З а гр у з и т е д а п п ы й ко д , в резул ьта те ч е го в ы д о л ж - cleaning сable tv, Apple
п ы у в и д е ть т о ч п о т а к о е ж е п о в е д е п и е , к а к и в п р о who needs gadget
it now?
ш л ы й раз. Д ж о эль, т ы у в и д и ш ь , ч т о т е п е р ь т в о й
к о д р а б о та е т д о л ж п ы м о б р а зо м !
J
Часш °
^адаВ аеМ ы е
B o llp o C b l
Tj J5*- Мы используем вить план относительно того, какие име Выбирайте схему
"sticky_" как на вы будете присваивать элементам.
префикс для имен наших элементов присваивания имеи
localStorage. А существует ли согла
1Если у меня будет много клейких
шение относительно схем присваи
заметок, то мой массив stickiesArray
для своих элементов
вания имен элементам localStorage?
станет очень длинным. Это будет про
блемой?
localStorage, которая ие
! Соглашения, касающегося присваи
вания имен элементам l o c a l S t o r a g e ,
! Если только вы не создадите тыся
приведет к конфликтам
не существует. Если ваше приложение
располагается на небольшом сайте в
чи заметок. В противном случае это не
должно превратиться в проблему (а если
с другими приложениями
домене, который находится под вашим
контролем, то с присваиванием имен не
вы все же создадите тысячи заметок, то
нам хотелось бы узнать, как вам уда
в том же самом домеие.
должно возникнуть проблем, поскольку
лось оказаться столько продуктивным!).
вы будете осведомлены обо всех именах,
В наши дни JavaScript работает довольно
которые используются разными страни
цами на данном сайте. Мы считаем, что
быстро.
Если вам потребуется
хорошей идеей будет использовать имя,
которое является индикатором страницы
или веб-приложения, полагающегося
на элемент с данным именем. Таким
& Просто чтобы прояснить ситу
ацию: мы сможем сохранить любой
объект в localStorage, всего лишь
сохранить массивы и м
объекты в localStorage,
образом, " s t i c k y _ " помогает нам предварительно преобразовав его
запомнить, что такие элементы связаны с помощью метода stringify A P I- используйте JSON.
с приложением Note to Self для работы интерфейса JSON?
с электронными заметками. stringify для создания
& Если мое приложение Note to
Self является лишь одним из многих
приложений в домене, то мне нужно
0 : Все верно. JSON-строки пред
ставляют собой упрощенные версии
JavaScript-объектов, а наиболее простые
JavaScript-объекты могут быть преоб
значения, которое
можно буцет сохранить,
беспокоиться о потенциальных кон разованы в строки с помощью JSON и
фликтах? сохранены в l o c a l S t o r a g e . Сюда и задействуйте
относятся массивы (в чем вы убедились
0 : Да. Вам (или тому, кто управляет ранее), а также объекты, содержащие JSON.parse иосле того,
веб-сайтами в соответствующем домене) имена свойств и значения, как вы вскоре
в данном случае будет полезно соста увидите. как извлечете его.
дальш е ► 479
еще одна т ребуемая ф ункция: удаление
Buy another
Pick UP dTY Apple
cleaning gadget
Learn tWW
db -clutter
Go grocery < vi d e o >
shopping
my d e ^ works
Find my
Order
mobile
Tweetshirt
phone
t-slni*
Learn how
Drink more
Get rid of to meditate
coffee
some of
these sticky
Б удьт е осторожны
Удаление клейких заметок с ост рыми предмет ами!
Она нрава: дан ное н рнлож енне не будет иметь большого уснеха,
если он о н е но зв о лит удалять заметки. Мы уже уноминали метод
l o c a l S t o r a g e . re m o v eltem , однако не беседовали о нем. М етод
remove I t e m нриним ает ключ элемента и удаляет данны й элемент
и з lo c a lS to r a g e :
lo c a l S t o r a g e . re m o v eltem (k ey );
r e m o v e l t e m и м е е т один
Д а н н ы й м е т о д у д а л я е т с о дер п а р а м е т р : кл ю ч э л е м е н т а ,
жащийся в localStorage э л е подлежащего у д а л е н и ю ,
м е н т с о пр еделен ны м к л ю ч о м .
480 глава 9
сохраняем данны е локально
Свой псевдокод
н а п и ш и т е здесь.
дальш е ► 481
реш ение упражнения
l o c a l S t o r a g e r e m o v e i t e m C s > t i c k y ^ 0 4 Z Z 0 0 0 ^ 3 4 Z ),
482 глава 9
сохраняем данны е локально
Функция deleteSticky
В ы с о с та в и л и п л а н т о г о , к а к будет о с у щ е с тв л я ть с я удаление к л е й к и х
за м е т о к, н о э т о м у да в а й те в згл я н е м н а ф у н к ц и ю d e l e t e S t i c k y :
дальш е ► 483
в ы бо р замет ок с п ом ощ ью h tm l и ja va s c rip t
т е , пр
замет ку. ^ ^ в и з ° ве ° т п р о м -
и
f u n c t i o n addStickyToDOM(key, v a l u e ) {
*^ т пражненке
аЖ н Ваша задача — обновить весь код таким образом, чтобы везде, где мы будем вызывать
addStickyToDOM, мы передавали ключ, а также значение. Вам не должно составить тру
да найти эти места. Выполнив данное задание, посмотрите его решение в конце главы,
чтобы проверить свои результаты.
Не п р о п у с к а й т е э т о у п р а ж н е -
ние, иначе п р е д с т о я щ и й т е с т -
драйв окажется неудачным!
484 глава 9
сохраняем данны е локально
I
< l i i d = " s t i c k y _ 1 3 0 4 2 70008375"> Э т о HTML для
зам ет ки, к о т о
< sp an c l a s s = " s t i c k y " > P i c k up d r y c l e a n i n g < / s p a n >
р у ю м ы создаем
< /li>
в addStickyToD O M .
Так или иначе , о б ъ е к т e ven t,
ta r g e t — э т о э л е м е н т , на к о т о р о м вы щ е л к н у л и
сгенерированный в а ш и м щ е л ч
и кот о ры й с генерировал о б ъ е к т event. Мы м ож ем и з
к о м > п ер едает ся d eleteSticky.
влечь и д е н т и ф и к а т о р данного э л е м е н т а из свойст ва
target. Если t a r g e t я вля е т ся <(/>, т о все в порядке.
f u n c t i o n d e l e t e S t i c k y (е) { Если ta r g e t окажется <span>,
v a r k ey = e . t a r g e t . i d ; т о нам п о т р е б у е т с я извлечь
if ( e . t a r g e t . tagN am e. t o L o w e r C a s e () == "span") {' идент ификат ор родит ель
ского э л е м е н т а , т о е с т ь <(/*>
k ey = e . t a r g e t . p a r e n t N o d e . i d ;
(<Ч> — э т о э л е м е н т с и д е н т и
} ф и к а т о р о м , ко т о р ы й я вля ет ся
lo c a lS t o r a g e . rem o v eltem (k ey ); необходимым на м клю чом).
var s t ic k ie s A r r a y = g e t S t i c k i e s A r r a y (); Теперь мы м ож ем в о с
if (stick iesA r ra y ) { п о ль зо ва т ь с я к л ю ч о м
for (var i = 0; i < s t i c k i e s A r r a y . l e n g t h ; i+ +) { для удаления э л е м е н т а
из localStorage , а также
if (k e y == s t i c k i e s A r r a y [ i ] ) {
из stickiesArray.
s t i c k i e s A r r a y . s p l i c e ( i , 1);
}
}
lo c a l S t o r a g e . s e t I t e m (" s tic k ie s A r r a y " , J S O N .s tr in g ify (s tic k ie s A r r a y )
removeStickyFromDOM (key) ; ^ __
Нам также п о т р е б у е т с я у д а л и т ь <li>, с о д е р
} жащий к л е й к у ю з а м е т к у , из с т р а н и ц ы , чтобы
данная з а м е т к а исчезла, когда вы на ней щ е л
кнет е. Э т и м м ы и з а й м е м с я далее...
дальш е ► 485
удаление замет ок из dom
-V Отличная работа! А не X
Umak, проведем т е с т .
м о гл и бы вы теперь сделать
Н а б е р и т е весь п р и в о д и в ш и й с я в ы ш е к о д , з а гр у зи т е с т р а н и так, чтобы я см огла раскрашивать
цу, доб авьте и удал ите н е с к о л ь к о к л е й к и х за м е т о к. З а в е р ш и свои заметки? Ну там, знаете, ж ел
те р а б о ту браузера, за те м сн о в а з а п у с ти те е го и х о р о ш е н ь к о ты м цветом те, на которы х записаны
протести руйте прилож ение срочные дела, синим — на которы х
помечены идеи, розовым — заметки
I со второстепенны ми делами.
В таком духе? у
I г.
t-ihirt
Теперь мы можем
удалять заметки!
Конечно моЖно!
У ч и т ы в а я ваш о н ы т в э т о м деле, м ы с м о ж е м с п р а в и т ь с я с д а н н о й зад ачей. К а к
и м е н н о м ы э то сделаем? Ч т о ж , м ы созд адим о б ъ е к т для р а зм е щ е н и я т е к с т а за
м е т к и и ее ц в е та , а за те м с о х р а н и м е го к а к з н а ч е н и е эл е м е н та за м е т ки , п р е д в а р и
т е л ь н о зад ействов а в JSON. s t r i n g i f y для п р е о б р а з о в а н и я е го в стр о ку .
486 глава 9
сохраняем данны е локально
Sx* ЮI;If
1+ л;tijttmi
Cotof: I у»ИвшЯ
для чего C o- p tio n v a lu e = " L ig- h t P i r i k " > p i n k < / o p t io n > ' е т с я и м е н е м ц в е т а , ко
ю еднаыа- , т о р о е мы мож ем в с т а -
реоназна < o p t io n v a lu e = " L ig h t B lu e n> b lu e < / o p t io n > п,,, . А п
чено данное о и т ь п р я м о в с т и л ь для
поле. < /se le c t> наш их за м е т о к .
^ ^ < l a b e l f o r = " n o t e _ t e x t n> T e x t : < / l a b e l > <i n p u t t y p e = " t e x t " i d = " n o t e _ t e x t ">
< i n p u t t y p e = " b u t t o n " id = " a d d _ b u t to n " valu e= "A d d S t i c k y N o te t o S e l f " >
< /fo r m > jk
•О с т а л ь н а я ч а ст ь ф о р м ы о с т а н е т с я прежней.
< /h t m l>
дальш е ► 487
использование js o n для сохранения цвета
Color: [pink Text: [Cancel cable tv, who needs it now? ~] (Add sticky Note to S eif) |
t
Мы будем д р а т ь введенные п о л ь з о в а т е И мы с охра ни м его
л е м значения для ц ве т а и т е к с т а з а м е т к и в localStorage с и с
и « у п а к о в ы в а т ь » их в п р о с т о и объект . поль зо ва ни е м клю ча
клейкой з а м е т к и . localStorage
Точно т а к же, как и
в случае со stickiesA rray,
var stick yO b j = {
н а м п р и д е т с я вы зва т ь
" v a lu e " : "C an cel c a b l e t v , who n e e d s i t now?",
JSO N .strin gify в о т н о - ‘
" c o l o r " : " L ig h tP in k "
илении значения з а м е т к и ,
};
прежде чем м ы вызовем
loc a lStorage.setltem для с о
хранения данного значения.
П е р е н и ш е м ф у н к ц и ю c re a te S tic k y для с о х р а н е н и я ц в е та вм е сте с т е к с т о м к л е й к о й за м е т к и .
Д л я н р е д с та в л е н и я т е к с т а и ц в е та будем и с н о л ь з о в а т ь н а ш у д о б н ы й о б ъ е кт:
f u n c t i o n c r e a t e S t i c k y () {
var s t ic k ie s A r r a y = g e t S t i c k i e s A r r a y (); Мы делаем т о , чт о
v a r c u r r e n t D a t e = new D a t e ( ) ; обычно п р и н я т о для
var colorSelectObj = document.getElementByld("note_color") извлечения значения
выбранного цвета.
var index = colorSelectObj.selectedlndex;
var color = colorSelectObj[index].value;
v a r k ey = " s t i c k y _ " + c u r r e n t D a t e . g e t T i m e ( ) ; З а т е м и с п о л ь з у е м данное
значение ц в е т а для соъда
var v a lu e = docum ent. g e t E l e m e n tB y ld (" n o t e _ t e x t " ) . v a l u e ;
ния S t i c k y O b j - объект а.
var stickyObj = { содержащего два с в о й с т в а ,
"value11: value, т ек ст зам ет ки и цвет ,
вы бранный п о л ь з о в а т е л е м .
"color": color
}; П реобразуем stickyO bj
у с пом ощ ью мет ода JSON
localStorage.set Item (key, JSON.stringify (stickyObj )) ; Stringify прежде чем
s t i c k i e s A r r a y . p u s h (key) ; м е с т и м его в localStorage.
l o c a l S t o r a g e . s e t lt e m ( " s t ic k ie s A r r a y " , J S O N .s t r i n g if y ( s t i c k ie s A r r a y ) );
addStickyToDOM (key, stickyObj); / Передаем о б ъ е кт в м е с т о т е к с т о в о й с т р о к и ф ун кц и и
addStickyToD O M . А э т о означает , ч т о ва м также п о
т р е б у е т с я обновит ь a d d S tic k y T o D O M , не т а к ли ?
488 глава 9
сохраняем данны е локально
Есть ещ е одно м есто, где нам н еобходи м о обновить код. И находится оно в функции
i n i t , где мы извлекаем заметки и з l o c a l S t o r a g e и нередаем их addstickyToDOM, когда
в нервый раз загружаем страницу.
f u n c t i o n i n i t () {
v a r b u t t o n = d o c u m e n t . g e t E l e m e n t B y l d ( " a d d _ b u tt o n " )
b u tto n . o n click = crea teS tick y ;
Теперь, когда мы будем и з
var s t ic k ie s A r a y = g e t S t i c k i e s A r r a y (); влекат ь значение за м ет к и из
localStorage, нам по т реб ует ся
преобразоват ь его с помощ ью
for (v a r i = 0; i < s t i c k i e s A r r a y . l e n g t h ; i+ +) { JSO N .parse, поскольку эт о
v a r k ey = s t i c k i e s A r r a y [ i ] ; больше не строка а объект.
var v a lu e = J S O N .p a r se (lo c a lS to r a g e [k e y ])
И м ы передадим данный о б ъ е кт
addstickyToD O M (key, v a l u e ) ; 4 ------------------
ф ункци и a d d stick y T o D O M в м е с т о
} с т р о к и (код вы глядит т а к же, одна
ко п ередаем м ы уже ч т о - т о другое).
дальш е ► 489
т ест ирование цвет ны х замет ок
Wrccic S:11
j j | + I* Ч-и 1-~У1гЧ-.1тг:у|па1:к1й‘ '-г,а С | '<Хг G z c j i
1 - ___ _ J
<s>инч-а- ^ wit Cl"j
n |*-п-*нч ’ •.r
n | ;*-«***■ Г" AI^J U.I№MI.2 11чМуг. >A'i U.1J 4dll|l||i' JW
j>
b U.tU W. .1 J'r I UMlft *>, i tJJ*Hl4Aa
■ >/ I ЫЛ& W I
I' 'llfl J*i tj; u.Sl»*«.+ u; l »V*‘ '»U'’JV,4'* i
* -j : "iintv
*■.. Vui'lm
*■ _•ЕнММ
*■^ Л1**
m *5________
490 глава 9
/ Я д ум а л ; раз м ы м ожем сохра- \
нять объекты и массивы, то почему q
. бы просто не сохранить все заметки в \
самом массиве, зачем нам нужны все эти I
остальные элементы? П о хо ж е , все только
усложняется, хотя м ы м о гл и бы просто /
у вложить и х в один элемент /
в localStorage. У
Н е с м о т р я н а т о ч т о н а ш а р е а л и за ц и я м о ж е т б ы т ь с л е гка
гр о м о з д к о й для о г р а н и ч е н н о г о к о л и ч е с т в а за м е т о к, м ы н а
деем ся, ч т о о н а о т л и ч н о н о м о гл а вам н о н я т ь , ч т о т а к о е A P I-
и н т е р ф е й с l o c a l S t o r a g e и к а к о б р а щ а ть с я с и м е ю щ и м и с я
в н е м э л е м е н та м и .
Ш ПЫТАЙТЕСЬ СДЕЛАТЬ ЭТО ДОМА
(И ЛИ КАК РАЗИКСТИ В ПУХ II ПРАХ ВАШ И 5 МБАЙТ)
Как мы уж е говорил и, в сумме у вас будет 5 М байт хранилищ а для браузера ка ж д ого из пользователей.
Несмотря на то что такой объем может показаться больш им, все ваши данные сохраняю тся в виде стро к,
а не в байтовом формате. Возьмите, к прим еру, размер госуд арственного долга: если вы разить его в виде
значения с плавающей то чко й , то для его размещ ения в хранилищ е потребуется не м н ого места, од н ако
если вы разить его в виде стр о ко в о го значения, то для его сохранения потребуется гораздо больш ий объ
ем. Таким образом , хранилищ е разм ером 5 М байт спо соб н о вместить не так м ного, ка к могло показаться.
Так что же произойдет, когда вы исчерпаете 5 Мбайт? К сож алению , это од но из поведений, которы е не
определяю тся специф икацией HTML5, и браузеры м о гут поступать по-разном у, когда вы превы сите свой
лимит. Браузер может спр оси ть у вас, хотите ли вы увеличь объем хранилищ а, либо сген ер и рует и скл ю че
ние QUOTA_EXCEEDED_ERR, которое м ож но перехватить следую щ им образом :
Вызов s e t l t e m в с е р е д и
не блока t r y ; если ч т о -
нибудь п о й д е т не т а к
' try { f и s e t l t e m с ге н е р и р у е т
l o c a l S t o r a g e . s e t l t e m (шуКеу, myValue)
и ск л ю ч е н и е , т о будет
t ru/catck пере _ c a t c h (е) {
задейст вован блок catch.
i f (e == QUOTA_EXCEEDED_ERR) {
и с к д к н е н и я , ге н е р и a lert(" O u t o f sto ra g e !" )
руемое 6 блоке try- }
П р о ве р я е м , ошибка ли э т о квот ы х р а н и л и щ а (а не
к а к о й - т о другой т и п и склю ч ен ия ). Если т а к оно
Э т о о бласт ь J a v a S c rip t,
и е с т ь j м ы выведем для п о л ь з о в а т е л я диа л о го
к о т о р у ю мы не з а т р а
вое окно ale rt с с о о т в е т с т в у ю щ и м сообщением.
ги в а л и , и вы м ож ет е
Вы, скорее всего, з а х о т и т е с д е ла т ь ч т о - т о более
з а х о т е т ь исследоват ь
зн а ч и т е л ь н о е , чем п р о с т о вывод окна alert.
э т о т вопрос подробнее.
492 глава 9
сохраняем данные локально
ОПАСНО
Взрывное
<html>
задание
<head> Начнем с односимвольной
с т р о к и с к л ю ч о м "fuse".
< scrip t>
И п р о с т о будем , не ост а н а вл и -
lo c a lS to r a g e . se tlte m ( "fuse", ; ваясь, у в е л и ч и в а т ь ее размер...
w h ile(tr u e ) { ..п у т е м удваивания э т о й
v a r f u s e = l o c a l S t o r a g e . g e t l t e m ("f u s e с т р о к и (п о с р е д с т в о м к о н к а
try { т ена ции ее с сам ой собой).
дальш е ► 493
инф орм ация о sessionstorage
О б ъ е к т s e s s i o n s t o r a g e п о д д е р ж и в а е т т о ч н о та
к о й ж е A P I-и н т е р ф е й с , ч т о и l o c a l S t o r a g e , но-
э то м у вам у ж е и з в е с т н о о н е м все н е о б х о д и м о е .
В о с п о л ь зу й те с ь и м !
494 глава 9
сохраняем данны е локально
dear И с п о л ь з у й т е м е п я для с о х р а п е п и я э л е м е п то в п а д л и т е л ь п ы й с р о к .
Я п р и п и м а ю к л ю ч и и з п а ч е п и я , к о т о р ы е за те м з а п и с ы в а ю
feffionStorage в l o c a l S t o r a g e . И м е й т е в виду, ч т о е сли в l o c a l S t o r a g e у ж е и м е
е тся т а к о й к л ю ч , я п е буду п р е д у п р е ж д а ть вас об э то м , а п р о с т о
п е р е з а п и ш у е го , п о э т о м у вам следует п о п и м а т ь , о ч е м в ы п р о с и т е .
key Е сл и в ы с та п е те з л о у п о т р е б л я т ь г о с т е п р и и м с т в о м в l o c a l S t o r a g e
и и с п о л ь зо в а ть с л и ш к о м м п о го п р о с т р а н с т в а , то будет с ге п е р и р о -
в а п о и с к л ю ч е н и е и в ы п о л у ч и т е о т м е п я и з в е с ти е .
setltem
Н у ж п о уд а л ить элем епт? Я а к к у р а т п о в ы п о л п ю э ту работу.
removeltem П р о с т о д а й те м п е к л ю ч , и я о т ы щ у эл е м е п т с д а п п ы м к л ю ч о м и п е
редам вам е го зп а ч е п и е .
Я — р а з п о в и д п о с т ь х р а п и л и щ а п а к о р о т к и й с р о к : буду с о х р а п я т ь
length в а ш и д а п п ы е , п о к а о т к р ы т о о к п о браузера. З а к р о й т е о к п о браузе
р а и — бац! — все в а ш и д а п п ы е и с ч е зл и .
localStorage Н у ж п о у зп а ть к о л и ч е с т в о эл е м е п то в в ваш ем l o c a l S t o r a g e ? Я п о
м о гу вам с э ти м .
QUOTAJXCEEDEDJRR Д а й т е м п е и п д е к с , и я п р е д о с та в л ю вам к л ю ч о т п е го в l o c a l S t o r a g e .
дальш е ► 495
вариант ы использования web storage
496 глава 9
сохраняем данны е локально
У меня есть
действительно класс
ная игра, которая работает
в двух разных окнах браузера, и я
использую localStorage для син
хронизации состояния.
Я сохраняю множество л о
кальных данны х, чтобы сделать
приложения м о и х клиентов бы стры
ми на м обильны х устройствах. Н аличие
больш ого хранилищ а на клиентской
стороне дает огр о м н ы й выигрыш.
дальш е ► 497
обзор web storage
КЛЮЧЕВЫЕ
-------------------------- МОМЕНТЫ
■ Web Storage — это хранилище в вашем браузере и API- пункт Delete (Удалить) (данный подход работает не во
интерфейс, который вы можете использовать для всех браузерах).
сохранения и извлечения элементов из хранилища. ■ Вы можете удалять элементы из l o c a l S t o r a g e
■ Большинство браузеров обеспечивают по крайней мере в коде, используя методы r e m o v e l t e m ( к л ю ч - ) и
по 5 Мбайт хранилища на каждый источник. c l e a r . Следует отметить, что метод c l e a r удаляет
498 глава 9
сохраняем данны е локально
U I M L 5 - K f ° CCB ° r A
Ц ^ Ф V tTA Trи
TTте
T»^ п
ТТ^Т^/ЛТ’
Уд ел е к о т оПГЧ/ЛА
р о е кТ/П
о лТТиТТчТТА
е с/'Т
т’
вЮ/Л
о врем епи тестир о ва
н и ю с в о е го с о б с т в е п п о го л о к а л ь п о го х р а п и л и щ а .
а
г г п ■ ■
м ■ ■ ■ ■ ■
По горизонтали По вертикали
4.Имя сестры Люка Скайуокера. 1. Мы создаем___________ для размещения текста заметки и ее
5.Когда мы использовали значение____________ l o c a l S t o r a g e цвета в одном элементе l o c a l S t o r a g e .
для генерирования имен ключей, то столкнулись с проблемой — 2. У файлов c o o k i e имеется проблема с _____________ .
в последовательности имен наших клейких заметок оказались 3. Мы использовали_____________ для размещения ключей
бреши. всех наших клейких заметок, благодаря чему отыскать их
7. l o c a l S t o r a g e позволяет сохранять только____________. в l o c a l S t o r a g e не составит труда.
9. Мы можем выяснить, на какой заметке щелкнул пользователь, 6. Сеансовое хранилище подобно локальному хранилищу за ис
обратившись к e v e n t . _____________. ключением того, что элементы, которые в него помещены, не
10. Нам необходимо преобразовать объект с помощью метода сохраняются там н а _____________ основе и удаляются, если
_____________ , прежде чем сохранять его в l o c a l S t o r a g e . вы закрываете окно браузера.
11. Большинство браузеров предлагает_____________ мегабайт 8. Используйте____________для преобразования строки в цело
хранилища на каждый источник. численное значение.
12. Данный метод используется для сохранения элементов в 13. Если вы сохраните что-то в своем браузере и полетите на
lo c a lS to r a g e. , то оно по-прежнему будет там, когда вы вер
14. Мы полагали, что можно лишь мечтать о возможности сохра нетесь.
нить ______________ в l o c a l S t o r a g e , но, как оказалось,
она существует, и дает ее JSON.
15. Используйте t r y / ________ для выявления ошибок, возника
ющих из-за превышения квоты хранилища, в l o c a l S t o r a g e .
дальш е ► 499
реш ение упражнения
Готовы испытать удачу (или, скорее, сноровку)? Данная игра позволит проверить, насколько хорошо вы
знаете l o c a l S t o r a g e , однако вам потребуется проявить решительность. Используйте свои знания об
извлечении и сохранении пар «КЛЮЧ — значение» В l o c a l S t o r a g e , чтобы уследить за горошиной, когда
она будет перемещаться от одной скорлупки к другой. Вот наше решение этого задания.
f u n c t i o n s h e ll G a m e ( ) {
l o c a l S t o r a g e . s e t l t e m ( " s h e l l l " , "p ea" );
l o c a l S t o r a g e . s e t l t e m ( " s h e l l 2 ", " e m p t y " ) ;
l o c a l S t o r a g e . s e t l t e m ( " s h e l l 3 " , "em pty"); Под какой с к ор луп к о й н а х о
l o c a l S t o r a g e [ " s h e l l l " ] = "empty"; дит ся горош ина ("реа")?
l o c a l S t o r a g e [ " s h e l l 2 "] = "pea";
l o c a l S t o r a g e [ " s h e l l 3 " ] = "empty";
v a r v a l u e = l o c a l S t o r a g e . g e t l t e m ( " s h e l l 2 " ); К люй З н а ч ен и е
lo c a lS to r a g e . s e tlt e m ( " s h e lll" , v a lu e );
v a lu e = l o c a l S t o r a g e . g e t l t e m ( " s h e l l 3 " ); sb e //X e m p ty
l o c a l S t o r a g e [ " s h e l l 2 "] = v a l u e ;
s h d lZ реа
v a r k ey = " s h e l l 2 " ;
l o c a l S t o r a g e [ k e y ] = "pea"; $1ле11з e m p ty
k ey = " s h e l l l " ;
l o c a l S t o r a g e [ k e y ] = "empty";
k ey = "s h e l l 3 "; Горошина ("реа") находится
l o c a l S t o r a g e [ k e y ] = "empty"; под скорлупкой Z ("skellZ")..
for (v a r i = 0; i < l o c a l S t o r a g e . l e n g t h ; i+ + ) {
v a r k ey = l o c a l S t o r a g e . k e y (i ) ;
var v a lu e = lo c a l S t o r a g e . g etltem (k e y ) ;
a l e r t ( k e y + ": " + v a l u e ) ;
}
пражнение Ваша задача заключалась в том, чтобы обновить весь код таким образом,
решение чтобы везде, где мы стали бы вызывать addStickyToDOM, мы передавали
ключ, а также значение.
500 глава 9
сохраняем данные локально
Сложно быстро сказать, сколько имеется клейких заметок; вам придется осуществлять
итерацию по каждому элементу в l o c a l S t o r a g e , чтобы извлечь все заметки.
пражненне Нам по-преж нем у нуж но вы яснить, как ф акти чески осущ ествл яется
решение со хр ан ени е м ассива в lo c alS to ra g e
Вы уже могли догадаться, что у нас есть возможность использовать JSON для создания строкового
представления массива. И если так и было, то вы правы. Располагая таким представлением, вы сможете
сохранить его в l o c a l S t o r a g e .
дальш е ► 501
реш ение упражнения
Как мы уже говорили, в сумме у вас будет 5 Мбайт хранилища для браузера каждого из пользователей.
Несмотря на то что такой объем может показаться большим, все ваши данные сохраняются в виде строк,
а не в байтовом формате. Возьмите, к примеру, размер государственного долга: если выразить его в виде
значения с плавающей точкой, то для его размещения в хранилище потребуется не много места, однако
если выразить его в виде строкового значения, то для его сохранения потребуется гораздо больший объ
ем. Таким образом, хранилище размером 5 Мбайт способно вместить не так много, как могло показаться.
Так что же произойдет, когда вы исчерпаете 5 Мбайт? К сожалению, это одно из поведений, которые не
определяются спецификацией HTML5, и браузеры могут поступать по-разному, когда вы превысите свой
лимит. Браузер может спросить у вас, хотите ли вы увеличь объем хранилища, либо сгенерирует исключе
ние QUOTA_EXCEEDED_ERR, которое можно перехватить следующим образом:
В о т вызов s e t l t e m в с е
редине блока t r y ; если
ч т о -н и б у д ь п о й д е т не
try { т ак и setltem сгенери
l o c a l S t o r a g e . s e t lt e m ( m y K e y , m y V a lu e ) ; р у е т исключение, т о
W c a t c k пере-
catch(e) { будет задейст вован
x6aw t>i6aew АУС блок catch.
и-
и скл ю ч е н и я , г Р if (e == QUOTA_EXCEEDED_ERR) {
руелльл 6 блоке 9 a lert(" O u t o f sto ra g e
Г )У
}
П р о ве р я е м , ошибка ли э т о квот ы х р а н и л и щ а (а не
J к а к о й - т о другой т и п исключения). Если т а к оно и
е с т ь , м ы выведем для п о л ь з о в а т е л я диалоговое окно
a le rt с с о о т в е т с т в у ю щ и м сообщением. В ы , скорее
всего; з а х о т и т е сд е ла т ь ч т о - т о более з н а ч и т е л ь
ное, чем п р о с т о вывод окна alert.
Не все браузеры в н а ст о я щ и й м о
м е н т г е н е р и р у ю т исклю чение QUOTA_
EXCEEPEP_ERR. Однако они все же
с г е н е р и р у ю т и с к л ю ч ен и е , когда вы
п р е в ы с и т е свой л и м и т , п о э т о м у н е
л и ш н и м будет р азоб р ат ь ся с общ им
с лу ч а е м исклю чения при сохранении
т о го или иного э л е м е н т а в храни лищ е.
502 глава 9
сохраняем данны е локально
<html>
<head>
Начнем с односимвольной
< scr ip t>
строки с клю чом "fuse".
И просто будем, не останавливаясь,
l o c a l S t o r a g e . s e t l t e m ( " f u s e ", ;
увеличивать ее размер...
w h ile(tr u e ) {
...путем удваивания этой с т р о
v a r f u s e = l o c a l S t o r a g e . g e t l t e m ("f u s e " )
ки (посредством конкатенации
try { ее с самой собой)..
lo c a lS to r a g e . se tlte m (" fu se " , fuse + fu se ); З а т е м попытаемся записат ь
} catch(e) { ее обратно в localStorage.
a l e r t ( " Y o u r b r o w s e r b l e w up a t" + f u s e . l e n g t h + " w i t h e x c e p t i o n : " + e);
break;
}
- Если браузер аварийно з а
Не будем ост авлять верш ит работ у — дело
} сделано! Выведем для
беспорядок и уда
l o c a l S t o r a g e .r e m o v e l t e m ( " fu s e " ); л и м данный элем ент пользователя диалоговое
< /sc rip t> из localStorage. окно alert с с о о т в е т с т в у
ю щ им сообщением и вы й
< /h e a d >
дем из данного цикла.
<body>
< /b o d y >
< /h t m l> Результат ы, получившиеся
у нас при использовании брау
Наберите этот код, «зажгите фитиль», загрузив его, зеров Safari и Chrome.
и поразвлекайтесь! Испытайте его в разных браузерах.
( ok ) ( o* )
дальш е ► 503
решение упражнения
-------------------------------------------------------------------------------------------------- + К Т 9 И
РЕШЕНИЕ
На данный момент вы полностью изучили API-интерфейс l o c a l S t o r a g e . Чуть ниже приведены глав
ные действующие лица данного API-интерфейса, скрытые под масками. Посмотрите, сможете ли вы
разобраться, кто из них для чего используется. В качестве примера мы соотнесли одно из описаний
с нужной позицией.
И с п о л ь з у й т е м е п я для с о х р а п е п и я э л е м е п то в п а д л и т е л ь п ы й с р о к .
Я п р и п и м а ю к л ю ч и и з п а ч е п и я , к о т о р ы е за те м з а п и с ы в а ю
ieiiion$tora?e в l o c a l S t o r a g e . И м е й т е в виду, ч т о е сли в l o c a l S t o r a g e у ж е и м е
ется т а к о й к л ю ч , я п е буду п р е д у п р е ж д а ть вас об э то м , а п р о с т о
п е р е з а п и ш у е го , п о э т о м у вам следует п о п и м а т ь , о ч е м в ы п р о с и т е .
Е сли в ы с та п е те з л о у п о т р е б л я т ь г о с т е п р и и м с т в о м в l o c a l S t o r a g e
и и с п о л ь з о в а т ь с л и ш к о м м п о го п р о с т р а н с т в а , т о будет с ге п е р и р о -
в а п о и с к л ю ч е н и е и в ы п о л у ч и т е о т м е п я и з в е с ти е .
removeltem П р о с т о д а й те м п е к л ю ч , и я о т ы щ у э л е м е п т с д а п п ы м к л ю ч о м и п е
редам вам е го з п а ч е п и е .
Я — р а з п о в и д п о с т ь х р а п и л и щ а п а к о р о т к и й с р о к : буду с о х р а п я т ь
в а ш и д а п п ы е , п о к а о т к р ы т о о к п о браузера. З а к р о й т е о к п о браузе
р а и — бац! — все в а ш и д а п п ы е и с ч е зл и .
localStorage Н у ж п о у зп а ть к о л и ч е с т в о эл е м е п то в в ваш ем l o c a l S t o r a g e ? Я п о
м о гу вам с э ти м .
504 глава 9
сохраняем данные локально
\Ш Ш /£ 1 П Ш - 1Т восВТ А - Г « т ен и е
дальш е ► 505
10 гриМеняеМ JavaScript на ДеЛе #
е тся т о , ч т о о п п о д д е р ж и в а е т в ы п о л п е п и е т о л ь к о о д п о го
д е й с т в и я за р аз — м ы о б ы ч п о п а зы в а е м э то о д п о п о т о ч -
п о с т ь ю . П о ч е м у д а п п а я о с о б е п п о с т ь п р и м е ч а те л ь п а ?
А п о то м у, ч т о о п а делает п р о ц е с с п р о гр а м м и р о в а н и я
п р о с т ы м . К о гд а у вас и м е е т с я м п о ж е с т в о п о т о к о в , п р о
т е к а ю щ и х о д п о в р е м е п п о , п а п и с а п и е к о р р е к т п о р а б о та
ю щ е й п р о гр а м м ы м о ж е т п р е в р а т и т ь с я в с л о ж н у ю задачу.
JavaScript-nom ok
Я здесь только один,
но взгляните, сколько
всего я делаю , обрабатывая
В о т ч т о мы и м е е м
в виду под о д н о п о т о ч -
сI Значение времени
таймера исте кло j
носты-о. J a v a S c r ip t
пошагово вы п о л н яе т
всеj ч т о е м у нужно
С Обработка собы тия subm it '
С
\ м одел и документа (D O M ) д е й с т в и т е л ь н о э ф ф е к т и ве н .
Все вы п о л н я е т с я , и и н т е р
Выборка данны х ф ормы ф ейс п о л ь з о в а т е л я вы гляди т
быстро ф у н к ц и о н и р у ю щ и м
I П роверка введенных
пользователем данны х * и от зы вчивы м .
508 глава 10
применяем ja v a s c rip t на деле
JavaScript-nom ok
В ы полнение ф ункции in it
ж -ж -ж
О й, обработ ка большого
Все б удет з а м е ч а
Обработка массива данны х м ассива з а н и м а е т м ного
тельно работ ат ь
врем ени!
до т е х п о р , пока ч а с т ь
J a v a S c r i p t -кода не н а ч
Ж-Ж-Ж
н е т т р е б о в а т ь много
врем ени на о б р а б о т к у ,
ж -ж - ж Кто это прибрал к ру
к о т о р о е будет з а
кам все время на обра
бират ься у работ ы
ботку?
J a v a S c r ip t по в з а и м о
д е й с т ви ю с п о л ь з о в а Обработка сл е д ую щ е го
^ собы ти я c lic k __ л Что у вас там
т елем и инт ерфейсом. наверху происходит? Задачи
Обновление объектной не выполняю тся!
1 ^ о д е л и докум ента ( D O M ) ^
дальш е ► 509
api-инт ерф ейс ja v a s c rip t web w orkers
i фоверка введенных
пользователем данны х
^И спользование массива
М ы о со б о п о д ч е р к и в а л и в а ж п о с т ь т о г о ф а кта , ч т о о д и п п о т о к у п р а в л е п и я о б е с п е ч и в а е т п р о с т о т у и л е г
к о с т ь п р о ц е с с а п р о гр а м м и р о в а н и я , и э то правда. К а к в ы ещ е у в и д и т е , A P I-и п т е р ф е й с W e b W o rk e rs б ы л
тщ а те л ь п о п р о р а б о т а л , ч т о б ы все о с та в а л о сь п р о с т ы м и п а д е ж п ы м для п р о гр а м м и с т а . Ч у т ь п о з ж е м ы
узп а е м п а с к о л ь к о .
510 глава 10
применяем ja v a s c rip t на деле
J A V A S C R IP T (С Й 0 1 3 А )
Интервью недели:
Где JavaScript проводит свое время?
дальше ► 511
как работ аю т веб-сценарии w orker
Для их использования браузеру сначала потребуется создать один веб-сценарий worker (или
более), который станет помощником в решении задач. Каждый worker определяется посред
ством своего собственного JavaScript-файла, содержащего весь код (или ссылки на код), необ
ходимый ему для выполнения своей работы. _ .
Каждый вео -сц енар ии
w o rk e r определяет ся
Я действительно м о г N посредст вом о т д е л ь -
бы воспользоваться по- ) ного Jav a S c rip t -файла.
мощью... создав один w o rke r, \
Браузер
Все веб-сценарии worker живут в очень ограниченном мире; у них нет доступа к множеству объ
ектов времени выполнения, который имеется у вашего основного браузерного кода, например
к объектной модели документа (DOM) или любым переменным либо функциям в коде.
Н ичего себе! Я не м о гу
получить доступ к DOM или
чем у-либо другом у в основном
браузерном коде.
512 глава 10
применяем ja v a s c rip t на деле
В твоем сообщении
сказано, что тебе нужно просчитать
се кц и ю изображения, создаваемого
У меня есть для тебя
методом трассировки лучей, размером
работа.
200 х 200 пикселов. Я м о гу сделать
это для тебя.
сообще
ние
Worker
Браузер
Вот работа,
которую ты просил
сделать.
дальш е ► 513
дост уп к dom
П очем у бы не разре
шить веб-сценариям w o rke r доступ
к объектной модели документа? П о х о
же, отправка сообщ ений туда-сю да доста
вит массу х л о п о т, если все веб-сценарии
w o rke r будут выполняться в одном
и том же браузере.
Т о >чего мы к о т и м
избежать!
514 глава 10
применяем ja v a s c rip t на деле
странице.
□ Анализ видео.
□ Управление
странице.
рекламой на вашей
□ □
□ □
□ □
Свои идеи н а п и ш и т е здесь!
дальш е ► 515
будьт е вним ат ельны с браузерной поддержкой
Вы такж е м ож ет е в о с
Браузер Google Chrome предусматривает п о ль з о ва т ь ся п е р е к л ю ч а
л дополнительные ограничения (для обе- т е л е м врем ени вы полнения
|^ у Д Ы 1 1 6 I спечения безопасности), которые не по- C h ro m e - - a llo w -file -a c c e ss-
о с гц о Р оЖ Н ы ! зволят вам запускать веб-сценарии worker fr o m - file s , однако м ы р е к о
напрямую из файла. Если вы попытаетесь м е н д у е м в а м и с п о ль з о ва т ь
данный п а р а м е т р т о л ь к о
это сделать, станица не будет работать и вы не получите никаких
при т е с т и р о в а н и и кода.
уведомлений о причинах такого поведения (в том числе никаких
сообщений об ошибках, где будет сказано, в чем дело!).
Поэтому для приведенных здесь примеров рекомендуем вам ис
пользовать другой браузер или свой собственный сервер и за
пускать их с http://localhost. Либо можете загрузить их на онлайн-
сервер, если у вас имеется к нему доступ.
8 подобной с и т у а ц и и ва м п р и д е т с я п о с т у п и т ь
т а к , как б удет нужно для вашего прилож ения.
Здесь м ы п р о с т о у в е д о м л я е м п о л ь з о в а т е л я п у т е м
р а зм е щ е н и я сообщения в э л е м е н т е с id="status".
516 глава 10
применяем ja v a s c rip t на деле
< ! d o c t y p e h tm l>
<htm l la n g= " en " >
<head>
< title > P in g P o n g < /title >
<meta c h a r s e t = " u t f - 8 ">
< s c r i p t s r c = " m a n a g e r .j s " > < / s c r i p t >
< /h e a d > \ ___^ Д а н н ы й J a v a S c r i p t -код создаст
<body> все веб -сцен а ри и w o r k e r и б удет
<p i d = " o u t p u t " > < /p > осущ ест влят ь управление и м и .
< /b o d y >
Г е н ери ру е м ы й в е б -с ц е н а р и ем w o r k e r
< /h t m l> вывод мы будем р а з м е щ а т ь здесь.
Д л я создания нового w o r k e r м ы г е н е р и р у е м
новый о б ъ е к т Worker.
)
v a r w ork er = new W o r k e r ( " w o r k e r . j s " ); В еб-сц ена ри й
w orker
П рисваиваем новый ...Ja v a S c rip t- ф а й л worker.js будет
W o rk e r J a v a S c r i p t - содержать код для w orker,
п е р е м е н н о й worker.
дальше ► 517
написание кода для управления w orker
Написание manager.js
Т е п е р ь , к о гд а в ы зп а е те , к а к созд ать w o rk er (и п а с к о л ь к о л е гк о э то д е л а е тся ), п о р а б о т а е м пад к о д о м
m a n a g e r . j s. О п будет п р о с т ы м , и се й ч а с м ы с ф о р м и р у е м т о л ь к о о д и п w ork er. С о зд а й те ф айл с и м е п е м
m a n a g e r . j s и доб авьте в п е го с л е д у ю щ и й ко д :
Мы дождемся полной
w in d o w .o n lo a d = f u n c t i o n () { загрузки страницы.
v a r w o rk er = new Worker ( " w o r k e r . j s ; ✓ л ^ ^
J 4— А з а т е м создадим
} новый worker.
Э то о т л и ч п ы й ста р т, о д п а ко т е п е р ь п а м п е о б х о д и м о сделать т а к, ч т о б ы w o rk er за п я л ся р а б о т о й .
К а к у ж е о тм е ч а л о с ь р а п е е , ч т о б ы за с т а в и ть w o rk er ч т о -т о сделать, н у ж п о о т п р а в и т ь ему со о б щ е п и е .
Д л я э т о го м ы во сп о л ьзу е м с я м е то д о м p o s t M e s s a g e о б ъ е кта w ork er. В о т к а к о п п р и м е п я е т с я :
w in d o w .o n lo a d = f u n c t i o n () {
v a r w o rk er = new W o rk er( " w o r k e r . j s ")
Используем м ет од
w o r k e r . p o s t M e s s a g e ( " p in g " ) ; ^ postMessage объекта
worker для отправки Хот ит е от прав
т ему сообщения. Н аш е"
сообщение п р едст ав
л ят ь более сложные
Метод postMessage определен для сообщения? Бот как
ляет собой про ст ую это делается...
вас в API -инт ерф ейсе Web Workers.
ст року "ping".
/>
под увеличительным сшекл°м
В ы с м о ж е те о т п р а в л я т ь п е ч т о б о льш ее, ч е м п р о с т о с т р о к и , и с п о л ь зу я
p o s t M e s s a g e . Д а в а й те в згл я п е м , ч т о м о ж п о о т п р а в л я т ь в с о о б щ е п и и :
О т п р а в л я т ь ф у п к ц и и нельзя:
О т п р а в л я т ь т у или иную ф ункцию нельзя —
w o r k e r . p o s t M e s s a g e (updateTheDOM) ; она МоЖет содержать ссылку на объ ект н ую
модель докум ент а, позволяя w orker вносить
изменения в РОМ!
518 глава 10
применяем ja v a s c rip t на деле
w o r k e r . o n m essage = f u n c t i o n (event) { О б ъ е кт ev en t, п е р е
v a r m e s s a g e = "Worker s a y s " + e v e n t . d a t a ; даваемый наш ем у
обработ чику , облада
d o c u m e n t . g e t E l e m e n t B y l d ( " o u t p u t " ) . innerHTML = m e s s a g e ;
ет свойст вом d a ta ,
содерж ащ им данные
При получении сообщения от сообщения (нуж ны е
w o rk e r м ы п о м ест и м его в э л е нам ), кот оры е о т
м ен т <р> в H T M L -ст ранице. правил w o rk er.
/>
oum e^age под ув е л и ч и те л ь н ы м с т е кл а м
дальш е ► 519
ваш первы й w orker
on m e ssa ge = p in g P o n g ;
Т а к и м о б р а зо м , ф у п к ц и я p in g P o n g будет п р и п и м а т ь с о о б щ е п и е и о т в е ч а т ь п а п е го "pong". Д о б а в ь те
п р и в е д е п п ы й далее к о д B w o r k e r . j s :
Когда w o r k e r п о л у ч и т сообщение
о т основного кода, п р о и зо й д е т вызов
ф ун кц и и p in g P o n g , к о т о р о й б удет
передано данное сообщение.
o n m essa ge = p in g P o n g ; EL.
Если сообщение будет содержать
f u n c t io n p in g P o n g (e v en t) {
с т р о к у "p in g ", м ы о т п р а в и м назад с о
if ( e v e n t . d a t a == "ping") {
общение со с т р о ко й "pong". О т в е т н о е
p o s t M e s s a g e ( "pong") ;
О б р а т и т е вн им ан и е, ч т о w o r k e r
тоже и с п о л ь з у е т postM essage для
о т п р а в к и сообщений.
520 глава 10
применяем ja v a s c rip t на деле
Проведение тест-драйба
У б е д и те сь в т о м , ч т о в ы п а б р а л и и с о х р а п и л и весь н е о б х о д и м ы й
к о д в p i n g p o n g . h t m l , m a n a g e r . j s и w o r k e r . j s. Т е п е р ь д е р ж и т е э т и
ф а й л ы о т к р ы т ы м и , ч т о б ы м о ж п о б ы л о за гл я д ы в а ть в п и х , и да
в а й те задумаемся пад те м , к а к все р а б о та е т. С па ча л а m a n a g e r . j s ООП
геперирует повый w ork er, присваивает ему обработчик сообщ е- S j p !^ ^ h tt ^ oca(hpSt/^Be~ ^ -
ПИЙ, а Затем ОТПраВЛЯеТ ЭТОМу w o rk er Сообщепие СО СТрОКОЙ Worker says pong
"ping". В св о ю о че р е д ь, w o rk er уб е ж д а е тся в т о м , ч т о фупкция
p in g P o n g задапа в ка ч е с т в е е го о б р а б о т ч и к а с о о б щ е п и й , после
ч е го п а ч и п а е т ж д а ть . В к а к о й -т о м о м е п т w o rk er п о л у ч а е т со о б
щ е п и е о т m anager, j s и п р о в е р я е т е го п а п р е д м е т с о д е р ж а п и я
с т р о к и "ping", к о т о р а я и будет в п е м п р и с у т с т в о в а т ь . З а те м
w o rk e r в ы п о л п я е т м ассу со все м п е м п о г о т я ж е л о й р а б о т ы и о т
п р а в л я е т в о т в е т с о о б щ е п и е со с т р о к о й "pong".
И т а к , п р о в о д и м ы е п а м и в ы ч и с л е п и я г о в о р я т о т о м , ч т о п а с тр а
п и ц е д о л ж п а п о я в и т ь с я ф раза "Worker s a y s pong"... Л а д п о , л а д по ,
м ы п о п и м а е м , ч т о в ы б о льш е п е м о ж е т е в ы п о с и т ь п а п р я ж е п п о г о
о ж и д а п и я . З а гр у з и т е ж е , п а к о п е ц , э ту с т р а н и ц у !
дальш е ► 521
СТАНЬбраумром -------------------
ДрхШдо Бремя п ри твориться £раузер°М, «ДениБа1°ЩиМ
JavaScript-Код. |J оп роси те се^я в р°Ли браузера для ^ — Свои о т в е т ы вы
см ож ет е п р о в е р и т ь
КаЖДоГо &л°Ка К«Да, приведенного ниже, и н а -
в р еш ении к э т о м у
пиШише Генерируемый UM ВыВод на стр о заданию в конце главы .
w in d o w .o n lo a d = f u n c t i o n () {
v a r w o rk er = new Worker ( " w o r k e r . j s " );
w o r k e r . o n m e ssage = f u n c t i o n ( e v e n t ) {
a l e r t ( "Worker s a y s " + ev e n t.d a ta );
}
for (v a r i = 0; i < 5; i++ ) {
w o rk er .p o stM essa g e(" p in g " ) ;
}
w in d o w .o n lo a d = f u n c t i o n () {
v a r w o rk er = new W o r k e r ( " w o r k e r . j s " );
w o r k e r . ommessage = f u n c t i o n ( e v e n t ) {
a l e r t ( "Worker s a y s " + ev e n t.d a ta );
}
f o r ( v a r i = 5; i > 0; i - - ) {
w o r k e r .p o stM e ssa g e (" p o n g " );
}
522 глава 10
применяем ja v a s c rip t на деле
w in d o w .o n lo a d = f u n c t i o n () {
v a r w o rk er = new W o r k e r ( " w o r k e r . j s " );
w o r k e r . o n m e ssage = f u n c t i o n ( e v e n t ) {
a l e r t ( "Worker s a y s " + e v e n t . d a t a ) ;
w o r k e r . p o s t M e s s a g e ( " p in g " ) ;
}
w ork er. p o stM essa g e(" p in g " );
a Б у д е т е осторожны с э т и м и блокам и
кода. Возможно , в а м п р и д е т с я п р и н у
д и т ель н о з а в е р ш и т ь р а б о т у б р а узе р а ,
чтобы п р е к р а т и т ь их вы полнение ...
w in d o w .o n lo a d = f u n c t i o n () {
v a r w o rk er = new W o r k e r ( " w o r k e r . j s " );
w o r k e r . o n m e ssage = f u n c t i o n ( e v e n t ) {
a l e r t ( "Worker s a y s " + e v e n t . d a t a ) ;
}
fu n c tio n p in g e r() {
w o r k e r . p o s t M e s s a g e ( " p in g " ) ;
дальш е ► 523
упражнение на использование компакт ного w orker
i-
v a r q u o te s = ["I hope l i f e i s n ' t a j o k e , b e c a u se I d o n ' t g e t i t . " ,
"There i s a l i g h t a t t h e end o f e v e r y t u n n e l . . . j u s t p ray i t ' s n o t a t r a i n ! " ,
"Do you b e l i e v e i n l o v e a t f i r s t s i g h t or s h o u ld I walk by a g a in ? " ] ;
v a r in d e x = M a th .flo o r (M a th .r a n d o m () * q u o t e s . l e n g t h ) ;
p o s t M e s s a g e ( q u o t e s [ i n d e x ] );
П опробуйт е ввест и
Свое описание п р и в е д и т е здесь: вы п о л н и т ь данный код!
524 глава 10
применяем ja v a s c rip t на деле
Г ф З Ж Н бН И б Давайте добавим несколько worker в нашу игру p ingP on g. Ваша задача заключается
в том, чтобы устранить имеющиеся пробелы и завершить приведенный внизу код, чтобы
в результате происходила отправка трех сообщений со строкой "ping" веб-сценариям
worker, а в ответ от них поступали три сообщения со строкой "pong".
w in d o w .o n lo a d = f u n c t i o n () { М и создаем т р и w o r k e r и со
v a r numWorkers = 3; в м ассиве workers.
хр а н я е м wx
var w orkers = [];
for (var i = 0; i < ; i++ ) {
v a r w o rk er = new ( " w o r k e r . j s ")
У с т р а н и т е пробелы,
за п олнив их с о о т w orker. = fu n ctio n (ev en t) {
в е т с т в у ю щ и м кодом .
a l e r t ( e v e n t . ta r g e t + " says "
+ even t.
};
w o rk ers. p ush (w orker);
Здесь м ы добавляем новый
}
w o r k e r в м а с с и в w o r ke r s
for (var i = 0; i < i+ + ) {
w o rk ers[i]. ("p ing" )
}
Ч а ст°
^адаВ аеМ ы е
B o llp o C b l
! / • Можно ли просто передать функцию вместо JavaScript- Если отправить веб-сценарию worker объект
файла при создании worker? Наверняка так было бы проще в сообщении, станет ли он объектом, совместно
и это лучше соответствовало бы стандартному поведению используемым основной страницей и этим worker?
JavaScript.
0 : Нет, когда вы отправляете объект веб-сценарию w o rk er ,
0 : Нет, нельзя. И вот почему: как вы знаете, одно из требо он получает его копию. Любые изменения, который вносит worker,
ваний, касающихся веб-сценариев w ork er, заключается в том, не затронут объект в вашей основной странице, w o rk er выпол
что они не должны иметь доступа к объектной модели документа няется в среде, отличной от вашей основной страницы, поэтому у
(или к любому состоянию главного браузерного потока). Если бы вас не будет доступа к находящимся там объектам. Аналогичным
можно было передать конструктору Worker функцию и при этом образом дело обстоит и с объектами, которые w orker отправляет
оказалось бы, что ваша функция содержит ссылку на DOM или вам: вы будете получать их копии.
другие части основного JavaScript-кодэ, это нарушило бы данное
требование. Таким образом, разработчики API-интерфейса Web
Workers предпочти сделать так, чтобы вы передавали URL-адрес либо возможность совершать запросы с использованием
JavaScript-файла во избежание данной проблемы. XMLHttpRequest?
дальш е ► 525
вклю чение ja va scrip t-кода в w orker
пражнение Давайте добавим несколько w o rk er в нашу игру p ingP on g. Ваша задача заключает
решение ся в том, чтобы устранить имеющиеся пробелы и завершить приведенный внизу код,
чтобы в результате происходила отправка трех сообщений со строкой "ping" веб
сценариям w orker, а В ответ ОТ НИХ поступали три сообщения СО строкой "pong".
Вот наше решение этого упражнения.
М ы задали о б р а б о т
w in d o w .o n lo a d = f u n c t i o n () { чик сообщений в коде
v a r numWorkers = 3; нашей основной
var workers = []; ст раницы , исполь
зуя свойст во w o r k e r
fo r (var i = 0; i < numWorkers; i+ + ) {
с и м е н е м onmessage.
v a r w o rk er = new Worker ( " w o r k e r . j s
w o r k e r . o n m e ssage = f u n c t i o n ( e v e n t ) {
Д а н н о е диалоговое
окно alert п оя вит ся (
на экране трижды.
526 глава 10
применяем ja v a s c rip t на деле
i m p o r t S c r i p t s ( "h t t p : / / b i g s c i e n c e . o r g / n u c l e a r . j s ",
"h t t p : / / n a s a . g o v / r o c k e t . j s ",
" m y l i b s / a t o m s m a s h e r . j s ") ;
П о м е с т и т е в im p o r tS c r ip t s нужное к о
ли ч е с т во (или нуль) разделенны х з а п я
т ы м и U R L -адресов J a v a S c r i p t -ф айлов.
З а те м , ко гд а ф у н к ц и я i m p o r t S c r i p t s будет вы зв а н а , к а ж д ы й
и з U R L -адресов J a v a S c rip t-ф айлов будет и з в л е ка ть с я и о ц е н и
в а ть с я н о н о рядку.
С ледует о т м е т и т ь , ч т о i m p o r t S c r i p t s я в л я е тс я н о л н о ц е н н о й
ф у н к ц и е й , в сил у ч е го (в о т л и ч и е о т о н е р а т о р о в im p o r t во
м н о г и х я з ы к а х ) в ы с м о ж е те н р и н и м а т ь р е ш е н и я об и м н о р т е
в о в р е м я в ы п о л н е н и я , к а к н о ка за н о далее:
Поскольку i m p o r tS c r ip t s — ф у н кц и я ,
вы см ож ет е и м п о р т и р о в а т ь код
по м е р с т о го , как эт о го б уд е т т р е
боват ь определенная задача.
дальш е ► 527
м ножест во Мандельброта
He х о т е л и St?i п р и о б р е с т и дом
с видом на пляж у самого края
« Л а зу р н о г о во доворот а»?
Осмотритесь
П о с е т и т е с т р а н и ц у h t t p : / / w i c k e d ly s m a r t . c o m / h f lit m l5 / c h a p t e r l0 / s in g le t h r e a d /
fr a c ta l.h tm l, ч т о б ы ув и д е ть в и з у а л и з а ц и ю м н о ж е с т в а М а н д е л ь б р о та . Щ е л к н и т е в
л ю б о м м есте к н о п к о й м ы ш и — и в ы у в е л и ч и т е с о о т в е т с т в у ю щ у ю о б л а сть к а р т ы .
П р о д о л ж а й т е щ е л ка ть , ч т о б ы иссл е д о в а ть р а з л и ч н ы е о б л а с ти , л и б о п е р е з а гр у з и
те с т р а н и ц у и н а ч н и т е все сначала. О с т е р е га й т е с ь о б л а с те й с ч е р н ы м и д ы р а м и ,
н о с к о л ь к у о н и будут п ы т а т ь с я за т я н у ть вас. Н а н а ш взгляд, х о т ь п е й з а ж и и в ы гл я
д я т н р е в о с х о д н о , п р о гр а м м а п р о с м о т р а м огл а б ы р а б о та ть н е м н о го б ы с тр е е ... К а к
в ы счи тае те? К р о м е т о г о , б ы л о б ы з д о р о в о , если бы на ш е п р и л о ж е н и е обладало
т а к о й п р о и з в о д и т е л ь н о с т ь ю , ч т о б ы м о ж н о б ы л о р а зв е р н у ть п р е д с та в л е н и е н а все
о к н о браузера! Д а в а й те о б е с н е ч и м все э т о , д о б а в и в в е б -с ц е н а р и и w o r k e r в н р и л о
ж е н и е F ra c ta l E x p lo re r.
528 глава 10
применяем ja v a s c rip t на деле
% +1 = % 2 + с
и ч т о е го о т к р ы л и иссл е до ва л Б енуа М а н д е л ь б р о т. В ы
т а к ж е зн а е те , ч т о э то н р о с т о м н о ж е с т в о к о м п л е к с н ы х
ч и с е л (ч и с е л с в е щ е с т в е н н о й и м н и м о й ч а с т ь ю ), ге н е р и
р у е м ы х с н о м о щ ь ю д а н н о го у р а в н е н и я .
Е сли ж е в ы н е м а т е м а т и к , т о н а и л у ч ш и й с п о с о б п р е д
с та в и ть себе м н о ж е с т в о М а н д е л ь б р о т а — э то с ч и т а т ь
е го б е с к о н е ч н о с л о ж н ы м ф р а к т а л ь н ы м и з о б р а ж е н и е м ,
нод к о то р ы м ноним ается изображ ение, ко то р о е м о ж но
у в е л и ч и в а т ь до л ю б о й с т е н е н и и н а х о д и т ь л ю б о п ы т н ы е
с т р у к т у р ы . В з гл я н и т е н а н е к о т о р ы е к а р т и н ы , к о т о р ы е
м о ж н о о т ы с к а т ь п у те м н е р е м е щ е н и я н о м н о ж е с т в у :
П о ч е м у ж е о н о нас т а к и н те р е с у е т? Д а н н о е м н о ж е с т в о
обладает р я д о м л ю б о н ы т н ы х с в о й с т в . В о -н е р в ы х , о н о
ге н е р и р у е т с я п о с р е д с т в о м о ч е н ь н р о с т о г о у р а в н е н и я
(о н о н р и в о д и л о с ь в ы ш е ), к о т о р о е м о ж е т б ы т ь в ы р а ж е н о
в с е го л и ш ь н е с к о л ь к и м и с т р о к а м и ко д а . В о -в т о р ы х , ге н е
П окойся С м и р о м ,
р и р о в а н и е м но ж е ства М андельброта заним ает изряд ное
ееН9« М я н Э е л ,б р о т ,
к о л и ч е с т в о в ы ч и с л и т е л ь н ы х ц и к л о в , ч т о делает е го о т
скоНыавмийся, когда
л и ч н ы м н р и м е р о м для и с н о л ь з о в а н и я в с о ч е т а н и и с A P I-
Z п и с а л , э т у кн и гу .
и н т е р ф е й с о м W eb W o rk e rs . И н а к о н е ц , э то ж е кл а с с н а я
Нам повезло
вещ ь, с к о т о р о й м о ж н о н о р а б о т а т ь , и у нас е сть зам еча
зн ако м ы м и с т а к
те л ь н о е н р и л о ж е н и е , ч т о б ы з а к о н ч и т ь и м к н и гу .
челобекоМ , как w w -
дальш е ► 529
вы числение фракталов
С ледует о т м е т и т ь , ч т о наша
цель з а к л ю ч а е т с я не в т о м ,
Как Вычисляется мноЖестВо Мандельброта чтобы с д е ла т ь из вас с п е ц и а л и
с т а по ч исленн ом у а на ли зу ( к о
П р е ж д е ч е м и с н о л ь з о в а т ь в е б -с ц е н а р и и w o rk e r, в згл я н е м , к а к т о р ы й у м е е т п и с а т ь уравнен и я
о б ы ч н о н р и х о д и т с я с т р у к т у р и р о в а т ь ко д для в ы ч и с л е н и я м н о ж е с и с по ль зо вани ем ко м плек сны х
ств а М а н д е л ь б р о та . М ы не х о т и м удел ять м н о г о в н и м а н и я п о д р о б чисел), а в т о м , чтобы а д а п
но стя м в ы чи сл е ни я зн а че н и й ни ксе л о в м нож ества М андельброта, т и р о в а т ь т р е б у ю щ е е большого
т а к к а к у ж е н о л н о с т ь ю н о з а б о т и л и с ь о с о о тв е т с тв у ю щ е м ко д е и
объем а вычислений прилож ение
к испо льзо вани ю веб -сцен а риев
со б и р а е м с я п р о д е м о н с т р и р о в а т ь е го ч у т ь н о з ж е . А се й ч а с м ы н р о -
worker. Если вас и н т е р е с у ю т
с то х о т и м , ч т о б ы в ы р а зо б р а л и с ь в о б щ е й к а р т и н е :
численные а спект ы множ ест ва
Д л я вычисления м нож ест ва М а н М андельбро т а — « В и к и п е д и я »
Г д ельброт а м ы со вер ш а ем цикл
по каждой с т р о к е изображения.
по м о ж ет н а ч а т ь исследование
данного вопроса.
fo r (i = 0; < n u m b e r O fR o w s ; i+ + ) {
va r ro w = c o m p u te R o w ( i) ; И для каждой
d ra w R o w (ro w ); с т р о к и вы числяем
пикселы.
А з а т е м р и с у е м каждую с т р о к у на экране.
Вы, в е р о я т н о , смож ет е у в и д е т ь п о с т р о ч н у ю
о т р и с о вк у изображения, когда з а п у с т иАте
т е с т о в ы й код в браузере.
В т е к у щ и й м о м е н т д а н н ы й ко д н р и з в а н б ы ть н р о с т ы м п с е в д о к о
дом . К о г д а ж е дело д о й д е т до н а н и с а н и я ко д а н о -на сто я щ е м у, н а м
н о т р е б у е т с я р а зо б р а ть с я с д о п о л н и т е л ь н ы м и д е та л я м и: н а н р и м е р ,
для в ы ч и с л е н и я с т р о к и н а м н о т р е б у е т с я зн а ть ее ш и р и н у , к о э ф ф и ш ирина
ц и е н т у в е л и ч е н и я , ч и с л е н н о е р а з р е ш е н и е , до к о т о р о г о м ы х о т и м
н р о и з в е с т и ее в ы ч и с л е н и е , а т а к ж е н р о ч и е м е л ки е де та ли. М ы м о
ж е м со б р а ть все э т и д е та л и в о д н о м о б ъ е кте ta s k : К оэф фициент
увелич ени я
fo r (i = 0; i < n u m b e r O fR o w s ; i+ + ) {
var ta s k F o r R o w = c re a te T a s k F o rR o w (i ) ;
var ro w = c o m p u te R o w (ta s k F o rR o w );
Объект
ta s k F o rR o w
d ra w R o w (ro w );
t содерж а Уровень т о ч
Передаем ta skF o rR ow ф у нкции данные, необхо
н о ст и для
c o m p u te R o w , к о т о р а я в о з в р а димые Зля вы -
вычисления
т и т вы численную с т р оку. ч и сл ен и я с т р о к и .
530 глава 10
применяем ja v a s c rip t на деле
^ Здесь изображение
ра зб и вает ся на н е -
<г- больш ие област и.
М ы будем р а зд а ва т ь
^ э т и област и в е б -
^ сценар иям w o r k e r
^ для вычисления.
Браузер
Вот р е зу л ь т а т , который мы
х о т и м получит ь п у т е м вы
числений. Ъраузерному коду
пот ребует ся разбить работу
по вычислению данного изобра
жения на несколько небольших
задач, выполнением которых Наши w o r k e r г о
зай м ут ся веб-сценарии worker. т овы п р и с т у п и т ь
к вы числениям!
дальш е ► 531
как производит ь вы числения с пом ощ ью w orker
R O D Fractal txplorer
[ *I ►j {+ http ,iIionhoM,'-"Beln/MlMLV/FMtUl/f'jcUi 1
532 глава 10
применяем ja v a s c rip t на деле
По мере того как части изображения поступают обратно от веб-сценариев worker, они
собираются в единое изображение в браузере. И если еще остаются части, вычисление
которых необходимо произвести, эти новые задачи поручаются веб-сценариям worker, ко
торые не заняты работой.
Когда будет вычислена последняя часть изображения, его сборка завершится и веб
сценарии worker будут бездельничать, пока пользователь не щелкнет кнопкой мыши для
увеличения изображения, после чего все начнется сначала...
дальш е ► 533
как веб-сценарии w orker улучш аю т прилож ения
534 глава 10
применяем ja v a s c rip t на деле
А может л и у меня
быть столько веб
сценариев w o rke r, сколько
я пожелаю ?
О
В о зь м и те на ш п р и м е р с м н о ж е с т в о м М а н д е л ь б р о та :
в т е о р и и в ы м о гл и б ы н а з н а ч и т ь w ork er , к о т о р ы й
стал бы за н и м а ть с я в ы ч и с л е н и е м к а ж д о го о д и н о ч н о
го п и кс е л а , ч т о , в е р о я т н о , б ы л о б ы н а м н о го н р о щ е с
т о ч к и з р е н и я р а з р а б о т к и ко д а . О д н а к о , у ч и т ы в а я то ,
ч т о в е б -с ц е н а р и и w o rk er я в л я ю т с я « тя ж е л о в е с н ы м и »
с р е д с тв а м и , м ы н и к о гд а б ы не в ы б р а л и т а к о й н о д х о д
п р и р а зр а б о тке н а ш е го н р и л о ж е н и я . В м е с то э т о го
м ы и с п о л ь зу е м г о р с т к у ве б -сц е н а р и е в w o rk er и с т р у к
т у р и р у е м в ы ч и с л е н и я т а к и м о б р а зо м , ч т о б ы о н и за
д е й с тв о в а л и и х п р е и м у щ е с тв а .
Д а в а й те н е м н о го у гл у б и м ся в р а з р а б о т к у F ra c ta l
E x p lo re r, а за те м в е р н е м с я и н о э к с н е р и м е н т и р у е м
с к о л и ч е с т в о м ве б -сц е н а р и е в w ork er , ч т о б ы р а зо
б р а тьс я , к а к э т о т н о ка з а те л ь в л и я е т н а у р о в е н ь п р о
изводительности.
дальш е ► 535
разработ ка кода как упражнение для ума
Ш ТУРМ
У вас, несомненно, уже имеется масса знаний о том, как создавать приложения с применени
ем API-интерфейса Web Workers, как генерировать и использовать веб-сценарии w o r k e r . Вы
также немного знаете о том, как решать проблемы с объемными вычислениями путем разбив
ки их на небольшие задачи, которые могут быть выполнены веб-сценариями w o r k e r , и даже
чуть-чуть в курсе того, как вычисляются множества Мандельброта. Попробуйте соединить
все это воедино и задумайтесь над тем, как бы вы переписали приведенный ниже псевдо
код, чтобы он задействовал веб-сценарии w o r k e r . Сначала можете предположить, что у вас
будет так много веб-сценариев w o r k e r , как вам потребуется (например, по одному w o r k e r на
каждую одиночную строку), а затем введите ограничение на количество w o r k e r (число веб
сценариев w o r k e r меньше, чем количество строк):
drawRow(r
}
сделать для того, чтобы добавить
сюда веб-сценарии worker?
536 глава 10
применяем ja v a s c rip t на деле
дальше ► 537
гот овы й к упот реблению код для ф ракт альны х изображений
v a r i_max = 1 . 5 ;
v a r i_ m in = - 1 . 5 ;
Глобальные п е р е м е н н ы е , и с п о ль зуе м ы е
v a r r_min = - 2 . 5 ; для вычисления множ ест ва М а н д е л ь
v a r r max = 1 . 5 ; бр от а и его отображения.
v a r m a x _ i t e r = 102 4;
v a r e s c a p e = 1025;
var p a l e t t e = [];
Д анн ая функция упаковывает все
f u n c t i o n c r e a t e T a s k (row) { данные, необходимые веб-сценарию
var ta sk = {
w o rk e r для вычисления с т р о -
ки пикселов, в объект. Позже вы
row: row,
цвидите, как мы будем переда
w id th : r o w D a t a .w id t h , ва т ь э т о т объект веб-сценарию
g en era tio n : g en er a tio n , w o r k e r для использования.
r_m in: r_m in ,
r_m ax: r_m ax,
i : i_max + (i_ m in - i_ m a x ) row / c a n v a s . h e i g h t ,
m a x _ ite r: m a x _ ite r ,
escape: escape
}; Д а н н ы й код б удет
return task ; р а з м е щ а т ь с я в ф а й ле
mandelhb.js.
538 глава 10
применяем javascript на деле
w ( Создать HTML-страницу
"J"*ojpoBo X I j l l o 0 H U I °
| | J^otuoBoкупртре^ленито
□ Создать веб-сценарии worker
(п р о д о л ж е н и е ) □ Запустить веб-сценарии worker
□ Реализовать код worker
I | Обработать результаты
□ Код, касающийся взаимо
действия с пользователями
function m a k ePalette() {
function wrap(x) {
x = ( (x + 256) & Oxlff) - 256; cm>o чисел в массив цвет ов R.QB. Мы 6ц -
дем использоват ь данный массив v a l e t t l
if (x < 0) x = -x;
return x;
}
c t x . put ImageData ( t h is . rowData f 0, w o rk e rR e su lts . row) ; Д д НН(?/ц код уже должен
} К а быть вам знаком; он п о -
Данный код будет 0т 2 5 запис 1 добен коду, который мы
р азм ещ ат ь ся в файле пикселы о ь е к т m age а применяли в главе 8 для
mandellib.js. 6 c w t e x t ^ м е н т я canvas! элем ен т ов video и canvas.
дальше ► 539
готовый к употреблению код для фрактальных изображений
У"*o jp o B o X
(п р о д о л ж е н и е )
canvas = document.getElementByld("fractal
ctx = canvas.getContext("2d");
Вот где мы извлекаем canvas
и c o n te x t, а также задаем исход-
canvas.width = window.innerWidth; 1*Г~
ную ширину и вы сот у canvas.
canvas.height = window.innerHeight;
< ir \
rowData = c t x .createlmageData(canvas.width, 1); Здесь мы инициализиру
ем п ерем ен н ую ro w D a ta
(и с п ол ь зуе м у ю для записи
makePalette();
пикселов в canvas).
А здесь мы инициализируем п а л и т р у
цв ет о вj к о т о р у ю используем для
рисования множества как ф р а к т а л ь
ного изображения.
540 глава 10
применяем javascript на деле
(п р о д о л ж е н и е )
for (iter = 0; z_r*z_r + z_i*z_i < escape && iter < max_iter; iter++) {
// z -> zA2 + с
var tmp = z_r*z_r - z_i*z_i + c_r; ...и еще один цикл, чтобы от ы скат ь
z_i = 2 * z_r * z_i + c_i; с о о т ве т с т в ую щ е е значение для дан -
ного пиксела. 3 э т о м внут реннем
z_r = t m p ;
цикле и заключается вы числит ель
} ная сложность, и именно п о э т о м у
if (iter max_iter) { код будет выполняться намного бы -
iter - 1; с т рее, если ваш к о м п ь ю т е р им еет
многоядерный процессор!
}
task.values.push(iter) Р е зу л ь т а т о м всех этих вычислений является
} значение, добавляемое в массив именованных
return task; значений, который помещ ает ся назад в объект
ta sk , чтобы w o rk e r смог от о сл а т ь р е з у л ь т а т
обратно основному коду.
V Ч ут ь позже мы пристальнее
Данный код будет взглянем на э т у часть.
р а зм ещ а т ь с я в файле
workerlib.js.
дальше ► 541
как управлять веб-сценариями worker и задачами
Worker
542 глава 10
применяем javascript на деле
Написание кода |
|
s/( |~отоо'3о к ynorjpebjienuK *
w o r k e r .onmessage = function(event) {
З а т е м задаем для обработчика сообщений
каждого w o rk e r ф ун кцию , кот орая вы зы
processWork(event.target, event.data)
вает ф ункцию processW ork, и передаем ей
e v e n t.ta rg e t ( w o rk e r , кот орый только что
закончил выполнение задачи) и eve n t.d a ta
wo r k e r .idle true; (р е зу л ь т а т ы от данного worker).
Помните, что нам будет нужно цзнать
сценарии w o rk e r заням ,,, * у зн а т ь, какие ве б -
workers.push(worker)
Ад» L o z o нам
startWorkers() присваиваем
еще не поручили
сценариям w o rk e r никакой работы.
Д обавляем только что создан
ный w o rk e r в массив workers.
дальше ► 543
запуск ваших worker для вычисления фрактальных изображений
Создать HTML-страницу
|у< |^| ^ощоВо кl j U o СНиК>
Запуск веб-сценариев worker [71Создать веб-сценарии worker
□ Запустить веб-сценарии worker
Итак, пам п еобходим о разобраться с еще песколькими делами: запустить □ Реализовать код worker
□ Обработать результаты
веб-сцепарии worker, паписать фупкцию, которая см ож ет обработать р е
□ Код, касающийся взаимо-
зультаты, поступающ ие обратпо от веб-сцепариев worker, а также паписать деиствия с пользователями
код для worker. Н ачпем с паписапия кода для запуска веб-сцепариев worker:
Сначала идет n ex tR ow , которая отслеж ива
Д обавляем еще две глобаль-
е т , на какой ст роке мы находимся, по м е р е т ого
как мы продвигаемся по вычисляемому изображению.
и“ Каждый раз, когда пользоват ель увеличивает изображение м н о -
var nextRow = 0; жества М андельброта, мы запускаем вычисление нового и зоора-
~ укения. Переменная gen eratio n отслеж ивает, сколько раз мы эт о
var generation =
сделали. Ъолее подробно об э т о м поговорим позже.
544 глава 10
применяем javascript на деле
:.data);
var workerResult = computeRow(task.data)
|Г Он извлекает содержимое в виде данных
postMessage(workerResult); ^ из task и передает его функции с о т р и te R o w ,
которая выполняет
— тяжелую р а б о т у по вы-
f числению множества Мандельброта
дальше ► 545
подробности об объекте task для вычисления фракталов
ta sk п о д у в е л и ч и т е л ь н ы м с ш е к л ^ м
Итак, ранее ВЫ видели ВЫЗОВ createTask И postMessage, ДЛЯ КОТОрЫХ ИСПОЛЬЗуеТСЯ task:
При этом вам, возможно, интересно, на что похож task. Что ж, это объект, состоящий
из свойств и значений:
О пределяет с т р о к у , для кот орой
мы ген ер и р уем значения пикселов.
task = {
row: 1,
О предел яет ширину строки.
task содержит все width: 102 4,
значения, необходимые — О п редел яет , сколько раз мы
generation: 1,
веб-сценарию w o r k e r прибегали к увеличению...
r_ min: 2.074,
для выполнения его
вычислении. r_max: -3.074, О п редел яю т вычисляемую нами об
i: -0.252336,
ласт ь множества Мандельброта.
546 глава 10
применяем javascript на деле
w o r k e ^ e ^ u lt л ° д у в е л и ч и т е л ь н ы м с ш е к л ° м
/> А как насчет результатов (workerResult), которые мы получаем, когда worker заканчивает
вычисление строки?
var workerResult = computeRow(task.data);
postMessage(workerResult);
workerResult = {
Здесь все т о же са м о е , что и в task.
row: 1,
И эт о здорово, поскольку когда мы
width: 102 4, получим workerResult от w o r k e r ,
w o rk e r прин им ает п е р е
данный ем у объект ta s k , generation: 1, мы будем зн а т ь все о task.
а з а т е м добавляет в него r_min: 2.074,
свойство values, содержащее r_max: -3.074,
А э т о ч т о - т о новень
данные, необходимые для р и кое. Здесь п р е д с т а в л е
i: -0.252336,
сования строки в canvas. ны значения каждого из
max_iter: 102 4, пикселов, которые нам
escape: 1025, все еще нужно п р е о б -
values: [3, 9, 56, - 1 , 22 ] ра зов ат ь в цвета (что
делается в drawRow).
дальше ► 547
обработка результатов работы worker
fy ] Создать HTML-страницу
Q
' I f l овдоВо к ynpiyppfijIfHulo
Вы уже видели, как веб-сцепарии worker геперирую т результаты. Теперь I~~| Обработать результаты
Код, касающийся взаимо-
взгляпем, что произойдет, когда мы получим их от worker. Как вы помпите, деиствия с пользователями
когда мы создавали паши веб-сцепарии worker, мы задали обработчик со
общ еп ий с им епем processWork:
Наш обработчик сообщений вызыва
var worker = new W o r k e r ("worker.js"); е т функцию processW ork, передавая
ей event.data от w o r k e r , а также
wo r k e r .опте ssage = function(event) { e v e n t.ta r g e t, представляющий собой
processWork(event.target, event.data); ссылку на w o rk e r, который прислал
} с о о т ве т с т в ую щ и е данные.
Когда worker отправит пам обратпо сообщ епи е со своими результатами, их обработкой займется фупк
ция processWork. Как вы м ож ете видеть, ей передаю тся два параметра: target сообщ епия, представ
ляющ ий со б о й ссылку па worker, которы й его отправил, и data сообщ епия (это объект task со зпаче-
пиями для строки изображ епи я). Таким образом , теперь паша работа будет заключаться в том, чтобы
паписать processWork (введите приведеппы й далее код в m a n d e l .j s):
Передаем р е з у л ь т а т ы d r a w R o w
для рисования пикселов в canvas.
function processWork(worker, workerResults)
drawRow (workerResults);
Наш w o rk e r оказывается полностью
свободным, п о э т о м у мы можем п о р у
reassignWorker(worker); чить ем у уже новую задачу. Для эт ого
напишем функцию reassignWorker.
Мы п о ч т и д о с т и г л и цели, так что давайте бы стро папиш ем фупкцию reassignWorker, раз уж мы о п ей
заговорили. Вот как опа работает: мы проверяем строку, которую вычисляем, используя глобальпую
перемеппую next Row, и если остаю тся ещ е строки для вычислепия (что мож по выяспить, взгляпув па
количество строк в пашем canvas), мы поручаем worker повое задапие. В противпом случае, если боль
ше п е остапется работы , которую требуется сделать, мы п росто присвоим свойству worker с имепем
idle зпачепие true. Введите приведеппы й далее код тож е в m a n d e l .j s:
л *лм ш пгкег сл е д у ю щ у ю с т р о к у ,
М ы создаем ся пор учим» э т о м у w o r k e r с У ^
function reassignWorker(worker) которую необходимо ^ ^ ^ Г е м значение nextRow (чтобы
var row nextRow++;
548 глава 10
применяем javascript на деле
ъпо
Психоделический тест-драйв SEJ
Ну хватит уже кода! Давайте проведем тест-драйв пашего
прилож епия. Загрузите файл fractal.html в браузере и
п осм отрите, как веб-сцепарии worker займутся работой.
В зависимости от «пачипки» вашего компьютера ско
рость прилож епия Fractal Explorer долж па стать пем по
го выше, чем была рапее.
Наши веб-сцепарии worker трудятся пад вы числепием мпож ества Мапдель- Создать HTML-страницу
брота и возвращ ают результаты, чтобы мы могли парисовать их в canvas. J"оП)оГС
оКIplonlpC&JICHUK»
Н о что произойдет, если вы щелкпете кпопкой мыши, чтобы увеличить Q Создать веб-сценарии worker
изображ епие? К счастью, поскольку мы используем веб-сцепарии worker Запустить веб-сценарии worker
\ у \ Реализовать код worker
для осущ ествления иптепсивпы х вы числепий в ф оповом реж им е, иптер-
Р Г Обработать результаты
ф ей с пользователя долж еп живо среагировать соответствую щ им образом
□ Код, касающийся взаимо
па ваш щелчок. Тем пе м епее пам потребуется паписать пем пого кода для действия с пользователями
Первое действие, которое нам потребуется предпринять, — это добавить обработчик, чтобы позабо
<D титься о событиях, инициируемых щелчками мыши (помните, что щелчки осуществляются в нашем
элементе canvas). Для этого мы просто добавим обработчик для свойства canvas с именем onclick:
Если пользоват ель щелкнет
canvas.onclick = function(event) {
на canvas, мы вызовем ф у н к
handleClick(event.clientX, e v ent.clientY) цию handleClick с использова
}; нием координат х и у м е с т а ,
где был сделан щелчок.
Добавьте данный код ниже вызова setUpGraphics в функции init в m a n d e l .j s.
Остается лишь написать функцию handleClick. Прежде чем мы это сделаем, на секунду задумаемся
© вот над чем: когда пользователь щелкает на canvas, это означает, что он хочет увеличить соответ
ствующую область (вы можете вернуться к однопоточной версии по адресу http://wickedlysmart.com/
hfhtml5/chapter10/singlethread/fractal.html, чтобы увидеть данное поведение). Таким образом, когда
пользователь щелкнет на canvas, нам нужно будет получить координаты области, которую он хочет
увеличить, а затем привлечь все веб-сценарии worker кработе по генерированию нового изображения.
Также не забывайте, что у нас уже имеется функция startWorkers для поручения новой работы любому
незанятому worker. Давайте испытаем ее...
дальше ► 549
тестирование и улучшения
var zoom = 8;
Задаем значения для глобальных п е р е м е н
ных, используемых для создания объектов task
r_min = click_r - width/zoom; для веб-сценариев worker, уровень увеличения
г_шах = click_r + width/zoom; определяет , насколько сильно мы увеличили
i_max = click_i - height/zoom; ф ракт альн ое изображение, что, в свою оче
редь, определяет , какие значения множества
i_min = click_i + height/zoom;
Мандельброта будут вычисляться.
550 глава 10
применяем javascript на деле
ж еп и е заполпяло окпо браузера, а это озпачает, что пам потребуется изм е O ' Реализовать код worker
Q T Обработать результаты
пить размеры canvas, если измепятся размеры окпа. К роме того, если мы
□ Код, касающийся взаимо
изм епим размеры canvas, то пам также придется поручить веб-сцепариям действия с пользователями
worker повый пабор задач по перерисовке фрактальпого изображ епия,
чтобы опо заполпяло canvas с повыми размерами. Давайте папиш ем код
для подгопки размеров canvas под размеры окпа браузера, а также п ереза
пустим веб-сцепарии worker, раз уж мы об этом заговорили.
w in d o w .o n r e s iz e = f u n c t i o n () {
r e s iz e T o W in d o w ( ) ;
дальше ► 551
управление фрактальными поколениями
На даппы й м омепт вы, вероятпо, пи разу бы пе обратили па это впимапия, поскольку у вас им еется пе
так мпого веб-сцепариев worker, при этом опи очепь бы стро вычисляют одпи и те ж е строки для пового
и зображ епия, перезаписы вая предыдущ ие, пекорректпы е строки. Тем пе м епее возпикает ощущ епие,
что здесь что-то пе так. К роме того, впести исправлепия пастолько легко, что мы п росто обязапы это
сделать.
Следует призпаться: мы зпали, что так будет, и вы, возм ож по, помпите малепькую перемеппую
generation, с к оторой мы сталкивались рапее. П ри каждом перезапуске паших веб-сцепариев worker
мы увеличиваем зпачепие generation. Также п е забывайте об объекте worker Results, которы й посту
пает обратпо от worker: у каждого результата имеется собствеп п ое поколепие в качестве свойства. Та
ким образом , мы мож ем использовать перемеппую generation для того, чтобы узпать, получили мы
результат, имею щ ий отпош епие к текущей или ж е к предыдущ ей визуализации.
В песем п еобходим ы е исправлепия в код, а затем смож ем поговорить о том, как опи работают. Отредак
тируйте фупкцию processWork в m a n d e l .j s и добавьте туда эти две строки:
Таким образом , мы удостоверяемся в том, что текущее поколепие, пад которы м мы работаем , соответ
ствует поколепию результата, возвращ еппого веб-сцепарием worker. Если так опо и есть —отличпо, тог
да пам потребуется парисовать строку. Если ж е соответствия пет, строка, скорее всего, является старой,
поэтом у мы п росто будем ее игнорировать (очепь жаль, что паш worker впустую потратил па п ее свое
время, одпако мы пе хотим рисовать старую строку из предыдущ его и зображ епи я па экрапе).
Итак, вот и все, па этот раз по-пастоящему. П ора убедиться в том, что вы впесли все приведеппы е выше
изм епепия, и подготовиться к...
552 глава 10
применяем javascript на деле
Создать HTML-страницу
Щ е лка й т е,
увеличивайт е,
дальше ► 553
г
В ЛАБОРАТОРИИ
Е сл и вы п и ш е т е в ы с о к о п р о и з в о д и т е л ь н ы й
ко д , то з а х о т и т е п р о в е р и т ь , к а к к о л и ч е с т в о
в е б -с ц е н а р и е в worker п о в л и я е т на в р е м я
в ы п о л н е н и я р а б о ты в а ш и м п р и л о ж е н и е м .
Д л я э то го вы м о ж е т е в о с п о л ь з о в а т ь с я м о
н и т о р о м за д а ч ка к в о п е р а ц и о н н о й с и с т е
ме O S X , т а к и в W in d o w s . Е с л и в е р н у т ь с я
к наш ей о р и ги н а л ь н о й о д н о по то чн о й версии О О О
(п о а д р е с у h ttp ://w ic k e d ly s m a rt.c o m /h fh tm l5 /
c h a p te r l O /s in g le th r e a d /fra c ta l.h tm l), то к а р т и
ну и с п о л ь з о в а н и я я д е р пр и в ы п о л н е н и и п р и
л о ж е н и я на н а ш е м к о м п ь ю т е р е вы м о ж е те
у в и д е т ь на д и а гр а м м е , п р и в е д е н н о й с п р а в а .
Н а ш к о м п ь ю т е р и м е е т в о с е м ь я д е р , ко т о р ы е v
б у д у т д о с т у п н ы п р и л о ж е н и ю F ra c ta l E x p lo re r 3 нашем к о м п ь ю т е р е — восемь
с в е б -с ц е н а р и я м и worker, и мы з а д а е м к о ядер. Одно из них использует ся по
ли чество worker, со о тв е тств ую щ е е этом у м а к с и м у м у и не может вычислять
ч и с л у я д е р , у к а з а в numberOfWorkers = 8. бы ст рее, чем позволяет его рабочая
К а к вы м о ж е т е в и д е ть на м о н и т о р е а к т и в н о част от а. Остальные семь ядер н и
с ти , все 8 я д е р и с п о л ь з у ю т с я по м а к с и м у м у . чего не д е л а ю т , чтобы помочь ему.
О О О
554 глава 10
применяем javascript на деле
О О О Fractal Explorer
[' < [V | [ + 1Q http': //focal host j - Beth/HTML 5/fracta I/f racta l~.tr <5 | (O* GoogTe *)
А
дополнительная функциональность api-интерфейсэ web workers
П р е р ы в а н и е В ы п о л н е н и я w o rk er
• о ц ж а о ш и б о к w o rk er
v J
worker.onerror function(error) {
document.getElementByld("output") .innerHTML =
556 глава 10
применяем javascript на деле
Вы могли упустить это из виду (мы бы стро прош ли мимо данного аспекта взглянув ня т
"There is a light at the end of every t unnel... just pray it's not a train!”,
"Do you believe in love at first sight or should I walk by again?"];
function postAQuote() {
Ц одм астее^ье ^ W o rk er
Если вашему worker потребуется помощь в вы полнении его задачи, он сможет создать свои соб
ственные веб-сценарии worker. Допустим, вы поручаете своему worker области изображ ения, ко
торы е он долж ен вычислить, a worker при этом м ож ет решить, что если область превышает некий
разм ер, то работу по ее вы числению следует распределить между его собственны ми субсценария
ми subworker.
worker генерирует subworker тем ж е путем, посредством которого код в вашей странице создает
worker: , . ....
var worker = new W o r k e r ("subworker.js );
П ом ните, что все subworker, как и обычные worker, являются довольно «тяжеловесными», они за
нимают память и выполняются как отдельные потоки. П оэтом у будьте осторож ны с количеством
создаваемых subworker.
дальше ► 557
обзор аpi-интерфейса web workers
КЛЮЧЕВЫЕ
— МОМЕНТЫ
■ Без веб-сценариев worker JavaScript является од Вы можете выяснить, какой именно worker от
нопоточным, то есть может выполнять только какое- правил сообщение, воспользовавшись свойством
то одно действие за раз. event.target.
■ Код для веб-сценария worker располагается в от Каждый worker выполняется в своем собственном
дельном файле и обособлен от вашего основного потоке, поэтому ваш компьютер обладает много-
кода. ядерным процессором, веб-сценарии worker смогут
выполняться параллельно, что повышает скорость
■ У веб-сценариев worker нет доступа к любым функ
вычислений.
циям в коде вашей страницы, а также к объектной
модели документа (DOM). Вы можете прервать выполнение worker, вызвав
worker .terminate () ИЗ КОДЭ СВОвЙ СТраНИЦЫ.
■ Код в вашей странице и веб-сценарий worker обща
В результате выполнение сценария worker будет
ются посредством сообщений.
прекращено, worker также может сам остановить
■ Для отправки сообщения веб-сценарию worker ис свое выполнение, вызвав close о .
пользуйте postMessage.
Все worker располагают СВОЙСТВОМ onerror.
■ Вы можете отправлять строки и объекты веб Вы можете задать для него значение в виде функции
сценарию worker С ПОМОЩЬЮ postMessage. От- обработчика ошибок, которая будет вызываться в
правлять функции веб-сценарию worker нельзя. случае возникновении ошибки при выполнении сце
нария worker.
■ Для приема сообщений обратно от worker не
обходимо задать для свойства worker с именем Для включения и использования JavaScript-
onmessage фуНКЦИЮ обработчика. библиотек в файле вашего worker используйте
importScripts.
■ Для получения сообщений веб-сценарием worker
от кода вашей страницы необходимо задать для его Вы также можете использовать importScripts
свойства onmessage фуНКЦИЮ обработчика. в сочетании с JSONP. Реализуйте функцию обратно
го вызова, которая передается в URL-запросе, в фай
■ Когда worker готов к отправке результата обратно,
ле worker.
он вызывает функцию postMessage и передает ей
данный результат в качестве аргумента. Несмотря на то что у веб-сценариев worker нет
доступа к объектной модели документа (DOM) и к
■ Результаты работы worker инкапсулируются в объ
функциям в вашем основном коде, они могут исполь
екте event и располагаются в свойстве data.
зовать XMLHttpReguest И localStorage.
558 глава 10
применяем javascript на деле
1 Л Щ ,5 - К Г °ссК °Г Д
Здорово! Вы добрались до конца главы 10. Откиньтесь на снин-
ку стула, расслабьтесь, а затем закрените изученны й материал,
немного но раб отав другим нолуш арием своего мозга и разгадав
кроссворд.
По горизонтали По вертикали
3. Аппаратная особенность процессора, дающая ему воз 1. ________________выполнения.
можность выполнять более одной задачи за раз. 2. Веб-сценарии worker могут использовать
6. Свойство, используемое для регистрации обработчика XMLHttpReguest И у НИХ ИМевТСЯ ДОСТуП К__________.
с целью приема сообщений. 4. Посредством НИХ о б щ а ю тс я manager, js И Ввб-
7. В нашем первом примере мы использовали эту игру. сценарии worker.
9. Вы можете передавать______________ веб-сценариям 5. Инструмент для импорта дополнительного кода
worker С ПОМОЩЬЮ postMessage. В worker.
11. У веб-сценариев worke г нет доступа к _____________ . 8. Что нужно ввести для того, чтобы прекратить выполне
12. Наиболее широко известный фрактал. ние worker?
13. _______________ /веб-сценарий worker. 10. В случае с множеством Мандельброта используются
15. Человек, который написал оригинальную версию числа.
Fractal Explorer. 14. ЧТО НУЖНО ВВеСТИ ДЛЯ ТОГО, ЧТОбы СОЗДаТЬ Worker.
16. Красивая область виртуальной сельской местности
в множестве Мандельброта называется «____________
острова». owie он cv)VY)dog
-02 ЭИ 020Wie wvg V(?20>iY)H IQW (OHQVV
дальше ► 559
решение упражнения
window.onload = f u n c t i o n () {
var worker = new W o r k e r ("wor k e r .j s " ); Данный код о т п р а в и т пя т ь сообщений
worker.onmessage = f u n c t i o n (e v e n t ) { со строкой "ping" § сб-сценарию w o rk e r, к о
a l e r t ("Worker says " + event.data); торый в о т в е т от ош л е т пят ь сообщений
} со строкой "pong", п о э т о м у на экране п о
for (var i = 0; i < 5; i++) { явится пя т ь диалоговых, окон a le r t с т е к
wo r k e r . p o s t M e s s a g e ("pin g " ); с т о м "W ork er says pong".
}
}
window.onload = f u n c t i o n () { Данный код о т п р а в и т пя т ь сообщений
var worker = new W o r k e r ("wor k e r .j s " );
со строкой "pong" веб-сценарию wor,ken
worker.ommessage = function(event) {
который пр о и гн о р и р ует их, поскольку они
a l e r t ("Worker says " + event.data);
не вклю ч а ю т ст р о к у "pj^g"- Никакого вы
} вода генерироват ься не будет.
for(var i = 5; i > 0; i— ) {
wo r k e r . p o s t M e s s a g e (" p ong");
560 глава 10
применяем javascript на деле
var quotes = ["I hope life isn't a joke, because I don't get it.",
"There is a light at the end of every tunnel....just pray it's not a train!",
"Do you believe in love at first sight or should I walk by again?"];
var index = Math.floor(Math.random() * quotes.length);
postMessage(quotes[index]);
В НТМL у нас имеется скрипт , создающий w orker, выполнение кот орого зап ускает
ся незамедлит елт о. worker произвольно выбирает цит ат у из массива quotes и о т
правляет ее основному коду с помощью postMessage- O сновной код извлекает цит а
т у из event.data и добавляет ее на страницу в элемент <р> с id в виде "quote".
дальше ► 561
решение упражнения
562 глава 10
применяем javascript на деле
Доздравляем!
1)ьх Д о Ш Л и Д о ХонДа.
дальше ► 563
П р и л ож ен и е. О ста в ш и еся т е м ы
№ 1. Modernizr
Читая книгу, вы, вероятно, обратили внимание на то, что нри н е
обходи м ости выяснить, ноддерж ивает ли браузер тот или и н ой
API-интерф ейс, оказывается, что едины й сн особ сделать это отсут
ствует; фактически, ноддерж ка ночти лю бого API-интерф ейса детек
тируется но-разному. Н анример, в случае API-интерф ейса G eolocation
мы ищ ем объект geolocation как свойство объекта navigator, в то
время как в API-и нтерф ей се Web Storage мы нроверяем , он ределен ли
localStorage в объекте window. Что касается API-интерф ейса V ideo,
то в дан ной ситуации мы нроверяем , есть ли у нас возмож ность соз
дать элем ент video в объектной модели документа (DOM ) и т. д. На
верняка существует сн особ но лучше?
566 приложение
оставшиеся темы
П омимо элемента <audio>, существует соответствую щ ий API-интерф ейс A udio, ноддерж иваю щ ий ме
тоды , которы е вы и ожидали бы увидеть, нанример play, pause и load. Если вам все это нокажется
знакомым — это хор ош о, носкольку API-интерф ейс A udio является отраж ением (в соответствую щ их
случаях) API-интерф ейса V ideo. API-интерф ейс A udio также ноддерж ивает м ногие свойства, с кото
рыми вы сталкивались в API-и нтерф ей се V ideo, нанример src, currentTime и volume. Н иж е нриведен
небольш ой связанный с аудио код, чтобы вы ночувствовали, как данны й API-интерф ейс иснользуется
в сочетании с элем ентом в странице:
Как и в случае с видео, каждый браузер но-своему реализует внеш ний вид элементов унравления нро-
игрывателем (в число которы х обы чно входит нолоса воснроизведения, кнонки ностановки на наузу
и регулирования громкости).
Н есм отря на нростую функциональность, элем ент audio и API-интерф ейс A udio нредоставляю т вам
ш ирокий контроль. П одобн о тому как мы ностунали с элем ентом video, вы см ож ете создавать и н терес
ные веб-нриложения, предусматривая скрытие элементов унравления из виду и унравление воснроиз-
ведением аудио в своем коде. А с номощ ью HTM L5 тенерь у вас есть возмож ность делать это без н ео б
ходим ости иснользовать (и изучать) нлагины.
дальше ► 567
j Query
Для начала вонрос: ном ните ли вы все те функции w indow .onload, которы е мы нисали \
но ходу книги? Нанример: т а к т и ч е ск о е
3 наши они ^
window, on load = f u n c t io n () { ^ а н и е jQ uery являете
a l e r t ("the page i s lo a d e d !" ); деЗНЫМ навыКОМ>
, п о м о га ет , п о н я т ь код,
д .п писанный другими.
А вот то ж е самое, но с иснользованием jQuery:
$ (document) . read y ( fu n c tio n () { <— К ак и в нашей версии: когда за гр узка докум ент а
a l e r t ("the page i s lo a d e d !" ); б удет закончена, вызвать м о ю функцию.
}) ;
М ожно сократить данный код ещ е больше, до:
$ ( fu n c tio n () { Это классно, но чтобы привы кнут ь, п от реб ует ся
немного времени. Не беспокойтесь — все эт о быстро
a l e r t ("the page i s lo a d ed ! ") ; ^ ^ npiAgm i M делоМ.
}) ;
А что с извлечением элементов и з объектной модели документа (DOM)? И м енно здесь jQ uery блистает.
Донустим, в вашей странице им еется якорь с id в виде "buynow" и вы хоти те назначить обработчик со
бы тий, инициируемы х нри щелчке кнонкой мыши, для собы тия c l i c k данного элемента (как мы уже
делали ранее несколько раз). Вот как это м ож но сделать:
Так что же здесь происходит ? Сначала мы задаем ф ун кцию ,
кот орая будет вызываться по завершении загрузки страницы.
568 приложение
оставшиеся темы
Н а самом деле это лишь начало; мы м ож ем так ж е легко задать обработчик собы тий c l i c k для каждого
якоря на странице:
Для эт ого нам п о т р еб ует ся использовать
$ ( f u n c t i o n () {
лишь с о о т ве т с т в ую щ е е имя тега.
$ ( " а ” ) . c l i c k ( f u n c t i o n () {
X
Ч_ Вообще т о здесь jQ u e ry лишь « ра зо гр е ва е т с я »; данная библиотека
позволяет делат ь вещ и, намного сложнее этик.
У jQ uery есть соверш енно другая сторона, которая нозволяет осуществлять лю боны тны е и н тер ф ей с
ные трансф ормации элементов, как ноказано далее:
$ ( f u n c t i o n () {
$ ( " # s p e c i a l o f f e r " ) . t o g g l e ( f u n c t i o n () {
},fu n c t i o n () {
Как вы м ож ете видеть, с номощ ью jQ uery возм ож но м ногое, нри этом мы даже еще не начинали раз
говор об иснользовании дан ной библиотеки для общ ения с веб-службами и обо всех нлагинах, которы е
работаю т с jQuery. Если вы заинтересовались дан ной тем ой, введите в браузере адрес h ttp ://jq u e r y .
с о т / и изучите имею щ иеся там учебны е материалы и документацию.
дальше ► 569
XHTML и SVG
То же самое определение
< ! D O C TY P E h t m l > . _____ d o c ty p e , что и раньше!
~ Это XML, нам нужно
Chtml xmlns="http://www.w3.org/1999/xhtml"> ^ _ у пр о с т р а н ст ^о имен!
<head>
< title > Y o u R ock!< /title > Все элементы должны быть правильными;
/ о б р а т и т е здесь внимание на идущие о конце
C m e ta c h a r s e t = " U T F - 8 '- /> сиМ ош исП0ЛЬЗуеАЛЬ1е для зак ры -
</head> тия данного п уст ого элемент а.
<body>
<p>I'm kinda liking this XHTML!</p>
Мы используем SVCi
<svg xmlns="h t t p ://www.w3.org/2000/svg"> для рисования прямо -
<rect stroke="black" fill="blue" x="45px" y="45px" угольника на нашей
width="200px" height="lOOpx" stroke-width="2 " /> странице. Изучите
</svg> ^ т е м у N~S (на следую -
</bod > 4. можем вложить XML щей ст ранице)> чтобы
° У прямо в страницу! И эт о у ЗИа т ь больше о SVQ.
</html> очень здорово.
А тенерь давайте взглянем на ряд вещ ей, которы е вам нотребуется нринимать во внимание в случае
с вашими XHTM L-страницами: Закры т ие всех ваших э л е м е н
т о в , кавычки вокруг значений
■ Ваша страница долж на нредставлять со б ой нравильный XML. а т р и б у т о в , допуст им ое вл о
жение элемент ов и т. п.
■ Ваша страница долж на загружаться с иснользованием тина MIME application/xhtml+xml, для чего
вам нотребуется удостовериться в том, что ваш сервер обеснечивает данны й тин (нроверив это са
м остоятельно либо связавшись с адм инистратором вашего сервера).
■ О беснечьте и включите пространство имен XHTM L в свой элем ент <html> (что мы уже сделали
в коде чуть выше).
Как мы уже отмечали ранее, относительно XML существует масса дополнительны х вещ ей, о которы х
м ож но узнать, а также м нож ество вещ ей, с которы ми следует быть осторож ны м и. И, как и всегда в слу
чае с XML, да нребудет с вами Сила...
570 приложение
оставшиеся темы
№ 5. SVG
Scalable Vector Graphics («Масштабируемая векторная графика» ), или SVG, иредставляет со бой еще один
сн особ — номимо canvas — включения графики нативно в ваши веб-страницы. SVG существует уже дол
гое время (с 1999 года или около того) и в настоящ ий м омент ноддерж ивается во всех текущих версиях
основны х браузеров, включая Internet Explorer 9 и выше.
В отличие от canvas, которы й, как вы знаете, иредставляет со бой элемент, нозволяю щ ий рисовать
никселы на н оверхн ости для растрового рисования с номощью JavaScript, SVG-графика определяется
использованием XML. XML, вы говорите? Да, XML! Вы будете создавать элементы , которы е нредстав-
ляют графику, а затем объединять эти элементы друг с другом комплексными путями для создания гра
ф ических сцен. Давайте взглянем на очень н р остой SVG-нример:
S
<body> HTML -разм е т к е ! ^
Наш SVG - п р и м е р прост: он сооер
<div id="svg"> v- ^ m w кот 0рый pacno
<svg xmlns=”http: //www.w3.org/2000/svg"> у ______
> У ложен по - ~ K00pduHamaM X=50, y=SO
<circle id="circle" и обладает радиусом 2-0 пикселов
c x = " 5 0 " c y = "50 " r= "2 0"
s tro k e = " # 3 7 3 7 3 7 " s tro k e -w id th = " 2 " ^ ...снабжен линией обводки шириной 2 пик
fill= " # 7 d 7 d 7 d " /> села, имеющей т ем н о -с е р ы й цвет...
</svg>
</div> ...и заливкой с исп оль
Вы можете извлечь
</body> зованием серого цвета
данный элем ен т
</html> со средним значением.
circle, как и любой
SVG онределяет ряд базовых фигур, таких как круги, нрямоугольники, многоу другой элем ен т из
гольники, линии и т. д. Если вам нотребуется нарисовать более сложные фигуры, объектной модели
то вы также см ож ете онределить контуры с номощ ью SVG — естественно, в этот докум ент а Р О М ,
м омент вещи начнут становиться более сложными (как вы уже могли убедиться и сделат ь с ним
в случае с контурами в canvas). Однако существуют графические редакторы , ко т о, что вам необ
торы е нозволят вам нарисовать сцену или экспортировать ее как SVG, избавляя ходимо... н а п р и м е р ,
вас от головной боли, которую вам доставила бы н еобходим ость самостоятель добавить о б р а б о т
но разбираться со всеми этими контурами! Вы см ож ете масштабировать свою чик событий click
графику, увеличивая или уменьшая ее но своему усм отрению , и она нри этом не и изменять зн аче
подвергнется никселизации, которая и м еет м есто нри масштабировании и зо ние а т р и б у т а fill
браж ений в ф ормате jp e g или png. Это облегчает новторн ое использование гра элем ен т а circle на
фики в различны х ситуациях. А носкольку SVG определяется с использованием 11r e d 11, когда п о л ь
текста, в случае с SVG-файлами м ож но осуществлять ноиск, индексировать их, зоват ель щелкнет
нрименять к ним сценарии, а также сжимать их. И сследуйте данпую технологию на данном э л е м е н
но др о б н ее, если она вас заинтересовала. те мышью.
дальше ► 571
автономные веб-приложения и api-интерфейс web sockets
№ 6. Автономные 6еб-прилоЖенця
Е с л и у вас им еется см артф он или нланш етный комнью тер, то вы, вероятно, выхо
дите в И нтернет, находясь в пути, и благодаря Wi-FI и сетям сотовой связи ночти
все время подключены к В сем ирной наутине. А как насчет того врем ени, когда вы
не подключены к ней? Разве не будет здор ов о, если вы см ож ете нродолжать ис-
нользовать все эти веб-нрилож ения HTM L5, которы е создаете для себя?
Ч то ж, тенерь у вас есть такая возмож ность. Автономны е веб-нрилож ения ноддер- ^
ж иваются всеми настольными и мобильными браузерами (с одним исключением: ^ благодаря т а -
Internet Explorer). кой вещ и, как
Как ж е сделать свои веб-нрилож ения достунными в автоном ном режиме? Нужно авт о но мные
создать файл манифеста кэша, которы й будет содержать снисок всех файлов, необ- веб-приложения,
ходимы х вашему нрилож ению для работы, и браузер загрузит все эти файлы и не- у вас ест ь
реключится на локальные файлы, когда ваше устройство н ерей дет в автономны й возможность
реж им. Ч тобы сообщ ить своей веб-странице о том, что у н ее имеется файл мани- пользоваться
ф еста, пужно н росто добавить его ф айловое имя в тег <html>, как ноказано далее: своими льо-
Chtml manif est="notetos elf .manifest " > биМЫМи веб -
Вот что содерж и т файл notetoself .manifest: прилож ениям и,
~ когда вы не п о д -
САСНЕ M A N IF E S T 4 ------- С э т о го должен начинаться каждый КЛМЧены к И н -
САСНЕ: ^ ф а й л м а н и ф е с т а кэша. т ернету'.
В тор ое, что вам будет пужно знать, заключается в том, что тестирование автономны х веб-нрилож ений
осущ ествляется мудреным снособом ! Мы рекомендуем вам изучить соответствую щ ие снравочны е мате
риалы на эту тему, а также спецификацию автономны х веб-нрилож ений HTML5.
Как только у вас заработает базовое кэш ирование, вы см ож ете иснользовать JavaScript для нолучения
уведомлений о связанных с кэшем собы тиях, которы е инициирую тся, нанрим ер, когда файл м аниф е
ста кэша подвергается обновлению , а также о состоянии кэша. Для нолучения уведом лений о собы тиях
н еобходим о добавить обработчики собы тий в объект window. applicationCache, как ноказано далее:
window. applicationCache.addEventListener("error", errorHandler, false);
Реализуйт е errorH andler для получений уведолл-
572 приложение лений, если в случае с кэш ем произойдет ошибка.
оставшиеся темы
Web Sockets — это новый API-интерф ейс, которы й нозволяет ноддерживать откры тое нодклю чение
к веб-службе, чтобы каждый раз, когда становятся достунными новы е данны е, эта служба могла нри-
сылать их вам (и ваш код мог нолучать соответствую щ ие уведомления). Считайте все это откры той
тел еф он н ой линий между вами и службой.
Вот вы сокоуровневы й об зо р того, как следует иснользовать данны й API-интерфейс: сначала для созда
ния веб-сокета вам нотребуется нрименить конструктор WebSocket: о б р а т и т е внимание: в с л у -
чае с данным URL-адресом
используется прот окол WS,
va r socket = new W e b S o cke t ( "ws :/ / y o u r d o m a in /y o u r s e r v ic e " ); a не п р о т о к о л HTTP.
Вы см ож ете нолучить уведом ление, как только сокет будет открыт носредством собы тия open, для кото
рого м ож но назначить обработчик: Здесь мы п р едусм о т рел и обработчик, который
ст а н е т вы зываться, когда сокет будет полност ью
s o c k e t . o n o p e n = f u n c t i o n () { п
о т к р ы т и гот ов к коммуникации.
a le r t( " Y o u r socket is now open w ith th e w eb s e r v ic e " ) ;
}
Вы см ож ете отнравить веб-службе сообщ ени е с номощ ью м етода postMessage:
Здесь мы от правляем серверу с т р о к у j
s o c k e t.p o s tM e s s a g e ( - - p la y e r m o v e d r ig h t- - ) ; двоичные данные н а с т у п а ю т , но пока еще
не поддерживаются широко.
А для нолучения сообщ ени й необходим о зарегистрировать другой обработчик, как показано далее:
З ар еги с т р и р ова в обработчик,
s o c k e t, onmessage = function ( event ) { мы сможем получат ь все
alert ("From socket: " + event.data); сообщения, содержа
щиеся в свойстве
*' event.data.
К онечно, но мимо всего этого есть немного ещ е кое-чего, и вам п о
требуется изучить учебны е материалы, имею щ иеся в И н терн ете, однако
относительно API-интерф ейса больше о со б о сказать нечего. Данны й API-
и н тер ф ей с отстает в развитии от некоторы х других API-интерф ейсов HTML5,
ноэтому читайте самые свеж ие руководства, где содерж ится инф орм ация о совме
стим ости с браузерами, нреж де чем браться за какой-либо крунный проект.
573
дополнительно о api-интерфейсе canvas
574 приложение
оставшиеся темы
ш context.translate(200, 200);
context.rotate(degreesToRadians(36));
context.fillRect(0, 0, 100, 100);
Когда вы т р а н с л и р уе т е иди п о
ворачиваете canvas., он п е р е м е
щается по координатной сет ке,
которая позиционируется о т
носительно верхнего левого угла
окна браузера. Если вы прим ен ит е
т 36
CSS для позиционирования canvas,
то данные значения б у дут п р ин и
м а т ь ся в расчет. Попробуйте!
дальше ► 575
api-интерфейс selectors и кое-что еще
№ 9. A P I-интерфейс Selectors
Вы уже знаете как нронзводнть выборку элементов и з объектной модели документа DOM с номощью
document.getElementByld; мы иснользовали данны й м етод как сн особ сделать так, чтобы HTML и
JavaScript работал и сообщ а. Вы также увидели, как сл едует иснользовать document.getElementsByTagName
(данный м етод возвращ ает массив всех элементов, соответствую щ их заданному тегу) и даж е метод
getElementsByClassName (возвращающий, как вы уже догадались, все элементы в он ределенн ом клас
се). Благодаря HTM L5 сейчас у нас им еется новы й сн особ выборки элементов из объектной модели до
кумента DOM , основанны й на j Query. Тенерь вы м ож ете задействовать те ж е селекторы , которы е при
м еняете в CSS с целью выборки элементов для стилизации в своем JavaScript, для выборки элементов из
объектной модели документа DOM с использованием м етода document.querySelector. Допустим, у нас
им еется приведенная далее нростая HTML-разметка:
<!doctype html>
<html lang="en">
<head> Пристально взгляните на с т р у к т у р у
< t it l e > Q u e r y s e l e c t o r s < / t i t l e > данной HTML-разм ет ки. Мы собираемся
<meta c h a r s e t = " u t f - 8 "> __ использовать A P I -инт ерф ейс Selectors
< /h e a d > gbl$0p KU элементов из страницы.
<body> С—
<div class="content">
<р id="avatar" class="level5">Gorilla</p> У нас &сть элем ен т <div> С классом
<р id="color">Purple</p> ^ " c o n te n t” и два элем ен т а <р>, каждый
</ div> из которых обладает собственным
</body> и ден т иф ик а т ор ом , при э т о м у одно -
</html> го из ниу имеет ся класс "le v e lsп.
Тенерь давайте воспользуемся API-интерф ейсом Selectors для выборки элемента <р> с id в виде "avatar":
document.queryS elect or ("# avatar" ) ; 4*—
П о сути, это то ж е самое, что и document . getElementld ("avatar"). Тенерь давайте иснользуем класс
элемента для его выборки: ^ ^
U , Сейчас мы используем имя т ега
document.querySelector("p.Ievel5"); u класс для его выборки.
Мы также мож ем нрои звести выборку элемента <р>, которы й является дочерни м но отнош ению к эле-
менту < d iv > , следующим образом: мы ислользуем селектор дочерних
d o c u m e n t.q u e ry S e le c to r (" d iv > p " ) ; эл е м ен т о 0 child для выборки элем ен т а <р>,
или даж е так: который является дочерним по отношению
л /" к э л е м е н т у <div>. По умолчанию он выби-
document.querySelector (". content>p") ; — л - ,,лл
^ J v * ' р а е т первый элемент.
А если нам но надобятся все элементы <р> в <div>, то мы см ожем воспользоваться другим м етодом в API-
и н тер ф ей се Selectors с им енем queryS elect orAll: , п _
Теперь мы извлекаем все дочерние
document.queryS elect о г All ("div>p" ) ; элемент ы <р> элем ен т а <dtv>!
queryS el ectorAll возвращ ает массив элементов точно так ж е, как и м етод getElementsByTagName.
Вот и всё! В API-интерф ейсе Selectors им еется только два метода. Данны й API-интерф ейс является н е
большим, однако он нривносит новую мощпую функциональность для выборки элементов.
576 приложение
оставшиеся темы
дальше ► 577
htm 15-руководство по новым конструкциям
578 приложение
оставшиеся темы
дальше ► 579
семантические элементы html5
Здесь, в Вебвилле, мы внесли ряд свежих изменений в наш «строительный» код и подготовили
<div> вместо
удобное руководство по всем новым конструкциям. Если вы используете элементы
обычных конструкций вроде <header>, <nav>, <f ooter> и <article> для блоговых статей,
то у нас есть для вас новые строительные блоки. Итак, давайте взглянем на них.
<section>
<article>
<header>
<footer>
<hgroup>
580 приложение
оставшиеся темы
<nav>
<nav> — это навигация, и данный элемент, конечно же, предназначен для ссы-
лок. Но не для любых ссылок: используйте <nav>, когда у вас имеется группа
ссылок, например навигация для вашего сайта или блога. Не используйте его
для одиночных ссылок в параграфах.
< a s id e >
< p ro g re s s >
< a b b r>
< m a rk >
Используйте <mark> для пометки слов, например, с целью выделения или редак
тирования. Данный элемент хорошо подходит для использования в сочетании
с результатами, выдаваемыми поисковыми движками.
дальше ► 581
css3-ceo0cmea
display: flexbox;
Благодаря flexbox вы получает е больший конт роль
flex-order: 1; <- над т е м , как б р аузер будет подходить к р а з м е щ е
Новые анимации нию блоков, наприм ер элем ен т ов d iv на странице
Благодаря анимациям у вас есть возможность анимировать переход между значениями свойств.
Например, вы можете сделать так, чтобы что-нибудь исчезало из виду путем перехода из не
прозрачного состоянии в полупрозрачное: Свойство transition определяет
transition: opacity 0.5s ease-in-out; свойство для перехода в кон
Задавая для opacity значение О, кретное состояние и выхода из
opacity: 0; п него (в данном случае речь идет
например, о случае наступления
события, инициируемого при на о непрозрачности), время, ко
ведении курсора мыши на элемент, торое будет занимать переход,
мы можем создать анимацию его и функцию замедления, чтобы
исчезновения/появления снова.
он был постепенным.
Новые селекторы
Появилась целая масса новых селекторов, включая nth-child, который позволяет на
целиваться на специфические дочерние элементы, заключенные в том или ином элементе.
Наконец-то у вас появилась возможность задавать цвет фона чередующихся строк в списке,
не прилагая при этом сумасшедших усилий. ^ п < ~
v v 3 м J Это означает: выдрать? каждый
ul l i : nth-child (2n) { color: gray; } вт орой элем ен т списка и з а
дат ь серый цвет фона.
582 приложение
информация о книге «Изучаем программирование на HTML5»
+Выходные сведения
дальше ► 583
/ А вы знаете о нашем веб-сайте? \
^ Там приводятся ответы на не-
которые вопросы из этой книги,
b i н е проЩ а^ с Вами!
а также руководства, из которых можно Заходите на
научиться дополнительным вещам,
и ежедневные обновления вблоге
от авторов! ]
Э. Фримен, Э. Робсон
Изучаем программирование на HTML5
Серия «Head First O’Reilly»
ООО «Мир книг», 198206, Санкт-Петербург, Петергофское шоссе, 73, лит. А29.
Налоговая льгота — общероссийский классификатор продукции ОК 005-93, том 2; 95 3005 — литература учебная.
Подписано в печать 10.09.12. Формат 84x108/16. Уел. п. л. 67,200. Тираж 2000. Заказ 0000.
Отпечатано с готовых диапозитивов в типографии «Вятка». 610033, Киров, ул. Московская, 122.