Изучаем программирование на html5 (head first o'reilly) 2013 part 001

Page 1


n * Эрик Фримен

* V v 4\

о * „ Элизабет Робсон

--------------------------------------------------------------------------------------------------

Изучаем гт программирование на

HTMlS

Учебное руководство по созданию веб-приложений с использованием JavaScript

Раскройте секреты гуру HTML5 Узнайте, почему все, что вашим друзьям известно о видео, может оказаться ошибочным Научитесь избегать досадных проблем с браузерной поддержкой I *

О REILLY

«Загрузите* HTML5 и JavaScript прямо в свой мозг

Изучите подводные камни, связанные с браузерами


Отзывы о книге «HTML5 является самой актуальной технологией создания веб-сайтов. М ногие разработчики го­ р ят ж еланием воспользоваться ею для создания гибких, насы щ енны х медиа-сайтов, с которы м и также будет удобно работать на нланш етны х комнью терах и смартфонах. К нига „Изучаем програм­ мирование на H T M L 5“ — наилучший и самый увлекательны й снособ освоить эту восхитительную технологию . О чень рекомендую». — М эр иэи и М арк, старш ий ви ц е-и р ези деи т ио техн ол оги я м в B lu e N ile Inc.

«Являясь н ростой, инф орм ати вн ой и увлекательной, книга „Изучаем программирование на H T M L 5 “ нредставляет собой настольное руководство для всех, кто ж елает изучить HTM L5 или нросто р е­ шил освеж ить свои знания но данной теме. С ерия „Head First“помотает мне ноддерж ивать знания на актуальном технологическом уровне, нозволяя более эф ф екти вн о унравлять нроектам и и ока­ зы вать содействие моим разработчикам». — Тодд Гуилл, м ен ед ж ер п р оек тов, A llR ecip es.co m

«Это вам не устареваю щ ий DHTML! „Изучаем программирование на H TM L5 “ рисует многообещ а­ ющую и онтимистичную картину будущего В сем ирной наутины через нризму HTML5, давая вам шанс но лучить туда билет. Если вы ищ ете нодробное, нанисанное достунным язы ком и н орой до­ вольно забавное руководство но HTM L5, данная книга то, что вам нужно». — М эиии О тто, веб-разр аботч ик и креативщ ик

«Авторы данной книги нонали в точку — навыки работы с 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

«В отличие от многих невразумительных книг но программированию , насы щ енны х техническим ж аргоном, руководства серии Head First jQuery номогаю т новичкам создавать их н ервы е страницы jQ u ery на нростом и достунном уровне». — Л и и дси Скурас, ю р и ст и ирограммист-самоучка


HTML5 Programming W ouldnt it be dreamy if th ere was an HTM L5 book th a t didn't assume you knew what the DOM, events, and APIs were, all by page three? It's probably ju st a fantasy

Ryan Benedetti Ronan Cranley

O ’REILLY Beijing • Cambridge • Koln • Sebastopol • Tokyo


Изучаем программирование на

HTML5 Как было бы здорово, если бы существовала книга о HTML5, в которой не предполагается заранее, что читателю знакомы такие понятия, как объектная модель документа (DOM), события и API-интерфейсы. Об этом можно лишь мечтать...

Эрик Фримен Элизабет Робсон

Москва ■Санкт-Петербург ■Нижний Новгород ■Воронеж Ростов-на-Дону - Екатеринбург - Самара - Новосибирск Киев ■Харьков ■Минск

2013

Создание веб-приложений с использованием JavaScript


ББК 32.988-02-018.1 УДК 004.43 Ф88

Ф88

Фримен Э., Робсон Э. Изучаем программирование на HTML5. — СПб.: Питер, 2013. — 640 с.: ил. ISBN 978-5-459-00952-1 Хотите создавать динамичные, интерактивные, насыщенные данными веб-страницы? Почему бы не использовать ПТМЬ5 для создания полнофункциональных веб-приложений? И почему бы не делать это с помощью современных методик, которые так же легко применимы к вашему настольному браузеру, как и к мобильным устройствам? Вам, конечно же, захочется использовать такие новейшие ПТМЬ5-технологии, как API-интерфейс Geolocation, элемент video, 2В-рисование, API-интерфейсы Web Storage и Web Workers и т. д. Пе так ли? С помощью данной книги вы научитесь создавать веб-нриложения с использованием современных стандартов и нередовых методик завтрашнего дня. Вы изучите основы новых API-интерфейсов ПТМЬ5 и узнаете, как они взаимодействуют со страницами и приво­ дятся в движение JavaScript-кодом, а также как использовать их для создания веб-приложений, которые впечатлят ваше начальство и изумят друзей.

ББК 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 (англ.) ISBN 978-5-459-00952-1

© 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. © Перевод на русский язык О О О Издательство «Питер», 2013 © Издание на русском языке, оформление О О О Издательство «Питер», 2013


П о с в я щ а е т с я С т и в у Д ж о б с у , б л а го д а р я к о т о р о м у п о ­ п у л я р н о с т ь H T M L 5 д о с т и гл а т а к и х в ы со т, ч т о д а н н а я к н и г а д о л ж н а р а з о й т и с ь о г р о м н ы м т и р а ж о м .. . И ещ е раз п о св я щ а е тся С ти в у Д ж о б су, п о то м у ч т о о н на ш ге р о й .


об авторах

Р о 5 со н

Эри к Ф р и м е н

Эрик — один из основонолож ников серии «Head First». К эти С иерра так характеризует Эрика: «Один из редких людей, которы е одинаково хоро­ шо владею т язы ком, практическим и навыками и знаниям и культуры в разны х областях, будь то сфе­ ра, в которой орудует хакер-хинстер, работает кор­ п орати вн ы й вице-нрезидент, нроектировщ ик или экснерт-аналитик».

Э лизабет совмещ ает деятельность п роекти ров­ щ ика программного обеспечения, нисателя и инструктора. О на увлеклась технологиям и еще во врем я учебы в Йельском университете, где нолучила стенень магистра ком пью терны х наук и занималась разработкой язы ка нараллельного визуального програм м ирования и нрограм м ной архитектуры.

В п роф ессиональном нлане Эрик недавно нодош ел к ночти десятилетней отметке в качестве долж­ ностного лица в медиа-комнании: он занимает ноет главного технического д иректора Disney O nline & Disney.com в Walt Disney Company. В настоящ ее врем я Эрик занят W ickedlySmart — стартаном, ко­ то р ы й он организовал совместно с Элизабет.

В свободное врем я Эрик серьезно увлекается музы­ кой; результат носледнего нроекта, над которы м он работал совместно с н ионером музыкального стиля «эмбиент» Стивом Роачем, им еется в элек­ тронном магазине нрилож ени й для iP hone и назы ­ вается Im m ersion Station.

Элизабет увлеклась созданием веб-нрилож ений на самом раннем этане разви тия И нтернета. О на участвовала в создании заслужившего нризнание веб-сайта T he Ada Project, которы й стал одним из нервы х ресурсов, нризванны х номочь женщ инам, заняты м в сф ере инф орм атики. О на является одним из основателей W ickedlySmart — образовательного онлайн-ресурса, носвящ енного веб-технологиям, на котором нредставлены ее книги, статьи, видео и нрочее. Ранее, когда Элизабет была руководителем снециальны х нроектов в O ’Reilly M edia, она лично нроводила семинары и онлайн-лекции на разны е техн и че­ ские темы, создавала образовательны е ресурсы. До сотрудничества с O ’Reilly M edia Элизабет довелось ноработать в Walt Disney Company, где она отвечала за руководство исследованиями и разработкам и в сф ере ц иф рового медиа.

П иш ите Эрику но адресу eric@ w ickedlysm art.com , а также носетите его сайт h t t p : / / ericfreem an.com

П иш ите Элизабет на beth@ w ickedlysm art.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 не менее важно для вас?

Для кого написана эта книга?

22

Мы знаем, о чем вы думаете

23

И мы знаем, о чем думает ваш мозг

23

М етапознание: учимся учиться

25

Технические р ецензенты

30

Б лагодарности

31

От издательства

33

9


зн аком ство с U IM L 5

Добро пожаловать в Вебвилль HTML стремительно развивается. Да, изначально HTML представлял собой простой язык разметки, однако с выходом новых версий он посте­ пенно наращивал мускулы. В настоящее время мы располагаем версией HTML, заточенной под создание полноценных веб-приложений с поддерж­ кой localStorage, 20-рисования, автономного режима работы, сокетов, по­ токов и т. д. История развития HTML не всегда была радужной: она полна драматизма (об этом мы поговорим позже), а в этой главе мы для начала совершим увеселительный тур по Вебвиллю, чтобы вы могли разобраться во всем, что вкладывается в понятие «HTML5». Поэтому запрыгивайте к нам — мы отправляемся в Вебвилль, где за 3,8 страницы (ровно) пройдем путь от исходной точки до HTML5.

П ер ехо д и те на HTML5 СЕГОДНЯ! Зачем ждать?

36

П редставляем вам наш новый Н Т М Ь б-м одернизатор. О бновите свой HTM L прямо сейчас

38

Вы ближ е к НТМ Ьб-разметке, чем думаете!

41

В стречаем HTML5: П ризнания новой версии HTM L

45

П росим встать НАСТОЯЩ ЕГО HTM L5...

46

Как на самом деле работает HTM L5...

48

Кто и что делает?

50

Ваша первая миссия: разведка в стане браузеров

51

Ч то м ож но сделать с помощ ью JavaScript

56

Пиш ем серьезны й JavaScript

59

Пиш ем серьезны й JavaScript: проверка ваших ответов

60

Ключевые моменты

65


содержание

знаком ство с JaVa^crij=>t и объектной м°ДеЛь1° Документа (J)Q]^)

Немного кода Благодаря JavaScript вы откроете для себя нечто новое. Вы уже все знаете о HTML-разметке (иначе называемой структурой) и CSS-стиле (также из­ вестном как представление), однако вам недостает знаний о JavaScript (или, как еще говорят, о поведении). Если ваш багаж знаний ограничивается лишь струк­ турой и представлением, то вы, конечно же, сможете создавать прекрасно вы­ глядящие страницы, однако они будут лишь простыми страницами. Но если вы добавите поведение, прибегнув к JavaScript, то сможете обеспечить для своих пользователей интерактивное взаимодействие; либо, что еще лучше, вы смо­ жете создавать роскошные веб-приложения. Добавьте в свой инструментарий веб-разработчика наиболее интересные и универсальные знания о JavaScript и программировании!

Н Т М ЬЪ -

с м а р сА> J a v a S c r ip t -

r В еп ери ,чес коерУк° ' Я Р » * * * ° У**4* яЦИИ 0ОДСТко М ^ н " Ка1 НИ*0 ,* е н Н«° 0т » * ОСГгТэфФе^ и в О»1*

Как работает JavaScript

70

Ч то мож но сделать с помощью JavaScript?

71

О бъявление п ер ем ен н ой

72

Как присваивать им ена перем енны м

74

С ерьезн ое програм м ирование

74

Вы ражения

77

М ногократное вы полнение одного и того ж е...

80

П ринятие реш ений с использованием JavaScript

83

П ринятие дополнительны х реш ений... и добавление перехваты вающ его блока

84

Как и куда добавлять JavaScript в свои х страницах

87

KaKjavaScript взаим одействует с вашей страницей

88

Рецепт приготовления со б ствен н ой объектной модели документа (DOM )

89

П ер вое испы тание объектной м одели документа (DOM )

90

Нельзя начинать взаимодействовать с DOM , пока веб-страница не загрузилась полностью

98

Для чего ещ е хорош о п одходи т DOM

100

Нельзя ли снова поговорить о JavaScript, или как осущ ествляется сохр ан ен и е м нож ественны х значений при использовании JavaScript

101

Как создать массив

101

Phrase-O-Matic

105

Ключевые моменты

109

11


собьшшя, обработчики и Весь эщощ джа£

Немного взаимодействия Вам все еще не удается соприкоснуться с пользователем. Вы изу­ чили основы JavaScript, однако могут ли ваши веб-страницы взаимодей­ ствовать с пользователями? Когда страницы откликаются на вводимые пользователем данные, они уже являются не простыми документами, а живыми, реагирующими приложениями. Из этой главы вы узнаете, как обрабатывать одну из форм ввода данных пользователем (извините за каламбур) и привязывать старомодный HTML-элемент < f o r m > к совре­ менному коду. Это может показаться необычным, однако такой подход также эффективен. Пристегните ремни, поскольку наше путешествие по данной главе будет проходить на большой скорости: путь от простого приложения до интерактивного мы пройдем очень быстро.

П риготовьтесь к встрече с W ebville Tunes

120

Приступаем...

121

Когда я нажимаю кнопку A dd Song (Добавить п есн ю ), ничего не п р ои сходи т

122

О бработка собы тий

123

Составляем план...

124

П олучение доступа к кнопке A dd Song (Добавить песню )

124

Задание обработчика собы тий click для кнопки

125

Более пристальный взгляд на происш едш ее...

126

И звлечение названия песни

128

Как добавить песню на страницу?

131

Как создать новый элем ент

133

Д обавлени е элем ента в DOM

134

С оединяем все воеди но...

135

...и проводим тест-драйв

135

О бзор того, что мы только что сделали

136

Как добавить приготовленны й код...

139

И нтегрирование пр иготовленного кода

140

Ключевые моменты

142


содержание

объекты и ^ункЦии JavaScript

Серьезный JavaScript Можете ли вы уже назвать себя создателем сценариев? Впол­ не возможно, поскольку вы уже многое знаете о JavaScript, однако кто захочет быть простым создателем сценариев, когда можно быть про­ граммистом? Пора проявить серьезность и поднять планку — настало время познакомиться с функциями и объектами. Они являются клю­ чом к написанию более эффективного, хорошо организованного и лег­ кого в сопровождении кода. Функции и объекты активно используются наряду с API-интерфейсами HTML5 JavaScript, поэтому чем лучше вы будете в них разбираться, тем быстрее сможете освоиться с тем или иным новым API-интерфейсом и начать его использовать. Пристегни­ тесь, поскольку эта глава потребует вашего всецелого внимания... Расш иряем ваш словарны й запас

148

Как добавить свои собственны е функции

149

Как работает функция

150

Локальные и глобальные перем енны е

157

Функции ещ е являются и значениям и

162

Ч то м ож но сделать посредством функций как значений?

163

Как создать объект на JavaScript?

166

Ч то м ож но сделать с объектами

167

П оговорим о передаче объектов функциям

170

Наш следующ ий сеанс состоится в...

174

Объекты также могут обладать поведением ...

176

В озвращ аемся к прилож ению W ebville C inem a...

177

Д обавлени е ключевого слова this

179

Как создать конструктор

181

Воспользуемся нашим конструктором

182

Как на самом деле работает t h i s ?

183

Сразу ж е проведем тест-драйв нашего конструктора

187

Ч то такое объект window?

189

Более пристальный взгляд на w indow .onload

190

Еще один взгляд на объект d o cu m en t

191

Более пристальный взгляд на d o cu m en t.getE lem en tB yld

191

Еще один объект, о котором нужно знать: объект элем ента 192 Ключевые моменты

194

13


содержание

API-интерфейс Geolocation Куда бы вы ни отправились, вас можно найти. Порой бывает так, что знание того, где вы находитесь, имеет существенное значение (особенно для веб-приложений). Из этой главы вы узнаете, как создавать веб-страницы с поддержкой определения ме­ стоположения. Иногда вы сможете определять местонахождение своих пользователей вплоть до угла, на котором они стоят, а иногда вам будет удаваться определить лишь район города, в котором они находятся (однако вы по-прежнему будете знать, какой это город!). Время от времени вы вообще не сможете получить хоть какую-нибудь информа­ цию о местоположении пользователей в силу технических причин или просто потому, что им не нравится ваше чрезмерное любопытство. Да, представьте себе! Так или иначе, но в данной главе мы рассмотрим API-интерфейс JavaScript под названием Geolocation. Бе­ рите свое самое лучшее устройство с поддержкой определения местоположения (даже если это будет ваш настольный компьютер), и давайте приступим к работе.

чv f

г

М естоп ол ож ен и е, м естоп ол ож ен и е...

200

Ш ирота и долгота...

201

Как API-ин терф ейс G eolocation опр едел яет м естоп ол ож ен и е пользователя

202

Так где ж е вы находитесь?

206

Как все это работает

210

Раскрываем наше тайное убеж ищ е...

213

Н аписание кода для опр едел ения расстояния

215

О тобр аж ение вашего м естополож ения на карте

216

Как добавить карту к странице

217

Прикалываем булавку на карту...

220

П р оч ие интересны е вещ и, которы е мож но сделать с использованием API-ин терф ейса G oogle Maps

222

М ож ем ли мы поговорить о точности?

225

“W herever you g o , there you are”

14

226

Приступаем к созданию прилож ения

227

Д орабаты ваем наш стары й код...

228

П ора отправляться в путь!

230

Параметр p osition O p tion s...

232

Мир парам етров tim eo u t и m axim um A ge...

233

Ш лифуем наше прилож ение!

238

И нтеграция наш ей новой функции

239

Ключевые моменты

241


содержание

общение с веб—сл уж б а м и

Приложения-экстраверты Что-то вы слишком засиделись на своей странице. Настало время немного пообщаться с веб-службами с целью сбора данных и последующего возврата этой информации, что даст вам возможность создавать более эффективные веб-ресурсы, которые объединяют собираемые данные. Это важный момент в написании современ­ ных НТМ1_5-приложений, и чтобы успешно им заниматься, вам необходимо знать, как происходит общение с веб-службами. Об этом мы и поговорим, а также научимся вне­ дрять данные от веб-служб в свои страницы. Усвоив изложенный материал, вы сможе­ те обращаться и взаимодействовать с любой веб-службой по своему выбору. Мы даже расскажем вам о новомодном жаргоне, которым следует пользоваться при общении с веб-службами. Вы познакомитесь с некоторыми новыми API-интерфейсами — так на­ зываемыми коммуникационными API-интерфейсами..

вас оЖиЭает hwm поворот!

К омпании M ighty G um ball требуется веб-прилож ение

248

П о д р о б п ее о систем е M ighty G um ball

250

Как выполпяются запросы , адресованны е веб-службам?

253

Как выполпять запросы из JavaScript

254

П одвинься, XML: встречайте JSO N

260

О тобр аж еп и е данны х об уровне продаж жвачки

264

Как установить собствепны й веб-сервер

265

Д орабаты ваем код с целью использования JSON

270

П ер еходи м к использованию действую щ его сервера

271

Н еож иданпы й поворот собы тий!

273

П ом н ите, как мы столкпулись с пеож идапны м повор отом собы тий? Н еполадки с прилож ением

276

Ч то за браузерная политика безопасности?

278

Какие у нас вариапты?

281

Знакомство с JSONP

286

Ч то означает буква Р в аббревиатуре JSONP?

287

О бн овление кода веб-прилож ения M ighty G um ball

290

Д орабаты ваем прил ож епи е M ighty Gum ball

298

О бн овление URL-адреса JSO N с целью включения lastreporttim e

309

К лючевые моменты

311

Специальпое со общ ен и е из главы 7...

313


содержание

раскрываем Б се^е художника

Элемент 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

Наш повы й стартап: TweetShirt

316

Взгляд па «оригинал-макет»

317

Как добавить canvas в свою веб-страницу

320

Как увидеть свой canvas

322

Рисование в элем енте canvas

324

Вы ходим до сто й н о из пр обл ем н ой ситуации

329

TweetShirt: общ ая картина

331

Спачала напиш ем н еобходим ы й HTM L

334

Теперь добавим <form >

335

П риш ло время добавить JavaScript для вы числений

336

Н аписапие функции drawSquare

338

Д обавлени е вызова fillB ackgroundC olor

341

Тем врем енем , возвращаясь к TweetShirt.com ...

343

Ч ер ч ен и е контуров

345

П о д р о б п о е исследование м етода arc

348

Н ебольш ой прим ер использования метода arc

350

Я говорю «градус», вы говорите «радиан»

351

Возвращ аемся к написанию TweetShirt-кода для рисования кругов

352

Пиш ем фупкцию drawCircle...

353

И звлечение твитов

357

Заверш аем написание функции drawText

365

Ключевые моменты

372


содержание

телевидение для нового поколения

Элемент video... и наш особый гость — элемент canvas Нам больше не нужны какие-либо плагины. Элемент v i d e o отныне является пол­ ноценным членом HTML-семейства — просто вставьте его в свою страницу, и вы обеспечите прямую поддержку воспроизведения видео на большинстве устройств. Однако v i d e o — это нечто значительно большее, чем просто элемент: это API-интерфейс JavaScript, по­ зволяющий управлять воспроизведением, создавать пользовательские видеоинтерфейсы и интегрировать видео с остальными HTML-элементами совершенно новыми способами. Го­ воря об интеграции, следует отметить, что между v i d e o и c a n v a s существует связь, — вы увидите, что объединение этих элементов открывает новые широкие возможности по об­ работке видео в режиме реального времени. В этой главе мы сначала научимся внедрять элемент v i d e o в веб-страницу, а затем поговорим об использовании соответствующего API-интерфейса JavaScript. Вы будете поражены тем, что можно сделать с помощью не­ большого количества разметки, JavaScript и элементов v i d e o и c a n v a s .

на Webville

TV

Знакомство с W ebville TV

384

Включите этот «телевизор» и протестируйте его...

385

Как работает элем ент video?

387

П ристальны й взгляд на атрибуты элем ента vid eo...

388

Ч то п еобходи м о зпать о ф орм атах видео

390

Как ж онглировать всеми этими форм атам и...

392

Я слышал, там будут API-интерфейсы ?

397

Н ем ного «программирования» содер ж им ого W ebville TV

398

Как написать обработчик «конца видео»

401

Как работает м етод canPlayType

403

Распаковка дем облока

409

Р ассм отрение остальной части «заводского» кода

410

О бработчики setEffect и setV ideo

412

Реализация элем ентов управлепия видео

418

Реализация остальны х элем ентов управления видео

419

Д орабаты ваем один нюанс...

420

Как п р ои сходи т обработка видео

426

Как обрабаты вать видео с использованием врем епного буф ера

427

Реализация врем енного буф ера в canvas

429

Займемся написапием эф ф ектов

433

Как использовать собы тия error

440


содержание

с о х р а н я е м Д анны е Л°КаЛьНо

API-интерфейс Web Storage Устали от того, что клиентские данные приходится втискивать в тесные шкафы файлы cookie? В 1990-е годы это не было проблемой, однако сейчас, в случае с веб-приложениями, запросы намного возросли. Как бы вы отнеслись к тому, если бы мы сказали, что у вас есть возмож­ ность выделять по 5 Мбайт на браузер каждого пользователя? Вы, веро­ ятно, подумали бы, что мы шутим. Однако не стоит быть скептичными, поскольку API-интерфейс HTML5 Web Storage как раз и позволят делать это! Из данной главы вы узнаете обо всем, что необходимо для сохране­ ния объектов локально на устройстве пользователя и использования их в работе ваших веб-приложений. Трудно разобраться во всех своих делах, если после того, как и х сделаешь, нельзя избавиться от клейких заметок, на которых они были записаны. Нельзя ли снабдить и х функцией удаления?

18

Как работает браузерпое хранилищ е (1 9 9 5 -2 0 1 0 )

448

Как работает Web Storage HTM L5

451

Заметка для себя...

452

Были ли локальное храпилищ е и массив разделены при рож дении?

458

С оздапие и п тер ф ей са

463

Теперь добавим JavaScript

464

Заверш аем создапи е и н тер ф ей са пользователя

465

П рервем ся для небольш ого заплапированпого м ероприятия

468

П оддерж ка типа «сделай сам»

469

Д орабаты ваем наше прил ож епи е с использованием массива

474

В песепие изм ен еп и й в createSticky с целью использования массива

475

Функция deleteSticky

483

Как выбрать заметку для удалепия?

484

Как извлечь заметку для удаления, используя объект event

485

Удаление заметки также из DOM

486

О бновление и н тер ф ей са пользователя для выбора цвета зам еток

487

М етод JSO N .stringify — не только для массивов

488

И спользование нового объекта stickyObj

489

Теперь, когда вы изучили localStorage, как вы соби р аетесь использовать его?

496


содержание

п о м е н я е м J a v a S c rip t н а д е л е

API-интерфейс Web Workers Медленный сценарий — хотите продолжить его выполнение? Если вам дово­ дилось достаточно тесно работать с JavaScript или путешествовать по Интернету, то вы, вероятно, сталкивались с диалоговым окном Slow Script (Медленный сценарий). Но как же сейчас, когда в компьютерах устанавливаются многоядерные процессоры, сценарии могут выполняться слишком медленно? Все потому, что JavaScript поддер­ живает выполнение только одного действия за раз. Однако с появлением HTML5 и Web Workers все изменилось. Теперь у вас есть возможность создавать множествен­ ные JavaScript-объекты w o r k e r для одновременного выполнения нескольких дей­ ствий. Независимо от того, пытаетесь ли вы создать более отзывчивое приложение либо просто хотите по максимуму задействовать все возможности центрального про­ цессора, API-интерфейс Web Workers придется кстати.

JavaS cript-n o m o k

Устрашающее диалоговое окно Slow Script (М едлепны й сценари й)

508

Как JavaScript проводит свое время

508

| Выполнение функции init

Когда одн оп оточ п ость — это П Л О Х О

509

^ Обработка события click

П оток веб-сцепария worker

510

Как работаю т веб-сценарии worker

512

Ваш первы й веб-сценарий worker...

517

Н аписание manager.js

518

П олучение со общ ен и й от веб-сцепария worker

519

А теперь папиш ем worker

520

I

Значение времени таймера | истекае т _

Обработка события submit

Чух-Чух ж -ж -ж

чух-чух чух-чух

О бработка массива данных

чух-чух ж -ж -ж

ж -ж -ж

чух-чух

Захват виртуальных земель

528

Как вычисляется м нож ество М андельброта

530

Как задействовать сразу несколько веб-сценариев worker

531

Займемся созданием прилож епия Fractal Explorer

537

С оздание веб-сценариев worker и раздача им задач...

542

Н аписание кода

543

Запуск веб-сцепариев worker

544

■Обработка след, события click *

Реализация кода worker

545

О бновление объектной ^модели документа DOM

Возвращ аемся к коду: как осущ ествляется обработка результатов работы worker

548

Выборка данных формы

______________I Ьалидация введенных пользователем данных

_

t

П одгоняем canvas под размеры окна браузера

551

Дотош ны й-ш сф п ов ар -программист

552

Время ф ипального тест-драйва!

553

Ключевые моменты

558

19


приложение: оставш иеся т е м ы

Десять важных тем (которые мы не рассмотрели) Мы рассмотрели массу различных тем, и вы почти закончили читать книгу. Нам грустно с вами расставаться, но прежде чем это сделать, нам необходимо поведать еще кое о чем, чтобы подготовить вас к свободному пла­ ванию. В этот сравнительно небольшой раздел нельзя уместить все, что вам требуется знать. Вообще-то сначала мы включили все, что чита­ телю следует знать о HTML5 (не рассмотренное в предыдущих главах), уменьшив размер шриф­ та до 0,00004. Все поместилось, однако текст стал слишком мелким и нечитаемым. Поэтому мы прилично сократили приложение и оставили только десять самых важных тем.

№ 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!

«т«к

6« -о * а " ТАКОЕ

дальше ►

21


как работать с этой книгой

Для кого написана эта книга? Если вы ответите утвердительно на все следующие вонросы: ( l ) У вас есть компьютер с установленным веб-браузером и текстовым редактором? Вы хотите узнать и разобраться, как создавать веб­ приложения, руководствуясь наилучшими методиками и самыми современными стандартами? Вам больше по душе оживленная интересная беседа, нежели сухие и скучные академические лекции? т о э т а к н и г а — д л я вас.

Кому зли книга пе подойдет? Если вы ответите ,™ «рД„тель„о на любой „ з с л е д я щ и х вонросов: /

Вы являетесь абсолютным новичком в созда­ * нии веб-страниц? (5 )

Вы уже заняты разработкой веб-приложений и ищете справочник по HTML5? Вы боитесь пробовать что-то новое? Вы пред­ почитаете однообразный узор цветному рисун­ ку? Вы полагаете, что техническая книга не мо­ жет считаться серьезной, если в нее включены кадры из забавных образовательных фильмов 1950-х годов и наделенные человеческими качествами API-интерфейсы JavaScript?

т о э т а к н и г а — н е д л я вас.

[Заметка от отдела продаж: вообще-то эта книга для любого, у кого есть деньги.]

22

введение

Ознакомьтесь с книгой « Изучаем H T M L , X H T M L u C SS» (Head First HTML with CSS & X H T M L ), где вы найдете превосходное введение в мир веб-разработок, а зат ем возвращайтесь и п р и ­ соединяйтесь к нам .


введение

Мы знаем, о чем вы думаете «Как это можно назвать серьезной книгой но програм м ированию на HTML5?» «Почему здесь так много картинок?» «Можно ли так чему-нибудь научиться?»

М о зг

ч^ 0 Э г о ~Я СЧЫ^ е^ , / U важно. U мы знаем, о чем думает баш мозг Ваш мозг жаждет новизны . О н ностоянно ищет, вы сматрива­ ет, ждет чего-то необы чного. Таким его создала нрирода, и это номогает нам выжить. Так что же ваш мозг делает со всеми рутинны ми, заурядны ми, обычными вещами, с которы м и вы сталкиваетесь? Все, что он может сделать, это не нозволить им номеш ать своей истинной работе, —ф иксированию того, что имеет значение. О н не сохраняет в намяти скучную информацию ; она никог­ да не нробьется через ф ильтр «это не является важным». А как мозг осознает, что именно является важным? Донустим вы выш ли на нрогулку, и вдруг неред вами выскакивает тигр. Ч то нроисходит у вас в мозге и в теле? А ктивизирую тся нейроны . Всныхиваю т эмоции. П роисходят химические реакции. И тогда ваш мозг нонимает.... Конечно, это важно! Следует запомнить! Но нредставим, что вы находитесь дома или в библиотеке. В безонасном, уютном месте, где не бывает никаких тигров. Вы что-то учите. Готовитесь к экзамену. Или нытаетесь освоить какой-то сложны й технический материал, на что, как считает ваш босс, уйдет неделя или, самое большее, десять дней.

ТЗач*

Замечательно. Еще 562 сухих, скучных страниц

" С » это гае. v* не л л о*ко

длинам-

И тут возникает нроблема. Ваш мозг будет ны таться ока­ зать вам большую услугу. О н станет следить за тем, чтобы явно несущ ественные сведения не засоряли ценны е ресур­ сы намяти. Эти ресурсы лучше нанравить на сохранение действительно важ ной инф орм ации. Н анрим ер, о том, что надо онасаться тигров, остерегаться огня или никогда боль­ ше не кататься на сноуборде в одних ш ортах. Но нри этом нельзя нросто сказать своему мозгу: «Послу­ шай, мозг, снасибо тебе, конечно, большое, однако н е­ важно, насколько скучна книга или что она не вы зы вает во мне сильных эм оций в данны й момент. Я в самом деле хочу заномнить инф орм ацию из нее». дальше ►

23


как работать с этой книгой

КнцГа ДЛЯ i» e x , К ш ° хоЧ еш учц щ ьса. Как мы что-то узнаем? Сначала нужно это «что-то» понять, а потом не забыть. Затолкать в голову побольше фактов недостаточно. Согласно новейшим исследованиям в области когнитивистики, нейробиологии и психологии обучения, для усвоения мат ериала тре­ буется что-то большее, чем простой текст на странице. Мы знаем, как заставить ваш мозг работать. Основные принципы серии «Head First»: Наглядность. Графика запоминается гораздо лучше, чем обычный текст, и значительно повышает эффективность воспри­ ятия информации (до 89 % по данным исследований). Кроме того, материал становится более понятным. Текст размещается на рисунках, к которым он относится, а не под ними или на соседней странице.

Разговорный стиль изложения. Недавние исследова­ ния показали, что при разговорном стиле изложения материала (вместо формальных лекций) улучшение результатов на итоговом тести­ ровании достигает 40 %. Рассказывайте историю, вместо того чтобы читать лекцию. Не стоит быть слишком серьезным. Что вам самим больше по душе: вести оживленный разговор с интересным собеседником или слушать лектора?

Активное участие читателя. Пока вы не начнете напрягать извилины, в вашей голове ничего не произойдет. Читатель должен быть заинтересован в результате; он должен решать задачи, фор­ мулировать выводы и овладевать новыми знаниями. А для этого необходимы упражнения и каверзные вопросы, в решении которых задействованы оба полушария мозга и разные чувства. Привлечение и удержание внимания читателя. Ситуация, знакомая каждому:

«Я очень хочу изучить это, но засыпаю на первой странице». Мозг обращает внимание на интересное, странное, притягательное, неожиданное. Изучение сложной технической темы не обязано быть скучным. Интересное узнается намного быстрее. Обращ ение к эмоциям. Известно, что наша способность запоминать в значительной

мере зависит от эмоционального сопереживания. Мы запоминаем то, что нам небезраз­ лично. Мы запоминаем, когда что-то чувствуем. Нет, сентименты здесь ни при чем: речь идет о таких эмоциях, как удивление, любопытство, интерес, и чувстве «Да, я крут!» при решении задачи, которую окружающие считают сложной, — или когда вы понимаете, что разбираетесь в теме лучше, чем всезнайка-Боб из технического отдела.

24

введение


введение

Метапознание: учимся учиться Е сли вы действительно хотите бы стрее и глубже усваивать новы е зн а­ ния —задумайтесь над тем, как вы задумываетесь. Учитесь учиться.

Мало кто из нас изучает теорию м етанознания во время учебы. Нам положено учиться, но нас редко этому учат. Н о раз вы читаете эту книгу, то, вероятно, хотите научиться разраба­ ты вать нрилож ения, к нримеру, для iPhone, и но возмож ности быстрее. Вы хотите запомнить нрочитанное, а для этого абсо­ лю тно необходимо сначала понять н рочитанное. Ч тобы извлечь максимум нользы из учебного нроцесса, нуж­ но заставить ваш мозг восприним ать н овы й материал как Н е­ что Важное. К рити чное для вашего сущ ествования. Такое же важное, как тигр. И наче вам нредстоит бесконечная борьба с вашим мозгом, которы й всеми силами уклоняется от запомина­ ния н овой инф орм ации.

Как же УБЕДИТЬ мозг, что знание HTML5 (и JavaScript) не менее важно, чем тигр? Есть снособ медленный и скучный, а есть бы стры й и эф ф ек­ тивны й. П ервы й основан на туном новторении. Всем известно, что даже самую скучную инф орм ацию можно заномнить, если н овторять ее снова и снова. П ри достаточном количестве н овторен и й ваш мозг нрикидывает: «Вроде бы несущ ественно, но раз одно и то же н овторяется столько раз... Ладно, уговорил». Б ы стры й снособ основан на повы ш еппп актпвпостп мозга и особенно на со­ четании разны х ее видов. Д оказано, что все ф акторы , перечисленны е на п ре­ дыдущей странице, номогаю т вашему мозгу работать на вас. Н анрим ер, ис­ следования ноказали, что разм ещ ение слов внутри рисунков (а не в ноднисях, в основном тексте и т. д.) заставляет мозг анализировать связи между текстом и граф икой, а это нриводит к активизации большего количества нейронов. Больше н ей ронов — выше вероятность того, что инф орм ац ия будет сочтена важ ной и достойной заноминания. Разговорны й стиль тоже важен: обычно люди н роявляю т больше внимания, когда они участвуют в разговоре, так как им н риходится следить за ходом бе­ седы и высказы вать свое мнение. П ричем мозг соверш енно не интересует, что вы «разговариваете» с книгой! С другой стороны , если текст сух и ф ор­ мален, то мозг чувствует то же, что чувствуете вы на скучной лекции в роли нассивного участника, —его клонит в сон. Н о рисунки и разговорн ы й стиль —это только начало.

дальше ►

25


как работать с этой книгой

Вот что сделали МЫ Мы иснользовали рпсункп, нотому что мозг лучше нриснособлен для воснрияти я граф ики, чем текста. С точки зрен и я мозга рисунок действительно стоит ты сячи слов. А когда текст комбинируется с граф икой, мы внедряем текст нрямо в рисунки, нотому что мозг нри этом работает эф ф ективнее. Мы иснользуем пзбы точпость: новторяем одно и то же несколько раз, нримен яя разны е средства нередачи и нф орм ации, обращ аемся к разны м чувствам — и все для новы ш ения вероятн ости того, что материал будет закодирован в не­ скольких областях вашего мозга. Мы иснользуем конценции и рисунки несколько пеож пдаппы м образом, но­ тому что мозг лучше восприним ает новую инф орм ацию . К роме того, рисунки и идеи обы чно имею т эмоциональное содержание, нотому что мозг обращ ает вни­ мание на биохимию эмоций. То, что заставляет нас чувствовать, лучше заноминается, —будь то шутка удивление или интерес.

,

Мы иснользуем разговорный стиль, нотому что мозг лучше восприним ает ин­ формацию , когда вы участвуете в разговоре, а не нассивно слушаете лекцию. Это нроисходит и н ри чтении.

КЛЮЧЕВЫЕ

В книгу вклю чены м ногочисленны е унраж нения, нотому что мозг лучше зано- МОМЕНТЫ минает, когда вы что-то делаете. Мы ностарались сделать их ненросты ми, но интересны м и —то, что нредночитает больш инство читателей. Мы совместили несколько стилей обучения, нотому что одни читатели нредночитаю т нош аговые онисания, другие стрем ятся сначала нредставить «общую картину», а третьи м хватает ф рагм ента кода. Н езависим о от ваших личны х н редночтений нолезно видеть несколько вариантов нредставления одного ма­ териала. Мы ностарались задействовать оба полушария вашего мозга; это новы ш ает веро­ ятность усвоения материала. П ока одна сторона мозга работает, другая часть им еет возмож ность отдохнуть; это новы ш ает эф ф екти вн ость обучения в тече­ ние продолж ительного времени. А еще в книгу вклю чены истории и унраж нения, отраж аю щ ие другие точки зрения. М озг глубже усваивает инф орм ацию , когда ему нриходится оценивать и вы носить суждения. В книге часто встречаю тся вопросы, на которы е не всегда можно дать н ростой ответ, нотому что мозг бы стрее учится и заноминает, когда ему нриходится что-то делать. Н евозм ож но накачать мышцы, наблюдая за тем, как занимаю тся другие. Однако мы нозаботились о том, чтобы усилия читателей были нриложены в верном нанравлении. Вам не нридется ломать голову над невразумитель­ ными нрим ерам и или разбираться в сложном, неренасы щ енном техническим ж аргоном или слишком лаконичном тексте. В историях, нрим ерах, на картинках фигурирую т люди — нотому что вы тоже человек. И ваш мозг обращ ает на лю дей больше внимания, чем на неодушевлен­ ные предметы. 26

введение

^

Кроссворды


введение

Что моЖете сделать ВЫ, чтобы заставить свой мозг повиноваться Мы свое дело сделали. О стальное за вами. Эти советы станут отнравной точкой; нрислуш айтесь к своему мозгу и опреде­ лите, что вам нодходит, а что не нодходит. Пробуйте новое.

(Т ) Не торопитесь. Чем больше вы поймете, тем меньше придется запоминать. Просто читать недостаточно. Когда книга задает вам вонрос, не нереходите к ответу. П редставьте, что кто-то действительно задает вам вонрос. Ч ем глубже ваш мозг будет мыс­ лить, тем скорее вы нойм ете и заномните ма­ териал.

(? ) Говорите вслух. Речь активизирует другие участки мозга. Если вы ны таетесь что-то нонять или нолучше заномнить, нроизн есите вслух. А еще лучше, нонробуйте объяснить кому-нибудь другому. Вы будете бы стрее усваивать материал и, воз­ можно, откроете для себя что-то новое.

(? ) Выполняйте упражнения, делайте заметки. (7[) Прислушивайтесь к своему мозгу. Следите за тем, когда ваш мозг начинает уста­ Мы вклю чили унраж нения в книгу, но вынолвать. Если вы начинаете новерхностно вос­ нять их за вас не собираемся. И не разглядывай­ приним ать материал или забы ваете только те унраж нения. Б ерите карандаш и ниш ите. что н рочи тан н ое — нора сделать нереры в. Ф изические действия во время учения новышаС определенного момента ноны тки «затол­ ю т его эф ф ективность. кать» в мозг дополнительную инф орм ацию не только не ускоряю т обучение, а скорее идут во 0 Читайте врезки. вред ему. Это значит: читайте все. Врезки —часть основно­ го материала! Н е нронускайте их. (^

(? ) Чувствуйте! Ваш мозг долж ен знать, что м атериал книги действительно важен. П ереж ивайте за героев наш их историй. П ридумывайте собственные нодниси к ф отограф иям . П ом орщ иться над неудачной шуткой все равно лучше, чем не ночувствовать ничего.

Не читайте другие книги после этой перед сном. Часть обучения (особенно неренос инф орм а­ ции в долгосрочную намять) нроисходит носле того, как вы отклады ваете книгу. Ваш мозг не сразу усваивает инф орм ацию . Если во вре­ мя обработки ностунит новая инф орм ация, часть того, что вы узнали ранее, мож ет быть (9 ) Творите! нотеряна. П онробуйте нрим енить новы е знания в своей новседневной работе. П росто сделайте хоть (б ) Пейте воду. И побольше. что-нибудь, чтобы нриобрести практический М озг лучше всего работает в условиях «высо­ оны т за рамками унражнений. Все, что для кой влажности». Д егидратация (которая мо­ этого нужно, — это карандаш и нодходящ ая ж ет настунить еще до того, как вы ночувствуезадача... задача, в которой изучаемые методы те жажду) сниж ает когнитивны е функции. и инструменты могут нринести нользу. дальше ►

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


обзор команды

Технические рецензенты

^ Дэвцд Пауэрс _____________ У

Пол bappu

Б ернл £>эйилс

Он не просто рецензент, а о п ы т н ы й а в т о р , на с ч е т у к о т о р о го т а к и е к н и г и , к а к « И з у ч а е м P y th o n » (H e a d F irst P y th o n ) и « И зуч а ем пр огр а м м и р о ва ни е»

Наш главный технический рецензент. Ребекка Д а н -К эн

Не только занимается рецензированием, но также пишет книги! Как он только все успевает...

(H e a d F irst P r o g r a m m in g )!

Тревор Фарлоу ^ A у bapp

Мы пытались убедить ее, что нам нужна только п о ­ мощь с графикой, но она не удержалась и выступила также техническим рецен­ зентом.

Ребекка стала нашей лишней парой глаз; она помогала нам с кодом, вы­ искивая в нем мелкие ошибки, кот о­ рые никто не замечал (включая нас!)

Наш рецензент, выложившийся на Н О %. Он даже совершал пробежки по ночам, тестируя наш геолокационный код.

Выражаем огромную п рнзпательпость комапде паш их технических рецепзептов. С воей рабо­ той опи доказали, что мы пе смогли бы обойтись без их технических зпапий и опыта, а также впим апия к деталям. Дэвид Пауэрс, Ребекка Дап-Кэп, Тревор Фарлоу, П ол Б арри, Луиза Барр и Б ер т Бэйтс прилож или максимум усилий в своих рецепзиях, благодаря чему эта кпига стала пампого-пампого лучше. Вы молодцы, ребята! 30

введение


введение

Благодарности За прекрасное техническое рецензирование: Э то уже превращ ается в традицию в иаш их киигах, и мы хотим еще раз горячо поблагодарить Дэвида Пауэрса, пашего уважаемого технического рец еп зеп та и автора мпогих издапий, вклю чая кпигу «РНР. Создапие дипам ических страпиц» (РНР Solutions: Dynamic Web Design M ade Easy). Благодаря зам ечапиям Д эвида содерж имое кпиг всегда зпачительпо улучшается, и пам крепче спится по почам от зпапия того, что если текст прош ел ч ерез Дэвида, то в тех­ ническом плапе там все отличпо. Еще раз спасибо, Дэвид.

^

Заметка для редактора: м о ж н о ли застолбить этого парня на три нами следующие книги? Причем на эксклюзивных правах!

Группе O’Reilly: Н а плечи К ортпи Нэш легла тяж елая обязаппость по руковод­ ству пе только проектом кпиги «Изучаем програм м ирование па HTML5», по и пами. К ортпи расчистила все нути для пас и деликатпо оказывала пе обходимое давлепие па каждого редактора, чтобы кпига смогла вы йти в свет. Одпако глав пая заслуга К ортпи заклю чается в том, что опа обеспечила пеоцепимую обратную связь касаемо кпиги и ее содерж имого, в результате чего текст под­ вергся ряду серьезпы х доработок. Благодаря усилиям К ортпи эта кпига стала пампого лучше. Выражаем ей свою призпательпость.

К ор тн и Нэщ _ У Лу Б арр также стала неотъем ле­ м ой частью процесса работы пад кпигой и впесла свой вклад, вы­ ступив в массе ролей: рецепзепта, граф ического дизайпера, главпого художпика, веб-дизайпера и масте­ ра Photoshop. Спасибо тебе, Лу, без тебя у пас пичего бы пе полу­ чилось!

\

А у Б арр j снова! (И Тоби.)

,

И спасибо всем остальным людям благодаря труду которых эта книга увидела свет: Благодарим остальпых члепов комапды из 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 стремительно развивается. Да, изначально HTML представлял Примечание:

собой простой язык разметки, однако с выходом все новых версий он по­

язв!К XHTML

степенно наращивал «мускулатуру». В настоящее время мы располагаем

получил «прощ аль ~

Иое письмо» в 2.004 году, о чем m w еще

1л.ого6ориМ-

версией HTML, заточенной под создание полноценных веб-приложений с поддержкой localStorage, 20-рисования, автономного режима работы, со­ кетов, потоков и т. д. История развития HTML не всегда была радужной: она полна драматизма (об этом мы поговорим позже), но в этой главе мы для начала совершим увеселительную поездку по Вебвиллю, чтобы вы могли разобраться во всем, что вкладывается в понятие «HTML5». Поэто­ му запрыгивайте к нам — мы отправляемся в Вебвилль, где за 3,8 страни­ цы (ровно) пройдем путь от исходной точки до HTML5.


Переходите на H T M L 5 СЕГОДНЯ! Зачем Ждать? Воспользуйтесь нашим новым

НТМЫЗ-модернизатором и сделайте зто всего за ТРИ ПРОСТЫХ ШАГА

Не раздумывайте! Акция действует в течение ограниченного вре­ мени. Мы возьмем ваши старые HTML-страницы и модернизируем их до HTML5 за ТРИ ПРОСТЫХ ШАГА.

J

/ I (

Неужели все действительно так просто? Конечно! Мы даже под­ готовили для вас небольшую демонстрацию. Взгляните на этот старый, потрепанный, видавший лучшие дни HTML; мы превратим его в HTML5 прямо у вас на глазах: < ! DOCTYPE h tm l PUBLIC " -//W 3 C //DTD HTML 4 .0 1 //E N " " 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"

4

щк

c o n t e n t = " t e x t / h t m l ; cha r s e t = U T F - 8 ">

Clink type="text/css" rel="stylesheet" h r e f = " l o u n g e .c s s " > <script type=" text/javascript" src="lounge .j s " X / s c r i p t > < /h e a d > <body>

Э т о вполне заурядны й код в е о -

м

& < im g

Л

й x

^

<Ь1>Добро пожаловать в Head First Lounge</hl> s rc = "d r in k s .g if"

a lt= " D r in k s " >

с т р а н и ц ы Неа

ЯлаЖ^Н

4-.ОИ, к о т о р ы м должен бы т ь 6 д м знаком по к н и ^ *5,, HTM L

цаеМ 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

Й

________________________________________________________________________________________________________________________________________ __________

Ш ТУРМ Вы увидите, насколько просто писать код на HTML5 Изучите приведенный выше пример кода, который написан на HTML 4.01 (это предыдущая вер­ сия языка). Взгляните на все строки и вспомните, что каждая из них делает. Отмечайте прямо на странице. Далее мы с вами разберемся в том, как переделать его в HTML5-KOfl.

!

V


знакомство с HTML5

^ Возьми в руку карандаш Внимательно взглянув на HTML-код на странице 36, заметили ли вы там какие-либо фраг­ менты разметки, которые могут претерпеть изменения при их переделке в HTML5? Или что бы вы сами там изменили? Дадим вам одну подсказку: определение d o c t y p e .

d o c tu pe

дляW m l -

ЭИД° ч т о н а м н у ж н о '

то

- ^

Это просто означает, что данный ст андарт я б д я ^ т с я открытым

этой части говорится, что мы используем HTML версии 4 .0 1 “ что разметка написана на английском языке (EN) В

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w 3 .org/TR/html4/strict.dtd">

t

Это указание на файл , который опреде­ ляет соответствующий стандарт Определение doctype относится к верхней части HTML-файла и сообщает браузеру, какого типа этот документ, в данном случае — HTML 4.01. Благодаря d o c t y p e браузер более точ­ но может осуществлять интерпретацию и рендеринг страниц. Настоятельно рекомендуем вам использовать d o c t y p e . Итак, что подсказывают ваши дедуктивные способности в плане того, как будет выглядеть определение d o c t y p e для HTML5? Напишите ответ здесь (вы сможете проверить его по­ сле того, как мы разберемся во всем чуть позже):

Зля

Ллихего

дальше ►

37


обнови свой html

Представляем наш новый

МШ-модернимтор.

Обновите свой HTML прямо сейчас!

Шаг 1 у д и в и т вас: мы начнем с верхней части HTML-страницы Head First Lounge и обновим определение d o c t y p e , придав ему новый блеск HTML5. Вот как выглядела старая версия

d o c ty p e

в случае HTML 4.01:

< 'DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

я ИзбмНЯб п еред т е м м . к т о успел c3eAamt> себе

Вы, наверное, подумали, что в d o c t y p e мы собираемся заменить любое упоминание «4» на «5»? А вот и нет Преимущество в том, татуировку ЧТО d o c t y p e для HTML5 ВЫГЛЯДИТ совсем просто: , doctype- 4 .< 3 i на |лЯлЛЯт17'

<! doctype html>

Вам больше не потребуется Google, чтобы узнать, как выглядит d o c t y p e для HTML5, как и не потребуется копировать и вставлять его из другого файла, поскольку это определение отличается крайней простотой и вам не составит труда его запомнить. Однако постойте, есть еще кое-что... Данное определение d o c t y p e подходит не только для HTML5, но и для всех будущих версий языка 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

А теперь шаг 3, заключительный. Здесь мы сосредоточим внимание на элемен­ те < h e a d > и модернизируем тег l i n k . Вот что у нас имеется на текущий момент: тег l i n k с атрибутом t y p e со значением t e x t / c s s , указывающий на каскадную таблицу стилей (значение s t y l e s h e e t ) : Clink t y p e = " text/css" rel="stylesheet" href="lounge.css ">

mapoM HTML

\С.од НД С

Чтобы обновить этот код до HTML5, нужно просто убрать атрибут t y p e . По­ чему? Потому что CSS объявлен стандартным языком стилей для HTML5 по умолчанию. Таким образом, после того как мы удалим атрибут t y p e , наш об­ новленный тег l i n k приобретет следующий вид: < l i n k г e l = " s t y l e s h e e t " h r e f = " lo u n g e . c s s " > ^ HTMLS

Поскольку вы работали быстро, у насесть специальный бонус для вас. Мы еще больше облегчим вам жизнь, упростив тег s c r i p t . JavaScript в случае HTML5 стал стандартным языком сценариев по умолчанию, поэтому вы можете уда­ лить атрибут t y p e также и из тегов s c r i p t . Вот каким станет наш тег s c r i p t без атрибута t y p e . i~i& беспокойтесь, если вы < s c r i p t s г с = пl o u n g e . j s " X / s c r i p t >

i T '

не слишком много знаете о теге script, мы еще дойдем до него...

Либо, если вы будете иметь дело со встроенным кодом, можете просто напи­ сать свой сценарий следующим образом: < s c r ip t > v a r youR ock = t r u e ;

y

</script>

n

Beet? бяид J a v a S c rip t

ёудет здесь-

Подробнее о JavaScript мы поговорим позже.

Поздравляем, теперь вы сертифицированы модернизировать любой HTML-код до HTML-5! Как продвинутый пользователь НТМ1_5-модернизатора, вы обладаете всем необходимым для того, чтобы обновить любую нормальную HTML-страницу до HTML5. Дерзайте, пришло время реализовать полученные знания на практике!

дальше ►

39


больше чем разметка

Постойте-ка, столько суеты вокруг H TM L5, и вдруг оказы­ вается, что это все, что от меня потребуется? О чем же тогда оставшаяся часть книги?

Ладно, ладно, вы нас поймали. Пока мы вели речь о модернизации кода HTM L-страниц, создан­ ных с помощью старой версии этого языка, с це­ лью паделить их всеми преимуществами, которы е дает HTML5. И, как можно было убедиться, если вы зпакомы с HTM L 4.01, то это просто отлично, поскольку HTM L5 — это расш иренны й HTM L 4.01 (то есть практически все имею щ ееся в нем под­ держ ивается и в HTM L5), и вам потребуется лишь зпать, как определять d o c ty p e и остальные теги в элемепте < head> , чтобы начать программировать па HTM L5. Но вы правы в том, что мы повели себя несколько глупо, поскольку, конечно же, язы к HTML5 —это не­ что большее, чем просто модернизация нескольких элемептов. Разработчиков в нем привлекает воз­ мож ность создавать насы щ енны е, интерактивны е страпицы (или даже сложные веб-приложения), а также то, что оп вклю чает в себя целое семейство технологий, которы е работаю т рука об руку с этим язы ком разметки. Одпако пе будем спеш ить. П реж де чем двинуться дальше, сделаем еще кое-что, чтобы окопчательпо разобраться с паш ей HTM L-разметкой.


знакомство с HTML5

Возьми в руку карандаш_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Вы ближе к НТМ1_5-разметке, чем думаете! Здесь приведена разметка на старом HTML, которая нуждается в обновлении. Осуществите НТМ1_5-модернизацию и обновите этот написанный на HTML 4.01 код до HTML5. Не бойтесь делать пометки в книге, вычеркивайте приведенную здесь HTML-разметку и добавляйте новый код, который вам потребуется. Мы немного помогли вам и выделили области, нуждающееся в изменениях. Закончив, напечатайте код (или внесите изменения в файл упражнения, если вам так больше нравится), загрузите его в браузер и, откинувшись на спинку стула, насладитесь своим первым творением на HTML5. Ах да, наши ответы вы найдете на следующей странице.

^

Чтобы загрузить весь код и файлы примеров для этой книги , посетите страницу h ttp ://w ic ke d lysm a rt.c o m /h fh tm ls.

< !DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtdn> <html> <head> <title>Head First Lounge</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link type="text/css" rel="stylesheet" href="lounge.css"> < script type="text/javascript" src= "lounge.js"X/script> </head> <body> <Ь1>Добро пожаловать в Head First Lounge</hl>

<P> < img src="drinks .gif11 a l t = 11D r i n k s 11>

< /p >

<p> Каждый вечер присоединяйтесь к нам для разговора за напитком <а href="elixirs .html11>elixirs</a>, и, возможно, игры в Тар Тар Revolution. Всегда к вашим услугам беспроводной доступ; ЗССВС (Захватите Свой Собственный Веб-Сервер).

< /р > </body> < /html>

дальше ►

41


решение упражнения

г< й Возьми в руку карандаш Решение Вы ближе к HTML 5-разметке, чем вы думаете! Здесь приведена разметка на старом HTML, которая нуждается в обновлении. Осуществите HTMLS-модернизацию и обновите этот написанный на HTML 4.01 код до HTML5. Не бойтесь делать пометки в книге, вычеркивайте приведенную здесь HTML-разметку и добавляйте новый код, который вам потребуется. Мы не­ много помогли вам и выделили области, нуждающиеся в изменениях. Вот наше решение.

Вот четыре строки , благодаря измене­ нию которых наша веб-страница Head First Lounge получила официальное право называться HTMLSстраницей.

Обновленный код будет выглядеть так:

yz.

Определение doctype

< ! d o c ty p & k t m l > <html> <head> <title>Head First Lounge</title>

< m e ta c k a r s e t= " u tf- 2 " >

^

' Тег m eta

< l i n k r e l = " s t y l e s h e e t " P \r e f= " lo u n g e .c s s " >

< s c rip t s r c = " lo u n g e .js " x /s c r ip t>

Тег lfnk

< 2=— . Тег script

</head> <body> <Ь1>Добро пожаловать в Head First Lounge</hl>

<P> <im g s r c = 11drinks .gif11 a l t = 11D r i n k s 11> </ p >

<p> Каждый вечер присоединяйтесь к нам для разговора за напитком <а h r e f = nelixirs .html11>elixirs</a>, и, возможно, игры в Тар Тар Revolution. Всегда к вашим услугам беспроводной доступ; ЗССВС (Захватите Свой Собственный Веб-Сервер). </ р > </body>

</html>

Не в е р и т е н а м ? З а й д и т е п о

адресу

k t t p Y / v a h d a t o r . w s . o r g / , и вы у д е -

°На

„ иС* ~ nP W od^ валидацию к а к H T M L s - с т р а н и ц а . Вез ш у т о к '

42

глава 1


знакомство с HTML5 Часш°

^адаВ аеМ ы е В опросы А как все это работает в старых версиях браузеров? Все эти новые doctype, meta и т. д... ведь как-то же могут старые браузеры работать с этим новым синтаксисом?

0 : Да, могут. Взгляните на атрибуты t y p e тегов l i n k

и

s c r i p t ; сейчас имеет смысл избавиться от них в HTML5, по­ скольку CSS и JavaScript теперь являются стандартами (и, конечно же, технологиями по умолчанию для работы со стилями и написания сценариев соответственно). Как оказалось, браузерам уже заранее было известно, что CSS и JavaScript являются таковыми. Так, по стечению обстоятельств новый язык разметки HTML5 уже довольно долгое время поддерживается существующими браузерами. Тоже самое справедливо и в случае с d o c t y p e и тегом m e ta . А как насчет нового doctype? Что-то с ним все стало слиш­ ком просто; у него нет даже версии или идентификатора DTD. 0 : Да, кажется немного необычным, что после многих лет при­ менения комплексных d o c ty p e теперь мы можем упростить их до фразы «мы используем HTML». А произошло вот что: HTML ранее основывался на стандарте SGML, который требовал как комплекс­ ных форм d o c ty p e , так и DTD. Новый стандарт отошел от SGML, преследуя этим цель сделать язык HTML проще и гибче. Таким образом, нужда в комплексных формах отпала. Здесь не обошлось без некоторой доли везения в том плане, что почти все браузеры просто ищут HTML в определении d o c t y p e , чтобы убедиться

0 : Да, это так, особенно пока HTML5 не обрел 100%-ную под­ держку всеми браузерами. Об этих аспектах мы поговорим позже. А почему вообще все это имеет значение? Я вот написал код веб-страницы без doctype и тега meta, и она отлично рабо­ тает. Зачем мне лишняя головная боль, если в таком подходе нет абсолютно ничего неправильного? 0 : Да, браузеры легко пропускают мелкие ошибки в HTMLфайлах. Однако если вы включите соответствующие d o c t y p e и теги m e ta , то сможете быть уверены в том, что браузеры будут знать, что именно вы от них хотите, а не гадать об этом. Кроме того, в случае с людьми, пользующимися старыми версиями браузеров, указание нового d o c t y p e означает, что они будут использовать стандартный режим, что как раз вам и нужно. Стандартный режим — это режим, в котором браузер считает, что написанный вами HTMLкод соответствует стандарту, поэтому он будет пользоваться прави­ лами данного стандарта при интерпретации вашей страницы. Если вы не укажете d o c t y p e , то некоторые браузеры могут перейти в режим совместимости и посчитать, что ваша страница написана для старых версий браузеров, когда соответствующий стандарт еще не был на должной высоте, и неправильно интерпретировать страницу (или решить, что она просто некорректно написана). А что случилось с XHTML? Ведь еще несколько лет назад казалось, что за ним будущее.

в том, что они осуществляют разбор именно HTML-документа.

Это было всерьез, когда вы говорили, что d o c t y p e останется неизменным? Как мне казалось, для браузеров важен контроль версий. Почему бы не использовать <!doctype html5>? Наверняка в будущем появится HTML6. Ведь так?

0 : Подход к использованию d o c t y p e претерпевал изменения, и разработчики браузеров применяли его для того, чтобы дать ука­ зание своим браузерам осуществлять рендеринг в их собственном стандартном режиме. Теперь, когда у нас имеется намного более точный стандарт, d o c t y p e в HTML5 сообщает любому браузеру, что конкретный документ является стандартным HTML, будь он версии 5, б или любой другой. Предполагаю, что разные браузеры пользователей будут поддерживать различающиеся наборы возможностей HTML5. Что делать в таком случае?

Q j Да, так оно и было. Однако потом гибкость возобладала над строгим синтаксисом, и XHTML (XHTML 2, если быть точными) по­ степенно стал умирать, поскольку новый HTML5 оказался более либеральным в плане написания людьми веб-страниц (и осущест­ вления их рендеринга браузерами). Но пусть вас это не смущает, так как знание XHTML лишь сделает из вас еще более успешного HTML5-pa3pa6oT4HKa. Кстати, если вы испытываете привязанность kXML, знайте, что существует также способ написания HTML5-KOfla в строгой форме. Подробнее об этом мы поговорим позже... • Что такое UTF-8? 0 : UTF-8 — это кодировка символов, поддерживающая множе­ ство алфавитов, включая незападные. Вам, вероятно, доводилось сталкиваться с другими наборами символов, использовавшимися в прошлом, однако UTF-8 продвигается как новый стандарт. Она также быстрее и легче запоминается, чем предшествующие коди­ ровки символов.

дальше ►

43


что вы должны знать

о

М С ЛШ ТМ ) Мы все-таки ие ож идаем, что вы зиаете HTML5. Даже если вы пикогда рапее пе запимались HTML5, это пе проблема, одпако у вас долж еп иметься опы т работы с HTM L и зпапие таких базовых аспектов, как элемепты , теги, атрибуты, влож епия, попимапие разп и цы между семаптической разм еткой и до­ бавлением стиля и т. д. Если вы пе зпакомы с даппы ми аспектами, то мы возьмем па себя смелость дать вам пеболы пой со­ вет (и бесстыдпым образом кое-что прореклам и­ ровать): есть еще одпа кпига из этой серии, назы ­ вающ аяся «Изучаем HTM L, XHTM L и CSS», и вам следует ее прочитать. Если же вы отчасти зпакомы с язы ками разм етки, мож ете бегло ознаком иться с даппым издапием или использовать его как справочпик при чтеп ии даппой кпиги.

Мы также предусм от ре­ ли небольшое руководство по размет ке HTMLS и CSS3 в приложении. Если вам нужен краткий обзор ново­ введенийj то вы найдете его в конце книги.

44

глава 1


знакомство с HTML5

Интервью недели:

Признания новой версии HTML Head First: Д обро пож аловать, HTM L5. Весь Иптерп ет просто гудит от разговоров о Вас. Как пам кажется, Вы во мпогом похож и па HTM L 4. В чем же п р ичи па всеобщ его аж иотаж а вокруг Вас? HTML5: Всеобщ ий аж иотаж объяспяется тем, что я предоставляю возмож пости по создапию соверш еппо пового п околеп и я веб-прилож епий и обе­ спечению качествеппого взаимодействия с пими. Head First: Согласеп, по почему HTM L 4 или казав­ шийся многообещающим XHTML пе сделали этого? HTML5: XHTM L 2 оказался тупиковой ветвью эво­ лю ции. К аж ды й, кому д овелось п и сать код вебстр ап и ц п а это м язы к е , т е р п е т ь его больш е пе может. XHTML запово изобрел подход к паписапию разм етки веб-страпиц, которы й уже и так исполь­ зуется, и пе привпосил в страпицы пичего пового. Я сказал: «Постойте-ка, я ведь могу делать повы е вещи и п ри этом заключаю в себе все те возмож ­ пости , к о то р ы е сущ ествовали до мепя». Я имею в виду, что если что-то работает, то зачем запово и зобретать колесо. Такова моя ф илософ ия. Head First: Н о и звестп о ли вам, что п ек о то р ы е разработчи ки стандартов по-прежпему заявляют, что И п тер п ету будет лучше, если оп стапет п р и ­ держ иваться их «безупречпых» стандартов? HTML5: Зпаете, мпе все равпо, что опи там говорят. Я прислушиваюсь к людям, которые реальпо запяты паписапием веб-страпиц: как опи используют мепя, как я могу им помочь. Вторыми в моем списке идут создатели веб-браузеров. А разработчики стандар­ тов стоят в этом списке последними. Я стапу п ри ­ слушиваться к их словам только при условии, что опи пе расходятся с мпепием пользователей. Head First: Почему же? HTML5: Потому что если пользователи и создатели браузеров пе согласпы с разработчикам и стандар­ тов, то это пав од ит па мысли о правильности мпе-

пия последпих. К счастью, с людьми, работающими пад специф икациям и HTML5, мы полпостью схо­ димся во взглядах. Head First: В озвращ аясь к п реды дущ ей в ер си и HTML, Вы отмечали, что являетесь расш ирепием HTM L 4.01. То есть Вы обратпо совместимы с пей, правильп о? О зп ач ает ли это, ч то Вам п р и д етс я справляться с пе всегда удачпыми в плапе дизайпа веб-страпицами из прошлого? HTML5: Обещаю, что приложу максимум усилий для того, чтобы справиться со всем, что мпе подкинут из прош лого. Но отмечу, что это пе зпачит, что со мпой так и нужпо обращаться. Я хочу, чтобы созда­ тели веб-страпиц приобщ ались к повейш им стан­ дартам и использовали мепя паилучшим образом. Благодаря этому опи смогут получить максимальную отдачу от моего примепепия. Но, с другой сторопы, я пе спасую и смогу обеспечить отображепие старой веб-страпицы в силу своих возможностей, даже если опа пе была м одерпизировапа до HTM L5. Head First: М ой следующий вопрос звучит так... HTML5: Стойте, стойте!!! Все эти вопросы касаются прош лого. Мы с Вами пе говорим о том, что важпо здесь и сейчас. П оскольку реч ь и дет о м оей р аз­ метке, хочу сказать, что моя персопальпая миссия заключается в том, чтобы охватить своими объяти­ ями весь И птерпет, впедрить повы е структурпые элементы, облегчающие жизпь веб-разработчикам, и помочь всем создателям браузеров поддерживать согласованную семаптику вокруг разметки HTML5. Но па самом деле я здесь для того, чтобы рассказать Вам о своем дополпительпом предпазпачепии: вебприложе... Head First: ...Жаль, HTML5, по паше время истекло. Спасибо, в следующем иптервью мы обязательно поговорим обо всем, о чем Вы пож елаете. HML5: Б-р-р -р, терпеть пе могу, когда так случается! дальше ►

45


отзывы об html5

Просим встать НАСТОЯЩЕГО HTML5... И так, вы терпеливо выслушали паше шуточпое повествовапие о «НТМ Ьб-модерпизаторе», и мы уверепы , что вы уже догадались о том, что HTM L5 представляет собой печто пампого большее, чем там было сказало. Если поспраш ивать разпы х людей, то в ответ можпо услышать, что, по слухам, HTM L5 устрапяет необходимость в плагипах, мож ет использоваться повсюду, пачипая от просты х страпиц и закапчивая играми типа Q uake, является кремом из взбиты х сливок па десерте. Каждый по-разпому представляет себе, что такое HTML5...

HTM L5 — это все о мультимедиа, о том, как избавиться от плагинов, о воз­ можностях собственной под­ держки аудио и видео.

Вообще-то он касается создания насыщенных клиентских интернет-приложе­ ний. Вместо того чтобы создавать их с помощью ин­ струментов вроде Flash, теперь я могу использовать элемент canvas, трансформации и JavaScript для гене­ рирования классных интерфейсов и анимаций.

46

глава 1


знакомство с HTML5

Замечательная вещь в HTM L5 — хранение информации на стороне клиента и кэши­ рование. Как вам возможность автономного доступа к данным из Интернета?

Так здорово, что я могу исполь­ зовать Web W orkers для повыше­ ния эффективности моего JavaScript и увеличения отзывчивости веб­ страниц.

В CSS также есть масса всего нового, что можно использовать вместе с HTML5: продвинутые селекторы, анимации и — да, эффект отбрасывания тени!

И не забудьте о мо­ бильных устройствах. Мне нравится возможность создавать страницы с поддержкой опре­ деления местоположения.

Хорош ая новость заклю чается в том, что HTML5 действительно является всем тем, о чем сказано выше. Когда люди говорят о HTM L5, они имею т в виду семейство технологий, которы е в сочетапии друг с другом образуют целую повую палитру для создапия веб-страпиц и прилож епий. дальше ►

47


как работает html5

Как на самом 9еле работает HTML5... В приложении вы найдете замеча­ тельное Вебвилль­ ское руководство по новой HTMLразмет ке и свой­ ствам CSS3.

И так, как было сказало выше, в оспове HTM L5 леж ит семейство техпологий, / • по что это зпачит? Ч то ж, как вам уже известпо, существует HTM L-разметка сама по себе, которая была расш ирепа с целью вклю чепия ряда повы х элемептов. К роме того, с выходом CSS3 мпого пового появилось в каскадпых та­ блицах стилей, что откры ло еще более ш ирокие возмож пости по стилизации веб-страпиц. Также существует турбопагпетатель под пазвапием JavaScript и целы й повы й пабор API-иптерф ейсов JavaScript, доступпых вам. Д авайте загляпем за кулисы и посмотрим, как все это объединяется. Браузер загружает документ, вклю­ чающий HTML-разметку и CSS-стили.

При загрузке страницы браузер также соз­ дает внутреннюю модель документа, ко­ торая будет содержать все элементы вашей HTML-разметки.

г т WelcometotheHeadFirst [.nun^e-

html

M I script

title

/

каждого элемента в вашей HTML-размет ке браузер создает объект, объект, который будет представлять соответствующий элемент, и размещает его в древовидной ст р ук ­ туре со всеми остальны­ ми элементами... Для

_____

71 Сг н и е м

глава 1

них в *

I

body I h2 l em

I P

...Это дерево называется объ­ ектной моделью документа (Vocum ent object Model, РОМ), g w б дете часто ст алкиват ^ся с ней ходу кни­ ги, поскольку данная модель играет важную роль в т ом , как мы добавляем поведение к веб-странии,ам с помощью J a va S c r i p t (подробнее в главе £)■

Стиль страницы (при наличии такового) берет ­ ся из CSS3, который стал расширением CSS2 и включил в себя множество распространенных идиом, используемых в Интернете (например, отбрасывание тени и закругленные углы).

HTMLS р а з м е н „ р е в е л а ^

из

48

I hi

в

^ессе

«

«»»>■


знакомство с HTML5

сЦ еной При загрузке страницы браузер также загружает ваш JavaScript-ко д , выполне­ ние которого обычно запускается сразу после окончания загрузки страницы.

Применяя JavaScript, вы сможете взаимо­ действовать со своей страницей пут ем манипулирования объектной моделью документа (РОМ), обеспечивать реакцию на действия пользователя или генериру­ емые браузером события либо использо­ вать весь набор новых API -интерфейсов.

JavaScript взаимодействует с вашей страницей посред­ ством объектной модели документа (РОМ).

API -интерфейсы, также известные как интерфейсы прикладного программирова­ ния (Application Programming Interfaces), обеспечат для вас набор объектов, методов и свойств, которые вы сможе­ те использовать для дост у­ па ко всей функциональности этих технологий. Многие из этих API -интерфейсов мы рассмот рим далее.

API-интерфейсы обеспечат вам до­

ступ к элементам a u d io и v id e o , 20-рисованию с использованием canvas, к lo c a lS to r a g e и прочим замечательным технологиям, необ­ ходимым для создания приложений. И не забывайте, что для использова­ ния всех этих API-интерфейсов необ­ ходим JavaScript.

Знакомьтесь: API-интерфейсы

Авто­ номное кэширо­ вание

Local Storage

JavaScript Web Workers

Geolocation

Forms дальше ►

49


семейство html5 +

К Т 9

И

НТ<

Мы с вами говорили о «семействе технологий» столько раз, что уже кажется, что мы сами одна семья. Однако мы по-настоящему так и не разобрались в том, что конкретно они собой представляют, поэтому, наконец, сделаем это. Ниже представлен перечень большинства членов этого семейства, посмотрите, сможете ли вы разобраться, кто есть кто. Мы вас опередили и в качестве примера соотнесли одно из описаний с нужной позицией. Не бес­ покойтесь, мы знаем, что это ваша первая встреча с членами семейства HTML5, поэтому ответы вы найдете в конце главы.

CSS3

Используя мепя, вы мож ете рисовать прямо п а своей веб-страпице. Благодаря мпе можпо рисовать текст, изображ епия, липии, круги, прямоугольпики, узоры, прим епять градиепты. Я помогу вам рас­ кры ть таящ егося в вас художпика.

Web Workers

М епя использовали в HTM L 4 для ввода и пф орм ации, по я стал еще лучше в HTML5. Я могу требовать от вас заполпять все поля и способеп проверять, ввели ли вы адрес электроп пой почты , URLадрес или пом ер телеф опа туда, куда требуется.

Forms

Рапее для обеспечепия фупкциопальпости, апалогичпой пашей, вам приходилось использовать плагипы , по теп ерь мы стали полпоцеппы м и члепами семейства элемептов HTML. Х отите посмо­ треть или послушать что-либо? Тогда мы нужпы вам.

Автономные вебприлоЖения

Мы здесь для того, чтобы помочь вам со структурой и семаптическим зпачепием ваш ей страпицы и обеспечить повы е способы создапия секций, заголовков, пиж пих колоптитулов и павигации па ваших страпицах.

Audio и Video

Я самый стильпы й во всем семействе. Зпаете ли вы, что теперь я могу апим ировать ваши элемепты , придавать их углам закруглеппость и даже обеспечивать эф ф ект отбрасы вапия тепи?

Новые элементы

Используйте мепя как часть локальпого храпилищ а в браузере лю­ бого пользователя. Вам пеобходимо сохрапять устаповки, элемеп­ ты, помещ еппы е в электропную корзину, или, возмож по, даже п ри ­ п рятать больш ой кэш для увеличения производительпости? Тогда я нужпый вам API-иптерфейс.

ражетки

Local Storage

Canvas

Geolocation

50

глава 1

Вам требую тся прилож ения, способпые работать даже тогда, когда отсутствует подклю чепие к Сети? Я могу вам помочь. Я —API-иптерф ейс, которы й помож ет вам определить свое место­ полож ение, и отличпо работаю с К артами Google. Я потребуюсь, когда вам будет пеобходимо, чтобы песколько сцена­ риев вы полпялись параллельпо в ф оповом реж им е, благодаря чему ваш иптерф ей с пользователя сможет оставаться отзы вчивы м.


ВАШ А М и с с и я знакомство с HTML5

■■■вели вы на нее со

4% ,

%

Р

СЯ'^ОСКОЛЬКу ИСТИНд

%

ВАША ПЕРВАЯ МИССИЯ: РАЗВЕДКА В СТАНЕ БРАУЗЕРОВ

с °1 *Ш Ч П Е 1 Щ о СЕК РЕТН О

Автономные веб­ приложения

Workers Web

Geolocatoin

Storage Web

Canvas

Audio

Video

Возможность

UJ

/

ВАМ ПОРУЧАЕТСЯ ОПРЕДЕЛИТЬ ■ ■ И Н Н ТЕКУЩИЙ УРОВЕНЬ ПОДДЕРЖКИ ПО КАЖДОМУ ИЗ ПРИВЕДЕННЫХ НИЖЕ БРАУЗЕРОВ (ПРИМЕЧАНИЕ: ВЫ СМОЖЕТЕ ОТЫСКАТЬ НУЖНУЮ ИНФОРМАЦИЮ ПО АДРЕСУ H T T P ://WICKEDbYSMART.COM/HFHTML5/BROWSERSUPPORT.H T M L , Щ Щ Ш Ш Ш • ПРИНИМАЙТЕ ВО ВНИМАНИЕ НОВЕЙШИЕ ВЕРСИИ БРАУЗЕРОВ. ПО КАЖДОМУ БРАУЗЕРУ, ПРИВЕДЕННОМУ В СТОЛБЦЕ «БРАУЗЕР/ВОЗМОЖНОСТЬ», ОТМЕТЬТЕ ВОЗМОЖНОСТИ, КОТОРЫЕ ОН ПОДДЕРЖИВАЕТ, А ЗАТЕМ ДАЙТЕ СВОЮ СУБЪЕКТИВНУЮ ОЦЕНКУ ТОГО, НАСКОЛЬКО ХОРОШО ОН СОВМЕСТИМ С HTML5 Н Н Н Н В В В Н Н ’ ПО ВОЗВРАЩЕНИИ ПРЕДСТАВЬТЕ ОТЧЕТ ДЛЯ ПОЛУЧЕНИЯ НОВОГО ЗАДАНИЯ*

Firefox Safari Chrome

Устрой­ ства под уп р а влением

Mobile WebKit Opera

операци онны х с и ­

IE 6, 7

с т е м iO S

и A n d r o id

(среди прочих)

IE 8 IE 9

дальш е ►

51


брэузерная разе едка

%

ВАША ПЕРВАЯ МИССИЯ С О В ЕРШ ЕН Н О РАЗВЕДКА В СТАНЕ СЕКРЕТНО БРАУЗЕРОВ Mbl немного схитрили при ответе и поставили флажки, ори -

Firefox

/

/

/

Safari

/

/

/

/ /

Chrome

/

/

/

/

Mobile WebKit

/

/

/

/

Opera

/

/

/

/

/ / / /

Автономные веб­ приложения

Workers Web

1

Geolocation

Storage

0

Web

В! 0J

0 $ i>

Canvas

Возможность

ентируясь на ситуацию, которая сложимся к Z O I S году. Но ваши ответы должны отражать положение вещей на момент чтения книги. Нам кажется, вам будет интересно заглянуть в будущее.

!/ /

/

/

/

/

/

/

/

/

IE 6, 7

/

IE 8 IE 9

/

/

/

/

/

Поддержку, вы бу УеТСЯ Как°е-то врем я п зоваться и м и з а д о л Шать’ Какие имепгю ^°’ ЧТобы стапдарт НТМ г к О д ер ж и в а ю т ся сои Д° ЭТ° Г° события ф я РаузеРы Полностью ег ° брСЛ Повсеместну.«

глава 1

Г

аС ™ ;“ — И НС m m U ne'

про.


знакомство с HTML5

Постойте-ка, если я начну использовать HTM L5 прямо сейчас, разве не получится так, что я оттолкну пользователей старых браузеров? Или мне придется писать две варианта своих веб-страниц: один для браузеров с поддержкой HTM L5, а другой — для старых версий браузеров?

Притормозите, сделайте глубокий вдох. Прежде всего HTML5 — расш ирение предыдущей вер­ сии HTML, поэтому вам придется писать только один вариант своих веб-страниц. Вы правы в том, что возмож­ ности, поддерж иваемы е браузерами, могут отличаться в зависимости от того, насколько новой является вер­ сия веб-обозревателя и как часто ваши пользователи об­ новляю т его. Таким образом, необходимо иметь в виду, что некоторы е из новейш их возмож ностей HTML5 могут не поддерж иваться браузерами пользователей, и это возвращ ает нас к вопросу о том, что делать в та­ ком случае. Сейчас один из принципов HTM L5-дизaйнa подразу­ мевает, что своим страницам необходимо давать воз­ можность плавно деградировать, то есть если браузер вашего пользователя не поддерж ивает какую-то новую фупкцию, вы долж пы позаботься о достойпой альтерпативе для пего. В кпиге мы покаж ем вам, как писать свои страпицы с учетом этого. Х орош ая повость заклю чается в том, что все браузеры двигаю тся по паправлепию к стапдарту HTM L5 и связаппым с пим техпологиям (даже мобильпые браузеры), в силу чего со времепем плавпая деградация стапет ско­ рее исклю чением, чем правилом (хотя вы всегда будете хотеть сделать все возмож пое, чтобы обеспечить для пользователей достойпое взаимодействие со своими веб-страпицами независимо от того, какие браузеры у пих будутустаповлепы).

дальше ►

53


общие вопросы html5

4acm°

Задаваем ы е БоЭЭроСЬ! »Я слышал, что стандарт HTML5 не получит статус финаль­ ной [ рекомендации до 2022 года! Это правда? НОИ Q : W3C - :■это организация по разработке стандартов, которая формально рекомендует стандарт HTML5. Входящие в W3C люди любят действовать осторожно, причем настолько, что предпочитают дождаться, пока сменится несколько поколений НТМ1_5-браузеров, прежде чем решиться сделать данный шаг. И это правильно, по­ скольку со стандартом все окончательно утрясется в ближайшие два года, а разработчики браузеров уверенно движутся по пути его реализации. Так что, да, может пройти какое-то время, прежде чем HTML5 обретет статус «финальной рекомендации». Ожидается, что он станет стандартом уже к 2014 году, и использовать HTML5 в практических целях следует начинать уже сейчас. Что произойдет, когда все окончательно решится с HTML5? 0 : Появится HTML6? Мы понятия не имеем, но, вероятно, что бы там ни было, оно придет к нам вместе с летающими автомобилями, ракетными костюмами и обедами в таблетках. Помните, что даже если мы перейдем на HTML6, d o c t y p e не изменится. Если пред­ полагать, что W3C сдержит свое обещание и будущие версии HTML окажутся обратно совместимыми друг с другом, то мы сможем без проблем перейти на нечто новое, что будет следующим на очереди.

>Chrome, Safari, Firefox, множество мобильных браузеров... вам не кажется, что ситуация лишь усугубляется? Будут ли наши страницы нормально работать во всех этих браузерах? 0 : Несмотря на конкуренцию на рынке браузеров (для настольных компьютеров и мобильных устройств), на самом деле большинство из них основано всего на нескольких общих HTML-движках. Напри­ мер, Chrome, Safari и мобильные браузеры для Android и iPhone базируются на Web К it, который представляет собой браузер ный движок с открытым исходным кодом. Поэтому веб-страницы, по большей части, смогут успешно работать в разных браузерах.

В

А почему бы просто не использовать Flash, чтобы из­ б бежать ежа проблем с межбраузерной поддержкой?

Q : Flash - <- отличныи инструмент, который получил повсеместное распространение в операционных системах и браузерах настоль­ ного сегмента. HTML5 со своим семейством технологий предлагает вам сделать с использованием открытых стандартов многое из того же, что и Flash. Что вам предпочесть? Задумайтесь о том, какой объем инвестиций в технологии HTML5 вкладывают такие компании, как 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 { шение к HTML-элемент ам 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 . . . " ;

} < / script>

54

глава 1

и идентификаторам.


знакомство с HTML5 Я просто хочу сказать, что если вы намерены серьезно заняться создани­ ем веб-приложений и использованием HTM L5, то вам потребуются навыки работы \ с JavaScript. ^

У нас к вам есть разговор. Если вы рапее прочитали кпигу «Изучаем HTM L, XHTM L и CSS», то мы по­ лагаем, что вы, вероятпо, хорош о разбираетесь в использовапии язы ков разм етки и таблиц стилей для создапия прекраспы х веб-страпиц. О риептируясь в обеих этих техпологиях, вы сможете преодолеть длиппы й нуть... С появлепием HTML5 веб-страпицы превращ аю тся в пасы щ еппы е п рило­ ж ения, обладающие поведепием, обповляю тся па лету и взаимодействуют с пользователями. Создапие страпиц подобпого рода требует изрядпого труда программиста, и если вы собираетесь писать код, которы й будет вы­ полняться в браузере, то вам пеобходимо использовать JavaScript. Если вам доводилось рапее запиматься програм м ировапием или паписапием просты х сцепариев, то вам это пригодится: JavaScript (песм отря па слухи) является фаптастическим язы ком, и в этой кпиге мы поведаем вам обо всем, что пеобходимо зпать для паписапия прилож ений. Если же у вас п ет опы та програм м ирования, мы сделаем все возмож пое, чтобы ввести вас в курс дела. В лю бом случае, одпим из огромпы х преимуществ JavaScript является легкость его попим апия для программистов-повичков.

&олее увлека­ тельного способа научиться програм ­ мированию Итак, что теперь? Д авайте кратко ознакомимся с JavaScript, а затем по- мы и пред­ пастоящему глубоко погрузимся в пего в главе 2. Н е старайтесь разобрать­ ставить не можем! ся во всех деталях па п ротяж ени и пескольких следующих страпиц —здесь вы долж пы лиш ь почувствовать, что такоеJavaScript. дальше ►

55


что умеет javascript

Взаимодействуйте со своими страницами новыми способами, которые подходят как для настольного сегмента, так и для портативных устройств.

Что моЖно С9елать с помощью JavaScript?

*

*

JavaScript открывает целый новый мир выражений и функциональностей для ваших веб-страниц. Да­ вайте взглянем на ряд вещей, которые вы сможете сделать с помощью JavaScript и HTML5...

£ p T » i! 7 гр» этом не потребуются никак»

Внедряйте в свои страницы под­ держку определения местополо­ жения, чтобы можно было узнать, где находятся ваши пользователи, показать им, что располагается поблизости, помочь отыскать то, что им нужно, задать им направле­ ние либо собрать людей с общими интересами в одном месте.

Используйте Web Workers, чтобы ускорить свой JavaScript-код и произвести важные вычисления либо сделать свои приложения более отзывчивы­ ми. Вы даже можете еще эффективнее задейство­ вать потенциал многоядерных процессоров, уста­ новленных на компьютерах ваших пользователей!

Получайте доступ к любой веб-службе и передавайте полученные от нее данные своему приложению почти в режиме реального времени.

\

Кзшируйте данньые локально, используя исполь ораузерное хранилище для ускорения работы мобильных приложений

Интегрируйте свои страницы с Картами Google и давайте пользователям возможность отслеживать их собственное перемещение в режиме реаль­ ного времени.

56

глава 1

Для воспроизведения видео больше не нужны специальные плагины.

Создавайте собственные элементы управления вос­ произведением, исполь­ зуя HTML и JavaScript.

j


знакомство с HTML5 Попрощайтесь с браузерными cookie-файлами и * используйте локальное хранилище в браузере.

Забрать вещи из химчистки

Используя JavaScript, вы сможете сохра­ нять множество установок и данных для своих пользователей локально в брау­ зере и даже сделать так, чтобы к ним имелся автономный доступ.

Слетать на Фиджи

( I '

D Выпить К0Фе

Помыть

Купить

ехце один

гаджет от ^ppie

Испечь

Браузер теперь не просто инструмент для просмотра скучных документов. Благодаря JavaScript вы сможете рисовать пикселы прямо в окне браузера.

Зарядите свои формы по­

,

средством JavaScrip бы обеспечить настоящую

повелся

эпюгп те

_ яоклонник

Если вы ф утболк и TW

[ интерактивность.

Создавайте веб-страницы, которые по-новому объединя­ ются с видео.

носите

«Ю tep

Используйте мощь JavaScript для тщательной обработки видео в своем браузере. Создавайте спец­ эффекты и напрямую манипулируй­ те отдельными видеопикселами.

Вы, вероятно, подумали, что мы об­ шарили весь Интернет, чтобы найти наиболее захватывающие примеры. На самом деле это не так. Мы просто сделали скриншоты созданных нами примеров, с которыми вы будете стал­ киваться в книге. Правда, они здорово выглядят? Итак, теперь, когда вы уже в Вебвилле, пришло время научиться местному языку — JavaScript. Что ж, приступим. дальше ►


знакомство с 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

Пишем серьезный JavaScript Д ерж им пари, что все эти разговоры о JavaScript разож гли в вас ж елапие п ерейти, пакопец, пепосредствеппо к паписапию кода. С ерия пе зря пазы вается «Изучаем...», и пиж е вас ож идает паглядпое суперсерьезпое бизпес-приложепие, па котором мы скопцептрируем ваше впимапие. Д ля пачала пройдитесь по коду, чтобы прочувствовать его. Н апиш ите, что, как вам кажется, делает каж­ дая строка. Н е беспокойтесь, мы пе ожидаем, что вы с ходу во всем разберетесь, по уверепы, что у вас будут успеш пые догадки пасчет того, что делает этот код. Закопчив, п ереверп и те страпицу и посм отрите, пасколько близко вам удалось подобраться к правильпы м ответам...

Свои о Э с ^ б ^ е с.«Ы

N/

0 №&&W\b\

ил\лиШи\ЛЛ£ 3 dcct>-

своего А

var drink = "Energy Drink" ;

6 w M 020 НЯ1Л.и^кЯ.

var lyrics = var cans = 99;

while (cans > 0 ) { lyrics = lyrics + drink lyrics = lyrics + drink

+ cans + " cans of

"

+ " on the wall <br>"; + cans + " cans of

"

+ "<br>";

lyrics = lyrics + "Take one down, pass it around,<br>";

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: проверка ваших ответов Снова нройднтесь но коду и но см отрите, что нривлекло ваше внимание. Вам нужно нросто нрочувствовать этот код; далее нош агово разберем ся во всех деталях. var drink = "Energy Drink";

Объявляем первую переменную и п р и ­ сваиваем ей значение "Energy Prink"

var lyrics = "";

Объявляем вторую переменную и п р и ­ сваиваем ей пустое строковое значение.

v a r cans = 99;

Объявляем трет ью переменную и п р и ­ сваиваем ей числовое значение <?<?.

while (cans > 0 )

Это цикл while. Он говорит: «Пока количество банок превышает О, вы­ полнять все, что заключено в ф игур­ ные скобки. Остановиться, когда банок больше не останется»

{

/Добавляем следующую строку песни в переменную lyrics с использованием оператора конкатенации строк « + »

lyrics = lyrics + cans + " cans of "

+ drink + " on the wall <br>";

Завершаем строку посредством разры­ ва строки HTML. Повторяем снова.

lyrics = lyrics + cans + " cans of " + drink + "<br>"; lyrics = lyrics + "Take one down, pass it around,<br>";

/Добавляем следующую строфу, снова с использованием конкатенации.

if (cans > 1 )

Если остались еще банки (то есть зна­ чение количества банок превышает 1)...

lyrics =

{ lyrics + (cans-1) + " cans of " + drink + " on the

...то добавить последнюю строку.

wall <br>";

}

в противном случае, когда банок не осталось...

else { lyrics =lyrics +

"No more cans of

+ drink + " on the

"

... добавить 11No more cans of 11 в конец lyrics.

wall <br>";

} cans = cans - 1;

document.write(lyrics) ;

60

глава 1

Уменьшаем количество оставшихся банок на 1. Мы сохранили все строки песни в пере­ менной lyrics, поэтому теперь даем веб-странице команду записать ее. Это означает, что строка будет до­ бавлена на страницу, в результате чего вы увидите текст песни.


знакомство с HTML5

ТЕСТАРЛИ* Вы же не думали, что, провернув всю сложную работу по выполнению упражнения, вы так и не подвергнете практическому испытанию наш JavaScript-код? Вам необходимо взять код с предыдущей страницы и перенести его (вместе с HTML-разметкой, приведенной ниже) в файл (например, index.html), а затем загрузить в браузере. Результат можно увидеть внизу:

^ <! doctype html>

эт о№

< 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 .

<head> <meta charset="utf- 8 "> <title>MY First JavaScript</title> </head>

Теги <script> и </script> окружают JavaScript-код. Они говорят странице, что все, что в них заклю­ чено, является JavaScript-кодом, а не HTML. Сюда нужно вставить JavaScriptкод с предыдущей страницы.

;= s £ g = 2 вот результат нашего тестового про­ гона данного кода. Он генерирует текст лирической песни о ЯЯ -бутылках банках гш&а энергетического напитка на полке и записывает его в документ браузера.

А

tnin,PM **c«anоsврo5.fdP--JT, i IktK ™ '‘rotM und, w*i %Scans<vfpn”tPWa » «аз g**ona»'W aJ

93fans<jf

SniUod>

« с*вд^2й22?в,,,1в»«ц tew»u

дальше ►

61


некоторые тонкости htm!5 Часш°

Задаваем ы е В сЩ роСъх

Почему в теле приведенного ранее HTMLдоку документа нет ничего, кроме тегов script?

f t

0:

Мы решили начать с пустого элемента b o d y , поскольку создали все содержимое данной страницы, используя JavaScript-код. Да, можно было бы просто внести текст лирической песни прямо в элемент b o d y (и при этом нам бы пришлось долго печатать на клави­ атуре), либо мы могли позволить коду выполнить всю тяжелую работу за нас (что мы и сделали), а затем дать ему команду вставить текст песни на страницу посредством 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 . Та­ ким образом, в данном случае d o c u m e n t . w r it e вставляет строку прямо в тело страницы. Вскоре вы познакомитесь с более тонкими способа­ ми изменения текста живого документа с помощью JavaScript, а данный пример призван дать вам по­ чувствовать, как код способен динамически вносить изменения в страницу.

Вы используете термины «веб-страница» и «веб-приложение»; под ними понимается что-то разное? Что именно делает нечто веб­ приложением?

0:

Это отличный вопрос, поскольку мы используем эти термины в широком смысле. Технически никакой разницы между двумя этими понятиями нет; другими словами, вам не нужно делать что-то особенное для того, чтобы превратить страницу, написанную на HTML, JavaScript и/или CSS, в веб-приложение. Появление различий — это скорее одна из возможных перспектив. Когда у нас имеется страница, ведущая себя скорее как приложение, нежели как статичный документ, мы начинаем думать о ней больше как о веб-приложении и меньше как о веб-странице. Приложение мы рассма­ триваем как нечто такое, что обладает рядом особен­ ных качеств, например способностью поддерживать множество состояний, управлять более комплексными взаимодействиями с пользователем, отображать динамические и постоянно обновляемые данные без необходимости в обновлении всей страницы или даже выполнять более сложные задачи либо вычисления. Весь этот JavaScript, конечно, замечательная вещь, но как насчет CSS? Мне не терпится восполь­ зоваться преимуществами CSSS-нововведений, чтобы улучшить внешний вид своих страниц. 0 : Да, CSS прошел долгий путь, и мы с воодушев­ лением смотрим на то, насколько хорошо он работает с HTML5. Несмотря на то что эта книга не о CSS, мы с вами обязательно воспользуемся преимуществами некоторых новых возможностей этого языка. Как вы, возможно, знаете, многие из трюков, к которым мы прибегаем для добавления закругленных углов и теней на изображениях при использовании HTML и создания простых анимаций на JavaScript, теперь мо­ гут быть с легкостью воспроизведены с помощью CSS. Так что в этой книге мы воспользуемся мощью CSS и обратим ваше внимание, когда это произойдет.

62

глава 1


знакомство с HTML5

Мы поговорили о массе вещей, включая H TM L-разметку, A P I-интерфейсы JavaScript, «семейство технологий» и CSS. А что именно представляет собой HTML5? Не может же он быть лишь простым языком разметки, кото­ рый сумел пробудить всеобщий интерес...

Дадим вам неофициальный ответ: ^

HTMLS*

Язык разметки + д API -интерфейсы JavaScript + CSS = Пум.уим .... Щ■г Отметим, что когда многие люди говорят о том, что такое HTM L5, они подразумевают совокупность всех этих техно­ логий. То есть у нас есть язы к разм етки для н остроен и я ос­ н овн ой структуры страниц, JavaScript вместе со всеми сво­ ими API-интерф ейсами для добавления новедения и новой функциональности, а также CSS для стилизации страниц — все эти технологии мы будем иснользовать для создания веб-нрилож ений завтраш него дня. Но ночему же мы сказали «неофициальный»? Ч то ж, есть люди, которы е лю бят нроводить ж есткие разграничитель­ ны е лин и и между этими технологиям и и говорить, к какому стандарту относится каждая из них. Это в норядке вещ ей и им еет место. Однако для нас важно вот что: какие техноло­ гии ноддерж иваю тся браузером и достаточно ли они п рора­ ботаны для того, чтобы иснользоваться для создания наших страниц и нрилож ений? Н а наш взгляд, HTML5 —это язы к разм етки + API-интерф ейсы JavaScript + CSS, и мы считаем, что именно это, как нравило, имею т в виду люди, когда гово­ рят о HTML5 как о технологии. Если вам действительно интересно , как эти технологии объединяются в единый набор стандартов (а интересовать это должно каждого), то совет уем посет ит ь ресурс w3.org для получения дополни­ тельной информации по данному вопросу .

дальше ►

63


ваш первый код на htm!5

]J°3A paBjlffeM , Б ы З а к о н ч и л и

f

и з д а т ь ГЛ аВ у

первы й Код н а

1 Л М §!

н а п и са Л и сВ о й

^

J

И свой первый код на JavaScript!

П режде чем н ерей ти к следующей главе, вынолним еще одно задание на закренление изученного материала. И снользуйте нриведенны е внизу карточки со словами для составления формулы, реш аю щ ей уравнение «что такое + HTML5?». Будьте внимательны , носкольку в эту кучу добавлены слова, которы е могут сбить вас с толку. С нравивш ись с задачей, немного отдохните и осве­ ж итесь, а затем нристунайте к главе 2.

Г HTML5

I

A P I -и н т е р ф е й с ы J a v a S c r i p t

JavaScript CSS

XML

M r . Pi b b

R e d Vines

I

Geol o c a t i o n

Canvas

XHTML

Язык CSS3

!

I <script>

64

глава 1

I Forms


знакомство с HTML5

КЛЮЧЕВЫЕ МОМЕНТЫ

HTML5 — это самая современная версия HTML. Она включает новые упрощенные теги, а также семантические и медиаэлементы, полагается на набор JavaScript-библиотек, обеспечиваю­ щих функционирование веб-приложений.

XHTML больше не является стандартом для веб-страниц. Вместо него разработчики и W3C решили продолжать расширять и совершен­ ствовать HTML.

HTML5 включает элементы, которые привносят новую семантику в станицы, открывая перед вами больше возможностей, связанных с соз­ данием структуры веб-страниц, чем было в HTML 4.01. Мы не будем рассматривать их в книге, однако в приложении вы найдете не­ большое руководство по ним. Для использования многих возможностей HTML5 наилучшим образом вам потребуется JavaScript.

Новое и более простое определение d o c ty p e в HTML5 поддерживается старыми версиями браузеров: когда они сталкиваются с ним, то переходят в стандартный режим.

Применяя JavaScript, вы сможете взаимодей­ ствовать с объектной моделью документа (Document Object Model, DOM).

Атрибут ty p e больше не требуется в теге < s c r i p t > или в ссылке на таблицу стилей CSS. JavaScript и CSS стали языками по умол­ чанию для HTML5.

Тег < m eta> , используемый для указания набо­ ра символов, был упрощен и теперь включает только кодировку символов.

Объектная модель документа (DOM) — это браузерное внутреннее представление веб­ страницы. Используя JavaScript, вы сможете получать доступ к элементам, изменять их, а также добавлять новые элементы в объект­ ную модель документа.

UTF-8 сейчас является стандартной кодировкой символов, используемой в Интернете.

Изменения в d o c t y p e и теге < m e ta > не ска­ жутся отрицательно на страницах, загружаемых в старые версии браузеров.

Совокупность новых элементов HTML5 пред­ ставляет собой расширенный набор элементов HTML 4. Это означает, что старые страницы смогут нормально функционировать в совре­ менных браузерах.

Работы над стандартом HTML5 не будут офи­ циально завершены до 2014 года, однако большинство современных браузеров станет поддерживать его задолго до этого (а многие поддерживают уже сейчас!).

API-интерфейсы JavaScript (Application Programming Interface — интерфейс приклад­ ного программирования) позволяют управлять всеми аспектами HTML5 (20-рисованием, вос­ произведением видео и др.). JavaScript является одним из наиболее попу­ лярных языков в мире. Реализации JavaScript значительно усовершенствовались за послед­ ние годы. Вы можете выяснять, поддерживается ли та или иная новая функция браузером, и обе­ спечивать плавную деградацию веб-страниц в случае отсутствия такой поддержки. CSS — это стандартный язык стилей для HTML5; многие люди вкладывают CSS в по­ нятие «HTML5», когда используют его для опи­ сания семейства технологий, применяемых для создания веб-приложений.

дальше ►

65


кроссворд

Ц

Щ

5 - К

Г 0С С В 0Г Д

Н астало врем я дать отдохнуть нрав о му нолушарию вашего мозга и за­ ставить ноработать левое. В нриведенном ниж е кроссворде все слова связаны с HTML5 и взяты из текущей главы.

По горизонтали

По вертикали

3. __________ реклама, также называемая спамом. 4. Ваша миссия заключалась в том, чтобы провести___________ в стане браузеров. 5. Инструмент, позволяющий обновить старый код до HTML5 за три шага__________ . 9. Стандартный язык сценариев для HTML5. 10. Это определение теперь стало намного проще, чем было в версии HTML 4.01. 12. Этот язык получил «прощальное письмо» в 2009 году. 14. Используйте цикл___________ для генерирования вывода строк песни.

1. Нам необходимо, чтобы деградация наших веб-страниц про­ исходила ___________ . 2. Новейшие____________ HTML5 привносят новую семантику и открывают дополнительные возможности, связанные с соз­ данием структуры веб-страниц. 6. Истинная мощь HTML5 заключается в __________ JavaScript. 7. Стандартный язык стилей для HTML5. 8. Тег <___________ > говорит браузеру, что все, что следует да­ лее, является JavaScript-кодом, а не HTML. 10. ___________ — это внутреннее представление веб-страницы.

15. JavaScript стал быстрее в

66

глава 1

раз, чем был 10 лет назад.

11. Данный атрибут тегов l i n k и s c r i p t больше не требует­ ся, если вы используете HTML5. 13. Версия HTML, предшествующая HTML5.


знакомство с HTML5

+

+

S f c e / * ! т?

Мы с вами говорили о «семействе технологий» столько раз, что уже кажется, что мы сами одна семья. Однако мы по-настоящему так и не разобрались в том, что конкретно они собой представляют, поэтому, наконец, сделаем это. Ниже представлен перечень большинства членов этого семейства, посмотрите, сможете ли вы разобраться, кто есть кто. Не беспокойтесь, мы знаем, что это ваша первая встреча с членами семейства HTML5, поэтому приводим решения задания. Иснользуя меня, вы мож ете рисовать нрямо н а своей веб­ странице. Благодаря мне можно рисовать текст, изображ ения, линии, круги, нрямоугольники, узоры, нрим енять градиенты. Я номогу вам раскры ть таящ егося в вас художника.

Web Workers

Forms Автономные вебприлоЖения

Audio и Video

Новые элементы ражетки

Local Storage

М еня иснользовали в HTM L 4 для ввода и нф орм ации, но я стал еще лучше в HTML5. Я могу требовать от вас занолнять все поля и снособен нроверять, ввели ли вы адрес электрон ной ночты, URL-адрес или ном ер телеф она туда, куда требуется. Ранее для обеснечения ф ункциональности, аналогичной на­ шей, вам нриходилось иснользовать плагины, но тен ерь мы стали полноценны м и членами семейства элементов HTML. Хо­ тите но см отреть или но слушать что-либо? Тогда мы нужны вам. Мы здесь для того, чтобы номочь вам со структурой и семанти­ ческим значением ваш ей страницы и обеснечить новы е снособы создания секций, заголовков, ниж них колонтитулов и нави­ гации на ваших страницах. Я самый стильны й во всем семействе. Знаете ли вы, что тенерь я могу аним ировать ваши элементы , нри давать их углам закру­ гленность и даже обеснечивать эф ф ект отбрасы вания тени? Иснользуйте меня как часть локального хранилищ а в браузере лю бого пользователя. Вам необходимо сохранять установки, элементы , помещ енны е в электронную корзину, или, возмож­ но, даже н рин рятать больш ой кэш для увеличения производи­ тельности? Тогда я нужный вам API-интерфейс. Вам требую тся прилож ения, снособные работать даже тогда, когда отсутствует подклю чение к Сети? Я могу вам номочь.

Canvas

Geolocation

Я —API-интерф ейс, которы й номож ет вам онределить свое ме­ стополож ение, и отлично работаю с К артами Google. Я нужен, чтобы несколько сценариев вы нолнялись нараллельно в ф оновом реж име, благодаря чему ваш интерф ей с пользо­ вателя сможет оставаться отзывчивым.

дальше ►

67


I еэеиг

'V c fo g ^ > o c b l —

gg

ЁМН «ВР egdosooodn епнетес!


2

Знакомство Д о ку м ен та

с

JaVa^cript и объектной

Ф о1» )

+

М°ДеЛь1°

+

Немного кода*

Благодаря JavaScript вы откроете для себя нечто новое. Вы уже все знаете о HTML-разметке (иначе называемой структурой) и CSS-стиле (также известном как представление), однако вам недостает знаний о JavaScript (или, как еще говорят, поведении). Если ваш багаж знаний ограничивается лишь структурой и представлением, то вы, конечно же, сможете создавать прекрасно выглядящие страницы, однако они будут лишь простыми стра­ ницами. Но если вы добавите поведение, прибегнув к JavaScript, то сможете обеспечить для своих пользователей интерактивное взаимодействие; либо, что даже еще лучше, вы сможете создавать роскошные веб-приложения. Приготовьтесь добавить в свой инструментарий веб-разработчика наиболее интересные и универсальные знания о JavaScript и программировании!

X.

е-сли вам н у ж н а дополнительная мотивация, то и наиболее, полезные!

А


как работает javascript

Как работает JavaScript Наша цель заключается в том, чтобы написать JavaScript-код, который будет выполняться в браузере после загрузки веб­ страницы. Данный код мог бы, например, реагировать на дей­ ствия пользователя, обновлять или изменять страницу, общаться с веб-службами и, в целом, создавать ощущение, что ваша стра­ ница ведет себя скорее как приложение, нежели как обычный до­ кумент. Давайте посмотрим, как это все работает.

0

<html> <head> <script> </script> <body> <hl>My first JavaScript</hl>

|

< p x /p >

html"

<script> X =

| head~

X + 2;

</script> </body> </html>

|

title

|

body script

[ |

hi

^ |

h2

\|

p

[

\~errT\

Написание

Загрузка

Выполнение

О Вы пишете свою разметку на HTML и код на JavaScript, а затем сохраняете их в фай­ лах, скажем, i n d e x . h t m l и i n d e x . j s (либо и то и дру­ гое в одном HTML-файле).

Браузер извлекает и загружает вашу страницу, осуществляя разбор ее содержимого сверху вниз. Когда браузер обнаруживает JavaScript-код, он разбирает его и проверяет на правильность, после чего выполняет этот код. Браузер также создает внутрен­ нюю модель HTML-страницы, называемую объектной моде­ лью документа (DOM).

Л 70

глава 2

JavaScript-код продолжает выполняться, используя DOM для исследования страницы, ее изменения, получения от нее событий или запроса браузера на извлечение дополнительных данных с веб-сервера.


javascript и dom

Что моЖно сделать с помощью JavaScript? Если у вас имеется страница с элементом < s c r i p t > (или со ссылкой на отдельный JavaScript-файл), то вы готовы нристунать к нанисанию кода. JavaScript явля­ ется нолноценным языком нрограммирования, с номощью которого можно сделать очень многое из того, что нредоставляют другие языки, и даже еще больше, но­ ско льку вы будете программировать внутри страницы! JavaScript нозволяет следующее. О

Ф орм ировать операторы Создавайте переменные и присваивайте им значения, склады­ вайте числа, производите другие вычисления, используйте встроенную функциональность библиотек JavaScript.

var temp = 98.6; var beanCounter = 4; var reallyCool = true; var motto = "I Rule"; temp = (temp - 32) * 5 / 9 ; motto = motto + " and so do you!"; var pos = Math.random () ;

ф

Д е л а т ь ч т о - т о дваЖды, неоднократно Выполнение операторов может осуществляться снова и снова, столько раз, сколько вам потребуется.

while (beanCounter > 0 )

{

processBeans(); beanCounter = beanCounter - 1;

} О

Принимать решения П иш ите условный код, зависящий от состояния вашего приложения.

if (isReallyCool)

{

invite = "You're invited!"; }

else { invite = "Sorry, we're at capacity.";

дальше ►

71


объявление переменных

Объявление переменной П ерем енны е содерж ат данные. В случае с JavaScript они могут содержать массу различны х вещей. Д авайте объявим несколько нерем енны х, содер­ жащих данные. var var var var

winners

Целочисленные значения . winners = 2 ; Или числовые значения с плаваю boilingPt = 212.0; точкой. name = "Dr. Evil"; 4 Или строки символов (кратко «строки»). isEligible = false; Или логические значения (true или false).

boilingPt

name

Три шага по созданию переменной isEligible

v a r

sco o p s

=

1 0 ;

П ервы й шаг заклю чается в объявлении нерем енной, в данном слу­ чае s c o o p s . Следует отметить, что JavaScript, в отличие от неко­ торы х других язы ков, не требует указания тина нерем енной, а нросто создает кон тей н ер общего тина, в котором мож ет содерж аться масса вещей:

scoops Далее нам необходимо значение, которое будет размещ аться в не­ рем енной. Указать значение можно несколькими снособами:

Значение может быть литеральным , например числом или строкой. var scoops = 10; var scoops = totalScoops / people; var scoops = Math.random () * 10;

72

глава 2

Или значение может быть результат ом оценки вы­ ражения.

Переменные— этоконтейнеры длязначений. JavaScript-

иеременные неимеютстрогих типов, поэтому любаяизних можетсодержать числовое, строковое нлнлогическое значение.


javascript и dom

<3>

Н аконец, у нас имею тся нерем енная и значение (лите­ ральное значение, нанрим ер 10, или результат оценки вы раж ения (вроде totalScoops / people). И все, что нам осталось сделать, — нрисвоить значение наш ей нерем енной.

О синтаксисе

■ Каждый оператор должен заканчиваться точкой с запятой. х

scoops Создав неременную , вы, конечно же, сможете изм енить ее значение в лю бой момент или даже нрисвоить ей значение, имею щее другой тин. Вот ряд нримеров:

ы можем присвоить переменной scoops, другое целочисленное значение.

м £—

scoops = 5 ; scoops = scoops * 1 0 ;

Или даже использовать scoops в выражении, которое изменит ее значение. В данном случае значение scoops будет равно 50.

f4

t 3 JavaScript даже есть значение, кото рое означает «зна­ чения нет». Оно на­ зывается null. О его использовании мы поговорим позже.

х

+

1;

■ Однострочный комментарий должен на­ чинаться двойным слешем. Коммента­ рии — это просто заметки о коде, пред­ назначенные для себя или для других разработчиков. Они никак не оцениваются. / /

Э то

ком м ентарий

■ Пробелы неважны (почти везде). х

=

2233;

■ Строки символов следует заключать в двойные кавычки. "Y o u

r u l e ! 11

■ Переменные необходимо объявлять с ука­ занием v a r и имени. JavaScript не требу­ ет указывать тип в отличие от некоторых других языков программирования.

scoops = "Tired of being an integer";

scoops = null;

=

Либо мы можем изменить значение и тип переменной scoops, в данном случае — на строковое значение v a r w id t h ; и соответственно тип. Но будьте ■ Не заключайте в кавычки логические зна­ осторожны, поскольку это может чения t r u e и f a l s e . привести к большим проблемам в коде, если вы ожидаете, что scoops r o c k i n = t r u e ; будет иметь числовое значение. ■ Переменным необязательно присваивать Подробнее об этом — чуть позже. значения при объявлении: var

Ч асцю

w id t h ;

^адаВ аеМ ы е БоЦр»оСьх Каким будет значение моей переменной, если я просто

1Мне доводилось иметь дело с другими языками програм­ мирования, в которых переменные объявляются с указанием

напишу так:

типа. Например, i n t

var

w in n e r ;

0:

После выполнения данного оператора переменной winner будет присвоено значение undefined, которое является другим значением и типом JavaScript. О том, где и как его использовать, мы поговорим позже.

х или S t r i n g

у. Разве в JavaScript

нет типов?

0 :'! В JavaScript есть типы, однако, в отличие от других языков, он

предусматривает динамическую типизацию, которая означает, что интерпретатор JavaScript сам определит, какой тип использовать.

дальше ►

73


присвоение имен переменным ( ^ ь е З Н

о е

п р о г р а м м

и р о в а н и е

Как присваивать имена переменным У вас мог возникнуть вонрос: «А как вы бирать им ена для своих неременных?». Если вам доводилось нрисваивать им ена идентиф икаторам в случае со своими HTM Lэлементами, то аналогичная нроцедура в отнош ении нерем енны х нокаж ется вам схожей. Есть только не­ сколько нравил нри ф орм и рован ии имен неременны х.

Правило 1. Начинайте имена своих переменных с буквы, символа подчеркивания или знака доллара. П ри грамотном нрисваивании имен своим нерем енны м необходимо не нросто нридумывать им вы разительны е названия, но также иснользовать букву (в ниж нем или верхнем регистре), символ подчеркивания или знак доллара в начале их имен. Вот ряд нримеров:

var thi s IsNo tAJoke ; var _myVariable; var $importantVar;

В JavaScript n u m b e r , s t r i n g и B o o l e a n называются прими­ тивными типами. В переменных также можно сохранять объекты. Об объектах мы поговорим до­ вольно скоро, а пока вы можете рассматривать объект как кол­ лекцию некоторых вещей, тогда как примитив — это просто вещь, которая не может быть разделе­ на на что-либо еще.

Имя начинается с числа , а это неправильно.

var 3zip; var %entage;

Имя начинается с недопу­ стимых символов (% и ~).

.var ~approx;

*

Правильно

Неправильно

Правило 2 . З а т е м вы моЖете указывать любое количество букв, цифр, символов подчеркивания или знаков доллара. П родолж айте иснользовать буквы, знаки доллара и символы под­ черкивания н ри ф орм и рован ии имени своей нерем енной. После нервого символа вы также н ри ж елании мож ете указывать числа: S---

my3sons;

Здесь имеется недопустимый пробел

cost$; vitaminBl2;

^ Правильно

74

глава 2

Знаки « - » и «±» недопусти­ мы и сильно сбивают с толку JavaScript.

var zip code; var first-name var to+do;

Неправильно

1


javascript и dom

Правило 3 . избегайте всех зарезервированных слов JavaScript. Я зык JavaScript вклю чает ряд зарезервированны х слов, нанрим ер i f , e ls e , w h ile , f o r (это лиш ь часть из них), и не будет слишком лю безен, если вы ноны таетесь иснользовать их в качестве имен для своих нерем енны х. П еречень зарезервированны х слов JavaScript нриведен ниже. Н е нужно сию же минуту заноминать их, но ходу освоения JavaScript у вас вы работается нонимание, что же они собой нредставляю т. Но если когда-либо JavaScript станет «ругаться» н а то, как вы объявили свои нерем енны е, то вам следует мыслить следующим образом: «Хм, а может, слово, которое я нытаю сь иснользовать, является зарезервированны м?». abstract

delete

goto

null

throws

as

do

if

package

transient

boolean

double

implements

private

true

break

else

import

protected

byte

enum

in

public

try typeof

case

export

instanceof

return

use

catch

extends

int

short

var

char

false

interface

static

void

class

final

is

super

volatile

continue

finally

long

switch

while

const

float

nam espace

synchronized

with

debugger

for

native

this

default

function

new

throw

x* '—

Избегайте использования этих слов в качестве имен для переменных!

Часто

Задаваем ы е

........

В опросы

l b ™

рованное слово как часть имени своей переменной? Могу ли я присвоить пере­ менной, например, имя ifOnly (то есть в ее имени будет содержаться зарезерви­ рованное слово if)? 0 : Конечно можете, просто избегайте точного совпадения имени переменной с зарезервированным словом. Также целе­ сообразно писать понятный код, в котором, как правило, не используются слова вроде e lz e , которое можно перепутать с e ls e .

Чувствителен ли JavaScript к ре­ гистру? Другими словами, есть ли разница между написанием myvariable и MyVariable? 0 : Если вам доводилось иметь дело в ос­ новном с HTML-разметкой, то, возможно, вы привыкли к нечувствительным к регистру языкам, ведь, в конце концов, < h e a d > и < h e a d > трактуются браузером как одно и то же. Однако в случае с JavaScript регистр имеет значение, поэтому m y v a r ia b le и M y v a r ia b l e будут рассматриваться как две разные переменные.

Как я понял, JavaScript позволяет присваивать нужное значение перемен­ ной (числовое, строковое и т. д.) в любой момент. Однако что произойдет, если я добавлю две переменные, одна из ко­ торых будет иметь числовое значение, а другая строковое, вместе? 0 : JavaScript старается осуществлять умное преобразование типов по мере не­ обходимости. Например, если вы добавите сразу две переменные с числовым и строко­ вым значениями, то он, как обычно, попы­ тается преобразовать числовое значение в строковое и конкатенировать их. Не во всех ситуациях это нужно. Держите эту мысль в уме, мы вернемся к ней совсем скоро.

дальше ►

75


присвоение имен переменным

Вебвилльское руководство по вы бору оптим альны х имен Вам предоставляется немалая свобода при выборе имен для своих переменных, поэтому мы возьмем на себя смелость дать несколько советов, чтобы облегчить вам эту задачу.

Отдавайте предпочтение именам, которые что-то означают Такие имена переменных, как, например, _ш, г и f о о , могут что-то означить для вас, однако в Вебвил­ ле на них, как правило, смотрят неодобрительно. Не только потому, что вы сами, скорее всего, забудете их со временем, но и в силу того, что ваш код будет более удобочитаемым, если вы предпочтете ис­ пользовать в нем переменные с именами вроде a n g l e , c u r r e n t P r e s s u r e и p a s s e d .

При формировании имен переменных из нескольких слов используйте стиль CamelCase В определенный момент у вас возникнет необходимость решить, как указать имя переменной, которая олицетворяет, скажем, огнедышащего двуглавого дракона. Просто используйте стиль CamelCase, кото­ рый подразумевает, что первая буква в каждом новом слове должна указываться в верхнем регистре (кроме слова, идущего первым): t w o H e a d e d D r a g o n W i t h F i r e . Стиль CamelCase прост в ис­ пользовании, широко распространен в Вебвилле и обеспечивает достаточную гибкость в формировании настолько специфических имен переменных, насколько вам потребуется. Существуют также и другие подходы, однако этот является одним из наиболее часто используемых (даже за пределами JavaScript).

Используйте переменные, имена которых начинаются с символов _ и $, только по очень веской причине Переменные, имена которых начинаются с $, обычно зарезервированы для JavaScript-библиотек и, не­ смотря на то что некоторые программисты используют переменные с именами, начинающимися с сим­ вола в силу различных соглашений, они не имеют широкого хождения. Мы рекомендуем держаться от них подальше, если только у вас не будет веской причины поступить иначе (если она появится, вы, естественно, будете это знать).

Будьте осторожны Проявляйте осторожность при присваивании имен переменным. Далее в книге мы дадим еще ряд советов по этой теме, а пока знайте, что для переменных нужно выбирать понятные имена, избегать зарезервированных слов и всегда указывать 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, поэтому важно знать, какого рода вещи вы сможете выражать. Вот ряд примеров... Вы м о ж е т е п и с а т ь в ы р а ж е н и я , р е з у л ь т а т о м оцен ки к о т о р ы х б у д у т чис ло вы е значения...

Числовые Выражения

(9/5)

* tempC + 32

* - 1 Math. random() * 10

2.123 + 3.2

Вы м о ж е т е п и с а т ь вы раж ения, результ ат ом о цен ки к о т о р ы х б у д ут логические зн а ч е н и я t r u e и л и false (они соот вет ст вен­ но н а з ы в а ю т с я логическим и вы ­ ра ж е н и ям и ).

^

Логические ВыраЖения 2 > з tenqpF <

s ta r tT :ime > nov 7 5

level == 4 =

"Duck"

...a т а к ж е п и с а т ь в ы р а ж е н и я , р е з у л ь т а т о м о цен ки к о т о р ы х б у д у т с т р о к о в ы е зн ачен и я. Строковые выражения

"super" + "cali" + youKnowTheRest

♦ -2 1 - * - f

Также с у щ е с т в у ю т д р у г и е т ипы выраж ений, о к о т о ­ р ы х м ы п о г о в о р и м позже.

P

phoneNumber. substring (0 , 3)

Прочие выражения

function () Внимательно отнеситесь к выражениям, представленным на нескольких следующих страницах (не говоря уже об оставшейся части книги), и вы поймете, как они использу­ ются для проведения вычислений, многократного повто­ рения действий и принятия решений в вашем коде.

document.getElementByld("pink") new Array (10)

дальше ►

77


упражнение

г Возьми в руку карандаш В ы р ази те себя! Ранее вы познакомились с различными типами вы­ ражений, которые можно использовать в JavaScriptкоде. Теперь пора применить эти знания на практике и самим оценить несколько выражений. Свои отве­ ты вы сможете проверить в конце главы.

(9/5)

* tempC + 32

Каким окажется результат, если значением te m p C будет 10?

В приведенном ниже перечне об­ ведите допустимые операторы.

va r

х

=

1138;

va r

у

=

3 /8 ;

va r

s =

level >= 5

x

у ;

Каким окажется результат, если значением l e v e l будет 10?

va r

n

=

3

va r

t

=

"o n e "

va r

3po

va r

le v e l_

va r

h ig h N o o n

va r

$ =

2 1 .3 0 ;

va r

z =

2000;

va r

is B ig

z

z

+

1;

z

*

t;

"Number" + " " + "2м Какова будет результирующая строка? .

А каким окажется результат, если значением l e v e l будет 5?

Подсказка: « / » «не».

color != "pxnk"

% означает Каким окажется результат, если значением color будет blu e ? ______________

(2 * Math.PI) * г Каким

с

Взяв за основу свои текущие зна­ ния о переменных, выражениях и операторах JavaScript, посмо­ трите, сможете ли вы сказать, ка­ кие из этих операторов являются допустимыми, а какие приведут к выводу ошибки.

окажется

П одсказка:

результат,

Math.Pl

если

значением

г

будет

3?

=

=

11o n e " ; +

"tw o " ;

tru e ; =

=

11; =

у

fa ls e ;

>

z;

z— ; z

y ;

x

=

w h ile

( h ig h N o o n )

z— ;

Так выражаться не стоит!

глава 2

=

-

возвращ ает

з н а ч е н и е п и (о н о , к а к вы з н а е т е , р а в н о 3 ,П4 ...)

78

"3 -8 ";

{


javascript и dom

Похоже, что все идет как по маслу, если я прибавляю числа к числам, а строки к строкам, но что, если я прибавлю число к строке или целочисленное значение к числу с плавающей точкой?

Помните, мы говорили, что программирование на JavaScript легко освоить? Одна из п ричин этого заклю чается в том, что JavaScript сам преобразует одни типы в другие но мере необхо­ димости, чтобы вы раж ения имели смысл. В качестве прим ера допустим, что у вас имеется следующее вы­ раж ение: m essage

=

2

+

м if

by

sea";

Нам известно, что символ + мож ет как иснользоваться для слож ения чисел, так и выступать оператором конкатенации строк. Так какую же роль он вы полняет в данном случае? Ч то ж, JavaScript знает, что строка " i f b y s e a " никогда не станет похож ей на число, поэтому он решает, что перед ним строковое вы раж ение, преобразует 2 в строку "2м и присваивает нерем ен­ ной message значение "2 i f b y s e a " . Л ибо, если у нас будет такой онератор: v a lu e

=

2

*

3.1;

JavaScript нреобразует целочисленное значение 2 в число с нлаваю щ ей точкой, а результат будет равен 6.2. Как вы уже догадались, JavaScript не всегда делает то, что вам нужно, и в некоторы х случаях ему требуется небольш ая номощ ь в осущ ествлении преобразований. К этой теме мы вернем ся не­ много нозже.

Ш ТУ РМ Каков будет результат оценки следующих операторов со стороны JavaScript? numORStringl = 113 м + "4м numORS tring2 = "3м * "4м

И почему?

дальше ►

79


javascript итерации

while

(j u g g l i n g )

{

keepBallsInAir() ; }

Многократное выполнение одного и того Же... Е сли бы в JavaScript-HporpaMMe все вынолнялось лишь один раз, то она, скорее всего, была бы довольно скучной. Вы сами неоднократно делаете массу вещей: сноласкиваете голову водой, наносите шампунь, затем снова новторяете про­ цедуру, нока ваши волосы не станут чистыми, либо нродолжаете ехать до тех нор, нока не достигнете места назначения, либо непрерывно чернаете моро­ женое ложкой, нока не съедите его нолностью. Для обработки нодобных ситу­ аций JavaScript предусматривает несколько снособов циклического выполне­ ния блоков кода.

Вы можете иснользовать JavaScript-цикл w h i l e для того, чтобы делать что-то до тех нор, нока удовлетворяется соответствующее условие:

нас имеется банка мороженого, в которой его осталось г о ложек. Вот переменная, которую мы объявляем и инициализируем значением ZO. Цикл while использует логическое выражение результат ом t i Z u к о ^ г о г о Л ж ,™ f a m e true « ш М и . В true » Э , расположенный далее, будет выполняться

у

var scoops = 10;

г- ^

while (scoops > 0) {

Пока ложек мороженого будет оставаться более нуля, мы продолжим выполнять все, что имеется в этом блоке кода. у

г ч

alert ("More icecream!11) ; scoops = scoops - 1;

При каждом выполнении цикла while мы уведомляем пользователя о том, что мороженое еще осталось а затем удаляем одну ложку мороженого пут ем ее ' вычитания из общего числа ложек.

alert("life without ice cream isn't the same");

^

80

глава 2

Когда значением условия (scoops > О) становится false, цикл завершается, а выполнение кода продол­ жается здесь, независимо от того, какова будет следующая строка программы.


javascript и dom

V

Таким образом, в нрим ере с циклом w h i 1 е мы инициализируем значение, в данном случае —ноказатель количества оставш ихся лож ек м орож еного, которы й проверяет­ ся циклом w h i l e , и если выдается t r u e , то мы выполняем блок кода. В результате работы этого блока кода в определенны й момент нроисходит обновление вовлечен­ ного в нр о верку условия ноказателя до такого уровня, нри котором значением условия становится f a l s e и цикл заверш ается. ИНИЦИАЛИЗИРОВАТЬ

var scoops = 10; ОСУЩЕСТВЛЯТЬ ПРОВЕРКУ УСЛОВ1 while (scoops > 0 )

{ ВЫПОЛНЯТЬ ДАННЫ Й

alert ("More icecream!11) scoops = scoops - 1;

ълок

КОДА, ПОКА ПРОВЕРКА УСЛОВИЯ В Ы Д А Е Т T R U E ОБНОВЛЯТЬ

>

ПРОДО ЛЖ АТЬ ВЫПОЛНЕНИЕ К О Л А / ------- ЗД Е С Ь ПОСЛЕ Т О Г О , К А К П РО ВЕРКА ^ УСЛОВИЯ В Ы Д А С Т FALSE alert("life without ice cream isn't the same"); JavaScript также предусматривает наличие цикла f o r , которы й еще больше формализует данную структуру. Вот как будет выглядеть наш код из н рим ера с морож еным, нерен и сан н ы й с прим енени­ ем цикла f o r : ИНИЦИАЛИЗИРОВАТЬ

I

ОСУЩЕСТВЛЯТЬ ПРОВЕРКУ УСЛОВИЯ \ ^ ------ ОБНОВЛЯТЬ ВЫПОЛНЯТЬ

for (scoops = 10; scoops > 0; scoops— ) {

КОДА, ПОКА

alert("There 1s more ice cream!") ;

^

УСЛОВИЯ

alert("life without ice cream isn't the same")

БЛОК П РО В ЕРК А

ДАННЫЙ

В Ы Д А Е Т TRUE

ПРОДО ЛЖ АТЬ ВЫПОЛНЕ­ НИЕ К О Д А З Д Е С Ь ПОСЛЕ ТОГО, К А К ПРОВЕРКА УСЛОВИЯ В Ы Д А С Т FALSE

Ч асцю

...................................................

Зад аваем ы е

В

..............................................................

В сЩ роСъх

• Я не вижу никакой разницы между циклами while и for. Как понять, когда следует использовать каждый из них?

w h i l e . Однако, как вы обеспечивает немного большую компактность, a w h i l e делает код

0 : В целом, вы сможете выполнять одни и те же задачи, используя либо цикл f o r , либо цикл могли убедиться в примере с мороженым, цикл f o r

более удобочитаемым. Как правило, циклы 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); о щ В ет н а к а ж д ы й ств ую щ и м

В опрос п о д с о о т в е т ­

Какой показатель общего количества будет отображен в диалоговом окне alert??

^ р а Щ ен т °М .

Свои ответы вы сможете

ФрДГМСМП2

проверить в конце главы.

var tops = 5; while (tops > 0 )

{

for (var spins = 0; spins < 3; spins++)

{

alert("Top is spinning!");

} tops = tops - 1;

Сколько раз на экране появится диалоговое окно alert с сообще­ нием "Top is spinning!"?

Фрагмент 3 for (var berries = 5; berries > 0; berries— ) { alert("Eating a berry");

Фрагмент 4

Сколько ягод вы съели?

for (scoops = 0; scoops < 10; scoop++)

^

{

alert("There1s more ice cream!");

} 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";

Принятие решений с использованием JavaScript Мы с вами иснользовали логические вы раж ения в онераторах for и while для н роверки условий с целью реш ить, долж но ли нродолж аться циклическое вы нолнение. Их также можно исноль­ зовать для н р и н яти я реш ений в JavaScript-коде. Рассмотрим нример: __

Вот наше логическое выражение, используемое для проверки прооерки количества оставшихся ---------- - • ложек мороженого.

if (scoops < 3) {

Когда останется менее трех ложек , мы будем выполнять соответствующий блок кода.

alert (нIce cream is running low!11) ;

} Мы также можем предусмотреть нроведение более чем одной нроверки: if (scoops < 3) { alert("Ice cream is running low!"); } else if (scoops > 9) {

Бы сможете добавить нужное количество проверок с использо­ ванием else if, каждая из которых будет ассоциирована со своим блоком кода> выполняемым , когда значением условия является true.

alert("Eat faster, the ice cream is going to melt!");

} дальше ►

83


javascript условия

Принятие дополнительных решений... и добавление перехватывающего блока Вы мож ете предусмотреть нерехваты ваю щ пй блок для своих он ераторов i f — ф иналь­ н ы й e l s e , которы й будет вынолняться, если все н рочи е условия окажутся оценены как f a l s e . Д авайте добавим еще несколько i f / e l s e , а также нерехваты ваю щ ий блок:

if if

Обратите внимание , что мы внесли изменение Т ~ > а к? то°Р °г0 соответствующее сообщение выведено только тогда , когда количество ложек окажется равным именно 3.

(scoo* s — з> t

(scoops — 3 ) { alert("Ice cream is running low!");

} else if (scoops > 9) { alert("Eat faster, the ice cream is going to melt!"); } else if (scoops == 2) {

Мы добавили дополнительные условия для того , чтобы обрат­ ный отсчет шел до нуля ложек.

alert("Going once!"); } else if (scoops =

1) {

alert("Going twice!"); } else if (scoops == 0) { alert("Gone!"); } else { alert("Still lots of ice cream left, come and get it.");

*

, A

„ „аш n e p e x f W ,

1 л о к есяи ш одно т ^ т Ш

^ тся.

/ ш.

пражнение

Возьмите приведенный выше код и вставьте его в цикл 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 )

{

Вставьте сюда код> приведенный вверху .

T

s c o o p s = s co o p s

a le r t( " lif e

84

глава 2

w it h o u t i c e

c re a m i s n ' t

th e s a m e " );

Генерируемый вывод напишите здесь.


javascript и dom

развлечения

с м а гн и т а м и

Данный код отображает известный палиндром в диалоговом окне a l e r t . Проблема заключа­ ется в том, что часть кода находилась на магнитных табличках, прикрепленных к холодильнику, однако они упали на пол. Ваша задача заключается в том, чтобы восстановить целостность кода и отобразить палиндром. Будьте внимательны, поскольку на полу уже лежало несколько табличек, не имеющих отношения к данному коду, зато некоторые из табличек вам придется использовать более одного раза! Проверьте свои ответы в конце данной главы, прежде чем двинетесь дальше.

var wordl

= "а”;

var word2

= "nam";

var word3

= "nal p M;

var word4

= "lan a c" ;

var word5

= "a man

h ttp ://Jo Ca lh o s t

a

a plan a canal panama.

ap" ;

Палиндром — это пред­ ложение, которое одина­ ково читается как слева направо; так и справа налево! Бот палиндром , который вы должны увидеть?, если правильно разместите все таблички на магнитах по м ест ам .

var phrase = MM;

for (var i = 0;

) {

if (i == 0) { phrase = _____

} else if (i == 1) { phrase = _____

+ word4;

} (i == 2) { = phrase + wordl + word3;

) { phrase = phrase +

+ word2 + wordl;

} alert(phrase);

else if (i == 0)

w ord5

i++

J

phrase

i < 3

word4

ГШ Л

I

else if

|^^Tord2

1 [Т Т 7 Г ) C D

Г 1- I

vro£ a i i = 3

] [

1 < 4

word3

дальше ►

85


как добавлять javascript в веб-страницы

Мне сказали, что мы будем добавлять JavaScript в свои веб-страницы. Когда мы, наконец, займемся этим? Или так и будем ходить вокруг да око­ ло, разбираясь в JavaScript?

Да, в ТОМ-ТО и дело. Для начала вам необ­ ходимо было изучить основы. Как раз этим мы и занимались до сих пор: теперь вы зна­ ете, как объявлять и использовать перем ен­ ные JavaScript, а также как осущ ествляется ф орм ирование базовых операторов и вы ра­ жений. Кроме того, вы узнали, как исполь­ зовать их все вместе для написания условно­ го кода с операторам и i f / e l s e , не говоря уже о циклическом вы полнении с прим ене­ нием операторов w h i l e и f o r . Вооружившись этими знаниями, теперь вы мож ете переходить к изучению того, как добавлять JavaScript в свои веб-страницы и, что более важно, как JavaScript взаимодей­ ствует с ними. То есть вы узнаете, как опре­ делять, что имеется на вашей странице, как ее изм енять и, чуть нозже, как нисать код, реагирую щ ий на то, что нроисходит на ва­ ших страницах. Таким образом, несм отря на то что мы еще не закончили с JavaScript, вашему ожида­ нию нриш ел конец. Настало врем я взгля­ нуть, как разм етка и новедение работаю т сообща...

86

глава 2


javascript и dom

Как u куда добавлять JavaScript в своих страницах Ч тобы иснользовать JavaScript, его необходимо добавить в страницу. Но куда именно и как? Вы уже знаете, что существует такой элемент, как < s c r i p t > , ноэтому давайте носмотрим, где мы можем ис­ нользовать его и как это влияет на вы нолнение JavaScript-кода на ваших страницах. Рассмотрим разны е снособы добавления кода в страницу.

Поместите элементы <scnpt> в <head> своей HTML-страницы, чтобы их выполнение осуществлялось до загрузки страницы. Вы можете внести т р е ­ буемый код прямо в код своей веб\ страницы либо внедрить ссылку на отдельный JavaS criptфайлj вос­ пользовавшись атрибутом scr тега script

Или вы м о ­ жете п о ­ местить свой код (либо ссылку на него) в элемент <body> Д а н ­ ный код будет выполняться , когда загру­ зится тело документа.

H T M L -файл | <head > <script> statement </script> I <script src="mycode.js"> 1</script>

<body> <script> statement statement </script>

■ Чаще

всего код добавляется в <Wead> страницы. Добавление кода в <body> страницы дает небольшие пре­ имущества в плане производительHocmuj однако поступать так следует только в т ом случае> если вам действительно необходимо сверхоптимизировать производи­ тельность своей страницы.

Разместите свой <script> как встроен­ ный элемент в <head>. Н аиболее расп р о стр ан ен н ы й снособ до­ бавления кода в страницу заклю чается в номещ ении элемента < s c r i p t > в <head> стр ан и ц ы . Если вы д о б ави те Jav a S c rip tкод в элемент <head>, то он будет выпол­ н ять ся, как только б раузер осущ ествит разбор < head> (а делает он это в нервую очередь!), но до того, как разбору подверг­ нется остальная часть страницы. Добавьте свой <script>, воспользо­ вавшись ссылкой на отдельный JavaScript-файл. Вы также можете указать ссылку на отдель­ ны й файл, содерж ащ ий JavaScript-код. П о­ местите URL-ссылку на файл в атрибут s c r откры ваю щ его тега < s c r i p t > и убеди­ тесь, что вы закры л и элем ен т s c r i p t с номощью < / s c r i p t > . Если вы указы ваете ссылку н а файл, располож енны й в том же каталоге, то мож ете нросто иснользовать имя этого файла. Добавьте свой код в элемент <body> документа либо как встроенный, либо посредством ссылки на отдельный файл. Кроме того, вы можете номестить свой код нрям о в < body> своей H TM L-страницы . Онять-таки, заключите свой JavaScript-код в элем ен т < s c r i p t > (или укаж ите ссыл­ ку н а отд ел ьн ы й ф ай л в атри буте s c r ) . JavaScript в <body> вашей страницы станет вынолняться, когда браузер будет осущест­ влять разбор тела страницы (обы чно он делает это сверху вниз). дальше ►

87


взаимодействие со страницей

Как JavaScript Взаимодействует с вашей страницей JavaScript и HTML— это две разные вещи. HTML представляет собой разметку, a JavaScript — код. Так как же заставить JavaScript взаимо­ действовать с разметкой на своей странице? Для этого необходимо воспользоваться объектной моделью документа (DOM).

о

Зам браузер

Л

При загрузке страницы в браузе­ ре он осуществляет разбор HTML и создает внутреннюю модель документа, которая будет содер­ жать все элементы вашей HTMLразметки.

html head |

title

|

Это мы называем объектной моделью документа (РОМ), посредством ко т о ­ рой можно узнать все о структуре и содержимом веб­ страницы.

body script

|| [

h2

О

Сокращенно мы также называем ее просто РОМ .

©

Когда JavaScript модифицирует объектную модель документа (DOM), браузер автоматически обновляет JavaScript страницу, благодаря чему на ней отобра­ жается новое содержимое.

Ваш JavaScript может взаимо­ действовать с объектной моде­ лью документа с целью полу­ чения доступа к элементам и их содержимому. JavaScript также использует DOM для создания или удаления элементов (и вы­ полнения множества других манипуляций, о которых мы по­ говорим позже).

П осредст вом счит ы вания, реагирования и и з м е н е н и я о б ь е к т н о й м о д е л и до

2 Т Г 1 JavaScHpt мож^ веб- r ! М На.писания интеРактивных -страниц/приложений. Из данной книги вы узнаете, как это делается

88

глава 2


javascript и dom

Рецепт приготовления собственной объектной модели документа (D 0 M ) Д авайте возьмем разметку и создадим для нее объектную модель документа (DOM ). Рецент здесь нрост. И н гр ед и ен ты

<! doctype html> <html lang="en"> <head> <title>My blog</title>

О дна норм альная НТМ Ьб-страница

<meta charset="utf-8"> <script src="blog. js"X/script> </head>

О дин веб-браузер или более

<body> <hl>My blog</hl>

Порядок д е й ств и й

<div id=Mentryl">

1. Сначала создайте узел d o c u m e n t, которы й будет рас­ полагаться в самом верху.

<h2>Great day bird watching</h2> <P> Today I saw three ducks!

document

I named them

2. Затем возьм ите элемент верхнего уровня вашей HTM L-страницы (в нашем случае это элемент < h tm l> ), которы й будет именоваться текущим элементом, и до­ бавьте его в качестве дочернего элем ента но отнош е­ нию к d o c u m e n t.

Huey, Louie, and Dewey. </p> <P> I took a couple of photos... </p> </div>

</body> </html>

document 1

html

j |

3. В случае с каждым элементом, влож енны м в текущий элемент, добавьте соответствую щ ий элемент в качестве дочернего но отнош ению к текущему в объектной моде­ ли документа (DOM). document html

head

j |

body

Мы заранее годность» приго­ товили для вас объектную мо­ дель документа. Переверните страницу - и вы увидите, как выглядит готовая D0M.

|

4. В ернитесь к каждому из только что добавленны х вами элементов и н овторяйте нроцедуру (шаг 3), нока не до­ бавите все необходимы е элементы.

дальше ►

89


внедрение объектной модели документа

Первое испытание объектной модели документа (D 0 M ) Вся прелесть объектпой модели докумепта заклю чается в том, что опа обеспе­ чивает для пас согласоваппый между всеми браузерами способ получепия досту­ па к структуре и содержимому HTM L из кода. И это здорово. А через песколько мгповепий мы с вами посмотрим, как все это работает... Верпемся к примеру. Если вы последуете приведеппому рапее рецепту приготов­ лен и я объектпой модели докумепта, то в результате у вас получится структура, изображ еппая чуть пиж е. Каждая DOM вклю чает объект docum ent, располага­ ю щ ийся вверху, после чего общее дерево дополпяю т ветви и узлы-«листья» для каждого элем епта в HTM L-разметке. Д авайте взгляпем па пих более пристальпо.

/

О бъект d o cu m en t — это словно корень перевернутого с ног на голову дерева.

Z l rn d Z

L

i=

:

Цемент а. ^

Эти объекты сродни л и ­ Great ст ьям на дереве (поскольку day bird внут ри них нет элем ент о в, watching а имеется только текст). Объектная модель документа включает содержимое ^ страницы, а также элементы (мы не всегда показываем текстовое содержимое, когда приводим рисунки РОМ, однако оно т а м п р и с у т с т в у е т ) . Теперь, когда у нас имеется объектная модель документа (DOM ), мы можем исследовать и изменять ее так, как нам потребуется.

90

глава 2

Мы сравнили данную с т р у к ­ т у р у с деревом, поскольку « д е ­ рево» — это ст руктура данных, которая берет свое начало в инф орм ат ике.

Эти объекты подобны вет вям дерева.

Today I saw three.. У

I took a couple of photos...


javascript и dom

’"-- -+Иhttp

Сlio-UXJ9^

Movie Showtimes Plan 9 from Outer Space Playing и З ЛОрт. 7:00pm. Spedal Д о И л * щ Д О и midnight!

Forbidden Planet

Playingat5Л0рсп.9:00pm.

СТАНЬ браумром

<! doctype html> <h tml 1ang=11en11>

p a llia ЗаД аЧ а З а к л ю ч а е т с я Б m °M ,

<head> Ч щ обы сы Г р а ш ь р°Л ь браузера.

<title>Movies</title> |) а М н е о б х о д и м 0 о с у щ е с т в и ш ь

</head> разбор

-р а З М е т К и и со з­

<body> д а ш ь Н а 00 оСНоВ0 c B o jo с ° ^ с ш Б 0 н —

<hl>Movie Showtimes</hl> HTJIO о £ Ь 01С щ н у 1о М °Д 0 Л ь Д°КХ)М0Н—

<h2 id=Mmovieln >Plan 9 from Outer Space</h2>

ФОМ)- П°э1Г,оМУ — вперед. произведите разбор т а

шмь

<p>Playing at 3:0 Орш , 7:0 0pm. <span>

К о то р ы й н ах о д и тся справа,

Special showing tonight at <em>midnight</em>!

-DO M

н а р и с у й т е В низу. Ц а Ч а Л о

</span>

о ^ Ь 0 К т н о й М °Д 0Л и Д о к у М 0 н т а М ы

</p> у Ж 0 н а р и с о В а Л и , а В аМ п р 0 Д с т ° и т 00 з а в е р ш и т ь .

<h2 id=nmovie2M>Forbidden Planet</h2> <p>Playing at 5:00pm, 9:00pm. </p> </body>

Проверьте свои о т в е т ы , посмотрев решение этого задания в конце главы, прежде чем двинетесь дальше.

</html>

|

docum ent

1 1

Д ор и су й т е здесь свою POM.

|

i

дальше ►

91


отношения между javascript и dom

Или история о том, как две абсолютно разные технологии смогли работать сообща.

P JTM L5 Q ja v a S c r ip 1 ' ,

Венеры т .1чесК ое Р Г ;

воде”

„ о у » 4* „v-wnr®1

HTML и JavaScript, несомненно, прилетели с двух разных планет. Доказательства? ДНК HTML состоит из декларативной разметки, позволяющей описывать набор вложенных элементов, входящих в состав веб-страницы. JavaScript, с другой стороны, сделан из чисто алгоритмического генетического материала, призванного описывать вычисления. Настолько ли они разные, что даже не способны взаи­ модействовать друг с другом? Конечно же, это не так, поскольку у них есть кое-что общее — объектная мо­ дель документа (DOM). Посредством DOM JavaScript может взаимодействовать с веб-страницами, и наобо­ рот. Существует несколько путей сделать так, чтобы это произошло, однако мы пока сконцентрируемся на одном из них— на своего рода небольшой червоточи­ не, позволяющей JavaScript получать доступ к любому элементу, и называется она getElementByld. Давайте посмотрим, как она работает...

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 > , одпако мы отбросили детали в целях простоты .

р id = "greenplanet"

j

р id = "redplanet"~|

Nothing to report

All is well

p id = "blueplanet"

All systems A-OK

Теиерь давайте задействуем 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 ocu m ent предст авляет всю страницу в браузере и целиком содержит объектную модель докум ент а, поэт ом у мы можем « п о п р о ­ с и т ь» его чт о-либо сделать: нап р и м ер , найти элем ент с определенным значением id.

Здесь мы просим d o c u m e n t о т ы ­ скать э л е м е н т , значение id к о т о ­ рого со о т вет ст в ует заданному.

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") возвра­ щ ает элем ен т <р>> значение id к о т о ­ рого с о о т в е т с т в у е т "greenplanet11...

•..после чего J a v a S crip t-код сможет сде­ л а т ь с ним много чего интересного.

дальше ►

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 на­ шего элемента planet для изменения содержимо­ го требуемого элемента.

7

Мы заменяем содержимое элемента greenplanet на наш новый текст... в результате чего объ­ ектная модель документа (и веб-страница) будет обновлена с использованием этого нового текста.

О свойствах элементов мы вскоре погорим подробнее...

|

р id =^ re e n p la n e t^ j| |

Red Alert: hit by phaser fire!

г

р id = V e d p la n e t“ ]

Nothing to report

|

р id = “blueplanet

All systems A-OK

Любые изменения в объектной модели документа отражаются на т о м j как браузер осуществляет рендеринг страницы , п о ­ этому вы увидите , что содержимое параграфа стало другим!

94

глава 2


Возьми в руку карандаш

javascript и dom

Вот объектная модель документа (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> <title>Planets</title>

Мы добавили JavaScript в <kead> страницы.

<meta charset="utf-8"> <script>

Точно т ак же, как и раньше, s r мы извлекаем элем ент <р> с id в виде "greenplanet" и и з ^ *меняем его содержимое.

var planet = document.getElementByld("greenplanet") planet.innerHTML = "Red Alert: hit by phaser fire!" </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

*■ -> с л Добавив требуемый код, загрузите страницу в сво­ ем браузере, после чего вы увидите, какие волшебпы е м етам орф озы произош ли с параграф ом, имею ­ щим id в виде g r e e n p l a n e t , в объектной модели докумепта (DOM). 01 Х ь ю с т о н , у нас проблема: в параграфе с id в виде, greenplanet по-преж нему отображается "All is well" 3 чем дело?

96

глава 2

О localhost/~Beth/HTML.. |Г| ф

G r e e n P la n e t АД is weH

R e d P la n e t Nothing to report

B lu e P la n e t All systems A-OK

Р , ^

^


javascript и dom

[

О

V

Я трижды перепроверил свою разметку и код, но все равно ничего не получается. Я не вижу ни­ каких изменений на своей странице

Ах да, мы забыли упомянуть об одной вещи. Чащ е всего имеет смысл начипать вы полпепие своего JavaScript-кода после того, как страпица полпостью за­ грузится. Почему? Если же вы пе стапете ждать, пока закончится загрузка страницы , объектпая модель до­ кумента не успеет полностью сгеперироваться, когда ваш код начнет выполняться. В пашем случае выпол­ нение JavaScript-кода начинается после того, как бра­ узер сначала загрузит элемент < h e a d > страпицы , по до того, как будет загружена остальпая часть страпицы , поэтому объектная модель докумепта окажется еще пе полностью сгенерированной. А если DOM пе готова, то и элемент <р i d = " g r e e n p l a n e t 11> пе будет суще­ ствовать! И что же тогда происходит? Вызов g e t E l e m e n t B y l d с целью поиска элем епта с i d в виде g r e e n p l a n e t пе приведет к возврату чего-либо, поскольку соответству­ ющ ий элемепт будет отсутствовать, из-за чего браузер просто продолж ит двигаться дальше и так или ипаче произведет репдерипг страпицы после того, как ваш код выполпится. П оэтому в результате вы увидите страпицу, прошедшую репдерипг, по текст в параграф е с i d в виде g r e e n p l a n e t остапется прежпим. Нам пеобходимо как-то сообщ ить браузеру следующее: «Выполпять мой код после того, как страпица полпо­ стью загрузится и будет создала объектпая модель до­ кумепта». П осмотрим, как это сделать.

дальше ►

97


ожидание загрузки страницы

Нельзя начинать взаимодействовать с D 0M , пока веб-страница не загрузилась полностью Но как приказать браузеру в ы п о л п я т ь ваш код только после того, как страпица загрузится? Ч тобы дать указапие браузеру ожидать, преж де чем пачипать вы полпепие кода, мы восполь­ зуемся двумя JavaScript-ипструмептами, с которы м и мы вас еще пе успели позпакомить: это объект window и фупкция. П одробпее о пих мы поговорим позже, а пока просто воспользуем­ ся ими, чтобы добиться пужпого эф ф екта. О бповите свой JavaScript, как показало пиж е Сначала создайте ф у н к ц и ю с именем init и п о м ест ит е в нее уже имеющийся у вас код. <script> function init()

{

var planet = document.getElementByld ("greenplanet")

О б ра т ит е внимание на то, что ваш код должен располагаться между открывающей и закрывающей ф и г у р ­ ными скобками.

p l a n e t .innerHTML = "Red Alert: hit b y phaser fire!"

.

я --------------------------------------------------------------------------------

window.onload = init;

< /s c rip t>

Здесь мы задаем значение свойства window.onload в виде имени нашей функции.

Здесь говорится: «когда страница полност ью з а ­ грузится, выполнить код, Перезагрузите страницу располагающийся в init». Теперь перезагрузите страпицу и посм отрите, все ли встало па свои места: ООО

PEanets

I< |► 1|+ |0 http:f/localhosl/-BethyHead- (5 ](От Google

G re e n P la n e t

")»

Да! Теперь в элемент е <р> с id в виде greenplanet отобразилось новое содер­ жимое. Здорово, не правда ли?

Red Alert: hit by phaser fire!

R e d P la n e t Nothing to report

B lu e P la n e t All systems A-OK

98

глава 2

Что ж, на самом деле здорово ТО, что т еперь вы знаете, как п р и к а ­ зат ь браузеру ждать, пока не будет полност ью сгенерирована объектная модель документа, прежде чем вы­ полнят ь код, который обращается к элементам.


javascript и dom

Возьми в руку карандаш <! doctype html>

/г*

HTML для веб-страницы.

<html lang=nen"> <head>

Ниже приведена HTML-разметка веб-страницы My Playlist, на ко­ торой отображается список песен для воспроизведения (плей­ лист), однако он пока пуст. Вам нужно завершить JavaScriptкод, чтобы песни добавились в список. Заполните пробелы в JavaScript-коде, который необходим для выполнения данной задачи. Проверьте свои ответы, посмотрев решение этого за­ дания в конце главы, прежде чем двинетесь дальше.

<title>My Playlist</title>

Это наш J a v a S crip t Данный код б у ­ дет обеспечивать заполнение списка песнями, указанными внизу, в <ul>.

<meta charset="utf-811> <script> ____________ addSongs()

{

Заполнит е пробелы недоста­ ю щ им кодом, чтобы песни были добавлены в список.

var songl = document.__

<" .getElementByld (11

.innerHTML

J

”)

"Blue Suede Strings, by Elvis Pagely"; "Great Objects on Fire, by Jerry JSON Lewis";

song3.

"I Code the Line, by Johnny JavaScript";

window. </script> </head> <body> <hl>My awesome playlist</hl> <ul id="playlist"> <li id=" songl"X/li> <li id=" song2"X/li>

Пустой список песен. Приведенный чут ь выше код должен добавлять содержимое в каждый <li> плейлиста.

<li id=" song3"X/li>

—Г______MvP(aytlst____

</ ul >

.1--1-->' + llTtP:/i,|ocalho5t/-Beth/Head- (TL/CW1

</body> </html>

M y awesome playlist Вели вы корректно заполнит е пробе­ лы в Ja vaS cript-коде, то веб-страница после загрузки будет выглядеть так.

* B lue Suede Strings, by E lvis Pagely • Great Objects on Fire, by Jerry JSON Lewis Code the Line, by Johnny JavaScript

дальше ►

99


функциональность dom

Для чего еще хорошо nogxogum D0M О бъектпая модель докумепта (DOM) позволяет делать пампого больше, чем мы видели до сих пор, и вы будете использовать ее фупкциопальпость далее в процессе чтеп ия кпиги, а пока давайте просто выполпим краткий обзор, чтобы эти сведепия отложились у вас в подсозпапии. И щ ит е и извле­ кайте один э л е ­ мент или более из объектной м о ­ дели документа.

Извлекайте элементы из объектной моде­ ли документа. fo rm

V iV y j |

input

label lab

Создавайте новые эле менты.. III

...и добавляйте их в РОМ п у ­ т е м присоеди нения к друго­ м у элем ент у в дереве. Удаляйте существу ющие э л е ­ менты.

Получайте до­ ст уп и н а с т р а иваите а т р и б у ­ ты э л ем е н т о в, наприм ер id или class.

100

глава 2

^

input

Конечно, вы уже знаете, что это можно делать, поскольку мы с вами использовали d o c u m e n t . g e t E l e m e n t B y l d . Однако существуют и другие способы извлечения элементов. Вы можете ис­ пользовать имена тегов, имена классов и атри­ буты для извлечения не только какого-то одного элемента, а целого набора элементов (например, всех элементов, имеющихся в классе " o n _ s a le " ) . Кроме того, вы можете извлекать значения фор­ мы, введенные пользователем (например, текст элемента ввода).

Создавайте и добавляйте элементы в объ­ ектную модель документа. Вы можете создавать новые элементы и добав­ лять их в DOM. Естественно, любые изменения, вносимые вами в объектную модель докумен­ та, будут незамедлительно проявляться по мере того, как браузер будет осуществлять ее ренде­ ринг (что просто замечательно!).

Удаляйте элементы из объектной модели документа. Вы также можете удалять элементы из DOM, для чего необходимо взять родительский элемент и удалить какой-либо из его дочерних элементов. Опять-таки, в окне браузера вы увидите, что эле­ мент удален, как только он будет убран из объ­ ектной модели документа.

Извлекайте и настраивайте атрибуты эле­ ментов. Ранее мы с вами получали доступ только к тек­ стовому содержимому элементов, однако вы также можете получить доступ к их атрибутам. Например, вам может потребоваться узнать, каков класс конкретного элемента, а затем «на лету» изменить класс его принадлежности.


javascript и dom

Нельзя ли снова поговорить о JavaScript, или как осуществляется сохранение множественных значений при использовании JavaScript Мы уже достаточпо поговорили о JavaScript и объектпой модели докумепта (DOM). П режде чем дать вам пемпого отдохпуть и расслабиться, мы хотим рассказать еще об од пом JavaScript-типе, которы й вы будете постояппо использовать. Это массив (A r r a y ). Допустим, вам пеобходимо сохрапить пазвапия 32 сортов м орож епого, или пом ера всех элемептов в электроп пой корзипе вашего пользователя, или, возможпо, почасовы е показатели уличпой температуры. Ч тобы сделать это с использованием просты х перем еппы х, потребуется масса времепи, особеппо если пужпо сохрапить десятки, сотпи или ты сячи зпачепий. К счастью, существует массив, которы й пас выручит. Вы можете добавМассив содержит к о л S л ят ь значения в массив лекцию значений. \ у /. по м ере необходимости.

Каждое значение им е ет индексный номер j при эт о м нумерация начи­ нается с нуля.

Д ля каждого индекса в массиве имеется соот вет ст вую щ ее значение.

Как создать массив Ч тобы использовать массив, его спачала пужпо создать, а также п рисвоить этот массив перемеппой, чтобы у пас было печто такое, посредством чего мы будем ссылаться па пего в своем коде. Д авайте создадим массив вроде того, которы й показап выше и содерж ит почасовы е показатели температуры (по Ф арепгейту): ^ -создание нового пустого Наша п ер е м е н массива ная для массива... ^ >t ^ Мы вернемся к эт о м у синтаксису , _ _ _ . в главе 4, а пока просто з н а й т е J, var tempByHour = new Array () ; r что он создает новый массив. tempByHour [0 ] = 59.2;

tempByHour [2 ]

6 0 .1 ; б3.

tempByHour [3 ]

65;

tempByHour [4 ]

62;

tempByHour [1 ]

* Индекс

Д ля добавления новых значений в массив мы просто ссылаемся на индексный номер э л е ­ м ент а массива и присваиваем ем у значение.

4-

— Как и в случае с переменными JavaScript, вы можете присвоить любое значение (или т и п значения) индексу массива.

JavaScript предусматривает также более бы стры й способ создапия и инициализации массива (мы пазы ваем его «литеральпым масси­ вом») с использованием зпачепий: Данный код создает т о т же массив, Т У тт гсго о сг\ л съ ЧИЛ0 и ко^> приведенный чут ь выше, var tempByHour = [59.2, 60.1, 63, 65, 62]; х 1 т однако им еет меньший объем. дальше ►

101


использование массива

Добавление нового элементе в массив Вы сможете в лю бой м омепт добавить повы й элемепт в свой массив, просто используя следующий п езап яты й ипдекс: tempByHour[5] = 61 ;

А

Используя новый порядковый индекс, мы добавляем новый элем ент в массив.

использование элементов своего массива Javascript Alert

Вы мож ете извлечь зпачепие элем епта массива путем ссылки па перемеппую массива с использованием ипдекса:

Th« tem perature at 5 was 61

var message = "The temperature at 5 was " + tempByHour[5]; alert (message) ;

yj'V

Д ля доступа к значению т е м пер ат у р ы с индексом S мы просто ссылаемся на массив с индексом 5. Знайте размер своего массива, иначе... Вы мож ете легко узпать разм ер своего массива путем ссылки па свойство массива, пазы ваемое l e n g t h : Подробнее о свойствах мы поговорим var numlterns = tempByHour.length;

~

в следующей главе, а пока просто зн а й т е , Что каждый массив обладает свойством length, которое позволяет узнат ь количество элементов в нем .

Теперь, когда вы уже зпаете, как вы яспить длипу массива, да­ вайте посмотрим, можпо ли объедипить ваши зпапия о циклах с массивами...

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. if (i ==

(id) ;

) {

li. else { l i .innerHTML

= "The temperature at noon was " + theTemp; "The temperature at " + ______

+ " was " + ___

} } window.onload = showTemps; </script> </head> <body> <hl>Temperatures</hl> <ul> <li id=" tempO"X/li> <li id=" tempi"X/li> <li id=" temp2"X/li> <li id=" temp3"X/li> <li id=" temp4"X/li> </ul> </body> </html>

К odj приведенный выше, будет з а п о л ­ нять каждый элем ент списка содержимым в виде фразы, вклю ча ­ ющей словосочетание The tem p e ra tu re at...

оОо

Temperatures • The temperature at noon was 59 2

• The temperature at 1 was 60.1 • The temperature at 2 was 63

• The temperature at 3 was 65 • The temperature at 4 was 62

дальше ►

103


пример приложения phrase-o-matic

Изучите данный код новенького приложения Phrase- о -Mat! с и п о ­ см о т р и т е, сможете ли вы п оня т ь, что он делает , прежде чем двинетесь дальше...

Испробуйте наше новое приложение Phrase-o-Matic, и вы превратитесь в блестяще­ го оратора, как ваш босс или ребята из отдела маркетинга.

<! doctype html> <html lang="en"> <head> <title>Phrase-o-matic</title> <meta charset=Mutf-8M> <style> body { font-family: Verdana, Helvetica, sans-serif;

</style> <script>

Вам показалось, что наше серьезное бизнес-приложение из главы 1 было недостаточно серьезным? Ладно. Тогда воспользуйтесь тем, которое приведено здесь, если вам нужно что-то показать боссу.

function makePhrases() { var wordsl = ["24/7", "multi-Tier", "30,000 foot", "B-to- I" , "win-win"]; var words2 = ["empowered", "value-added", "oriented", "focused", "aligned"]; var words3 = ["process", "solution", "tipping-point", "strategy", "vision"]; var randl = Math, floor (Math, random() * wordsl.length); var rand2 = Math, floor (Math, random() *

words2 .length) ;

var rand3 = Math, floor (Math, random() *

words3 .length) ;

var phrase = wordsl[randl] + " " + words2[rand2] + " " + words3[rand3]; var phraseElement = document.getElementByld("phrase"); phraseElement.innerHTML = phrase;

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 дней в неделю»), и мы очень надеемся, что и будущие слоганы окажутся не хуже. Д авайте но смотрим, как он работает. Сначала мы онределяем функцию makePhrases, которая будет вы нолняться носле нолной загрузки страницы , благодаря чему мы знаем, что сможем благонолучно но лучить достун к объектной модели документа (DOM): ^

Мы определяем функцию с именем makePhrases, кот орую будем вызывать позже.

function makePhrases() {

}

? г+г \

Весь код для makePhrases будет размещ ат ься здесь, и до него мы дойдем через несколько мгновений...

window.onload = makePhrases;

выполнять makePhrases, как только закончится загрузка страницы.

Вынолнив нредыдущий шаг, мы можем нристунать к нанисанию кода для функции makePhrases. Н ачнем с создания трех массивов. Каждый из них будет содержать слова, которы е мы станем иснользовать для ген ери рован ия фраз. Мы нрим еним бы стры й снособ создания этих массивов: Мы создаем переменную с именем w o r d s l, кот орую ^ с м о ж е м использовать для ссылки на первый массив■ var wordsl = ["24/7", "multi-Tier", "30,000 foot", "B-to-B", "win-win"];

^

Помещаем пят ь ст рок в массив. Но вы свободно можете —" зам енит ь их какими-нибудь модными звучными словами.

var words2 = ["empowered", "value-added", "oriented", "focused", "aligned"] var words3 = ["process", "solution", "tipping-point", "strategy", "vision"]

Здесь вы можете видеть два дополнительных массива, присвоенных двум новым переменным с именами wordsZ и words3.

дальше ►

105


как работает phrase-o-matic

( 3 ) И так, у нас есть три новы х массива, содержащ их красивы е звучные слова. Тенерь мы будем осуществлять случайную выборку но слову из каждого массива, которы е затем объединим в одну фразу. Вот как п роизводится вы борка но одному слову из каждого массива: Мы генерируем по одному случайному числу для каждого массива и присваиваем его новой переменной ( r a n d l , r a n d z и rand3 с о о т ­ ветственно). var randl

=Math, floor (Math, random() * wordsl.length) ;

var rand2

=Math, floor (Math, random() * words2 .length) ;

var rand3

=Math, floor (Math, random() * words3 .length) ;

Данный код генерирует случайное число исходя из количества элементов в каждом массиве (в нашем случае их п ят ь, однако вы свободно можете добавлять элементы в любой массив, и код по-преж нему сможет генери­ роват ь числа, беря за основу уже новое количество элементов). ^

Тенерь сформируем отличны й м аркетинговы й слоган, для чего возьмем все слу­ чайно вы бранны е слова и конкатенируем их друг с другом в одну фразу, разделив нробелами для удобочитаемости: Мы определяем еще одну переменную для размещения фразы.

Каждое случайное число мы используе м как индекс в массивах слов...

var phrase = wordsl[randl] + " " + words2[rand2] + " " + words3[rand3];

Мы но чти нодош ли к финалу: у нас есть фраза, которую тенерь необходимо отобразить. Вы уже знаете, как мы будем действовать: нрим еним g e tE le m e n tB y ld для ноиска нашего элем ента <р>, а затем иснользуем его свойство innerHTM L для того, чтобы номестить в него новую фразу ^ var phraseElement = document.getElementByld ( "phrase") ; phraseElement.innerHTML = phrase;

З а т е м задаем нашу фразу в качестве содержимого элем ент а <р>.

106

глава 2

Извлекаем элем ент <р> с id в виде "phrase".


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

t

Простая перезагрузка страницы открывает перед вами возможноеv почти бесконечного генерирования все новых фраз. Незамысловатый код позволяет делать интересные вещи! Част®

....................

^аД аВ аеМ ы е

................................................................

В опросы Что именно представляет собой Math и что делают Math.random и Math, floor?

Q ; В отличном справочнике по JavaScript под авторством Дэвида Флэнагана «JavaScript. Подробное руководство»

0

(JavaScript: The Definitive Guide).

undefined, являющееся значением пере­

0 : Ma t h — это встроенная JavaScriptбиблиотека, содержащая набор математи­ Ранее вы отмечали, что примитивы ческих функций. Math, random генери­ (значения number, string и boolean) можно рует случайное число в промежутке между сохранять в переменных или объектах. О и 1. Мы умножаем его на количество Но мы сохраняем массивы в перемен­ элементов в массиве (которое извлекаем ных. Так чем является массив: прими­ посредством свойства length массива), тивом или объектом? чтобы получить число в промежутке между О и значением length массива. В резуль­ Отличный вопрос! Массив — это тате, скорее всего, получится число с плава­ особый род объекта, который встроен в ющей точкой (например, 3 .2 ), поэтому мы JavaScript. Особый он потому, что его мож­ применяем Math, floor, чтобы получить но использовать для доступа к значениям, целое число, которое сможем использовать располагающимся в массиве, чего нельзя в качестве индекса в массиве для выборки сделать с помощью остальных объектов случайного слова. Все, что делает M a t h . (немассивов) или объектов, которые вы соз­ floor, — это отбрасывает цифры, идущие даете сами. О создании своих собственных после знака десятичной дроби в числах объектов мы поговорим в главе 4. с плавающей точкой. Например, Math, floor (3.2) возвращает результат 3. Что будет, если я попытаюсь полу­

0 : °'

Где можно найти документацию к Math?

в myWords, а я при этом попытался бы получить доступ KmyWords[10].

чить доступ к индексу массива, кото­ рый не существует? Например, если бы у меня было пять сохраненных слов

I

Будет возвращено значение

менной, которой еще не было присвоено некое значение. Можно ли удалить элемент из мас­ сива? Если да, то что в таком случае про­ изойдет с индексами других элементов? Q j Удалить элемент из массива можно двумя разными способами. Вы можете за­ дать значение для массива с соответству­ ющим индексом в виде null (например, myArray [2] = null). Однако это бу­ дет означать, что длина массива останется прежней. Либо вы можете удалить требуе­ мый элемент полностью (с помощью функ­ ции splice). В данном случае индексы элементов, идущих после удаленного вами элемента, сдвинутся вниз на единицу. Таким образом, если myArray [2 ] = "dog" и myArray [3] = "cat", а вы удалите "dog", то myArray [2] = " с а ^ ’,адлина вашего массива станет короче на единицу.

дальше ►

107


Изучение языка является непро­ стой задачей, и важно, чтобы ваш мозг не только трудился, но и отдыхал. Поэтому, закончив читать данную главу, устройте себе передышку, перекусите немного и, прежде чем перейти к следующей главе, ознакомь­ тесь с рубрикой «Ключевые моменты» и ре­ шите кроссворд, чтобы закрепить изучен­ ный материал. '

о

'■ 3

Мы еще не научились преобразовывать цифровые изображе­ ния с едой в нечто вещественное, т ак что вам самим п р и ­ дется позаботиться о закусках.

108

глава 2


javascript и dom

кл ю ч евы е

МОМЕНТЫ Объявлять JavaScript-переменную необходимо с ис­

Сделать свои веб-страницы интерактивными можно

пользованием var.

путем исследования и изменения DOM с использова­

boolean, n u m b e r и s t r i n g — это примитивные типы. Логическими значениями являются tr u e и false.

нием JavaScript. Для получения доступа к требуемому элементу на своей веб-странице необходимо воспользоваться

d o c u m e n t .g e t E l e m entByld. Числовыми значениями могут быть целочисленные величины или числа с плавающей точкой.

d o c u m e n t .g e t E l e m e n t B y l d использует зна­ чение i d элемента для поиска этого элемента в объ­

Неинициализированная переменная имеет значение

ектной модели документа.

undefined. Для изменения содержимого элемента следует ис­

u n d e f i n e d и n u l l — это два разных значения.

пользовать свойство i n n e r H T M L этого элемента.

Первое означает, что переменной еще не было при­ своено значение, a null — что переменная имеет зна­ чение, под которым подразумевается «значения нет».

Если вы попытаетесь получить доступ или изменить элементы до того, как веб-страница полностью за­ грузится, появится сообщение об ошибке JavaScript

Результатом оценки числовых, логических и строковых

и ваш код не сработает.

выражений будут соответственно числовые, логиче­ ские и строковые значения.

Присвойте функцию свойству w i n d o w , onload, чтобы выполнение кода, имеющегося в этой функции,

Для повторяющегося выполнения блоков кода следует

осуществлялось после того, как браузер завершит за­

использовать цикл while.

грузку веб-страницы.

Циклы for и w h i l e позволяют выполнять одни и

Используйте массив для сохранения более одного

те же действия; используйте тот из них, который наи­

значения.

лучшим образом подходит в вашей ситуации. Для доступа к значению в массиве необходимо исполь­ Чтобы выполнение цикла f o r или w h i l e завер­

зовать индекс. Индекс — это целое число, означающее

шилось, проверка условия в некий момент должна

позицию элемента в массиве (нумерация при этом

выдать false.

начинается с нуля).

Операторы i f / e l s e могут использоваться для при­

Свойство l e n g t h массива позволяет узнать количе­

нятия решений в зависимости от результатов проверок

ство элементов в массиве.

условий. Комбинируя циклы и массивы, вы сможете последова­ Проверки условий являются логическими выражени­

тельно получать доступ к каждому элементу массива.

ями.

M a t h — это JavaScript-библиотека, включающая набор Вы можете добавлять JavaScript-код в < h e a d > или

математических функций.

< b o d y > своей веб-страницы либо размещать его в отдельном файле, внедрив ссылку на него в страницу.

M a t h . r a n d o m возвращает число с плавающей точкой в промежутке между 0 и 1 (но никогда ровно 1).

JavaScript-код (или ссылку на него) необходимо за­ ключать в элемент <script>.

M a t h .floor преобразует число с плавающей точкой в целое число, отбрасывая все цифры, идущие после

Когда браузер загружает веб-страницу, он создает

знака десятичной дроби.

объектную модель документа (DOM), которая является внутренним представлением этой веб-страницы.

дальше ►

109


кроссворд

U IM L 5 -K f° < r B ° fA Настало врем я заставить ноработать левое нолуш арие вашего мозга нутем реш ения кроссворда. Удачи!

По горизонтали

По вертикали

Если написать 3 + 11stooges11, то JavaScript осуществит_______ 3 в строку. 4 . _________используется для извлечения значения из массива. 5. 5 < 1 0 — э т о ____________ выражение. 7. Вы можете добавлять свой JavaScript-код в ____________ или body HTML-документа. 8. Количество элементов в массиве можно узнать с помощью свойства

I. Объектная модель документа (DOM) — это внутреннее представление веб-___________ . 3. Браузер созд ает_______________________ документа при загрузке страницы. 6. Добавьте его в свои веб-страницы, чтобы сделать их интерактивными. 9. Значение id элемента <р>, содержащего текст 11Red Alert : hit

2.

Имена переменных могут начинаться с _________ , знака $ или символа подчеркивания. 12. Выбирайте подходящие имена для переменных и используйте стиль для указания имен, состоящих из нескольких слов. 13 . __________ — это корень дерева DOM. 16. Повторяйте выполнение одних и тех же блоков кода посредством цикла___________ .. 17. В JavaScript document.____________ позволяет извлечь требуемый элемент из объектной модели документа (DOM). _

10.

19. Сохраняйте названия сортов мороженого все вместе в одном

110

глава 2

.

by phaser fire!11. I I . Заключайте свой JavaScript-код в тег <___________ >, если помещае­ те его в HTML-страницу. 14. Если вы почти закончили, то выпейте чаю, а если, как в условии ___________ , конец работы еще не близок, продолжайте дальше! 15. Циклы while и for используют____________выражение в качестве проверки условия. 18. С ___________нельзя начинать взаимодействовать, пока страница не загрузилась полностью.


javascript и dom

гпражнение решение

Возьми в руку карандаш_ Решение

Выразите себя! Ранее вы познакомились с различными типа­ ми выражений, которые можно использовать в JavaScript-коде. Теперь пора применить эти знания на практике и самим оценить несколько выражений. Приведем решение этого задания.

(9/5)

* tempC + 32

Каким окажется результат, если значением tem pc будет

ю?

5 0 ___

Взяв за основу свои текущ ие зна­ ния о переменных, выражениях и операторах JavaScript, посмотрите, сможете ли вы сказать, какие из этих операторов являются допустимыми, а какие приведут к выводу ошибки. В приведенном ниже перечне обве­ дите допустимые операторы.

(^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 будет 10?

true

А каким окажется результат, если значением l e v e l будет

^

/ var п ____

>= означает «больше либо равно»

3 - "one"

Технически данный оператор является допустимым, однако получаемое в результате зна­ чение нельзя использовать.

color != "pink" Каким окажется результат, если значением c o l o r будет b lu e ?

^ color «не равен» pink

(Svar

t

"one" + 11tw o j^

var Зро =

t r u e ;

недопусти­ мый!

(2 * Math.PI) * г Каким окажется результат, если значением г будет 3? 3 - 8 . 8 4 ___

с

Math.Pi возвращает значение пи (оно, как вы зна е т е, равно 3,14...)

С.Приблизительно!

у ; недопустимый.

Так выражаться не ст оит!

дальше ►

111


решение упражнения

СТАНЬ б р а у к р е м . Р еш ение }(аж Д ы й u s ИриБеДенньхХ на э т о й ст р а н и ц е J a V a ^ c r ip t—ф р а Щ е н т ° В

п р е д с т а в л я е т

собой

Фрагмент 1 о щ -

ДеЛьНый ёлок К°Да. ^аШ а заДаЧа З ак л ю ч ается

var count = 0;

В т °М , Ч т °£ ы С ы Грать р»Ль браузера ^

for

и оДенищь Бее ф р а г м е н т ы К°Да

(var i = 0; i < 5; i++)

{

count = count + i ;

ДЛЯ- о т Б е т а на Вопросы о резуЛь—

}

т а m ax, Ц апиШ ите сВой о т В е т

alert (’’count is ” + count);

на к а ж д ы й Вопрос ц 0д с о о т в е т ­

Какой показатель общего количества бу­ дет отображен в диалоговом окне alert

р

ствующим ^раГМенщоМ

Фрагмент 2

го f

var tops = 5; while (tops > 0 )

{

>

for (var spins = 0; spins < 3; spins++)

J

alert("Top is spinning!”);

3-5*

Внешний цикл while выполняется п ят ь р а з, а внутренний цикл for — } т р и раза при каждом выполнении внешнего цикла, п оэт о м у по луч а ­ & ется 5 * Ъ, или И5!

V

«г

л

/

Сколько раз на экране появится диалоговое окно alert с сообще­ нием "Top is spinning!"?

Фрагмент 3

Здесь мы начинаем с 5 и выполняем цикл до тех пор пока количество ягод не станет равным О ведя от ­ счет в убывающем порядке при каж­ дом заходе (а не в возрастающем). Фрагмент 4

,

При каждом выполнении цикла мы добавляем значение i к п о с п казат елю общего количества> а значение i все время ув ел и ч и ­ вается} по эт ом у при каждом выполнении цикла мы добавля­ ем к показат елю общего к о л и -

,

for

(var berries = 5; berries > 0; berries-

-) {

alert("Eating a be r r y ”);

Сколько ягод вы съели?

for (scoops = 0; scoops < 10; scoop++)

$

{

a l e r t ("T h e r e 's more ice cream!”),

} alert("life without ice cream i s n ’t the same");

ХО 112

глава 2

Здесь все просто: цикл вы ­ полняется Ю р а зj поэт ом у вы съели Ю ложек!

Сколько ложек мороженого вы съели?


javascript и dom

Пражнение решение

Возьмите приведенный выше код и вставьте его в цикл w h i l e внизу. Пройдитесь по циклу w h i l e и напишите сообщения диалоговых окон a l e r t в той последова­ тельности, в которой они будут выводиться. Вот наше решение этого задания.

var scoops = 10; while (scoops >= 0) { if (scoops = 3) {

в с т а в л е н н ы й ко д

p

л * /пт л 1 ,,^ alert("Ice cream is running low!"); ,} else n ox г{ if ^ (scoops ^ > 9)

Это сообщение выводится один р а з , когда 3. K U C °значение scoops 1 равно '

alert (--Eat faster, the ice cream is going to melt!--) ;

Это тоже выводится один р а зj когда значены£ scoops р а в т m

} else if (scoops == 2) { alert ( "Going once!") ;

} else if (scoops == 1) { alert ("Going twice!") ; } else if (scoops == 0) { alert("Gone!");

}

else {

%— Каждое из этиК сообщений выводится ^ - один раз, когда значение scoops равно с о о т в е т с т в е н н о 7-, 3- и O. А это выводится всякий р а з, когда ни одно из п р о ­ чих условий не и м е ет значения true, то есть когда значение scoops равно Я, 8, 7, (о, 5 и 4.

alert("Still lots of ice cream left, come and get it.");

} scoops = scoops

- 1;

вычитаем no одной ложке при каждом выполнении цикла.

alert ("Life without ice cream isn't the same.") ;

I \r t\

Это сообщение выводится, когда в„ лолнение цикла завершено.

Eat faster , the ice cream is going to melt! Still lots of ice cream left, come and get it Still lots of ice cream left, come and get it Still lots of ice cream left, come and get it Still lots of ice cream left, come and get it Still lots of ice cream left, come and get it Still lots of ice cream left, come and get it Ice cream is running low! Going once! Going twice! Gone! Life without ice cream isn't the same.

дальше ►

113


решение упражнения

развлечения

с м а гн и т а м и ,

реш ение

Данный код отображает известный палиндром в диалоговом окне a l e r t . Проблема заключа­ ется в том, что часть кода находилась на магнитных табличках, прикрепленных к холодильнику, однако они упали на пол. Ваша задача заключается в том, чтобы восстановить целостность кода и отобразить палиндром. Будьте внимательны, поскольку на полу уже лежало несколько табличек, не имеющих отношения к данному коду, зато некоторые из табличек вам придется использовать более одного раза! Приведем решение этого задания.

var wordl

= "а";

var word2

= "nam";

var word3

= "nal p " ;

Jf-

h ttP ' / / b c a lh o s t 3 man a P,an a canal panama

var word4

= "lan ac";

var word5

= "a man a p " ;

var phrase = "";

) {

} else if (i == 1) {

+ word4;

phrase =

J else if i -phrase J

(

Палиндром — это предложе­ ние, которое одинаково ч и т а ­ ется как слева направо, т ак и справа налево! Вот палиндром, который вы должны увидеть, если правильно р а зм е ст и т е все таблички на магнитах по м ест ам.

= phrase + wordl + word3;

else if l( I i == 3 phrase = phrase +

} alert(phrase);

114

глава 2

+ word2 + wordl;


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> <title>Movies</title>

jjaiHa ЗаДаЧа З а к л ю ч а е т ­ ся Б т °М , Ч т °^ ы с ы Г р а т ь роЛь браузера. ^аМ необхо­

</head> <body> <hl>Movie Showtimes</hl>

димо о с у щ е с т в и т ь р азбор

ЩЩ-раЗМешКи и создать

<h2 id="moviel" >Plan 9 from Outer Space</h2>

на ее °сноВе сВок» собственную

<p>Playing at 3:0 0pm, 7:0 0pm.

объектную Модель документа

ФОМ)- Поэвдому сначала про­ изведите разбор HTML’ к°щ орый находится справа, а

D0M

нарисуйте Внизу. ЦаЧаЛ© объектной м°дели документа Мы уже нарисовали, а ВаМ предстоит ее завершить.

<span> Special showing tonight at <em>midnight</em>! </span> </p> <h2 id=nmovie2M>Forbidden Planet</h2> <p>Playing at 5:00pm, 9:00pm.</p> </body> </html>

дальше ►

115


решение упражнения

- Возьми в руку карандаш Решение

ООО

Ниже приведена HTML-разметка веб-страницы My Playlist, на которой отображается список песен для воспроизведе­ ния (плейлист), однако пока он пуст. Вам нужно завершить JavaScript-код, чтобы песни добавились в список. Вот наше решение этого задания.

My Playlist

My awesome playlist • Blue Suede Strings, by Elvis Pagely ♦ Great Objects on Fire, by Jerry JSON Lewis * Code the Line, by Johnny JavaScript

<!doctype html>

г

<html lang="en"> <head>

Если вы корректно заполнит е пробелы в Jav a S crip t-коде, то веб-страница после загрузки будет выглядеть? так.

<title>My Playlist</title> <meta charset=Mutf-8M> <script> fu n c tio n

addSongs() {

var songl = document. t f C t E l e w e n t S y l d var s o n q Z =

К од, благодаря к о т о ­ р о м у будет заполнен наш плейлист.

)

d o c u m e n t . q e t E l e m e n t f t c j l d (" s>ongZ

var S 0 n q 3 = d p C U l^ C n t

SOntj3-

(" SOnq^L

•getElementByld (11 S0nCj3 ")

.innerHTML = "Blue Suede Strings, by Elvis Pagely";

SOnqZ. in n er HTML = "Great Objects on Fire, by Jerry JSON Lewis"; song3. innerH TM L

= 111 Code the Line, by Johnny JavaScript";

} window,

o n lo a d

=

addSongs

</script>

Вы можете свободно подставить? сюда названия своих любимых песен!

</head> <body> <hl>My awesome playlist</hl> <ul id="playlist"> <li id="songl"X/li> <li id="song2"></li> <li id="song3"></li> </ ul> </body> </html>

116

глава 2

Приведенный чут ь выше код зада­ ет содержимое для этих э л ем е н ­ тов <И> п у т е м извлечения каждого элем ент а из РОМ и присваивания свойству innerHTML значения в виде названия соот вет ст вую щ ей песни.


javascript и dom

^Возьми в руку карандаш Решение <! doctype html> <html lang="en"> <head> <title>Temperatures</title> <meta charset="utf-8"> <script> function showTentps() { var tempByHour = new tempByHour[0] =

5 9 .2 ;

tempByHour[1] =

6 0 .1 ;

tempByHour[2] =

63;

tempByHour[3] =

65;

tempByHour[4] =

62;

for (var i = 0; i < var theTenrp = var id = "

Внизу вы найдете веб-страницу со списком пустых элементов, гото­ вых к тому, чтобы ваш JavaScript заполнил их температурными пока­ зателями. Мы привели большую часть кода; вам необходимо устра­ нить имеющиеся в нем пробелы, чтобы он смог задать содержимое для каждого элемента списка в виде соответствующего показателя температуры из массива. Рассмотрим решение этого задания.

Создаем новый массив для р а зм е щ е­ ния т ем п ера т ур ны х показателей.

A rratfQ

tempByHour.lengtW . J+ + _ )

{<

t e m p B y H o u r [i] ; + i;

temp

var li = document. g e t E l e m e n t B y l d if (i ==

Комбинируем циклы и м а с ­ сивы. О б р ат и т е внимание на то, что мы используем значение i в качестве индекса в массиве, поэт ом у получаем доступ к каждому элем ент у по мере т ого, как значение i увеличивается при каждом выполнении цикла.

о

(id) ;

) {

li. in n e rH T M L

= "The temperature at noon was

+ theTemp ;

} else { li.innerHTML = "The temperature at " H

I

+ " was " +

theTemp ;

} У

Генерируем ст р о ку, к о т о ­ рая будет использоваться, для чего задействуем п е р е ­ менные i и theTemp.

} window.onload = showTemps; </script> </head> <body> <hl>Temperatures</hl> <ul> <li id="tempO"></li> <li id="tempi"></li> <li id="temp2"></li> <li id="temp3">C/li> <li id="temp4"></li> </ ul> </body> </html>

по о

Temperatures А вот наши результ ат ы !

* * * * *

The temperature at noon was 59.2 The temperature at 1 was 60.1 The temperature at 2 was 63 The temperature at 3 was 65 The temperature at 4 was 62

дальше ►

117


решение кроссворда

K M L 5 ” K F4><rBoP A’ f e ffleHue

5Л 0

г

и ч

Е С к

Юг 11с

13r

U

м

17л

118

глава 2

14г

N


3

собьипия, о б р а б о т ч и к и и Весь эггк>гп ДЖ аЗ

*

-ф -

Немного взаимодействия

Человек или манекен? решать вам.

Вам все еще не удается соприкоснуться с пользователем. Вы изучи­ ли основы JavaScript, однако могут ли ваши веб-страницы взаимодействовать с пользователями? Когда страницы откликаются на вводимые пользователем данные, они уже являются не простыми документами, а живыми, реагирующими приложениями. В этой главе вы узнаете, как обрабатывать одну из форм ввода данных пользователем (извините за каламбур) и привязывать старомодный HTML-элемент < f o r m > к современному коду. Это может показаться необыч­ ным, однако такой подход также эффективен. Пристегните ремни, поскольку наше путешествие по этой главе будет проходить на большой скорости: путь от простого до интерактивного приложения мы пройдем очень быстро.


добавляем мелодию webville

Приготовьтесь к встрече с Webville Tunes И т а к , ра не е в н р о ц е с с е ч т е н и я к н и г и в ы у зн а л и массу в с е го об о с н о в а х Ja va S c rip t, и , н е с м о т р я н а то ч т о м ы с в а м и м н о г о го в о р и л и о с о зд а н и и в е б -н р и л о ж е н и й , р е а л ь н ы е н р и м е р ы и х с о зд а н и я м ы ещ е н р и с т а л ь н о н е р а ссм а тр и в а л и . П о э т о м у давайте те н е р ь н р о я в и м се р ье зн о сть (н а са­ м о м деле, н а э т о т раз без ш у т о к !) и создадим р е а л ьно е в е б -н р и л о ж е н и е . П у с т ь э т о будет м е н е д ж е р н л е й л и с т о в . М ы д а д и м ем у ка к о е -н и б у д ь о р и ги н а л ь н о е н а з в а н и е , н а н р и м е р ... с ка ж е м , W e b v ille Tunes.

Добавляйте новые песни в любой момент.

See ваши любимые песни будут от о­ бражаться прямо л окне браузера.

Blue Suede Strings, by Elvis Pagely Great Objects on Fire, by Jerry JSON Lewis I Code the Line, by Johnny JavaScript That'll be the Data, by Buddy Bitty and the Variables Your Random Heart, by Hank "Math" Williams

Вот что мы будем создавать.

Ш ТУ РМ Если вам известно, для чего нужен этот код: w in d o w .o n lo a d = i n i t ;

то что, как вам кажется, делает вот этот код? b u tto n . o n c lic k

120

глава 3

= h a n d le B u tto n C lic k ;

^ V -

Приложение будет полностью браузерным. Код на стороне сервера не потребуется.


события и обработчики

Приступаем... Д л я н а ча л а н е т н е о б х о д и м о с т и созд авать б о л ьш у ю , к о м п л е к с н у ю в е б -стр а н иц у. Н а сам ом деле м ы м о ж е м н а ч а ть о ч е н ь н р о с т о . Д а в а й те со зд а д им H T M L 5 д о к у м е н т с ф о р м о й и э л е м е н т о м с н и с ка , где будет с о д е р ж а т ь с я н л е й л и с т :

Стандартные H T M L S -элементы head и body. < ! d o c t y p e htm l>

Beet? JavaScript-код мы п о ­ местим в файл playhst.js.

<htm l lan g= " en " > <head> < title> W eb v ille T u n e s< /title> <meta c h a r s e t = " u t f - 8">

Мы включили таблицу стилей , чтобы придать красивый внеш­ ний вид нашему приложению .*

< sc r ip t s r c = " p la y lis t . js" > < /sc rip t> < l i n k r e l = " s t y l e s h e e t " h r e f = " p l a y l i s t . c s s "> < /h e a d > <body> <form>

Set, 4mQ наМ Иу ЖИ0j эт0 простая форма. Вот она , с текстовым полем для ввода названий песен. Мы используем HTM LS-ат рибут placeholder , который демонстрирует пример того, что можно печатать в поле ввода.

< i n p u t t y p e = " t e x t " i d = " s o n g T e x t I n p u t " s i z e = " 4 0 " p l a c e h o l d e r = " S o n g name"> ^ < i n p u t t y p e = " b u t t o n " id = " a d d B u tto n " valu e= "A d d Song"> f4 _

< /fo r m > < u l i d = " p l a y l i s t ">

А вот button с id в виде "addButton" для отправки но­ вых дополнений в плейлист.

Мы будем использовать список для размещения песен. Он пока пуст j однако скоро мы это испра­ вим с помощью JavaScript-Koda...

< /u l> < /b o d y > < /h t m l>

Проведите тест-д р ай в Н а н е ч а т а й т е н р и в е д е н н ы й вы ш е ко д , за гр у зи т е е го в своем л ю б и м о м браузере и н о л ю б у й те с ь н а результат, н р е ж д е че м н е р е й д е те к сл е д ую щ е й с т р а н и ц е .

non webviiie Tunes Г«Т»П [+ ie http://>ocaihOSt/~Beth/HTML5/javasc еП [Song

coogie

~)

^Add Song^

Вот что вы должны увидеть.

* Не забывайтеу что использованную в этом примере таблицу стилей (и весь код) вы можете загрузить на свой компьютеру посетив страницу kttp.//wickedlysm art.com /kfktm l5.

дальше ►

121


о событиях нажатия кнопки

Когда я наЖимаю кнопку Add Song (Добавить песню), ничего не происходит Ч то

ж , и да, и нет. В ам к а ж е т с я , ч т о н и ч е г о н е н р о и с х о д и т , о д н а к о б раузеру с т а н о в и т ­ ся и з в е с т н о , ч т о в ы щ е л к н у л и н а к н о н к е (к р о м е т о г о , в з а в и с и м о с т и о т и с н о л ьзу е м о го б раузера в ы т а к ж е у в и д и те , к а к к н о н к а « о то ж м е тс я » назад но сл е ее н а ж а т и я ).

Н а са м ом деле в о н р о с за кл ю ч а е тс я в т о м , к а к за с т а в и ть к н о н к у делать ч т о -т о , к о гд а в ы щ е л ка е те н а н е й . Т о ч н е е , в о н р о с с о с т о и т в т о м , к а к будет н р о и с х о д и т ь в ы зо в н е ­ о б х о д и м о го J a v a S c rip t-кода, к о гд а в ы н а ж и м а е те к н о н к у ?

Здесь нам потребуются две вещи: ^

JavaS cript-код, который будет оцениваться, когда пользователь щелкнет на кнопке Add Song (Добавить песню). Данный код (как только мы его напишем) обеспечит добав­ ление новой песни в плейлист. Способ «прицепить» данный код таким об­ разом, чтобы при нажатии кнопки JavaScript знал, что необходимо добавить песню в плейлист.

Когда пользователь щелкает на кнс (или, к примеру, нажимает ее пальцег сенсорном экране какого-либо уст| ства), мы хотим узнать об этом. Поэтому нас интересует событие, кото­ рое инициируется, когда «пользователь только что щелкнул на кнопке». 122

глава 3


события и обработчики

ЭЙ, кнопка, ты меня интересуешь... Не могла ли бы ты дать мне знать, если кто-нибудь щелкнет на тебе?

Добавить песню

Ваша кнопка

Обработка событий Далее в ы у зн а е те , ч т о в б раузере н р и о т о б р а ж е н и и веб-стран и ц ы н р о и с х о д и т м н о ж е с т в о д е й с т в и й : п о л ь зо в а те л ь щ е л ка ­ е т н а к н о н к а х , н о с е т и м о гу т н о с т у н а т ь з а н р о ш е н н ы е в а ш и м к о д о м д о п о л н и т е л ь н ы е д а н н ы е , з н а ч е н и я в р е м е н и та й м е р о в м о гу т и с т е к а т ь (до э т о го м ы еще д о й д е м ). В се э т и в е щ и н р и в о д я т к и н и ц и и р о в а н и ю с о б ы т и й , с в и д е те л ь с тв у ю щ и х о т о м , ч т о к н о н к а б ы ла н а ж а т а , ста л и д о с т у н н ы д о п о л н и т е л ь н ы е д а н н ы е , в р е м я и с т е к л о и т. д. (е сть ещ е м н о г о р а з н ы х с о б ы т и й ).

Ваш код

В с я к и й раз, к о гд а и н и ц и и р у е т с я с о б ы т и е , ваш ем у к о д у нр ед о ста в л яе тся в о з м о ж н о с т ь обработать е го ; то есть вам н е о б х о ­ д и м о п р е д у с м о тр е ть ко д , к о т о р ы й будет в ы зы в а т ь с я н р и и н и ­ ц и и р о в а н и и о п р е д е л е н н о го с о б ы т и я . В ам н е н у ж н о с и ю ж е м и н у т у о б е с н е ч и в а ть о б р а б о т к у к а к и х -л и б о с о б ы т и й , о д н а ко э то н о т р е б у е т с я сделать, е сли в ы х о т и т е , ч т о б ы н р и и х и н и ц и ­ и р о в а н и и ч т о -т о н р о и с х о д и л о : н а н р и м е р , к о гд а и н и ц и и р у е т с я с о б ы т и е н а ж а т и я к н о н к и , вам м о ж е т п о т р е б о в а т ь с я , ч т о б ы за э т и м н о сл е д о в а л о д о б а в л е н и е н о в о й н е с н и в п л е й л и с т; ко гд а н о с т у н а ю т д о п о л н и т е л ь н ы е д а н н ы е , в ы м о ж е т е за х о т е ть о б р а ­ б о та ть и х и о т о б р а з и т ь н а с в о е й с т р а н и ц е ; ко гд а за п у с ка е тся т а й м е р , вам м о ж е т п о н а д о б и т ь с я с о о б щ и т ь п о л ь з о в а те л ю , ч т о е го б р о н ь н а б и л е т ы в н е р в о м р я д у с к о р о и с т е ч е т, и т. д. Т а к и м о б р а зо м , м ы зн а е м , ч т о н а м н е о б х о д и м о о б е с н е ч и т ь об­ ра б о тку со б ы тия , и н и ц и и р у е м о го н р и н а ж а ти и к н о н к и , н о это­ му н о с м о т р и м , к а к э то м о ж н о сделать.

дальше ►

123


код для обработчика кнопки

Составляем план... Д а в а й те н е м н о го н р и т о р м о з и м , н р е ж д е ч е м угл у б и м с я в м и р о б р а б о т ч и к о в и с о б ы т и й . Н а ш а ц ель се й ч а с — сделать т а к , ч т о б ы но сл е щ е л ч ка н а к н о н к е A d d S o n g (Д о б а в и т ь н е с н ю ) н р о и з о ш л о д о ­ бавлени е н е с н и в н л е й л и с т н а с т р а н и ц е . П о д о й д е м к р е ш е н и ю э т о й за д а чи н а о с н о в е с л е д у ю щ и х э та н о в : 1 . Задание об р а б о тч и к а для о б р а б о тк и с о б ы т и й c lic k 6 о тн о ш е н и и кнопки A d d S on g ( Д о б а в и т ь п е с н ю ). 2 . Написание об р а б о тч и к а для извлечения названия песни, введ енного п ол ь з ов ател ем , после чего п о с л е д у е т ... 3 . Создание нов о го эл е м ен та для размещ ения новой песни и . . . 4 . Д обавл ение н ов ого эл е м ен та в D 0 M с т р а н и ц ы .

Н е б е с н о к о й т е с ь , е сли э т и э т а н ы н е со все м я с н ы для вас, н о с к о л ь к у н о х о д у дела м ы все вам о б ъ яс­ н и м . С е й ч а с о т вас тр е б у е тс я н р о с т о н р о ч у в с т в о в а ть и х , следуя за н а м и , н о к а м ы будем за н и м а ть с я н а н и с а н и е м н е о б х о д и м о го о б р а б о т ч и к а . И т а к , о т к р о й т е н о в ы й ф айл p la y lis t.js , где будет р а с п о л а ­ га т ь с я весь ваш J a v a S c rip t-код .

Получение доступа к кнопке Add Song (Добавить песню) Ч т о б ы « н о н р о с и ть » к н о н к у дать н а м зн а ть , к о гд а будет и н и ц и и р о в а н о с о б ы т и е , сви д е те л ь ств ую щ е е о т о м , ч т о н о л ь зо в а те л ь щ е л кн у л н а н е й , сна ча ла н е о б х о д и м о н о л у ч и т ь д о с т у н к э т о й к н о н к е . К сча­ с ть ю , м ы создали д а н н у ю к н о н к у с и с н о л ь з о в а н и е м H T M L -р а з м е тки , и э то озна ча е т, ч т о ... к а к в ы у ж е д о га д а л и сь, о н а н р е д с та в л е н а в о б ъ е к т н о й м о д е л и д о ку м е н т а ( D O M ) , а в ы у ж е зн а е те , к а к и з в л е ка ть э л е м е н т ы оттуда. Е сл и в ы ещ е раз в згл я н е те н а H T M L -разм етку, т о за м е т и те , ч т о м ы н р и с в о и л и i d к н о н к и з н а ч е н и е a d d B u tto n . Т а к и м о б р а зо м , м ы в о с п о л ь зу е м с я g e t E l e m e n t B y l d для и з в л е ч е н и я ссы л ки на кн о н ку:

:

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 tto n " ) ;

Т е н е р ь н а м н у ж н о н р о с т о задать для к н о н к и ко д , к о т о р ы й будет в ы зы в а т ь с я н р и с о б ы т и и c l i c k . Д л я э т о го м ы созд а д им ф у н к ц и ю с и м е н е м h a n d l e B u t t o n C l i c k , к о т о р а я за й м е тс я о б р а б о т к о й дан­ н о г о с о б ы т и я . П о д р о б н е е о ф у н к ц и я х м ы н о г о в о р и м н е м н о го н о з ж е , а н о к а н е о б х о д и м а я н а м ф у н к­ ц и я будет в ы гл я д е ть в о т та к:

ф ункция носит имя h a n d le B u tto n C lick ; об о с о б е н ност ях синт аксиса мы п о го в о р и м ч у т ь позже. X

фу н к ц и я п о з в о л я е т у п а к о в а т ь код в р а м к и о т д е л ь н о г о блока. 1 Вы м о ж е т е п р и с в о и т ь е м у имя и повт орно использоват ь

>v

)

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

]

4_/ пт,

4_о_

r t ( " B u tto n was

К\

При в ы зове данной ф у н к ц и и будет выводиться диалоговое окно a lert.

124

глава 3

{

c l-Ii ■c k1 e dл !и"х) ;

\

г\

X

э т о т бл о к кода в е з д е > где в а м п о т рг е б уие т с я .

В есь к о д, к о т о р ы й д о л жен в ы п о л н я т ь с я п р и вы зове ф у н к ц и и , м ы з а к льо ча е м в скобки.


Задание обработчика событий click для кнопки

1. Задание обработчика для обработки событий click 2. Написание обработчика для извлечения названия песни 3. Создание нового элемента для размещения новой песни 4 . Добавление нового элемента в D0M страницы

И т а к , т е н е р ь у нас е сть к н о н к а , а т а к ж е ф у н к ц и я h a n d l e B u t t o n C l i c k , к о т о р а я будет в ы стун а т ь о б р а б о т ч и к о м , т а к ч т о д а в а й те с о е д и н и м и х вм е сте . Д л я э т о го м ы в о с п о л ьзу е м с я с в о й ­ с тв о м b u t t o n н о д и м е н е м one l i c k . С в о й с т в о o n c l i c k м ы зад адим сл е д ую щ и м о б р а зо м :

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 tto n " ) ; b u t t o n .o n c l ic k = h a n d leB u tto n C lic k ; /

Л

Имея под рукой b u tto n , после вызова getElementByld мы задаем для свойства onclick функции?, которая будет вызываться при наступлении события click. К а к в ы н о м н и т е , м ы делали н е ч т о н о д о б н о е , к о гд а и с н о л ь з о в а л и с в о й с т в о w in d o w .o n lo a d для в ы зо в а ф у н к ц и и н о с л е о к о н ч а н и я з а гр у з к и о к н а . О д н а к о в д а н н о м случае м ы в ы зы в а е м ф у н к ц и ю но сл е н а ж а т и я к н о н к и . Т е н е р ь с о е д и н и м все:

К а к и в предыдущей главе, здесь мы используем ф унк цино m itj которая не будет вызываться и выполняться w in d o w .o n lo a d = i n i t ; f u n c t i o n i n i t ()

£

meX

n0PJ пОКа с т РаниЧа полностью не загрузится.

{

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 tto n " ) ; b u t t o n .o n c l ic k = h a n d leB u tto n C lic k ; К.

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 tto n was c l i c k e d ! 1

Ь

После окончания загрузки ст р а ­ ницы мы извлекаем button и задаем его обработчика onclick.

Обработчик событий click будет выводить диалоговое окно alert в случае щелчка на кнопке.

Проведение т е с т а . Н а н е ч а т а й те н р и в е д е н н ы й в ы ш е ко д (в своем ф айле 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

Более пристальный Взгляд на происшедшее... На нескольких носледних страницах мы нознакомили вас с м ассой новых аснектов, ноэтому давайте ещ е раз нройдем ся но коду, чтобы убедиться в том, что вы все четко усвоили. Итак, нристуним:

Первое, что мы сделали, — это добавили кнопку в свою HTML-срорму. Затем нам потребовалось средство перехвата событий click в отношении этой кнопки, чтобы в результате был выполнен кое-какой код. Для этого мы создали обработ­ чика и присвоили его свойству onclick нашего button.

function init() { var button = document.getElementByld ("addButton") button.onclick = handleButtonClick; }

Объект button об­ ладает свойством onclick, для которого мы задаем функцию handleButtonClick.

Задаем обработчика событий click в ф унк­ ции in it (то есть выполнение будет запускаться после завершения загрузки страницы).

Когда пользователь щелкает на кнопке , инициируется событие click и происхо­ дит вызов функции handleButtonClick.

function handleButtonClick() { alert("Button was clicked! ') ; }

Мы также написали простой обработчик, который выводит диалоговое окно a l e r t с сообщением о том, что кнопка была нажата. Чуть позже мы напишем настоящий код для обработ­ чик а, а этот отлично подходит для тестирования.

I

г 126

глава 3

'и

Обработчик в вашем коде


события и обработчики

Итак, код написан, страница загружается и отображается в окне браузера, обработ­ чик задан. Теперь все зависит от поль­ зователя...

Наконец, пользователь щелкает на на­ шей кнопке, в результате чего она активизируется, замечает, что у нее имеется обработчик, и вызывает его...

_/ Г N.

Очнись,

/

1 этот случай, нужно дать ему знать. >

О

_____ П

Г

Вижу, у меня Ч есть обработчик на \

f

пользователь щелк- \ нул на тебе. )

0

----------- '

о

Добавить песню

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 ! " ) }

Меня попросили сообщить вам, что кноп­ ка была нажата... Я знаю, что для диалогового окна ale rt это не слишком впечат­ ляюще, но, как бы там ни было, я просто делаю свою работу.

http://localhost Button was clicked!

(

Q*

)

дальше ►

127


извлечение названия песни из dom

1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick

2. Написание обработчика для извлечения названия песни 3. Создание нового элемента для размещения новой песни 4 . Добавление нового элемента в D0M страницы

извлечение названия песни

М ы готовы н е р е й т и к о в т о р о м у э та н у р е ш е н и я н а ш е й за д а ч и — и з в л е ч е н и ю н а з в а н и я н е с н и , в в е д е н н о го п о л ьзо в а те л е м . Сделав э т о , м ы с м о ж е м задум аться над те м , к а к н а ш н л е й л и с т будет о т о б р а ж а т ь с я в браузере. О д н а к о к а к м ы и з в л е ч е м н а з в а н и е н е с н и ? Э то н е ч т о т а к о е , ч т о ввел п о л ь з о в а те л ь , ведь так? А х да, все, ч т о п р о и с х о д и т н а в е б -с тр а н и ц е , о тр а ж а е т с я и в о б ъ е к т н о й м о д е л и д о ку м е н та (D O M ), н о э т о м у те кс т , в в е д е н н ы й п о л ьзо в а те л е м , т о ж е д о л ж е н б ы т ь там . Д л я и з в л е ч е н и я т е к с т а и з т е к с т о в о го э л е м е н та ввода ф о р м ы н а м сна ча ла н о т р е б у е т с я и з в л е ч ь э т о т э л е м е н т и з D O M , и в ы у ж е зн а е те , к а к о й и н с т р у м е н т для э т о го н у ж е н — g e t E l e m e n t B y l d . Сделав э то , м ы см о ж е м в о с п о л ь зо в а ть с я с в о й с т в о м v a l u e т е к с т о в о го э л е м е нта ввода для п о л у ч е ­ н и я д о стун а к тексту, вве д е н н о м у в но л е ф о р м ы по л ьзо ва те л е м , и в о т к а к это все будет вы гл яд е ть:

Вот элем ент j к о т о ­ рый м ы х о т и м извлечь из DOM. Д л я э т о ­ го м ы и с п о л ь з у е м его id со значен и ем ".S o n g T e x tln p u t".

до к у м е н т а

ul id="playlis+"

\ input id^'songTextlnput” value="Blue Suede Strings, by Elvis Pagely"

nput id="addButton"

j

З а т е м м ы и с п о л ь з у е м свойст во value э л е м е н т а ввода для извлечения т е к с т а , набранного п о л ь з о в а т е л е м в п оле вчооа.

С пом ощ ью мет ода g e tE le m e n tB y l d м ы сможем получит ь доступ к элем ент у ввода s o n g T e x tln p u t в ф орм е.

^Возьми в руку карандаш Доработайте ф ункцию h a n d l e B u t t o n C l i c k , приведенную ниже, чтобы извлечь на звание песни, набранное пользователем в элементе ввода формы. П роверить пра вильность своих ответов вы сможете, посмотрев реш ение д ан н ого задания на с. 130.

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 = alert(" A d d in g " +

128

глава 3

. v a lu e;


события и обработчики

Возьми в руку карандаш А вдруг вам потребуется провести проверку, чтобы убедиться в том, что пользо­ ватель действительно ввел текст до того, как щелкнул на кнопке? Как это можно будет сделать? (Решение данного задания вы также сможете отыскать на с. 130.)

Часш°

ЧаДаВаеМые Вопросы

Каким будет значение свойства value текстового элемента ввода, если пользователь ничего не ввел? Будет ли оно null?

Ка ки е ещ е типы с о б ы ти й м ож но о б р а б а ты в а ть на JavaScript помимо click?

Или кнопка Add Song (Добавить песню) не станет вызывать обработчик, если пользователь ничего не ввел?

0 : Кнопка Add Song (Добавить песню) не настолько умна. Если вы хотите определять, ввел ли что-нибудь пользователь, для этого вам потребуется соответствующий код. Чтобы узнать, является ли текстовое поле ввода пустым (то есть пользователь ничего в нем не напечатал), можете проверить, не равно ли его значение строке, в которой ничего нет, также называемой пустой строкой и помечаемой как,,м(пара двойных кавычек, между которыми ничего не стоит). Мы понимаем, почему вы решили, что значение может быть равно null, поскольку ранее отмечали, что это значение переменной, под которым подразумевается «значения нет», однако с точки зрения текстового поля ввода оно будет содержать не ничто, а строку, в которой ничего нет. Представьте себе!;-). Я думал, что "value" текстового элемента ввода — это атрибут. Но вы называете его свойством. Почему?

0 : Вы правы, value — это атрибут текстового элемента ввода. Вы можете инициализировать значение текстового элемента ввода с использованием атрибута value. Однако в случае с JavaScript для доступа к значению, введенному пользователем, вам потре­ буется использовать свойство value элемента ввода, которое извлекается из объектной модели документа (DOM).

0 : Существует масса прочих событий, связанных с манипу­ ляциями мышью, которые можно обрабатывать. Например, вы можете отслеживать и обрабатывать события, инициируемые при нажатии кнопки мыши, при наведении указателя мыши на элемент и убирании его прочь с элемента, при перетаскивании элемента с помощью мыши, при нажатии и удержании кнопки мыши (они от­ личаются от событий click). Кроме того, существует множество иных типов событий, о которых мы уже упоминали (например, со­ бытия, инициируемые, когда становятся доступны дополнительные данные, события, связанные с таймерами и окном браузера, и т. д.). В процессе чтения книги вы увидите еще довольно много других типов событий, которые можно обрабатывать; если вы знаете, как обрабатывать события одного типа, то вы с большой долей вероятности сможете обработать события любых других типов!

В

Что делает JavaScript, пока ждет инициирования событий?

0 : Если вы не запрограммировали свой JavaScript на выполнение каких-либо действий в это время, он будет бездельничать, пока что-нибудь не произойдет (пользователь начнет взаимодействовать с интерфейсом, поступят данные из Интернета, истечет значение времени таймера и т. д.). И это хорошо, поскольку вычислительная мощь вашего компьютера сможет быть направлена на другие вещи, например на то, чтобы сделать ваш браузер более отзывчивым. Позже мы расскажем, как создавать задачи, выполняемые в фо­ новом режиме, чтобы ваш браузер одновременно выполнял код задачи и реагировал на события.

дальше ►

129


решение упражнения

Возьми в руку карандаш Решение

Доработайте функцию h a n d l e B u t t o n C l i c k , приведенную ниже, чтобы извлечь название песни, набранное пользовате­ лем в элементе ввода формы. Вот наше решение этого задания.

Сначала на м необходимо извлечь ссылку на т е к ст овы й э л е м е н т ввода в ф о р м е. Мы пр исвои ли id эт о го э л е м е н т а значение ".s o n g T e x tln p u t", п о э т о м у мож ем и с п о ль з о ва т ь его в сочет ании с g e tE le m e n tB y l d для извлечения ссылки.

с ж э

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); }

Ь у д е т выводиться диалоговое окно alert, в к о т о р о м о т о б р а зи т с я "Adding" и название песни.

Свойство value текстового элемента ввода содержит все, что набирается в т е к стовом поле и представляет собой строку. Здесь мы при сваиваем введенный текст переменной 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

if и ср а в н и т ь с т р о к у so n g N a m e с п у с т о й с т р о к о й , чтобы у б е ­ дит ься, ч т о п о л ь з о в а т е л ь д е й ­ с т в и т е л ь н о ч т о - т о напечат ал. Если п о л ь з о в а т е л ь ничего не н а п е ­ ч а т а л , т о мы выведем диалоговое окно a le rt и п о п р о с и м его ввест и название песни.

(songName == "")

{

^ —

a l e r t ( " P lea se e n t e r a song"), } else

{

a l e r t ( "Adding " + songName);

130

глава 3


1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick 2 . Нап и сан ие о б р а б о т ч и к а для и звлечения назВания песни

3. Создание нового элемента для размещения новой песни

Как добавить песню на страницу?

4-А»б»в».н«...вого«««м.»™вdom^«„цы

М ы с в а м и у ж е м н о г о ч е го сделали, и все р а б о та е т! В ы м о ж е т е в в е с ти назва­ н и е н е с н и в ф орму, щ е л к н у т ь н а к н о н к е A d d S o n g (Д о б а в и т ь н е с н ю ) и и з в л е ч ь т о , ч т о в в о д и л и в ф орму, — все в рамках вашего кода . Т е н е р ь м ы о т о б р а з и м п л е й ­ л и с т н а са м о й с т р а н и ц е . В о т к а к э то будет в ы гл я д е ть.

ООО [ А | ► | [ +

W eb ville T u n e s | 0 h ttp ://lo calh o st/->B e th /H e ad -F irst-H T M

Song name

<5 ] (С^т Google

j

Г A d d Song^)

Blue Suede Strings, by Elvis Pagely

При нажатии кнопки Add Song (Добавить песню) ваш JavaScript добавляет соответ­ ствующую песню в список на странице.

Нам потребуется сделать следующее

©

©

Вы могли заметить, что мм уже добави­ ли пустой список в HTML-разметку (пу­ стой элемент < u i > ) , когда в первый раз вводили данные. В результате объектная модель документа (DOM) сейчас будет выглядеть так.

Каждый раз, когда вводится название но­ вой песни, нам нужно добавлять новый элемент в неупорядоченный список. Для этого мы создадим новый элемент <и>, в котором будет размещаться название новой песни. Затем мы возьмем новый элемент <и> и добавим его в < u i> в объ­ ектной модели документа. В результа­ те этого, когда браузер сделает свои дела, вы увидите, что страница подвер­ глась обновлению, словно данный эле­ мент <и> был там всегда. И конечно же, все это мы сделаем в коде.

body

ul id= "p la y lis t"

Это список в объектной модели доку­ мента. Сейчас он пуст.

При вводе на­ звания песни мы создаем новый эле­ мент списка (элемент <И>) и добавляем его в список <ul>.

дальше ►

131


создание нового элемента

пражненке Здесь приведен плейлист, для которого вам необхо­ димо нарисовать объектную модель документа в том виде, который он приобретет после добавления всех этих песен. Обратите внимание на порядок, в котором песни были добавлены на страницу, и разместите соответствующие элементы на своих местах в DOM. Один из них мы уже расположили в нужном месте, вам остается лишь сделать то же самое в отношении остальных элементов. Посмотрите решение данного задания в конце главы, прежде чем двинетесь дальше.

п По

Blue Suede Strings, by Elvis Pagely Great Objects on Fire, by Jerry JSON Lewis 1Code the Line, by Johnny JavaScript That'll be the Data, by Buddy Bitly and the Variables Your Random Heart, by Hank "Math" Williams

Blue Suede Strings, by Elvis Pagely

Д о р и с у й т е зд е сь о с т а л ь н у ю ч а с т ь РОМ д л я п л е й л и с т а , п р и в е д е н н о г о в в е р ху.

Придется ли вам строить какие-либо предположения насчет порядка, в котором элементы < i i > добавляются в родительский элемент?

132

глава 3


события и обработчики

Как создать новый элемент В ы у ж е в и д е л и , к а к м о ж н о н о л у ч и т ь д о с т у н к существующим элементам н о с р е д с т в о м о б ъ е к т н о й м о д е л и д о ку м е н та . О д н а ко D O M та кж е м о ж н о и сн о л ьзо в а ть для со зд а ния н о в ы х элем ентов (с н о с л е д у ю щ и м их добавлением в D O M , о ч е м м ы н о г о в о р и м

— Нам лучше заняться созданием этих элементов, Бетти. Они снова обновляют D ОМ.

со все м с к о р о ). Д а в а й т е н р е д с т а в и м , ч т о н а м н у ж н о с о зд а ть э л е м е н т < l i > . В о т к а к м ы э то сделаем:

Д л я создания новых э л е м е н т о в и с п о л ь з уе т с я 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

Наша п е р е м е н ная I'-

=

songN am e;

^

з а д а ш со д е р ^

жимое в виде названия песни для э л е м е н т а <h>. ^

Blue Suede Strings, by Elvis Pagely

Наш новый о б ъ е кт э л е м е н т а li, готовы р и н у т ь с я в бой. О д н а ­ ко он еще не явля е т с я ч а с т ь ю РОМ! дальше ►

133


добавление нового элемента

1. Задание о б р а б о т ч и к а для о б р а б о т к и с о б ы т и й c lick 2 . Нап и сан ие о б р а б о т ч и к а для и звлечения назв ан и я песни 3 . С о здание нового э л е м е н т а для р а з м е щ е н и я новой песни

Добавление элемента В DOM

4 . Добавление нового элемента в D0M страницы

Ч т о б ы д о б а в и ть н о в ы й э л е м е н т в о б ъ е к т н у ю модель д о ку м е н та , вам н е о б х о д и м о зн а ть , куда е го н о м е щ а ть . Ч т о ж , н а м э то у ж е и з в е с т н о : м ы со б и р а е м ся н о м е с т и т ь э л е м е н т < l i > в э л е м е н т < u l> . Н о к а к э то сделать? Д а в а й те еще ра з взгл я н е м н а D O M . П о м н и т е , к а к ра не е м ы о т м е ч а л и , ч т о о н а с р о д н и дереву? М о ж е т е т а к ж е с ч и т а т ь ее че м -то вр о д е родословного дерева.

ре-

d o c u m e n t я вля е т с я н еким подобием « м а т е р и » всего с е ­ м ейного рода и р а с п о л а г а е т с я на с а м о м верху дерева. р

'" Л

document

с

к

б&нкоМ» (У

V ...... б да н но м п о ко л е ни и

У h t m l и м е ю т с я два дочерних э л е м е н т а —

html

head

title

hea d и body. Р о дит е ле м body явля е т с я h tm l.

i

~ Г ~

с

р 0Эителелл

|

script

j * '

body

form

ul id="playlist"

h

А вот наш ul. Роди­ |

input

|

|

телем ul я в л я е м с я body, а у ul пока н е т дочерних элем ент ов...

input ~ |

Т а к и м о б р а зо м , ч т о б ы д о б а в и т ь н а ш э л е м е н т < l i > , н е о б х о д и м о сделать е го д о ч е р н и м н о о т н о ш е н и ю к < u l> . Д л я э т о го н а м с н а ч а ­ ла н у ж н о о т ы с к а т ь э л е м е н т < u l> в де р е в е (м ы н р и с в о и л и е го i d з н а ч е н и е "p la y lis t", ч т о б ы е го н р о щ е б ы л о н а й т и ) . З а те м , ч т о б ы н р о и з о ш л о д о б а в л е н и е э л е м е н т а < l i > , м ы н р е д л а га е м э л е м е н т у < u l> д о б а в и т ь н о в ы й д о ч е р н и й элем ент. Все э т о будет в ы гл я д е ть сл е д ую щ и м об р а зо м :

IT )

...мы х о т и м сде­ л а т ь наш новый э л е м е н т <(/> дочерним по о т ­ нош ению к <ul>.

Blue Suede Strings, by Elvis Pagely

И с п о л ь з у е м g e tE le m e n tB y l d для извлечения ссылки на э л е м е н т <ul> с id -"playlist1'.

2 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 11) ;

u l .a p p e n d C h i l d ( li) ;

Здесь мы п р е д ла га е м э л е м е н т у <ul> добавить <h> в качест ве дочернего э л е м е н т а . К ак т о л ь к о э т о будет сделано, в РОМ <(/> с т а н е т дочерним э л е м е н т о м <ul>, и браузер обновит с т р а н и ц у , чтобы в ней о т р а зи л с я новый <h>.

134

глава 3

При каждом вызове appendC hild новый э л е м е н т <Ц> б удет добавлят ься в э л е ­ м е н т <ul> после любых других э л е ­ м е н т о в <li>j ко т оры е уже т а м б уд у т р а с ­ полага т ься.


события и обработчики

Соединяем все воедино... Давайте соединим весь код и добавим его в функцию h a n d l e B u t t o n C l i c k . Наберите нриведенный ниже код, если вы еще этого не сделали, чтобы затем можно было нровести тестирование. 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>, ___ g к о т о р о м б удет р а з м е щ а т ь с я н а з в а -

v a r songName = t e x t l n p u t . v a l u e ;

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 ) ;

-- ------------^

Л

О б рат ит е вним ание , чт о мы предлага~

к н а ш е м у новом у <И>. П о эт ом у он след у ю щ и й в очереди на извлечение.

Д обавляем объект II в ul с и сп о ль30^анием appendChild.

сал р о д и т е л ь с к о м ц э л е м е н т у ul добавить в себя Н в ка чест ве дочернего эл е м е н т а .

...и проводим тест-драйв ____ I______ -

Протестируйте Webville Tunes, добавляя в нлейлист несни. Вот наши результаты.

О О О

[ < |

W eb v ille T u n es

C j (O? Google

| | + |Q h ttp ://lo c a lh o s t/-'B e th /H e a d -F irs t-H T M L 5 ;

Song name

u N d = " p la y list'^ L

Так б удет вы глядет ь о б ъект ная м о ­ дель д о к у м е н т а после добавления всех новых э л е м е н т о в <Н>.

(Add Song^i

Blue Suede Strings, by Elvis Pagely Great Objects on Fire, by Jerry JSON Lewis I Code the Line, by Johnny JavaScript That'll be the Data, by Buddy Bitly and the Variables Your Random Heart, by Hank "Math" Williams

Т е п е р ь , когда мы вводим название песни и наж имаем кнопку A d d Song ( Д о б а в и т ь песню ), с о о т в е т с т в у ю ­ щая песня добавляется в РОМ, б л а го ­ даря ч ем у м ы видим , ч т о с т р а н и ц а п р е т е р п е в а е т и зм енения и в о т о браж аемом на ней списке по я вля е т с я новая песня.

дальше ►

135


обзор приложения playlist

Обзор того, что мы только что сделали В э т о й главе мы с вами много чего сделали (иричем за короткий нромежуток времени!). Иснользуя^уаБспр):, мы создали менеджер нлейлистов, который нозволяет ввести название несни, щелкнуть на кнопке и добавить данную несню в снисок на странице Первое, что мы сделали, — это задали обработчик для обработки событий c l i c k в отношении кноп­ ки Add Song (Добавить песню). Мы создали функ­ цию h a n d l e B u t t o n C l i c k и задали ее для свой­ ства o n c l i c k кнопки Add Song (Добавить песню).

с

Add Song

_J

Когда п о л ь з о в а т е л ь щелкает на кнопке Add Song (Добавить песню ), пр о и с х о д и т вызов нашего обработчика handleButtonClick.

ф

Затем М Ы написали КОД ДЛЯ h a n d l e B u t t o n C l i c k , чтобы извлекать название песни из текстово­ го поля ввода. Мы воспользовались свойством i n p u t . v a l u e для извлечения текстовых данных и даже позаботились о проведении проверки, чтобы убедиться, что пользователь ввел название песни. Если он этого не сделал, то мы выводим диалого­ вое окно a l e r t с соответствующим сообщением. 3 ha n d le B u tto n C lic k м ы извл е ка е м введенное п о л ь з о в а т е л е м название песни, и с п о ль зуя свойст во input.vatue для извлечения т е к с т о в ы х данных из об ъ е кт н о й м о дели д окум ент а.

j

# \*

input id=''songTextInput" value="Blue Suede Strings by Elvis Pagely''

input id=''addButton"

Чтобы добавить песню в плейлист, далее мы создали элемент < l i > , используя d o c u m e n t . c r e a t e E l e m e n t , и задали содержимое в виде названия песни для этого элемента с помощью innerHTM L.

М и С03дали новый э л е м е н т Blue Suede S trin g s , <li> и задали для него содерж и- -А. У v' s а9е У м о е в виде названия песни.

Наконец, мы внедрили новый элемент < i i > в объ­ ектную модель документа, добавив его в качестве дочернего элемента по отношению к родительско­ му < u l > . Мы сделали это С ПОМОЩЬЮ a p p e n d C h i l d , дав элементу < u l > команду «добавить < l i > в ка­ честве дочернего элемента», в результате чего он был внедрен в объектную модель документа. При добавлении элемента в DOM браузер обновляет страницу, которую видит пользователь, и в плей­ листе появляется название новой песни. 136

глава 3

body Д обавление нового дочер­ него э л е м е н т а в DOM п р и в о ­ д и т к обновле­ нию ст раницы.

|^ u M d = ^ p la y li^ rJ |


события и обработчики

ТТостойте-ка, я понимаю, что мы взаимодей­ ствуем с DOM и все такое, но как данный код можно назвать реальным веб-приложением? Если я закрою окно браузера, то все мои песни пропадут. Разве не должны элементы моего плейлиста сохраняться, если это действительно приложение?

Мы с вами согласны, плейлист должен сохраняться; в к о н ц е к о н ц о в , к а к о й см ы сл д о б а в л я ть все э т и п е с н и в п л е й л и с т, если о н и не будут с о х р а н е н ы ? К р о м е т о г о , сущ е ствуе т масса д р у г и х ф у н к ц и й , к о т о р ы е в ы т а к ж е м о ж е те за х о те ть в н е д р и ть . Н а п р и м е р , вам м о ж е т п о н а ­ д о б и т ь с я д о б а в и ть а у д и о и н т е р ф е й с с и с п о л ь зо в а н и е м A P I-и н те р ф е й с а a u d i o / v i d e o , ч т о б ы м о ж н о б ы ло п р о ­ сл у ш и в а ть п е с н и , д е л и т ь с я и м и со с в о и м и д р у з ь я м и п о с р е д с т в о м в е б -с л у ж б (в р о д е F a c e b o o k и T w itt e r ) , и с к а т ь в л о к а л ь н о й с е ти л ю д е й , к о т о р ы м н р а в я т с я те ж е и с п о л н и т е л и , ч т о и вам (и с п о л ь зу я A P I-и н те р ф е й с G e o lo c a tio n ). К т о м у ж е м ы у в е р е н ы , ч т о у вас м о гу т в о з н и к н у т ь и д р у ги е п о ж е л а н и я в э т о м пла не . В о зв р а щ а я с ь к п л е й л и с т у ... М ы х о т е л и б ы с т р о п р о ­ д е м о н с т р и р о в а т ь вам п р и м е р с о з д а н и я н е б о л ь ш о го и н те р а кт и в н о го п р и л о ж е н и я , и п лейл ист о тл и чн о п о ­ до ш е л в д а н н о м случае. К р о м е т о г о , с о х р а н е н и е н е с е н тр е б уе т 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

ь б у д ь т е оС Ш ороЖ Н ы

Приготовленный код не будет ра­ ботать в Internet Explorer 6 и 7.

Данные версии браузера Internet Explorer не поддержи­ вают localStorage. Поэтому если вы используете Internet Explorer, позаботьтесь о том, чтобы его версия была 8 или выше.

138

глава 3

J ДЫ НС | о о ц о р о Ж Н з» 1.

Приготовленный код не будет работать в некоторых браузерах, если вы загру­

жаете свои страни­ цы из file://, а не с сервера (например, localhost://) или онлайн-сервера.

В следующих главах мы поговорим об этой ситуации более подробно (она довольно часто возникает в случае с новыми функ­ циями HTML5). А пока, если вы не хотите запускать выполнение сервера или копиро­ вать файлы на онлайн-сервер, используйте браузер Safari или Chrome.


события и обработчики

Как ({обабить приготовленный код...

j^ o rfro B o К JjH oriip>0gjX0H ulo

Ч у т ь н и ж е н р и в е д е н н р и г о т о в л е н н ы й ко д , к о т о р ы й н у ж н о д о б а в и ть в н р и л о ж е н и е W e b v ille Tunes, ч т о б ы в ы м о гл и с о х р а н и ть с ф о р м и р о в а н ­ н ы й в а м и за м е ч а те л ь н ы й пл е й л и с т. В се, ч т о вам н у ж н о сделать, — э то созд а ть н о в ы й ф айл с и м е н е м p l a y l i s t _ s t o r e . j s , н е р е н е с т и в н е го н р и в е д е н н ы й в н и з у ко д , а за те м в н е с т и н а р у и з м е н е н и й в у ж е и м е ю ­ щ и й с я у вас к о д (н а сл е д ую щ е й с т р а н и ц е ).

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 " ) ; }

fu n c tio n g etS toreA rray(k ey) { var p la y lis tA r r a y = lo c a lS to r a g e . g e tlte m (k e y ); ") i f ( p l a y l i s t A r r a y == n u l l I I p l a y l i s t A r r a y == p l a y l i s t A r r a y = new A rr a y ( ) ;

{

}

else

{ p l a y l i s t A r r a y = JSON. p a r s e ( p l a y l i s t A r r a y ) ;

}

return p la y lis tA r r a y ;

дальше ►

139


сохранение плейлиста

интегрирование приготовленного кода

j^ o ip o B o к употребл ение

Н ам необ ход им о в не сти нару неб о л ьш их и зм е н е н и й , ч т о б ы и н т е гр и ­ р о в а т ь к о д для с о х р а н е н и я н л е й л и с та . С на ча л а м ы д о б а в и м с с ы л ку н а 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 ();

^ __________

}

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 ()

Д а н н а я с т р о к а загр уж а ет сохраненные песни из localStorage, когда вы за груж ает е свою с т р а н и ц у , благодаря чем у они о т о ­ бразят ся на экране в п л е й л и с т е .

{

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);

дую новую п е с н ю , к о т о р у ю вы добавляете в п л е й л и с т .

Тест-драйв сохраненного плейлиста °

И т а к , п е р е з а гр у з и т е с т р а н и ц у и в в е д и те назва­ н и я н е с к о л ь к и х н е се н . З а к р о й т е о к н о браузера. С н о в а о т к р о й т е е го и о н я т ь з а гр у з и т е с т р а н и ­ цу. П о с л е э т о го в ы д о л ж н ы у в и д е ть п л е й л и с т со в се м и с в о и м и с о х р а н е н н ы м и н е с н я м и .

З а м надоел в а Л л е й л и с т , и бы р е ш и ­ ли у д а л и т ь его ? Тогда вам п р и д е т с я з а г л я н у т ь в гла ву , п освящ ен ную A P I -

и н т е р ф е й с у W eb Storage!

140

глава 3

I * I

MfrbvUteTunes______ 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 Tfiatll be the Data, b y B u d d y Bitly an d the V ariab les

Your Random Heart, by Hank "Math” Williams

Мы добавили все э т и п е с ­ ни, закры ли окно б раузера, зат ем сно­ ва о т к р ы л и его, з а г р у з и ­ ли с т р а н и ц у , и перед нам и предстал со­ храненный плейлист с песнями.


события и обработчики

Классно! Мы действительно начали де­ лать так, чтобы код и веб-страница взаимо­ действовали друг с другом. Однако меня заинтересовали функции, объекты и вещи вроде element.appendChildQ. Нужно ли мне знать еще что-то о них?

Подходящее время. М ы с тр е м и л и с ь п р о д е м о н с т р и р о в а т ь вам н о д р о б ­ н ы й п р и м е р т о г о , к а к 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

КЛЮЧЕВЫЕ — МОМЕНТЫ ■

В браузере постоянно происходит масса со­

а затем добавить в качестве дочернего эле­

бытий. Если вы хотите обеспечить реакцию

мента по отношению к другому элементу.

на эти события, то вам потребуется обраба­ тывать их с помощью обработчиков событий. ■

Событие c l i c k инициируется при нажатии кнопки на странице.

Для обработки событий c l i c k необходимо

Для добавления элемента в качестве дочер­ него по отношению к родительскому элементу

написать функцию, а затем присвоить ее имя

в DOM необходимо извлечь ссылку на роди­

свойству КНОПКИ o n c l i c k .

тельский элемент и вызвать в отношении него

Если обработчик событий c l i c k зарегистри­

При добавлении множественных дочерних

мощью мыши.

элементов в родительский элемент с исполь­

Для реагирования на события c l i c k не­

сообщения для пользователя в диалоговых окнах a l e r t , обновлять страницу, а также выполнять другие действия. Для извлечения данных, введенных пользова­ телем в текстовое поле формы, необходимо использовать свойство v a l u e поля ввода. Если пользователь ничего не ввел в текстовое поле формы, значением данного поля будет пустая строка (""). ■

142

глава 3

зованием a p p e n d C h ild КЭЖДЫЙ НОВЫЙ ДОчерний элемент будет добавляться после всех прочих уже имеющихся там дочерних элементов, в результате чего они окажутся расположены позади или под дочерними элементами, которые уже присутствовали на странице (при условии, что вы не станете вно­ сить изменения в макет посредством CSS). Вы можете использовать API-интерфейс Web 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.

и ==. ■

ap pend C h ild , передав при этом дочерний элемент, который требуется добавить.

когда пользователь щелкнет на кнопке с по­

в функции обработчика. Можно выводить

ции, чтобы указать, какой элемент вы хотите создать.

ся их обработкой. Для этого нужно сначала

обходимо написать соответствующий код

имя тега (например, " l i " ) в вызов функ­

зарегистрировать функцию, которая и займет­

рован, то данная функция будет вызываться,

Используйте d o c u m e n t . c r e a t e E l e m e n t для создания новых элементов. Передайте

В следующей главе мы еще больше расска­

Для добавления нового элемента в объектную

жем о DOM и JavaScript-возможностях, таких

модель документа его сначала нужно создать,

как функции и объекты.


события и обработчики

Ц

Щ

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


решение упражнения

гр ш е н и е ПОП

решение Здесь приведен плейлист, для которого вам необхо­ димо нарисовать объектную модель документа в том виде, который он приобретет после добавления всех этих песен. Обратите внимание на порядок, в котором песни были добавлены на страницу, и разместите

Blue Suede Strings,

byElvis Pagely

Great Objects on Fire,

byJerry JSON Lewis

byJohnny JavaScript

соответствующие элементы на своих местах в DOM.

I Code the Line,

Наше решение выглядит так.

That'll be the Data, by Buddy Bitlyand the Variables

|

С |

head

|

Your Random Heart, by Hank "Math" Williams

document

html

body

title

|

А вот остальная часть POM | ul id= “playlist” ^

Blue Suede Strings, by Elvis Pagely

Great O bjects on Fire, by J e rry J S O N Lewis

Your Random H e a rt, by Hank “Math" Williams That'll be the Data, by Buddy Bitly and the Variables I Code th e Line, by Johnny JavaScript

Пришлось ли вам строить какие-либо предположения насчет порядка, в котором элементы < i i > добавляются в родительский элемент?

144

глава 3

Д а , поскольку он влияет на п о ­ рядок отображения песен на странице; appendChild всегда добавляет новый элемент после дочернего элементаj который уже т ам был до него.


события и обработчики

Ц

Щ

§

- к

Г °с с Б о Г д . ^ ш е н и е

дальше ►

145



4

^JJhkUuu и ойьетсщы jaVaScript

Серьезный JavaScript+

М ожете л и вы уже назвать себя создателем сценариев? Вполне возможно, поскольку вы уже многое знаете о JavaScript, однако кто захочет быть простым писателем сценариев, когда можно быть программистом? Пора проявить серьезность и поднять планку, — настало время познакомиться с функциями и объектами. Они являются ключом к написанию более эффек­ тивного, лучше организованного и легкого в сопровождении кода. Они также активно используются наряду сАР1-интерфейсами HTML5 JavaScript, поэтому чем лучше вы будете в них разбираться, тем быстрее сможете освоиться с тем или иным новым API-интерфейсом и начать его использовать. Пристегнитесь, поскольку эта глава потребует вашего всецелого внимания...


оценка своих сил

Расширяем ваш словарный запас В ы у ж е м н о го е ум еете делать с н о м о щ ь ю Ja v a S c rip t. Д а в а й те в згл я н е м н а т о , ч т о вам у ж е н о силам :

Извлечение элемента из объект ной модели документа (РОМ)

С

<script>

var guessInput = document.getElementByld(Mguess M); var guess = guessInput.value;

Извлечение значения т е к­ стового поля ввода формы.

var answer = null;

Создание нового массива, заполненного строками.

var answers = [ "red", "green" , "blue"];

Г

И спользование библиот ек ф ункций.

V

И звлечение т акого свойства м ассива, к а к len gth.

var index = Math.floor (Math, random() * answers.length); ^

if (guess =

answers [index]) {

ч

Принятие решений на основе результатов проверки условий.

answer = "You're right! I was thinking of " + answers[index]; } else {

^

answer = "Sorry, I was thinking of " + answers[index]; }

Использование элементов массива.

alert(answer); </script>

Использование браузерных функций (например , alert).

О д нако н о ка м н о ги е ваш и зн а н и я явл яю тся неф орм альны м и. В ы , ко н е ч н о , зн а е те , к а к и з в л е ка т ь э л е м е н т ы и з о б ъ е к т н о й м о д е л и д о к у м е н т а ( D O M ), п р и ­ сва и ва ть н о в ы е з н а ч е н и я , н о е сли м ы н о н р о с и м вас о б ъ я с н и т ь , ч т о т а к о е d o c u m e n t . g e t E l e m e n t B y ld в т е х н и ч е с к о м п л а н е , в е р о я т н о , у вас в о з н и к н у т с эти м н е ко т о р ы е труд ности. Н о не с то и т б е сно ко иться , но ско л ьку к ко н ц у гл а в ы в ы с м о ж е те без труда сделать э то . А ч т о б ы вам э то д е й с т в и т е л ь н о удалось, м ы н е с та н е м н а ч и н а т ь с гл у б о к о го ана л и за g e t E l e m e n t B y ld , а за й м е м ся ко е -ч е м более интересным: р а с ш и р и м ваш с л о в а р н ы й занас в о б л а с ти J a v a S c rip t и н а у ч и м с я делать н о в ы е ве щ и .

148

глава 4


функции и объекты javascript

Как добавить свои собственные функции Ранее мы с вами иснользовали встроенны е функции, нанример a l e r t или даж е Math, random, но вдруг у вас возникнет необходим ость добавить свою собственную функцию? Донустим, мы захотели нанисать код вроде следующего: var guessInput = document.getElementByld("guess"); var guess = guess Input, value;

guess поль3о ват еля

*4^ ^

т очно т а к же, как и на п р е д ы д у щей странице...

var answer = checkGuess (guess) ; al

/ a n e w p r\ •

A\

^

ЖеА| з а м е н и т ь на и з я и ш ,, ^ д,

--

основного кода , м ы м о -

смож ем вы зы ват ь и M m ^ J ^ deTa^m Cke° kQuess‘ ко^ о р у н > *мо же самое.

Создание функции checkGuess Q

Для создания функции необходимо воспользоваться ключевым словом function, после которого следует указать ИМЯ, например checkGuess.

function checkGuess(guess)

{

var answers = [ "red" , "green" ,

Своей функции вы можете передавать ноль и более параметров. Используй­ те параметры для передачи значений функции. Здесь нам требуется один параметр: guess пользователя.

"blue"];

var index = Math, floor (Math, random () * answers.length);

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


как работают функции

Как работает функция Т а к к а к ж е все э то р аб отает? Ч т о п р о и с х о д и т , к о гд а м ы действительно вызываем ф у п кц и ю ? Д а в а й те в згл я п е м в о б щ и х ч е р т а х .

function bark(dogName f dogWeight)

Итак, сначала нужно создать ф ункцию .

{

if (dogWeight <= 10) {

Д о п усти м , м ы то л ько ч т о паписал и повую ф у п к ц и ю b a r k , у к о т о р о й и м е е т с я два па р а м е ­ тр а : dogN am e и d o g W e i g h t , а т а к ж е весьм а зап и м а т е л ь п ы й ф р а гм е п т ко д а , в о з в р а щ а ю щ и й к л и ч к у с о б а к и и т о , ч т о о п а лает, в за в и с и м о ­ с т и о т т о г о , к а к о й о п а и м е е т вес.

return dogName + " says Yip"; } else { return dogName + " says Woof"; }

В о т н а ш а удобная ф у н к ц и я bark.

Теперь давайте вызовем функцию !

Имя нашей функции

В ы у ж е зп а е те , к а к в ы зы в а т ь ф у п к ц и ю : п у ж п о п р о с т о в в е с ти ее и м я и п е р е д а ть е й все н е ­ о б х о д и м ы е а р гу м е п т ы . В д а п п о м случае п а м п о т р е б у е т с я п е р е д а ть два а р гу м е п та : с т р о к у с к л и ч к о й с о б а к и и вес с о б а к и в вид е ц е л о го чи сл а .

Здесь мы переда­ ем два аргумента: кличку и вес.

bark("Fido", 50)

Д а в а й те в ы п о л п и м в ы зо в и п о с м о т р и м , к а к все э то р а б о та е т:

При вы зо ве b a r k а р г у м е н т ы присваиваю т ся им енам п а ­ р а м е т р о в в ф у н к ц и и bark.

function bark(dogName , dogWeight) if (dogWeight <= 10) { return dogName +

says Yip";

else {

И каждый раз , когда параметры встреча­ ются в функцииj будут использоваться пере­ данные нами значения.

150

глава 4

return dogName +

says Woof";


функции и объекты javascript

А теперь давайте позволим телу ф унк­ ции сделать свою работу. П осле то го ка к м ы п р и с в о и л и зпа чепие ка ж ­ д о го а р гу м е п та с о о тв е т с тв у ю щ е м у п а р а м е тр у в ф у п к ц и и (п а п р и м е р , "Fido" для dogN am e и целое ч и с л о 50 для d o g W e i g h t ) , м ы г о т о в ы п е р е х о д и т ь к о ц е п к е в се х о п е р а т о р о в в теле ф упкц ии . О п е р а то р ы о ц е пи в а ю тся сверху в п и з, к а к и л ю б о й д р у г о й к о д , к о т о р ы й в ы п и ш е т е . Разп и ц а з а кл ю ч а е тс я в т о м , ч т о м ы будем делать э то в среде, где и м е п а п а р а м е тр о в d ogN am e и d o g W e i g h t п р и с в а и в а ю т с я а р гу м е п та м , п ередаппы м в ф упкц ию .

function bark(dogName, dogWeight)

{

if (dogWeight <= 10) { return dogName + " says Yip"; } else { return dogName + " says Woof"; }

Здесь мы оцениваем весь код в теле функции.

Помните, что функции необязательно должны возвращать значения. Однако в данном случае О пционально у нас могут иметься функция bark возвращает значение. операторы return в теле ф ункции... А когда строка ... где м ы будем в о зв р а щ а ть з п а ч е п и е коду, возвращается, с о в е р ш и в ш е м у в ы зо в . Д а в а й те п о с м о т р и м , она присваива­ к а к э то р а б о та е т: Строка "Fido says Woof" ется переменной возвращается вызывающе­ sound, которая м у коду (то есть коду, вы­ затем переда­ К а к «кЗ ко « “„Л и ам ' звавшему функцию bark). ется alert, в р е ­ „ д „ не ровен зультате чего на экран выво­ дится диалоговое окно с соот­ "Fido says W o o f ветствующим сообщением. function bark(dogName, dogWeight) {

ED У

^ if (dogWeight <= 10) { (

return dogName + " says Yip";

var sound = bark("Fido " , 50); alert(sound);

} else {

V

c

return dogName + 11 says Woof" ; }

h ttp ://lo c a lh o st Fido

дальше ►

151


важность функций и объектов

Я неустанно твержу вам, что все A P I-интерфейсы HTM L5 битком набиты функциями, объектами и прочими продви­ нутыми JavaScript-возможностями...

Если бы у нас была лишняя минутка поговорить... В ы дум али, ч т о в главе 4 будете а к т и в п о п о з п а в а т ь п о в о е в H T M L 5 ? К о п е ч п о ж е , т а к и будет. О д п а к о п р е ж д е вам о б я ­ за те л ь н о п у ж п о р а зо б р а ть с я в т о м , ч т о и м е п п о я в л я е тс я 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 в H T M L 5 с о с т о я т и з о б ъ е кт о в , м е­ т о д о в (т а к ж е п а зы в а е м ы х функциями) и с в о й с т в . Ч т о б ы п о -п а с то я щ е м у овлад еть A P I-и п т е р ф е й с а м и J a v a S c rip t, вам п е о б х о д и м о х о р о ш о р а зб и р а т ь с я в э т и х вещ ах. Е с те с тв е п п о , в ы м о ж е т е п о п ы т а т ь с я о б о й т и с ь и без з п а п и й о п и х , од­ п а к о в т а к о м случае п р и и с п о л ь з о в а п и и А Р 1 -и п те р ф е й с о в вам п р и д е т с я п о с т о я п п о с т р о и т ь д о га д к и , ч т о п е п о з в о л и т вам п о л п о с т ь ю за д е й с тв о в а ть и х п о т е п ц и а л (п е го в о р я уж е о т о м , ч т о в ы будете с о в е р ш а ть м ассу о ш и б о к и п и с а т ь пек а ч е с т в е п п ы й к о д ). М ы р е ш и л и о б р а т и т ь ваш е в п и м а п и е п а д а п п ы е а с п е к т ы , ч т о б ы в ы зп а л и , ч т о вас о ж и д а е т в п е р е д и . С ам ое замечате л ь п о е за к л ю ч а е тс я в т о м , ч т о к к о п ц у гл а в ы в ы будете р а зб и р а т ь с я в о б ъ е кта х , ф у п к ц и я х , м е то д а х и массе п р о ч и х с в я з а п п ы х с п и м и в е щ е й л уч ш е , ч е м п р и м е р п о 98 % л ю д е й , за н и м а ю щ и х с я п а п и с а п и е м с ц е п а р и е в . И э то п е ш у тка .

152

глава 4


функции и объекты javascript

« р у н к ц и ю Интервью недели:

Вещи, о которых вы не знали Head First: Д о б р о п о ж а л о в а ть , Ф у п к ц и я ! Н а д е ю сь, с е го д п я В ы п ове д а е те п а м м п о го е о себе. Function: Рада б ы т ь здесь. Head First: М ы за м е т и л и , ч т о в п а с то я щ е е в р е м я м п о ги е п о в и ч к и в J a v a S c rip t п е с к л о п п ы с л и ш к о м ч а с т о и с п о л ь з о в а т ь Вас. О п и п р о с т о п и ш у т с в о й ко д , с т р о к а за с т р о к о й , д в и га я с ь с в е р х у в п и з . П о ­ ч е м у и м с то и л о б ы уделять В ам б о льш е в п и м а п и я ?

о п и исп о л ь зую т и х п о с то я п п о : a l e r t , docum ent. g e tE le m e n tB y ld , M ath. random. О п и п р о с т о п е о п р е ­ д е л я ю т свои собственные ф у п к ц и и .

Head First: Ч т о ж , в е р п о , в случае с a l e r t все п о п я т п о , п о в о т д р у ги е две совсем п е п о х о ж и па ф у п кц и и .

Function: Э то ф у п к ц и и , в и д и т е л и ... п о с т о й т е -к а , м и п у т о ч ку ... ...М п е т о л ь к о ч т о с к а з а л и , ч т о ч и т а т е л и ещ е п е

Function: Д а , п е с к л о п п ы , и э то п р и с к о р б п о , п о ­ с к о л ь ку я пе су в себе б о л ьш и е в о з м о ж п о с т и . Д у м а й ­ те о б о м п е т а к: я — т о , ч т о п о з в о л я е т вам п а п и с а т ь к о д о д и п раз, а за те м п о в т о р п о и с п о л ь з о в а т ь е го .

п о з п а к о м и л и с ь с э т и м и т и п а м и ф у п к ц и й , о д п а ко

Head First: П р о с т и т е , ч т о с п р а ш и в а ю , п о е сли В ы

Head First: И т а к , ф у п к ц и я в о зв р а щ а е т з п а ч е п и е , п равил ьпо? В связи с э ти м х о ч у с п р о с и ть : а ч т о ,

п р о с т о даете и м в о з м о ж п о с т ь делать о д п и и те ж е в е щ и с п о в а и спо ва ... э то ведь п е м п о г о с к у ч п о , п е т а к ли?

Function: Н е т-п е т, ф у п к ц и и я в л я ю т с я п а р а м е т р и ­ з о в а н н ы м и . Д р у г и м и сл о в а м и , к а ж д ы й р а з, к о гд а в ы и с п о л ь зуе те ф у п к ц и ю , в ы м о ж е те п ередавать ей а р гу м е п т ы , б л а го д а р я ч е м у ста п е те п о л у ч а т ь пазад резул ьта ты , к о т о р ы е будут о тл и ч а т ь с я д р у г о т д р уга в з а в и с и м о с т и о т т о г о , ч т о в ы е й пе р е д а л и .

о п и сдел аю т э то ч е р е з п е с к о л ь к о с т р а п и ц . Т а к и л и и п а ч е , след ует о т м е т и т ь , ч т о ф у п к ц и и и с п о л ь з у ­ ю т с я повсю ду.

е сли у м е п я п е т з п а ч е п и я , к о т о р о е я х о ч у верпуть?

Function: М п о г и е ф у п к ц и и в о з в р а щ а ю т зп а ч е п и я , о д п а к о ф у п к ц и я во все п е о б я за те л ь п о д о л ж п а п о ­ с ту п а ть та к. Е сть п ем ало ф у п к ц и й , к о т о р ы е п р о с т о де л а ю т ч т о -то , п а п р и м е р о б п о в л я ю т о б ъ е к тн у ю м о­ дель д о ку м е п т а (D O M ) , п о с л е ч е го п е в о зв р а щ а ю т п и к а к о г о з п а ч е п и я , и все п р е к р а с п о .

Head First: То есть в т а к и х ф у п к ц и я х о т с у т с т в у ю т

Head First: А п е л ь зя л и п р и в е с т и п р и м е р ?

о пе р а то р ы return?

Function: Д о п у с т и м , в а м п е о б х о д и м о с о о б щ а т ь пользователям сто и м о сть то ва р о в, ко то р ы е о п и п о м е с ти л и в св о ю э л е к т р о п н у ю к о р з и н у в и п т е р п е т м а га з и п е , п о э т о м у в ы р е ш и л и п а п и с а т ь ф у п к ц и ю com puteShoppingC a r t T o t a l . Сделав э то , в ы с м о ж е ­ те п е р е д а в а ть ф у п к ц и и р а з л и ч п ы е э л е к т р о п п ы е к о р з и п ы , п р и н а д л е ж а щ и е р а з п ы м п о л ь зо в а те л я м , и к а ж д ы й ра з п о л у ч а т ь с о о тв е т с тв у ю щ е е з п а ч е п и е сто и м о сти товаров в ко п к р е т п о й ко р зи п е .

Function: Д а , и м е п п о та к.

...К с т а т и , в о з в р а щ а я с ь к В а ш е м у з а м е ч а п и ю пасчет то го , ч то п о в и ч к и пе о чепь часто использу­ ю т ф у п к ц и и ; п а с а м о м деле э то п е т а к , п о с к о л ь к у

Head First: Ч т о ж , а к а к п а с ч е т п р и с в а и в а н и я и м е п с в о и м ф у п кц и я м , а то м п е д о в о д ил о сь слы ш а ть, ч т о э то делать п е о б я за те л ь п о , е сли п е х о ч е т с я .

Function : Д а в а й те п е будем и з л и ш п е п у га ть ауди то ­ р и ю . Д а в а й те в е р п е м с я к э т о й тем е, ко гд а ч и т а т е л и у з п а ю т о б о м п е п е м п о г о больш е?

Head First: О б е щ а е те м п е д ать э к с к л ю з и в п о е и п те р в ь ю ?

Function: М ы э то ещ е обсудим ... дальше ►

153


параметры и аргументы

Не уверена, что понимаю разницу между параметром и аргументом: это случайно не одно и то же?

Нет, это разные понятия. П р и о п р е д е л е н и и ф у н к ц и и в ы м о ж е т е определишь ее с и с п о л ь з о в а н и е м о д н о го и л и более параметров.

Здесь мы определяем три параметра: degrees, mode и duration.

j func t i o n coo k ( d e g r e e s , mode,

duration)

{

// здесь будет валя код }

П р и в ы зо в е ф у н к ц и и в ы вызываете ее с и с п о л ь зо в а ­ н и е м аргументов:

\ т?

cook(425.0, "bake", 45);

Это аргументы. Здесь имеются три аргумента: число с плавающей точкой строковое значение и целое число. cook(350.0, "broil", 10); Т а к и м о б р а зо м , с в о и п а р а м е т р ы в ы будете о п р е д е л я ть т о л ь к о о д и п р аз, а в ы зы в а т ь с в о и ф у п к ц и и ста п е те с и с ­ п о л ь з о в а н и е м м а ссы р а з п ы х а р гу м е н то в .

^

3 ас удивит, насколько много людей путается в том, где исполь­ зуются параметры, а где аргументы. 3 некоторых книгах даже встречается неверное толкование, поэтому если вы где-то увидите, что утверждается обратное, то будете знать, где правда...

Функцию определяют с использованием параметров, а вызывают с использованием аргументов. 154

глава 4


функции и объекты javascript

Днапк>Мия «^нкДии Т е п е р ь , ко гд а в ы зп а е те , к а к о п р е д е л я ть п в ы зы в а т ь ф у п к ц и и , давай те уб е д и м ся , ч т о в ы х о р о ш о р а зб и р а е те с ь в с и п т а к с и с е . В о т к а к в ы гл я д я т с о с та в п ы е ч а с т и а п а т о м и и ф у п к ц и и :

Вначале всегда должно идти ключе­ вое слово function.

г Затем идут з а После ключевого слова ключенные в круглые function следует имя скобки и разделенные вашей функции. запятой параметры, которых может быть ноль и более.

к

var bonus = level * score * .1; return score + b o n u s ;

Это закрыва­ ющая скобка тела функции.

Даже если у вашей ф ункции нет параметров, вам по-прежнему необходимо указать открывающую и закрывающую скобки,

Тело функции заклю ­ чается в две фигурные скобки и содержит набор операторов (точно так же, как привычные для вас операторы).

Оператор re tu rn включает выражение, которое возвра­ щается в качестве резуль­ тата вызова функции.

Функция может вклю ­ чать оператор с ключе­ вым словом return, однако это вовсе не обязательно.

Часш°

зад аваем ы е

.........

B o T L j= > o tb l Почему перед именами параметров

] ) • Я передаю переменную своей функ­

не ставится var? Параметр — это же но­

ции; если я изменю значение соответ­

вая переменная, ведь так?

ствующего параметра в моей функции, то приведет ли это также к изменению

0 : Да, так и есть. Функция сделает за вас всю работу по созданию экземпляра пере­ менной, поэтому вам не нужно указывать ключевое слово v a r перед именами своих параметров.

моей исходной переменной?

Смогу ли я изм енять значен и я в функции?

0 : Вы сможете изменять только значения глобальных переменных (они определяются вне функций) или переменных, которые вы

0 : Нет. Когда вы передаете примитивное значение, оно копируется в параметр. Мы

явно определили в своей функции. Вскоре мы чуть подробнее затронем эту тему.

называем это «передача по значению». Таким образом, если вы измените значение

Котсутствует - - оператор — , *return? ™

. -

^ 3 * Каковы правила присваивания имен

параметра в теле своей функции, то это

функциям?

никак не повлияет на оригинальное значе­

0 : Они аналогичны правилам присваива­ ния имен переменным.

является передача массива или объекта, но

0 : Функция без оператора r e t u r n воз­

об этом мы поговорим чуть позже.

вращает значение u n d e f in e d .

ние вашего аргумента. Исключением здесь

дальше ►

155


упражнение

^озьлли в руку карандаш_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Воспользуйтесь своими знаниями о функциях и передаче аргументов параметрам для оцен­ ки приведенного ниже кода. Сделав это, напишите внизу, какое значение будет иметь каждая из переменных. Проверьте свои ответы, посмотрев решение этого задания в конце главы, прежде чем двинетесь дальше.

function dogsAge(age)

{

return age * 7; }

var myDogsAge = dogsAge (4) ; function rectangleArea(width, height)

{

var area = width * height; return area; }

var rectArea = rectangleArea(3, 4); function addUp(numArray)

{

var total = 0; for (var i = 0; i < numArray.length; i++) { total += numArray[i]; }

return total; }

var theTotal = addUp([1, 5, 3, 9]); function getAvatar(points)

{

Напишите здесь, какое значение б у ­ дет и м ет ь каждая из

var avatar; if (points < 100) { avatar = "Mouse"; } else if (points > 100 && points < 1000) {

С

avatar = "Cat"; } else { avatar = "Ape";

myDogsAge = .............

}

rectArea =

.............

}

theTotal =

.............

var myAvatar = getAvatar(335);

myAvatar =

.............

return avatar;

156

глава 4


функции и объекты javascript

Налл нужно поговорить о некото­ рых особенностях использова­ ния переменных...

Локальные и глобальные переменные НуЖно знать разницу меЖду ними В ы у ж е зп а е те , ч т о м о ж е т е о б ъ я в л я ть п е р е м е п п ы е с и с п о л ь зо в а ­ н и е м к л ю ч е в о го слова v a r и и м е п и где у го д п о в св о е м J a v a S c rip tко д е :

Это гл о б а л ь н ы е п е р е м е н н ы е j

var avatar;

\ С ~ они п о в с е м е с т н о д о с т у п н ы в в а ш е м J a v a S c r i p t -коде.

var levelThreshold = 1000;

В ам т а к ж е и з в е с т п о , ч т о п е р е м е п п ы е м о ж п о о б ъ я в л я ть и в п у т р и ф у п к ц и и :

function getScore(points) var score;

^

{

Переменные points> score и i объявляются внутри функции.

for (var i = 0; i < levelThreshold; i++)

{

//code here }

return score;

Мы называем их локальны­ ми переменными, потому что они доступны только локально в самой функции.

Даже если мы используем levelThreshold внутри функцииj она будет глобальной переменной, п о ­ скольку объявлена вне функции.

Еслииеремеииая объявлена внефункции, тооиаявляется ГЛОБАЛЬНОЙ. Еслиже иеремеииая объявленавнутри функции, тооиа— ЛОКАЛЬНАЯ

О д п а к о к а к о е все э то и м е е т зп а ч е п и е ? П е р е м е п п ы е есть п е р е ­ м е п п ы е , п е т а к ли? Ч т о ж , о т т о г о , гд ^ в ы о б ъ яв л яе те с в о и п е р е ­ м е п п ы е , за в и с и т, насколько о п и будут видимы для о с т а л ь п о й ч а с т и ва ш е го код а. А п о п и м а п и е т о г о , к а к р а б о т а ю т две э т и р а зп о в и д п о с т и п е р е м е п п ы х , в п о с л е д с т в и и п о м о ж е т вам п и с а т ь более л е г­ к и й в с о п р о в о ж д е п и и к о д (п е г о в о р я у ж е о т о м , ч т о э то п о м о ж е т вам р а з о б р а ть с я в ко д е , п а п и с а п п о м д р у ги м и л ю д ь м и ).

дальше ►

157


локальная и глобальная область видимости

Понятие области видимости локальных и глобальных переменных От т о г о , где вы определяете своп перемеппые, будет зависеть их область видимости', то есть там, где перемеппые определепы и пе определепы, опи соответствеппо будут видимы и певидимы для вашего кода. Давайте взгляпем па пример, где присутствуют перемеппые как с локальпой, так и с глобальпой областью видимости. Помпите, что перемеппые, которые вы определяете впе фупкции, будут обладать глобальпой областью видимости, а перемеппые, определяемые впутри фупкции, —локальпой областью видимости. Э т и ч е т ы р е п ер ем енны е обла даю т г л о ­ бальной о б ла с т ь ю в и д и м о с т и , т о ест ь они определены и видимы во всем п р и в е ­ денном ниже коде.

var avatar = "generic"; var skill = 1.0;

С ледует о т м е т и т ь , ч т о если вы у к а ­ жете ссылки на д о п олни т ель ны е с ц е ­ нарии в своей с т р а н и ц е , т о они тоже с м о г у т у в и д е т ь глобальные перем енны е!

var pointsPerLevel = 1000; var userPoints = 2008;

function getAvatar(points)

{

var level = points / pointsPerLevel;\ 4

if (level =

o) (

\

return "Teddy bear";

\ \

} else if (level == 1) { return "Cat"; } else if (level > =2 )

\

return "Gorilla";

О б р а т и т е в н и м а н и е , чт о в случае с g e t A v a t a r также и с п о л ь з у е т с я г л о ­ бальная пер ем е н н а я p o in ts ? e rL e v e i

function updatePoints(bonus , newPoints)

newPoints += skill * bonus; }

return newPoints + userPoints;

userPoints = updatePoints(2, 100) avatar = getAvatar(2112);

158

глава 4

Не будем забы ват ь о п а р а м е т р е p o in ts , к о т оры й также обладает лок а ль ной о б ла с т ь ю ви д и м о с т и в ф у нкции g e tA v a ta r.

{

for (var i = 0; i < bonus; i++)

Переменная level здесь я вля ет с я л о к а л ь - ной и видимой т о ль к о для кода в н у т р и ф ун кц и и g e tA v a ta r. Это о з н а ч а е т , чт о т о ль к о данная ф у нкци я см ож ет п о л у ­ ч и т ь д о с т у п к пер ем е н н о й level.

{

8 u p d a te P o in ts у нас и м е е т с я л о к а л ь ­ ная п ер е м е н н а я L Д а н н а я п ер е м е н н а я видима для всего кода в updatePoints. bonus и n e w P o in ts также я в л я ­ ю т с я л о к а ль н ы м и по о т н о ш е ­ нию к u p d a te P o in ts , в т о вр е м я как userPoints я вля е т с я глобальной п е р е ­ менной. А здесь в коде м ы мож ем и с п о л ь з о в а т ь т о л ь к о глобальные п е р е м е н н ы е , пр и

э т о м у нас н е т д о с т у п а к к а к и м - л и б о п е р е м е н н ы м в н у т р и ф у н к ц и й , поскольк у они невидимы в глобальной области.


функции и объекты javascript

Готов поклясться, что переменная была прямо у меня за спиной, но когда я обернулся, она уже исчезла.

Недолгая Жизнь переменных Е сли вы — и е р е м е и и а я , т о вам п р и х о д и т с я пел е гк о и ваш а ж и з п ь м о ж е т о ка за т ь с я к о р о т к о й . Т а к и будет, е сли в ы , к о п е ч п о , п е я в л я е те сь гл о ­ б а л ь п о й п е р е м е п п о й , х о т я д а ж е в случае с п и м и п р о д о л ж и т е л ь н о с т ь ж и з п и о гр а п и ч е п а . Н о ч т о о п р е д е л я е т д л и т е л ь н о с т ь с у щ е с тв о в а н и я п е р е ­ м е п п о й ? Д е л о о б с т о и т сл е д у ю щ и м о б р а зо м :

Глобальные переменные существуют столько же, сколько и соответствующая веб-страница. Ж и з п ь гл о б а л ь п о й п е р е м е п п о й п а ч и п а е т с я , ко гд а ее J a v a S c rip t з а гр у ж а е тс я в стр а п и ц у . О д ­ п а к о ж и з п ь в а ш е й гл о б а л ь п о й п е р е м е п п о й за­ к о н ч и т с я , к а к т о л ь к о п о л ь зо в а те л ь п о к и п е т ве б -стра п иц у. Д а ж е е сли о п п е р е з а гр у з и т ту ж е сам ую стр а п и ц у , все в а ш и гл о б а л ь п ы е п е р е м е п ­ п ы е будут у п и ч т о ж е п ы , а за те м в о с с о зд а п ы в за­ по во за гр у ж е п п о й страпиц е.

Локальные переменные обычно исчезают по за­ вершении работы функции. Л о к а л ь п ы е п е р е ­ м е п п ы е со зд а ю тс я п р и п е р в о м в ы зо в е в а ш е й ф у п к ц и и и ж и в у т до т е х п о р , п о к а э та ф у п к ц и я п е з а к о п ч и т с в о ю р а б о ту (в о з в р а т и в п р и э т о м з п а ч е п и е и л и ж е п е т ). С ледует о т м е т и т ь , ч т о в ы м о ж е т е в зя ть з п а ч е п и я с в о и х л о к а л ь п ы х пер е м е п п ы х и в о з в р а т и т ь и х и з ф у п к ц и и до т о г о , к а к э ти пе р е м е ппы е предстапут перед ц и ф р о ­ в ы м т в о р ц о м п а т о м свете.

Мы сказали «обычно», поскольку существуют особые способы сохра­ нить жизнь локальным переменным на более длительный срок, однако мы не станем беспокоиться о них сейчас.

Т а к ч т о ж е , п о л у ч а е тс я , «сбеж ать» о т с т р а п и ц ы п и к а к Н Е Л Ь З Я ? Е сл и в ы — л о ка л ь п а я п е р е м е п п а я, т о ваш а ж и з п ь п р о л е т а е т б ы с т р о . Н о если вам п о в е зл о р о д и т ь с я гл о б а л ь п о й п е р е м е п п о й , т о в ы будете зд р а в с тв о в а ть , п о к а п о л ь зо в а те л ь п е п е р е з а гр у з и т с т р а п и ц у в б раузере.

Присоединяйтесь к нам в главе, посвященной A P I -инт ерф ейсу Web Storage, где мы помож ем ваш им _ данным избежать «уж асаю щ их» О д п а к о в с е -та ки должен с у щ е ств о в а ть с п о с о б для н и х последствий перезагрузки «сбежать» о т с т р а п и ц ы ! М ы м о ж е м е го п а й т и ! веб-странии,ы! К а к в ы считаете?

дальше ►

159


переменные в тени

Интересно, что будет, если я присвою локальной переменной то же имя, которое имеет уже суще­ ствующая глобальная пере­ ев

V

менная?

Помещаем «в тень» глобальную переменную. В о т ч т о м ы и м е е м в виду. Д о п у с т и м , у вас е сть гл обал ь­ н а я п е р е м е н н а я b e a n C o u n t e r и в ы о б ъ яв л яе те ф у п к ­ ц и ю , к а к п о к а з а н о далее:

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 Част°

ЧаДаВаеМые В опросы

При отслеживании области видимости всех этих локаль­ ных и глобальных перемеренных можно запутаться, так почему же не использовать только глобальные переменные? Я именно так всегда и поступаю.

0 : Если вы пишете код, который является сложным или будет нуждаться в длительном сопровождении, то нужно внимательно следить за тем, как вы распоряжаетесь своими переменными. Если вы слишком рьяно будете создавать глобальные переменные, вам станет сложно уследить за тем, где они используются (и где вы вносите изменения в значения своих переменных), что может привести к написанию некачественного кода. Все это окажется даже еще более важным, если вы будете писать код совместно с коллегами или станете использовать сторонние библиотеки (даже если они окажутся грамотно написанными, то все равно должны быть структурированы во избежание проблем). Таким образом, глобальные переменные следует использовать там, где это имеет смысл, но при этом необходимо проявлять умерен­ ность, и всякий раз, когда предоставляется возможность, делать свои переменные локальными. По мере увеличения опыта работы с JavaScript вы будете узнавать дополнительные методики структу­ рирования кода, чтобы он оказался более легким в сопровождении.

К

............. ...................................

создаете глобальную переменную. Следует отметить, что мы не рекомендуем прибегать к такой практике кодирования; не только потому, что она потенциально способна сделать ваш код неудобо­ читаемым, но и потому, что, как считают некоторые люди, данное поведение может однажды измениться в реализациях JavaScript (что, возможно, приведет к нарушению вашего кода). Нужно ли мне определять функцию, прежде чем исполь­ зовать ее, и может ли объявление функции появиться где угодно в моем сценарии?

0 : Объявления функций могут появляться где угодно в вашем сценарии. Если захотите, вы можете объявить функцию ниже, там, где будете использовать ее. Это можно делать, поскольку когда вы загружаете свою страницу в первый раз, браузер производит разбор всего JavaScript, имеющегося на странице (или располагающегося во внешнем файле), и видит объявление функции до того, как начнет выполнение кода. Вы также можете размещать объявления глобальных переменных в любой части своего сценария, однако мы рекомендуем объявлять все свои глобальные переменные в верхней части файлов, чтобы их легче было отыскать. При использовании более одного внешнего JavaScript-файла следует учитывать, что при наличии двух функций с одинаковым именем в разных файлах будет использоваться та, которую браузер увидит последней.

однако я загружаю еще и дополнительные JavaScript-файлы. Эти файлы будут видеть отдельны е наборы глобальных переменных?

Кажется, что все жалуются на чрезмерное использование глобальных переменных в JavaScript. Почему так происходит? Язык JavaScript был не слишком удачно спроектирован, или же

0 : Поскольку существует только одна глобальная область види­ мости, каждый файл, который вы загружаете, будет видеть один и тот же набор переменных (и генерировать глобальные перемен­ ные в одном и том же пространстве). Вот почему так важно быть внимательным при использовании переменных — это позволит избежать конфликтов (кроме того, необходимо стараться снизить количество или вообще убрать глобальные переменные, если это представляется возможным). ^ 3 * Мне доводилось видеть код, в котором не используется ключевое слово var при присваивании значения имени новой переменной. Как такое возможно?

0 : Да, так можно поступать; когда вы присваиваете значение имени переменной, которая ранее не была объявлена, она будет рассматриваться как новая глобальная переменная. Поэтому будьте осторожны, если делаете это внутри функции, в которой

люди не знают, что делают, или причина в чем-то еще? И как нам быть в данной ситуации?

0 : Глобальные переменные часто с излишком используются в JavaScript. Отчасти причина этого заключается в том, что язык JavaScript позволяет легко освоиться и начать писать код, и это хорошо, поскольку JavaScript не навязывает вам массу всяких структур и прочей нагрузки. Недостатки начнут проявляться при написании серьезного кода, который будет претерпевать измене­ ния и нуждаться в сопровождении в течение длительного времени (что в большой степени характеризует все веб-страницы). Следует отметить, что JavaScript является мощным языком и включает различные возможности, например объекты, которые вы можете использовать для организации своего кода модульным образом. На эту тему написано много книг, а «попробовать на вкус» объекты вы сможете во второй части этой главы (до нее осталось всего несколько страниц).

дальше ►

161


функции как значения

Функции еще являются и значениями И т а к , м ы с ва м и и с п о л ь зо в а л и п е р е м е п п ы е для р а зм е щ е п и я ч и с л о в ы х и л о г и ч е с к и х з п а ч е п и й , с т р о к , м а сси в о в и в с е го п р о ч е г о , п о у п о м я п у л и л и м ы о т о м , ч т о в ы т а к ж е м о ж е т е п р и с в а и в а т ь ф у п к ц и ю п е р е м е п п о й ? В з гл я п и т е п а с л е д у ю щ и й п р и м е р :

function addOne(num)

1 ^

Определим простую функцию, которая прибавляет 1 к своему аргументу.

return num + 1;

Теперь сделаем кое-что новенькое. Мы воспользуемся именем функции addOne и присвоим addOne новой переменной plusOne.

}

Г var plusOne = addOne;

Обратите внимание , что мы не вызываем функцию посредством addOneQ, а просто указываем имя функции. var result = plusOne(l);

ч

После выполнения данного вызова result будет равен 2.

plusOne присваивается функции , поэтому мы сможем вызывать ее с использованием Целочисленного аргумента в виде г

Ч т о ж е , р а п е е м ы п е т о л ь к о за б ы л и у п о м я п у т ь об э т о й п е б о л ы н о й де та л и , к а с а ю щ е й ­ ся ф у п к ц и й , п о т а к ж е п е со все м б ы л и ч е с т п ы , к о гд а р а с с ка зы в а л и вам об а п а т о м и и ф у п к ц и и , — о ка зы в а е тс я , вам даж е п е п у ж п о п р и с в а и в а т ь и м я с в о е й ф у п к ц и и . Все в е р п о : ваш а ф у п к ц и я м о ж е т б ы ть анонимной. Ч т о ж е все э то з п а ч и т и за ч е м вам м о ­ ж е т п о т р е б о в а т ь с я п о с т у п и т ь так? Д а в а й те сп а ча л а п о с м о т р и м , к а к созд ать ф у п к ц и ю без и м е п и :

function (num) {

Здесь мы создаем функцию , не указывая при этом имени... Хм... Но как же мы тогда сможем сделать что-нибудь при помощи нее?

^

return num + 1;

Давайте сделаем это снова и на этот раз присвоим ее переменной.

r ~ 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);

{ А затем мы сможем ^ использовать нашу . - вызова п .-.~ переменную_ для функции

^

После выполнения данного вызова result будет равен 2.

162

глава 4


функции и объекты javascript

М 9 *Г 9 ? 9 Й Ш ТУРМ Взгляните на данный код: как вы думаете, что он делает? var element = document.getElementByld ("button" ) ;

Все это должно быть для вас немного более понятным, учит ы ­ вая то, что мы сейчас с вами рассмотрели...

element.onclick = function () { alert("clicked!");

к

}

Не беспокойтесь, если вы так и не с м о жете на ZOO % во всем здесь разобраться, поскольку мы еще дойдем до этого...

Что моЖно сделать посредством функций как значений? Т а к в ч е м ж е здесь в а ж п о с ть ? В ч е м польза? В а ж п о с т ь з а к л ю ч а е тс я п е с т о л ь к о в т о м , ч т о м ы м о ж е м п р и ­ сва и ва ть ф у п к ц и ю п е р е м е п п о й , с к о л ь к о в т о м , ч т о э то п а ш с п о с о б п о ка з а т ь вам, ч т о ф у п к ц и я действи­

тельно является значением. А в ы у ж е зп а е те , ч т о м о ж е т е с о х р а п я т ь з п а ч е п и я в п е р е м е п п ы х и л и м а сси ва х, пер е д а ва ть и х в ка ч е с т в е а р гу м е п т о в ф у п к ц и я м и л и , к а к м ы в с к о р е у в и д и м , п р и с в а и в а т ь и х с в о й с т в а м о б ъ е кт о в . О д п а к о в м е с то т о г о , ч т о б ы р а с с ка зы в а т ь ва м о п о л е з п о с т и а п о п и м п ы х ф у п к ц и й , п р о с т о в згл я п е м п а о д и п и з м п о ж е с т в а л ю б о п ы т п ы х с п о с о б о в и с п о л ь з о в а н и я ф у п к ц и й к а к з п а ч е п и й :

Вот простая функция init function init() {

Здесь мы присваиваем определенную нами \load. функцию обработчику событии onl,

alert("you rule!") }

Посмотрите-ка, мы уже исполь­ зовали функции как значения!

window.onload = init;

Л и б о м ы м о ж е м п о с т у п и т ь ещ е и п т е р е с п е е :

ству window.onload. window.onload = function() { alert("you rule!"); }

^

Красота! Разве это не проще и удобнее для чтения?

Не беспокойтесь, если window.onload кажется вам несколько непонятным, поскольку позже мы под< Q Q н ш поговорим,

К а к в ы уж е п а ч а л и п о п и м а т ь , ф у п к ц и и п о з в о л я ю т делать к о е -ч т о п о л е зп о е п о м и м о п р о с т о й « у п а ко в ки » ко д а для п о в т о р п о г о и с п о л ь з о в а п и я . Ч т о б ы л у ч ш е р а з о б р а ть с я в т о м , к а к п о л п о с т ь ю за д е й с тв о в а ть все п р е и м у щ е с тв а ф у п к ц и й , д а в а й те в згл я п е м п а о б ъ е к т ы и п о с м о т р и м , к а к о п и в п и с ы в а ю т с я в J a v a S crip t, п о с л е ч е го о б ъ е д и п и м и х в е д и п ы й м е х а п и зм .

дальше ►

163


зажигательная речь

Эй, авторы! Еще раз привет! Я девушка, которая купила вашу кни­ гу о программировании на HTM L5, помните меня? Какое все это имеет отношение к HTML5?

Мы полагали, что уже ответили на этот вопрос... н о если вам к а ж е т с я , будто м ы п о д о б р а л и вас и у ж е п о л д о р о г и п р о в е з л и о к о л ь н ы м и п у т я м и п о го р о д у с в к л ю ч е н н ы м с ч е т ч и к о м (в то в р е м я к а к м о гл и бы п о п р я ­ м о й о т в е з т и в ц е н т р го р о д а ), ч т о ж , то гд а в с п о м н и т е о то м , ч т о в следующей главе м ы со­ б и р а е м с я н а ч а ть и з у ч е н и е A P I-и н т е р ф е й с о в , р а б о т а ю щ и х с H T M L 5 . А ч т о б ы сделать э то , вам п о т р е б у е т с я действительно хорошо разби­ раться, в ф у н к ц и я х , о б ъ е к т а х и п р о ч и х связ а п п ы х с н и м и а с п е кта х . Так ч то п о те р п и те — ф а кти ч е с ки , вы уж е п р о ш л и п о л о в и н у п у т и ! И не за б ы в а й те , ч т о в д а п н о й главе в ы п р е в р а т и т е с ь и з п и с а те л я с ц е п а р и е в в п р о гр а м м и с т а , и з H T M L /C S S п а е з д н и к а в т о г о , к т о с п о с о б е н создавать с е р ь е зн ы е п р и л о ж е н и я .

L

164

глава 4

А мы уже упоминали о т о м ,

что все это также может позволить вам заработать намного больше денег?


функции и объекты javascript

Благодаря объектам N будущие перспективы выглядят настолько яркими, что нам действи­ тельно НЕ ОБОЙТИСЬ без солнцеза­ щитных очков...

Kmo-mo сказал «объекты»?! О , э то н а ш а л ю б и м а я те м а ! О б ъ е к т ы н е р е н е с у т в а ш и н а в ы к и в J a v a S c rip t-н р о гр а м м и р о в а н и и н а с л е д у ю щ и й у р о в е н ь — о н и вы с т у н а ю т к л ю ч о м к у н р а в л е н и ю с л о ж н ы м к о д о м , к н о н и м а н и ю об ъ ­ е к т н о й м о д е л и д о ку м е н т а (D O M ) , к о р га н и з а ц и и в а ш и х д а н н ы х и да ж е я в л я ю т с я о с н о в н ы м с н о с о б о м « у н а ко в ки » A P I-и н т е р ф е й с о в J a v a S c rip t в H T M L 5 (д а н н ы й с н и с о к м о ж н о н р о д о л ж а т ь !). С у ч е ­ т о м э т о го вам н о ка з а л о с ь , ч т о о б ъ е к т ы — с л о ж н а я тем а, н е т а к ли? Х а ! М ы с в а м и н р о с т о б р о с и м с я сл о м я го л о в у в н е р е д и не за м е д л и ­ те л ь н о н е р е й д е м к и х и с н о л ь з о в а н и ю .

Раскроем вам секрет JavaScript-объектов: о н и н р е д с т а в л я ю т с о б о й все­ го л и ш ь к о л л е к ц и и с в о й с т в . Д а в а й те в ка ч е с т в е н р и м е р а в о зьм е м , с ка ж е м , собаку. С о б а ка обладает р я д о м с в о й с т в :

У большинства собак есть клички (пате), как , например , идо (Fido) в данном случае. £ -------- Каждая собака имеет определенный вес (weight). У всех собак есть набор люби­ мых занятий , например гулять (walks) и приносить обратно брошенный мячик (fetching balls).

К Собака (dog)

-

И относится к определен­ ной породе. В данном случае у фидо (Fido) смешанная (mixed) порода (breed).

дальше ►

165


объекты и свойства

Размышления о свойствах... Е с те с тв е н н о , н а ш не с F id o , е сли б ы м о г го в о р и т ь , сразу ж е о т м е т и л б ы , ч т о у н е го и м е е т с я н а м н о го б о льш е с в о й с т в , ч е м м ы н е р е ч и с л и л и в ы ш е , о д н а ко в д а н н о м н р и м е р е и м е н н о и х м ы и о т р а з и м в н р о г р а м м н о м ко д е . Д а в а й те в згл я н е м н а э т и с в о й с т в а с т о ч к и з р е н и я т и н о в д а н н ы х Ja v a S c rip t:

Набор свойств

Строки, представля­ ющие кличку и породу нашей собаки.

name: "Fido" К а к вы догадались, у нас будет объект, пред­ ставляющий собаку.

weight: 40

3 качестве значения веса у нас будет целое число.

<;

breed: "M ixed" loves: ["walks”, "fetching balls”]

8 массиве строк мы собираем значения свойства loves объекта dog, при этом значений может быть ноль и больше; здесь у нас два значения, которые олице­ творяют любимые занятия Fido.

Как создать объект на JavaScript? И т а к , у нас е сть о б ъ е к т с р я д о м с в о й с т в . А к а к о н со зд а е тся с и с п о л ь з о в а н и е м JavaS cript? В о т к а к :

присвоим наш объект переменной fido. Мы

Начинаться объект должен ^ отКрывающейся фигурной скоб^ после которой следуют все свойства, находящиеся внутри.

var fido = { паше: 11Fido11,

Нам объект обладает четырьмя свой­ ствами : name, weight, breed и loves.

weight: 40, breed: "Mixed11, loves: ["walks11

Обратите внимание, что каждое свойство отделяется запятой. НЕ точкой с запятой!

"fetching balls"]

Обратите внимание, что значение weight является числом ( 40 ), а зна­ чения breed и пате — строками.

И конечно же, у нас имеется массив для р а з ­ мещения значений свойства loves объекта dog.

166

глава 4


функции и объекты javascript

моЖно сделать с объектами Обращение к свойствам объекта с помощью «точечной» нотации: И с п о л ь з у й т е т о ч ку (.)

h -----------if (fido.weight > 25)

И спользуйт е объект н а ­ ряду с т очко й и и м е н е м свойст ва для п о л у ч е ­ ния д о с т у п а к значению эт ого свойства.

alert ("WOOF") ; } else { alert ("yip") ;

I £ id o .w e ig h t

^

... а в о т и м я

В о т объект..

свойства.

}

На э т о т р а з з а к л ю ­ ч и т е и м я свойст ва в квадрат ны е скобки.

Обращение к свойствам с использованием строки и скобочной нотации: var breed = fido ["breed" ] , if (breed == "mixed")

{

alert("Best in show");

И спользуйт е объ­ е к т наряду с и м е н е м с в о й с т в а , за к л ю ч е н н ы м в кавы чкиj и к в а д р а т ­ ные скобки для п о л у ­ чения дос т у п а к з н а ч е ­ нию эт ого свойства.

С

fido.weight = 27;

^

fido.breed = "Chawalla/Great Dane mix";

t

свойст ва в к а ­ вычках.

и зм ен я ем значение свойст ва

w e ig h t об ъ е кт а fido...

[ " w e ig h t" ]

В о т о б ъ е к т ............. а в о т и м я

Изменение значения свойства: Mw

f id o

Мы с ч и т а е м , чт о т очечная нот а ц и я более у д о б о ч и т а е м а , чем скобочная.

■■■ Значение его свойст ва breed...

fido. loves, push ("chewing bones") ; <£__ ••• и добавляем новый э л е м е н т в его

А

м ассив loves.

^ push п р о с т о добавляет новый

э л е м е н т в конец массива. ^ —

ТТеречиспение

Д л я перечи слени я свойст в мы и с п о л ь з у е м ц икл for in

var prop; for (prop in fido)

^

{

alert ("Fido has a " + prop + if (prop == "name")

^

--------------------------------- При каждом вы полнении цикла

property ");

{

alert("This is " + fido[prop]); ^

}

« П ер ечи сли т ь» означает п р о й т и с ь по в с е м с в о й с т в а м о б ъ е к т а

всех свойств объекта:

О б р а т и т е в н и м а н и е '. п о р я д о к с в о й с т в п р о и з в о л ь н ы й , т а к ч т о не с т о и т р а с с ч и т ы в а т ь на к а к у ю - т о о п р е д е ­ ленную последоват ельност ь.

п е р е м е н н а я p rop п о л у ч а е т с т р о ­ ковое значение следую щ его по очереди им ени свойства.

Мы и с п о л ь з у е м скобочную н о т а ц и ю для по луч ения д о с т у п а к значению с о о т в е т с т в у ю щ е г о свойства.

дальше ►

167


что могут объекты

Q

Действия в отношении массива объекта: 4

var likes = fido.loves;

Здесь мы п р и с ва ива ем значение м ассива loves о б ъ е кт а fido п е р ем енно й likes.

var likesString = "Fido likes"; for (var i = 0; i < likes.ltr^th; ± + + ) ^ 4

^

likesString += •• - + likes [i] ;

^

М О Ж е М вы п о л н и т ь цикл в о т ношении массива likes и создат ь gcey л ю 6иМШ з а н я т и и fido.

т л к ж е мо>кем вы вест и диалоговое

alert (likesString); ^

окно a le rt с с о о т в е т с т в у ю щ е й ст рокой.

Передача объекта функции: --■----------V. М ы м о ж е м п е р е д а т ь объ-

е к т функции т о ч н о т а к

function bark (dog) {

же, как в случае с людои другой перем енной.

if (dog.weight > 25) { alert ("WOOF") ;

3 ф у нкци и м ы мож ем

} else {

alert("yip") }

}

п о л у ч и т ь д о с т у п к с во й ­ с т в а м о б ъект а как обычно, и с п о л ь з уя j конечно ж е , им я п а р а м е т р а для объекта.

b a r k ( f i d o ) T >N^ Мы п ередаем fido в качест ве а р г у м е н т а ф у нкции b a r k , к о ­

т о р а я ожидает о б ъ е к т dog.

Оператор «точка» (.) Оператор «точка» (.) обеспечивает доступ к свойствам объ­ екта. В целом код получается более удобочитаемым, чем при использовании скобочной нотации (["строка"]):

168

fido . w e i g h t ЭТО вес fido.

f i d o . b r e e d ЭТО порода fido.

f i d o . паше ЭТО КЛИЧКЭ fido.

f i d o . l o v e s это массив, содержащий значения, олицетво­ ряющие любимые занятия fido.

глава 4


функции и объекты javascript

А можно ли добавлять свой­ ства в объекты после того, как они уже были определены?

Да, вы сможете добавлять и удалять свойства в любой момент. Ч т о б ы д о б а в и ть с в о й с т в о в о б ъ е кт, н у ж н о н р о с т о н р и с в о и т ь н о в о м у с в о й с т в у зн а ч е н и е , к а к н о к а з а н о далее: f i d o . age = 5 ; по сл е ч е го у 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


объекты как аргументы

Поговорим о передаче объектов функциям М ы с в а м и у ж е н е м н о го о б суж д а л и т о , к а к а р гу м е н т ы н е р е д а ю тс я ф у н к ­ ц и я м , — о н и н е р е д а ю тс я по значению , т а к ч т о е сли м ы не р е д а д и м ц елое ч и с л о , с о о т в е т с т в у ю щ и й н а р а м е т р ф у н к ц и и н о л у ч и т копию д а н н о го ц е л о ч и с л е н н о го значения для и с п о л ь з о в а н и я в ф у н к ц и и . А н а л о г и ч н ы е н р а в и л а д е й с т в у ю т и в случае с о б ъ е кта м и , однако н а м н у ж н о более н р и ста л ь н о в згл я н у ть н а то , ч т о будет с о д е р ж а т ь с я в н е р е м е н н о й , к о гд а о н а н р и с в а и в а е т с я объ екту, ч т о б ы в ы с м о гл и н о н я т ь , ч т о все э то о зн а ча е т. К о гд а о б ъ е к т н р и с в а и в а е т с я н е р е м е н н о й , о н а будет с о д е р ж а т ь н е сам э т о т о б ъ е кт, а ссылку н а н е го . С ч и т а й т е с с ы л ку у ка за те л е м н а о б ъ е кт.

fid o

name: "Fido" weight: 40 breed: "M ixed"

Когда объект присваивается переменной, она наделяется ссылкой на этот объект. Переменная не будет «содер­ ж а т ь » сам объект.

loves: ["walks", "fetching balls"]

Т а к и м о б р а зо м , н р и в ы зо в е ф у н к ц и и и пе р ед а че е й о б ъ е кта в ы будете н ер е д а ва ть с с ы л ку н а о б ъ е к т — не сам о б ъ е кт, а т о л ь к о ука за те л ь на не го , К о н и я с с ы л к и п е р е д а е тс я в н а р а м е т р , п р и э т о м у ка зы в а т ь о н а будет на о р и г и н а л ь н ы й о б ъ е кт.

Если вы вызовем функцию bark и передадим ей fido в качестве аргумента , то получим копию ссылки на объект dog.

?

f u n c t i o n b a r k (d o g ) ...

code here

{

...

}

Т а к ч т о ж е все э то о значает? П р и и з м е н е н и и с в о й с т в а о б ъ е кта в ы и з м е ­ н я е те д а н н о е с в о й с т в о в о р и г и н а л ь н о м о б ъ е кте , а н е в к о н и и , н о э т о м у у в и д и т е все в н е с е н н ы е в а м и и з м е н е н и я в о б ъ е к т в н у т р и и в н е в а ш е й ф у н к ц и и . Д а в а й те р а с с м о т р и м н р и м е р , где в случае с dog и с н о л ь з у е тс я ф у н к ц и я l o s e W e i g h t .. .

170

глава 4


функции и объекты javascript

СаЖаем Fido на guemy... сД еной

Д а в а й те в згл я н е м н а т о , ч т о н р о и с х о д и т , к о гд а м ы нер е д а е м f i d o ф у н к ц и и l o s e W e ig h t и и з м е н я е м с в о й с т в о d o g . w e i g h t .

Мы определили объект f i d o функции lo s e W e ig h t .

с

и передаем его

fido — это ссылка на объект, то есть соответствующий объект не рас­ полагается в_ переменной fidoj однако эта переменная на него указывает.

name: "Fido" weight: 48 — breed: "Mixed"

У

loves: ["walks", "fetching balls"]

fido.weight = 48;

loseWeight(fido)

При передаче fido функции мы передаем ссылку на объект.

( 2 \ Параметр d o g функции l o s e W e ig h t получает копию ссылки на f i d o . Таким образом, любые из­ менения в свойствах параметра будут отражаться на переданном объекте. Когда мы передаем fido функции loseWeight, параметру dog п р и ­ сваивается копия ссылки, а не копия объекта. Так что fido и dog будут указывать на один и тот же объект.

Ссылка dog это копия ссылки fido

function loseWeight(dog) dog.weight = dog.weight

{ 10;

e Таким

образом , при вычитании НО фунтов* из dog.weight мы изменяем значение fido.weight.

alert(fido.паше + " now weighs " + fido.weight);

10 ф у н то в ® 4,5 4 кг.

дальше ►

171


приложение webville cinema

ПРИЛОЖЕНИЕ WEBVILLE CINEMA ДЛЯ ПОКАЗА АФИШИ КИНОТЕАТРА

Здесь речь пойдет о приложении Webville Cinema и APIинтерфейсах JavaScript; вам нужно будет создать объекты

m ovie. Всего вам потребуются два таких объекта, каждый ИЗ КОТОРЫХ будет ВКЛЮЧаТЬ название ( t i t l e ) , Жанр (genre) и рейтинг фильма ( r a t i n g ) (выставляемый по шкале от 1 до 5 звездочек), а также время киносеансов (show tim es). Вот образцы данных, которые вы сможете использовать для заполнения своих объектов.

Название фильма: Plan 9 from Outer Space. Время киносеансов: Жанр:

3:00pm, 7:00pm and 11:00pm.

Cult Classic.

Рейтинг в звездочках: Название фильма:

Forbidden Planet.

Время киносеансов: Жанр:

2.

5:00pm и 9:00pm.

Classic Sci-fi.

Рейтинг в звездочках:

5.

Г Р еш е н и е к д а н н о м у з а д а н и ю

V - 8*' моЖете св°* °дН0 ^

н а х о д и т с я на с л е д у ю щ е й с т р а -

ЭГ

н и ц е , о д н а к о не з а г л я д ы в а й т е

6 о льШ е н Р а в я т с я

т у д а , п о к а не с д е л а е т е все с а м и . С е рь езн о.

Mt?/

не ш у т и м .

■ж

Код для создания ваших об ъект ов н а п и ш и т е здесь.

172

глава 4

Ц Т в а м Р


функции и объекты javascript

ПРИЛОЖЕНИЕ WEBYILLE CINEMA ДЛЯ ПОКАЗА АФИШИ КИНОТЕАТРА--------РЕШЕНИЕ Ну как у вас прошло создание объектов movie? А вот наше решение к данному заданию:

m o v i e l обладает ч е т ы р ь м я с в о й с т в а м и : title , g e n r e , ra tin g и show tim es.

M bi создали два

о б ъ е кт а с и м е ­ нам и movielи m o vieZ для двух ф и льм ов.

var moviel = { title: "Plan 9 from Outer Space" genre: "Cult Classic",

Значение rating — э т о число.

rating: 5, showtim.es: };

^

Значения title и g e n r e являю т е я строками.

["3:00pm", "7:00рт", "11:0 Орт"]

A s k o w tim e s п ред с т а вля е м , собой м ас с и в, содержа­

щ и й значения вр ем ени сеансов ф и л ь м а в виде ст рок. у m o v i e z тоже и м е ю т с я ч е т ы р е

свои -

ства: title, g e n re , rating и sho w tim es.

var тоvie2 = {

title: "Forbidden Planet", genre: "Classic Sci-fi", rating: 5, showtimes: ["5:00pm", "9:00pm"]

He с л е д у е т з а б ы в а т ь , ч т о свойст ва необходимо р а з д е л я т ь за п я т ы м и .

};

Мы использовали т е ж е самые им ена с в о й с т в , как и в случае с m o v i e l , но значения с во йст в на э т о т раз б уд у т уже другие.

дальше ►

173


внедрение следующего сеанса

Наш следующий сеанс состоится в... Итак, мы с вами уже немного отведали на вкус, что значит смешивать объек­ ты и функции. Давайте нойдем еще дальше и нанишем код, который станет выводить сообщение о времени следующего сеанса фильма. Наша функция будет нринимать movie в качестве аргумента и возвращать строку, содержа­ щую значение времени следующего сеанса фильма, отталкиваясь нри этом от значения текущего времени. Л В о т наила новая ф у н к ц и я , п р и ­ н и м а ю щ а я о б ъ е к т movie.

М ы и звл е ка е м значение т е к у щ е го в р е м е н и с п о м о щ ь ю

Л

J a v a S c r i p t - о б ъ е к т а Date. Не б еспокойт есь о д е т а лях - п р о с т о з н а й т е , ч т о он в о з в р а щ а е т зн а ч е н и е т е к у щ е г о врем ени в м и л л и с е к у н д а х .

function getNextShowing(movie)

{

var now = new Date().getTime();

Теп ер ь мы з а д е й с т в у е м м ассив s k o w t i m e s о б ъ е к т а m o v ie и со ве р ш а е м и т е р а ц и и по нему.

j I

▼ for (var i = 0; i < movie.showtimes .length; i++) { ^ ^ var showtime = ge tTimeFromSt ring (movie.show times [i]) ;

if ((showtime - now) > 0) {

В случае с каждым з н а ч е н и ем s k o w tim e s мы и звл е ка е м Л n значение т е к у щ е го врем ени g миллисекундах, а зат ем пр оводим сравнение.

return "Next showing of " + movie.title + " is " + movie.show times [i] ; |^_

}

Если вр е м я еще не н а с т у п и л о , т о э т о значение в р е м е ­ ни следую щ его сеанса , п о э т о м у оно и возвращ ает ся.

return null;

Если сеансов больше не о с т а ­ е т с я , м ы во звр ащ а ем null. j^oijloBo

function getTimeFromString( time String)

к уно^е^леншо

{

var theTime = new D a t e (); var time = timeString.match(/(\d+)(?:: (\d\d))?\s*(p?) /); theTime.setHours( parselnt(time[1]) + (time[3] ? 12 : 0) ) theTime.setMinutes( parseInt(time[2])

II

0 ) ;

return theTime.getTime() ; }

He беспокойт есь насчет данного кода; в нем и с п о л ь з у ю т с я р е гу ля р н ы е выражения , о ко т о р ы х вы у з н а е т е по ходу и з у ч е ­ ния Ja vaS cript. А пока п р о с т о в зг л я н и т е на них!

var nextShowing = getNext Showing (moviel) ; Г Х alert (nextshowing) ; next Showing = getNext Showing (movie2) ; alert(nextshowing);

В о т п р и го т о вл е н н ы й нам и кодj ко т о р ы й п р о ­ ст о б е р е т с т р о к у ф о р ­ м а т а , например l a m или Ърт> и п р е о б р а з у е т ее в значение вр ем ени в м и ллисекунда х.

Здесь МЫ вызываем ф у н к ц и ю g e t N e x tS h o w in g и и с п о л ь з у е м с т р о к у , к о т о р у ю она возвращаотображения в диалоговом окне alert.

) И де ла ем т о же сам ое в случае с movieZ.

174

глава 4


функции и объекты javascript

К а к р а б о т а е т «объединение в д е п о чку » _________________________________ В ы о б р а т и л и в н и м а н и е н а д а н н у ю с т р о к у в н р е д ы д у щ е м коде?

movie.showtimes.length Э та с т р о к а н е н о х о ж а н и н а ч т о и з т о г о , ч т о н а м д о в о д и л о с ь в и д е ть р а н ь ш е . О н а нр е д с та в л я е т с о б о й с о к р а щ е н н ы й в а р и а н т с е р и и ш а го в , к о т о р ы е н а м п о ­ тр е б о в а л о с ь б ы в ы н о л н и т ь , ч т о б ы и з в л е ч ь д л и н у м а сси в а s h o w tim e s и з об ъ ­ е к т а m o v ie . В м е сто нее н а м н р и ш л о с ь б ы н а н и с а т ь следую щ ее: —

var showtimes Array = movie.showtimes;

Сначала мы извлекаем ллассив showtim es.

^

^ ____ Затем МЫ используем его

var len = show timesArray, length;

для доступа к свойству length. О д н а к о м ы м о ж е м делать все э то за о д и н н о д х о д н у т е м о б ъ е д и н е ­ н и я в ы р а ж е н и й в ц е н о ч к у . Д а в а й те н о с м о т р и м , к а к э то р а б о та е т:

movie.showtimes.length А

^

ЧЭОценива ется как объект movie...

t

...который и м е ет свойство showtimes , что яв ляется массивом...

^

...который имеет свой ство с им е нем 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

genre: "Cult classic",

■00pm

rating: 5, showtimes: ["1:0 0pm" , "5:0 0pm" , "7:0 0pm" ] 'jV

J var next Showing = getNextShowing (banzaiMovie) ; alert (nextshowing);

С

Примечание: качество нашего кода явля ется не совсем т а к и м , как у « производ ственного кода»; если вы выполните его после наступления времени последнего киносеанса , то получите значение null. Повторите попытку на следующий день>.\& дальше ►

175


объекты и методы

Объекты такЖе м огут обладать поведением... В ы ж е н е дум али, ч т о о б ъ е к т ы го д я т с я т о л ь к о для с о х р а н е н и я ч и с е л , с т р о к и м ассивов? О б ъ е к т ы а к т и в н ы — о н и м о гу т делать о п р е д е л е н н ы е в е щ и . С о б а ки , к н р и м е р у , н е с и д я т н а м е сте : о н и л а ю т, б е га ю т, и г р а ю т в м я ч , и н а ш о б ъ е к т d o g т о ж е д о л ж е н в е с т и себя н о д о б н ы м о б р а зо м ! П р и н и м а я во в н и м а н и е все и з у ч е н н о е в э т о й главе, в ы н о л н о с т ь ю г о т о в ы к тому, ч т о б ы с н а б д и ть с в о и о б ъ е к т ы н о в е д е н и е м . В о т к а к э то делается:

var fido = {

паше: "Fido11, weight: 40, breed: "Mixed11, loves: ["walks", "fetching balls"] bark: function()

{

alert("Woof woof!") }

};

i

Мы м о ж е м добавить функцию напрямую в наш объект, как показано здесь.

К

Вместо того чтобы говоритъ, что это «функция в объекте » , мы просто говорым , ч т о это метод. М ежду

Обратите внимание , что “ с™ л»зуем анонимную и присваиваем ее ^ о и с ^ в у bark объекта,

ними нет никакой разницы, однако функции в объектах все называют методами. Д л я в ы зо в а м ето д а в о т н о ш е н и и о б ъ е кта следует у ка за ть и м я д а н н о го о б ъ е кт а н а р я д у с и м е н е м м е то д а , и с н о л ь з у я т о ч е ч н у ю н о т а ц и ю , а т а к ж е все н е о б х о д и м ы е а р гу м е н т ы .

f i d o .b a r k () ; Мы говорим объекту сделать чт о-т о, вызывая его методы. 3 данном случае мы вызываем метод bark объекта fido.

176

глава 4

Когда объект включает в себя функцию, мы говорим, что даииый объект включает в себя метод.


функции и объекты javascript

Возвращаемся к приложению Webville Cinema... Т е н е р ь, к о гд а в а ш и з н а н и я об о б ъ е кт а х р а с ш и р и л и с ь , м ы м о ж е м в е р ­ н у т ь с я и у с о в е р ш е н с тв о в а ть к о д н а ш е го н р и л о ж е н и я W e b v ille C in e m a . М ы у ж е н а н и с а л и ф у н к ц и ю g e t N e x t Showing, н р и н и м а ю щ у ю m ovie в к а ­ ч е ств е а р гу м е н та , о д н а к о вза м е н м о гл и б ы сделать э ту ф у н к ц и ю ч а с т ь ю о б ъ е кта m ovie, н р е в р а т и в ее в м е то д . Д а в а й те т а к и н о с т у н и м :

var moviel = { title: "Plan 9 from Outer Space", genre: "Cult Classic", rating: 5, showtimes: ["3:0 0pm" , "7:0 0pm" , "11:0 0pm" ]

M ы взяли наш код и пом ест и­ ли его в метод объекта m o v ie l с использованием имени свойст\ getNextShowing.

getNext Showing: function (movie) { var now = new Date () .getTime () ;

for (var i = 0; i < movie.showtimes.length; i++) { var showtime = getTimeFromString (movie.showtimes [i]) ; if ((showtime - now) > 0 )

{

return "Next showing of " + movie.title + " is " + movie.showtimes[i]; } }

return null; }

Но мы знаем, что моЖем быть не совсем правы... Н а сам ом деле м ы н е м о ж е м н р о с т о в б р о с и т ь ф у н к ц и ю в д а н н ы й о б ъ е кт, н о с ко л ь ку g e t N e x t S h o w in g н р и н и м а е т m ovie в ка ч е с т в е а р гу м е н та . П р и э т о м н а м х о ч е т с я вы зы в а т ь g e t N e x t S h o w in g сл е д ую щ и м о б р а зо м :

^

^ var nextshowing = moviel.getNextShowing () ;

^

т р е Ш а т ь с я к а к ц е - л и 6о а р г у -

м е н т ы , п оско льк у б у д е м вполне ясно, вр ем я

следую щ его сеанса какого ф и л ь м а МЫ ХотиМ и звл е ч ь j т о е с т ь т о г о , ко т о р ы й п р е д с т а в л е н объект ом m o v ie l.

И т а к , к а к и е ж е и е н р а в л е н и я н а м н е о б х о д и м о вне сти ? Н у ж н о уд а л ить н а р а м е т р m ovie и з о н р е д е л е н и я м е то д а g e t N e x t S h o w in g , о д н а ко то гд а н а м н р и д е т с я ч т о -т о делать со все м и с с ы л ка м и н а m o v ie , s h o w tim e s в ко д е , н о с к о л ь к у к а к т о л ь к о м ы удалим н а р а ­ м е тр , m o v ie н е р е с т а н е т с у щ е с тв о в а ть к а к н е р е м е н н а я . Ч т о ж , д а ва й те н о с м о т р и м ...

дальше ►

177


переработка функции как метода

Давайте уберем параметр movie... М ы н о з в о л и м себе уда л ить н а р а м е т р movie и все с с ы л к и н а н е го . В резул ьтате у нас н о л у ч и т с я с л е д у ю щ и й ко д :

Внизу мы выделили изменения n серым цветом...

var moviel = {

genre: --Cult Classic--,

_ n See это выглядит вполне сносно, однако ^ ^ иео$кодиМО пр о д ум а т ь как

rating: 5,

метод getNextShowing будет использо

showtimes :["3:00pm", "7:00pm", "11:00pm"],

8amt> свойство skowtimeS--

title: "Plan 9 from Outer Space",

v

£ getNextShowing: function ()

{

. .. . m. .. var now = new n Date().getTime(); for (var i = 0 ; i < showtimes.length; i++) {

- HaM пРи$ЫЧны либо локальные переменные (но к hum N showtimes r не относится), лиоо глобальные переменные (к которым showtimes тоже не относится). Хм...

var showtime = getTimeFromString (showtimes [i]) ; if ((showtime - now) > 0 )

{

return "Next showing of " + title + " is " + showtimes[i];

}

}

return null;

1

А вот и еще одно

свойство -

title.

} };

U что теперь? И т а к , в о т в ч е м з а кл ю ч а е тс я го л о в о л о м к а : у нас и м е ю т с я с с ы л к и н а с в о й с т в а showtimes и title. О б ы ч ­ н о в ф у н к ц и и м ы ссы лаем ся н а л о к а л ь н у ю н е р е м е н н у ю , н а гл о б а л ьн у ю н е р е м е н н у ю и л и н а н а р а м е т р ф у н к ц и и , о д н а ко showtimes и title я в л я ю т с я с в о й с т в а м и о б ъ е кта moviel. В н р о ч е м , м о ж е т все и ср а б о ­ тает... ведь Ja v a S c rip t, к а ж е т с я , д о с т а т о ч н о у м е н для т о г о , ч т о б ы с а м о с то я те л ь н о во всем р а зо б р а ться? Н е т. Н е сраб отает. М о ж е т е н р о в е с т и те с т-д р а й в , и J a v a S c rip t с о о б щ и т вам, ч т о н е р е м е н н ы е showtimes и title и м е ю т з н а ч е н и е undefined. К а к т а к о е в о зм о ж н о ? Д е л о в о т в че м : э т и н е р е м е н н ы е я в л я ю т с я с в о й с т в а м и о б ъ е кта , о д н а ко м ы н е с ка за л и J a v a S c rip t, к а к о г о и м е н н о о б ъ е кта . В ы м о ж е т е н о д ум а ть: «Ведь о ч е в и д н о ж е , ч т о м ы и м е е м в ви д у Д А Н Н Ы Й о б ъ е кт, в о т э то т, к о т о р ы й н а х о д и т с я н р я м о здесь! Ч т о т у т м о ж е т б ы т ь н е н о н я т н о го ? » . И , да, м ы п о д р а зум е ваем св о й с т в а и м е н н о э т о го о б ъ е кта . В J a v a S c rip t п р и с у т с т в у е т к л ю ч е в о е сл о во this, к о т о р о е н о з в о л я е т т о ч ­ н о дать н о н я т ь , ч т о в ы и м е е те в в и д у данный конкретный объект. Н а сам о м деле с и т у а ц и я н е м н о го более с л о ж н а я , ч е м о н а к а ж е т с я здесь, и об э т о м м ы н о г о в о р и м со всем с к о р о , а н о к а за й м е м ся д о б а в л е н и е м к л ю ч е в о го слова this, ч т о б ы н а ш к о д р а б о та л к а к надо.

178

глава 4


функции и объекты javascript

Добавление ключевого слова this Д а в а й те д о б а в и м t h i s в ка ж д о е м е с то , где м ы у ка зы в а е м с в о й с т в о , и те м са м ы м д а д им н о н я т ь J a v a S c rip t, ч т о и м е е м в ви д у с в о й с т в о данного к о н к р е т н о г о о б ъ е кта :

var moviel = { title: "Plan 9 from Outer Space", genre: "Cult Classic", rating: 5, showtimes:

3dect> МЫ д о бавили к л ю ч е в о е слово

["3:00pm", "7:00pm", "11:00pm11],

getNextShowing: function()

{

w T

th is п е р е д каж ды м с в о й с т в о м , обо зна чив т е м с а м ы м , ч т о и м е е м 6 6 иду с с ы л к у на о б ъ е к т m o v i e l .

var now = new Date().getTime(); for (var i = 0; i < this.showtimes.length; i++)

{

var showtime = getTimeFromString(this.showtimes[i]); if ((showtime - now) > 0 )

{

return "Next showing of " + this.title + " is " + this.showtimes[i]; } }

return null;

Tecm-gpau6 с участием this Н а б е р и т е н о к а з а н н ы й в ы ш е к о д , а т а к ж е добавьте ф у н к ц и ю g e t N e x t S h o w in g в с в о й о б ъ е кт m o v i e 2 (н р о с т о с к о н и р у й т е и вставьте ее). З а те м в н е с и т е п р и в е д е н ­ н ы е в н и з у и з м е н е н и я в с в о е й н р е д ы д у щ и й т е с т о в ы й ко д . И н р о в е д и т е те ст-д р а й в ! В о т ч т о н о л у ч и л о с ь у нас: г httP'/Zfocalhost Next showing of Plan 9 from Outer Space is 3:00pm

var nextShowing = moviel.getNextShowing () ; alert(nextShowing);

*■

ж

)

nextShowing = movie2 .getNextShowing () ; alert(nextShowing); 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

Как создать конструктор Д авайте создадим копструктор объектов d o g . Мы уже зпаем, как долж пы вы­ глядеть паш и объекты d o g : опи будут иметь свойства nam e, b r e e d и w e i g h t , а также вклю чать метод b a r k . Таким образом, пашему копструктору п отре­ буется п рип ять зп ачеп ия свойств в качестве парам етров и возвратить пам объект d o g , вклю чаю щ ий метод b a r k . Вот пеобходимы й пам код: ф у н к ц и я - к о н с т р у к т о р во м н о г о м

Параметры конст рукт ора п р и н и ­ м а ю т значения свойств, которыми должен обладать наш объект.

схожа с обычной ф у н к ц и е й . О д н а к о по с о г л а ш е н и ю ее и м я должно н а ­ ч и н а т ь с я с п р о п и с н о й буквы.

Л

D o g (п а ш е , b r e e d

fu n c tio n

t h i s , nam e = t h is , b re e d

Имена свойств и имена п а р а ­ м е т р о в необяза­ тельно должны быть одинако­ выми, однако зачастую они оказываются таковыми — о п я т ь -т а к и , по соглашению.

,

=

b re e d ; =

th is .b a r k

f u n c t i o n ()

=

( th is .w e ig h t

e ls e

Мы можем вклю чит ь м ет од bark в конст руируемы й объект п у т е м инициализации свойства bark значением функции точно м а к жел как делали раньше.

w e ig h t;

>

{ 25)

a l e r t ( t h i s .п а ш е }

Здесь мы инициализируем свойства объекта значениями, ~ переданными к о н ст р ук т о р у.

{

пате;

th is . w e ig h t

i f

w e ig h t)

+

{ "

says

W o o f! " )

{

a l e r t ( t h i s . nam e

+

says

Y ip ! ")

}

Нам необходимо использовать this.weight и this.name в методе для ссылки на свойства в объек­ те т ак же, как и раньше.

); ) О бра т ит е внимание, насколько данный синтаксис отличается о т синтаксиса объект а. Это операторы, поэт ом у каждый из них должен заканчиваться точкой с запят ой (как это обычно бывает в функции). П ройдем ся по коду еще раз, чтобы убедиться в том, что вы во всем разобра­ лись. 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


использование конст рукт ора Вам не нужно бес­ покоиться о создании всех этих объектов, поскольку мы сделаем это за вас.

Воспользуемся нашим конструктором Теперь, когда мы п остроили нашу «фабрику», можно пачипать использовать ее для создания объектов d o g . Вам потребуется вызы вать функцию-конструктор осо­ бым образом —нутем разм ещ епия ключевого слова new перед вызовом. Вот ряд примеров: Д ля создания объекта dog мы используем ключевое слово new в сочетании с конст руктором.

А за т е м вызываем его подобно любой другой функции.

var fido = new Dog("Fido", "Mixed", 38); va r

tin y

=

new

va r

C liffo r d

=

D o g ( " T in y " ,

" C h a w a lla " ,

new D og ( " C lif f o r d " ,

f i d o . b a r k () ; tin y .b a r k ( ) ;

8 );

" B l o o d h o u n d 11,

Мы создаем т ри разных объекта dog п у т е м п е р е ­ дачи разных аргум ент ов для конфигурирования каж­ дого из этих объектов.

6 5 );

Получив объект ы, мы м о ­ жем вызывать их методы bark для возврата с о о т ­ вет ст вую щ и х значений.

c liffo r d .b a r k () ;

Д авайте еще раз разберемся, что здесь происходит: мы соз­ даем три разпы х объекта d o g , каждый из которы х будет об­ ладать своими свойствами, для чего используем клю чевое слово new в сочетапии с рапее создаппым копструктором D og. К опструктор возвращ ает объект d o g , скопфигурироваппы й в соответствии с передаппы м и пами аргументами. Д алее мы вызы ваем метод b a r k в отпош епии каждого объекта d o g . О братите впимапие, что мы используем одип и тот же метод b a r k в случае со всеми объектами d o g , а при каждом вы зове b a r k клю чевое слово t h i s будет указывать па объект d o g , в отпош епии которого был соверш еп вызов. Таким образом, если мы вы зовем ме­ тод b a r k в отпош епии fido, то в методе b a r k клю чевое слово t h i s будет указывать па объект f i d o . Давайте более пристальпо взгляпем па то, как все это работает. 182

глава 4

http://localhost ijf

Fido says Woof!

ht(p://laca1ho$t Tiny s*ys V i»

http://!ocalh ost Clifford says Woof!

r


ф ункции и объект ы ja v a s c rip t

Как на самом деле работает this? В сякий раз, когда мы помещ аем клю чевое слово t h i s в код метода, опо будет иптерпретироваться как ссылка па объект, в отпош епии которого был вызвап даппы й метод. Таким образом, если мы вызовем f i d o . b a r k , то t h i s будет указывать па f i d o . Л ибо, если мы вы зовем его в отпош епии объекта t i n y , то t h i s будет указывать па t i n y в вы зове метода. Но откуда t h i s зпает, какой объект опо представляет? Д авайте посмотрим.

Допустим, у нас имеется объект

fid o

=

dog,

new D o g ( " F id o " ,

присвоенный

" M ix e d " ,

3 8 );

xname; "Fido"

V ^

_ breed: "Mixed"

fid o :

Вот экземпляр нашего нового объекта dog с нужными значе­ ниями свойств.

^ ___ _

— weight: 38 bark: functionQ { ... }

(2 ^ Теперь мы вызываем b a r k

о

в отношении th is

f i d o . b a r k ()

Г

name: "Fido" breed: "Mixed” — weight: 38 bark: functionQ { ... }

fid o :

При каждом вызове метода в о т но ш е­ нии объекта JavaScript делает т а к > чтобы ключевое слово this указывало на сам э т о т объект. Таким образом, здесь this указывает на fido. Так что когда мы ссылаемся на this.п а т е , мы знаем, что имя объекта будет "Fido11.

( 3\ Таким образом, t h i s всегда будет указывать на объект, в отношении которого был вызван метод, независимо от того, как много объектов dog мы создадим: f i d o . b a r k ()

t i n y . b a r k ()

c l i f f o r d . b a r k () th is

th is name: "Fido" breed: "Mixed"

Вы можете вызывать bark в отношении любого объ­ екта dogj a this при эт ом будет присваиваться ко н. к рет н о м у dog до выполне^ ния вашего основного кода.

name: "Tiny" breed: "Chawalla"

th is name: "C lifford" breed: "Bloodhound"

— weight: 38

- weight: 8

— weight: 65

bark: functionQ { ... }

bark: functionQ { ... }

bark: functionQ { ... }

дальш е ►

183


конструктор movie

184

глава 4


ф ункции и объект ы ja v a s c rip t

Часш°

ЧаДаБаеМые В опросы

В чем заключается истинная разница между функцией и методом? В конце концов, если они являются одним и тем же, почему называются по-разному?

Q i По соглашению, если объект включает функцию, мы называем ее методом. Функция и метод работают одинаково, за исключени­ ем того, что вызов метода объекта осуществляется с применением оператора «точка», при этом метод может использовать this для доступа к объекту, в отношении которого был вызван. Считайте функцию отдельным блоком кода, который можно вызывать, а ме­ тод — поведением, привязанным к определенному объекту. Если я с помощью конструктора создам объекты, вклю­ чающие метод, то в случае со всеми этими объектами будет совместно использоваться один и тот же код данного метода?

Q i Да, все верно, причем в этом заключается одно из преиму­ ществ объектно-ориентированного программирования: вы можете создать код для класса объектов (например, для всех своих объ­ ектов dog) в одном месте, и он будет совместно использоваться в случае со всеми объектами dog. Чтобы сделать его специфичным для каждого из объектов dog, необходимо обратиться к их свой­ ствам, для доступа к которым вам потребуется использовать this. Могу ли я задавать для this значения по своему выбору, и если да, не приведет ли это к тем или иным отрицательным последствиям?

0 : Нет, вы не сможете задать для this какие-либо значения. Помните, что this — это ключевое слово, а не переменная! Оно выглядит и ведет себя отчасти как переменная, но не является ею.

&

Есть ли у this значение вне метода объекта?

0 : Нет, если вы не вызываете метод объекта, то this будет undefined. Насколько я понимаю, когда я вызываю метод в отно­ шении объекта, этот объект задается как значение this на все время, пока будет идти оценка метода. Так ли это?

Q l Да, в теле объекта this всегда будет указывать на сам объект. Нов некоторых особых ситуациях это может быть не так; например, все окажется несколько сложнее, когда объекты будут находиться внутри объектов, и если вы решите предпринять дан­ ное действие, то вам придется принимать во внимание семантику, поскольку таково общее правило. Мне доводилось слышать о том, что при объектно-ориентированном программировании у меня могут иметься классы объектов, которые способны наследовать свойства и методы друг от друга по цепочке. Например, у меня мог бы быть класс mammals, от которого наследуют свойства и методы dog и cat. Возможно ли это на JavaScript?

Q i Да, возможно. В случае с JavaScript используется так назы­ ваемое прототипное наследование, которое представляет собой даже более мощную модель, чем модели, основанные строго на классах. Рассмотрение прототипного наследования немного выходит за рамки данной книги, хотя, может, нам и стоило бы написать больше о нем в сфере JavaScript.

тор, не так ли?

0 : Да, абсолютно верно! Date — это встроенный JavaScriptконструктор. Когда вы указываете new Date () в коде, то полу­ чаете в свое распоряжение объект Date с набором полезных методов, которые можно использовать для работы с датами. В чем разница между объектами, которые мы пишем сами и которые создаем с помощью конструктора?

0 : Основное различие заключается в том, как вы их создаете. Объекты, которые вы пишете сами, используя фигурные скобки и разделенные запятыми свойства, называются литералами объектов. Вы символ за символом вносите их в свой код! Если вам потребуется еще один такой объект, то придется самим напи­ сать его и позаботиться о том, чтобы он располагал аналогичными свойствами. Объекты, генерируемые конструктором, создаются с использованием new и функции-конструктора, возвращающей объ­ ект. Вы можете использовать функцию-конструктор для создания множества объектов с одинаковыми свойствами, но с разными значениями свойств, если пожелаете.

дальш е ►

185


реш ение упражнения

развлечения с м а гн и т а м и , ^ е^ ен и е Таблички с рабочим кодом функции-конструктора Movie были прикреплены к холодильнику, однако некоторые из них упали на пол. Можете ли вы восстановить целостность данного кода? Будьте внимательны, поскольку на полу уже лежало несколько лишних табличек, которые могут сбить вас с толку. Приведем реш ение данного задания.

Это к о н ст р ук т о р , в качестве имени которого мы используем Movie. r a tin g ,

s h o w t im e s )

{

Мы передаем значения свойств, которые к о т и м сконфигурировать: titlej gen re> rating и showtimes... r a tin g t h i s . s h o w t im e s

и инициализируем эти свойства. =

t h is .g e tN e x tS h o w in g va r fo r

now

=

(v a r va r i f

=

f u n c t i o n ()

Д ля ссылки на свойства в объекте мы используем ключевое слово this.

{

n e w D a t e ( ) . g e t T i m e () i

=

0;

i

s h o w t im e ( ( s h o w tim e re tu rn

< =

t h i s . s h o w t im e s

-

"N e x t

now)

> 0 )

s h o w in g

{ o f

"

}

-O -

186

глава 4

[i]) ;

g e tT im e F r o m S tr in g ( th is .

He забудьте п ост авит ь в конце данного опера ­ тора точку с запятой!

+

th is .t it le

is

"

+

t h i s . s h o w t im e s [i]


ф ункции и объект ы ja v a s c rip t

Сразу Же проведем тест-драйв нашего конструктора Теперь, когда у пас есть копструктор M ovie, п ора запяться создаппем объектов m ovie! Н апечатав код фупкции-копструктора M ovie, добавьте приведеппы е пиж е строки и проведите тест-драйв даппого копструктора. Мы полагаем, вы согласитесь с тем, что это намного более легкий способ создапия объектов. Сначала мы создаем объект va r

b a n z a iM o v ie

=

n e w M o v ie

" C u lt

пбрат ит е внимание, знаиенше массива для showtimes М О Ж Н О п о м е с т и т ь прямо

movie для фильма Вискагоо Banzai (один из наших Любимых представителей жанра культ овой классики), а также передаем значения для параметров.

( " B u c k a r o o B a n z a i" , C la s s ic " ,

'

' ["1:00pm", "5:00pm", "7:00pm",

"11:00рт"]);

в вызов функции. var plan9Movie = new Movie ("Plan 9 from Outer Space", " C u lt 2

C la s s ic " ,

д йлее

,

следуем plan

,

from

Outer Space...

["3:00pm" , "7:00pm", "11:00pm"]) ;

var forbiddenPlanetMovie = new Movie ("Forbidden Planet",

^

•••и, конечно же, Forbidden Planet

"Classic Sci-fi",

5, ["5:00pm", "9:00pm"]);

a l e r t ( b a n z a iM o v ie . g e tN e x tS h o w in g ( ) ) ;

Л - ------^

alert (plan9Movie.getNextShowing () ) ; a l e r t ( f o r b id d e n P la n e t M o v ie . g e tN e x tS h o w in g

() ) ;

Создав все необходимые объекты, мы мо~ Жем вызывать м ет од getNextShow ing и выводить для пользователя в диалоговых окнах alert сообщения о времени следую щего сеанса соот вет ст вую щ его фильма.

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 Next showing Of Buckaroo Banzai is n o o p m

дальш е ►

187


тур по объектам

Поздравляем! Вы справились с изуче­ нием функций и объектов! Теперь, когда вы все знаете о них, и прежде, чем мы завершим эту главу, потратим немного времени и взгля­ нем на Java S crip t-объекты в «дикой природе», то есть в их родной среде — в браузере!

Вы, возможно, уже стали замечать... ...что объекты буквально окружают вас. К прим е­ ру, docum ent и w indow — это объекты, равно как и элементы , возвращ аемы е посредством d ocu m en t, g e t E lem en t By Id. Но это лиш ь часть того множ е­ ства объектов, с которы м и мы будем сталкиваться в дальнейшем, —когда дойдем до API-интерф ейсов HTML5, вы увидите, что объекты встречаю тся на каждом шагу! Д авайте еще раз взглянем на некоторы е объекты, которы е уже использовали ранее в книгет

movie А вот наш объект movie.

N— 7

1

Объекты, с к о ­ торы ми мы уже сталкивались.

title genre rating showtimes

document domain title URL getElementByld getElementsByTagName createElement

getNextShowing window Мы изобразили объекты следующим образом: вверху приводятся свойства... ^ ...а внизу — методы, благодаря чему вы сразу можете увидеть свод­ ку по каждому объекту со всеми его свойствами и методами.

188

глава 4

button

on click

document \ocation onload I status alert prompt

L

value

innerHTML childElementCount

firstChild

open

dose setTimeout setlnterval

appendChild insertBefore

~1 I


ф ункции и объект ы ja v a s c rip t

Что такое объект window? Когда вы будете писать код, вы полняем ы й в бра­ узере, объект window станет частью ваш ей ж изни. Д аппы й объект представляет собой глобальную среду для JavaScript-nporpaM M , а также главное окпо п рилож ения и как таковой содерж ит множе­ ство важпых свойств и методов. Д авайте взглянем па пего. Вот наш объект window вм ест е с н е­ сколькими примечат ельны ми свойствами и м е т о д а м и >о которых вам нужно знать. Помимо нихj есть еще множество других...

W e b v ille C in e m a

7

@ hnp:/ localhosi/mavle.htm l

Google

h tt p : / /lo c a l h o s t

Next showing of Butkaroo Banzai is i:00pm

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

Мы все время писали alert, а не window alert... А откуда браузер будет знать, что мы име­ ем в виду метод a le rt объекта window?

Объект window является глобальным. Это может показаться немного страппым, но объект window действует как глобальпая среда, поэтому любые имена свойств или ме­ тодов из данного объекта разреш аю тся даже в том случае, если вы не указали перед пими слово window. К роме того, лю бые глобальные перем еппы е, которы е вы определяете, также помещ аю т­ ся в пространство имен window, так что вы сможете ссылаться на них следующим обра­ зом: w in d o w .имя_переменной.

Более пристальный Взгляд на window.onload По ходу к п иги мы с вами часто использовали обработчик собы тий w in d o w .o n lo a d . Путем присваивания фупкции свойству w in d o w .o n lo a d мы сможем гараптировать, что паш код пе будет вы полпяться до тех пор, пока загрузка страпицы пе закопчится и объектпая модель докумепта (DOM) пе будет полпостью сгеперировапа. В операто­ ре w in dow , o n lo a d мпого чего происходит, поэтому давайте еще раз взгляпем па пего, чтобы вы четко во всем разобрались.

Вот наш глобальный

onload является свой -

объект window

ст вом объекта window.

L

^

Это анонимная функция, которая f присваивается свойству onload.

*

^ 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

Еще один взгляд на объект document О бъект docum ent также уже вам зпаком — мы использовали его для доступа к объектпой модели докумепта (DOM). О п является свойством объекта window. Мы, копечпо, пе указы­ вали его как w indow , docum ent, поскольку в этом пе было пеобходимости. Д авайте загляпем внутрь пего и посмотрим, какие еще там имею тся и птересп ы е свойства и методы: Свойство dom ain — это домен сервера, с которого загружается докум ент , например wickedlysmart.com.

Свойства

domain title

URL

£

getElementByld getElementsByTagName getElementsByClassName

Методы

createElement

Свойство title можно использовать для и з ­ влечения заголовка докум ент а, для чего нужно указат ь document.title. URL -адрес докум ент а. Как вы уже зна е т е, данный м ет од позволяет извлекать элем ент в соот вет ст вии с его идент иф икат ором. Эти два схожи с g e t E lem e n ts у Id за и с к л ю ­ чением т огоj что они позволяют извлекать элементы в соот вет ст вии с именами тегов и классов. Мы использовали данный м ет од в главе 3 для создания новых элемент ов плейлиста. Как вам уже известно, он генерирует э л е ­ м е н т ы , подходящие для включения в DOM.

Более пристальный взгляд на document.getElementByld В пачале главы мы обещали, что к ее копцу вы пойм ете, что такое d o c u m e n t.g e tE le m e n tB y ld . Ч то ж, вы справились с изучепием фупкций, объектов и методов и теперь готовы к этому! Взгляпите па следуЮЩее’

r

э т о объект document, который является в с т р о ­ енным JavaScript-объектом, обеспечивающим доступ к объектной модели документа (РОМ).

var div = document.getElementByld("myDiv"); Это м е т о д , который...

...принимает один аргу м е н т в виде значения id элемент а <div> и возвря щ ает объект элемента.

То, что рапее выглядело как приводящ ая в замеш ательство строка сиптаксиса, теперь каж ется пампого более попятпы м, пе так ли? Перемеппая d iv также является объектом —объектом элемепта. Д авайте более пристальпо взгляпем и па пего. дальше ►

191


объект элемента

Еще один объект, о котором нуЖно знать: объект элемента Не забы вайте, что п ри работе с методами вроде g e tE le m e n tB y ld элемепты , которы е опи возвращают, также являю тся объектами! Ладпо, вы могли и пе осозпавать этого, по теперь, с учетом того, что вам уже известпо, вы, возможпо, пачали считать, что все в JavaScript является объектами (что, впрочем , в больш ой степепи верпо). Вы уже зпакомы с пекоторы м и свойствами элемептов, паприм ер со свойством innerHTML; давайте взгляпем па ряд более прим ечательпы х свойств и методов. Свойство innerHTML уже вам знакомо; два других свойства - э т о childElementCount (количество дочерних элементов у эле мент а) u firstChild (первый дочерний э л е - _ м е н т , если таковой имеется). Бы можете использовать м е т о ­ ды appendChild и insertsefore для вставки новых элементов в РОМ / в качестве дочерних по отношению к определенному э л е м е н т у .

inner HTML childElementCount firstChild

Свойства и методы элемент а <р>, од­ нако их поддержи­ ва ю т и все другие элементы.

appendChild in sertBefore setAttribute getAttribute

Мы будем использовать setA ttrib ute и g e tA ttr ib u te для задания и извлечения а т ри б ут о в>таких как src, class и id, в случае с элементами. Част°

ЧаДаБаеМ ы е В опросы Поскольку windo______ —

„ „ . „ а

.

чает ли это, что я могу использовать его свойства и методы, не указывая перед ними слово window?

0 : Все верно. Вам решать, указывать ли слово w indow перед именем свойства или метода объекта window. В случае, напри­ мер, с a l e r t все знают, что это за метод, и никто не указывает перед ним window. С другой стороны, если вы используете менее известные свойства или методы, то можете захотеть сделать свой код более легким для понимания, и в таком случае вам потребуется указывать перед их именами слово window. Технически, я могу написать onload = init вместо window, onload = init, не так ли?

192

глава 4

0 » Да, правильно. Однако мы не рекомендуем так поступать в данном конкретном случае, поскольку существует масса других объектов, имеющих свойство o n lo a d , в силу чего ваш код будет намного яснее, если вы укажете window, перед o n lo a d . Причина, по которой мы не пишем window.onload = initO, в том, что в результате этого произошел бы вызов данной функции, а не присваивание ее значения свойству onload?

0 : Все верно. Когда вы указываете круглые скобки после имени функции, например i n i t (), то этим вы говорите, что хотите вы­ звать функцию i n i t . Если же вы укажете ее имя без круглых скобок, то под этим будет подразумеваться, что вы присваиваете значение функции свойству o n lo a d . Это тонкий момент, который легко упустить из виду при создании кода, однако он влечет за собой весомые последствия, так что будьте очень внимательны.


ф ункции и объект ы ja v a s c rip t

• Какой из двух способов создания обработчика window, onload лучше: с указанием имени функции или посредством использования анонимной функции?

Q l Один не является лучше другого, поскольку при использовании любого из этих способов вы, по сути, будете делать одно и то же — задавать значение w in d o w , o n lo a d в виде функции, которая станет выполняться после полной загрузки страницы. Если вам по какой-то причине потребуется вызывать i n i t из другой функции позже в своей программе, то придется определить функцию i n i t . В противном случае не будет важно, какой способ вы предпочтете.

J y * В чем разница между встроенными объектами вроде window и document и теми, которые создаем мы?

0 : Первое различие заключается в том, что встроенные объекты отвечают принципам, определяемым спецификациями, и вы можете обраться к спецификациям W3C, чтобы разобраться во всех их свойствах и методах. Во-вторых, многие встроенные объекты (на­ пример, s t r i n g ) обладают свойствами, которые не могут быть изменены. Кроме того, объекты есть объекты. Замечательная вещь, касающаяся встроенных объектов, состоит в том, что они уже созданы и готовы к использованию вами.

(

Д а , String — это объект! Загляните в хороший справочник по JavaScript, чтобы узнат ь все подробности о его свойствах и методах-

Поздравляем! Вы завершили свое путешествие по объектам и преодолели несколько глав учебного курса по 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 используется передача параметров по значению.

"

Вы можете изменять значения свойств, удалять свойства и добавлять новые свойства в объекты.

■ Когда вы передаете объект (например, d o g ) в качестве аргумента функции, соответствующий параметр получает копию ссылки на данный объект.

■ в

Функция, присвоенная свойству объекта, называ­ ется методом.

■ Переменные, определяемые внутри функций, включая параметры, называются локальными.

и

Метод может использовать специальное ключе­ вое слово t h is для ссылки на объект, в отноше­ нии которого он был вызван.

и

Конструктор — это функция, создающая объекты.

и

Работа конструктора заключается в создании но­ вого объекта и инициализации его свойств.

■ Правила присваивания имен функциям являются теми же самыми, как и в случае с переменными.

■ Для вызова функции необходимо указать ее имя и передать все необходимые аргументы.

■ Переменные, определяемые вне функций, назы­ ваются глобальными. ■ Локальные переменные невидимы вне функции, в которой они определены. Это называется обла­ стью видимости переменной. ■ Если объявить локальную переменную с тем же именем, что и у глобальной переменной, то гло­ бальная переменная окажется «в тени» локаль­ ной переменной. ■ При указании ссылок на множественные JavaScript-файлы на странице все глобальные пере­ менные должны определяться в одинаковом глобальном пространстве.

194

глава 4

Обращаться к свойствам объектов можно с ис­ пользованием точечной или скобочной нотации.

Вы можете перечислять свойства объектов, ис­ пользуя ЦИКЛ f o r - i n .

Для вызова конструктора с целью создания объ­ екта необходимо использовать ключевое слово new. Например, new Dog () .

По ходу книги мы с вами уже использовали не­ сколько объектов, включая docum ent, window, а также различные объекты элементов.

МеТОД

d o cu m e n t. g e tE le m e n tB y ld

ет объект элемента.

ВОЗВраща-


ф ункции и объект ы ja v a s c rip t

U I M L 5 - K f ° CCB ° r A Это была ураганная глава о функциях, объектах, свойствах и методах, так что вам много чего необходимо закренить в намяти. Вот кроссворд к главе 4, которы й вам нужно реш ить.

По горизонтали

По вертикали

2. Функция без имени. 6. Эти переменные доступны только внутри функций. 8. Функции без операторов return возвращают это. 9. Функция в объекте. 12. Объект__________ представляет собой объектную модель до­ кумента (DOM). 13. Аргументы передаются по__________. 15. Данное ключевое слово необходимо использовать в начале определения функции. 17. Настоящий глобальный объект. 18. То, что указывается в объявлении функции.

I. По соглашению, имена конструкторов должны начинаться с __________ буквы. 3. Связывание свойств и вызовов функций посредством оператора «точка». 4. То, что указывается в вызове функции. 5. Функция данного рода создает объекты. 7. Свойство в window, которое мы присваиваем функции обработ­ чика. 10. Оператор «________ » позволяет получить доступ к свой­ ствам и методам объекта. 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

fu n c tio n va r

=

d o g s A g e (4 ) ;

r e c t a n g le A r e a ( w id t h a re a

re tu rn

=

w id th

*

,

h e ig h t )

{

h e ig h t ;

a re a ;

} va r

re c tA re a

fu n c tio n va r

=

a d d U p (n u m A rra y ) to ta l

fo r

r e c t a n g le A r e a ( 3 ,

(v a r

= i

to ta l

4) ;

{

0; =

+=

0;

i

<

n u m A r r a y . le n g t h ;

i+ + )

{

n u m A r r a y [ i] ;

} re tu rn

to t a l;

} va r

th e T o ta l

fu n c tio n va r i f

}

=

5,

g e tA v a ta r ( p o in ts )

3,

( p o in ts

<

100)

a v a ta r

=

"M o u s e " ;

^

e ls e

i f

e ls e

{

re tu rn

( p o in ts =

>

100

&& p o i n t s

=

"A p e ";

a v a ta r;

m y A v a ta r =

глава 4

<

1000)

{

"C a t" ;

}

196

Hanuvuume ^ здесьj какое значение будет и м е т ь каждая из переменных.

{

[

{

a v a ta r

va r

9 ]) ;

a v a ta r;

a v a ta r

}

addU p([1 ,

g e t A v a t a r (3 3 5 ) ;

m yD ogsA ge re c tA re a

=

.

О

О

.......................

. . . Ш . .......................

=

th e T o ta l

=

...% Z ............................

m y A v a ta r

=

.

...C & t. ...................


ф ункции и объект ы ja v a s c rip t

K M L 5 ” K F4><rBoP A* Г еШ ение

дальш е ►

197



g

создание 1 П Ж -ст р а н и ц с поддержкой определения м есто п о л о ж ен и я

^

_ф _

Куда бы вы ни отправились, вас можно найти. Порой знание того, где вы находитесь, имеет существенное значение (особенно для веб-приложений). Из этой главы вы узнаете, как создавать веб-страницы с поддержкой опреде­

ления местоположения, — иногда вы сможете определять местонахождение своих пользователей вплоть до угла, на котором они стоят, а иногда вам будет удаваться выяснить лишь район города, в котором они находятся. Время от времени вы вообще не сможете получить хоть какую-то информацию о местопо­ ложении пользователей в силу технических причин или просто потому, что им не нравится ваше чрезмерное любопытство. Да, представьте себе! Так или иначе, в этой главе мы рассмотрим API-интерфейс JavaScript под названием Geolocation. Возьмите свое лучшее устройство с поддержкой определения местоположения (даже если это будет настольный компьютер), и давайте приступим к работе.


api-интерфейс geolocation Ваши пользователи путешествуют с мобильными устройствами, поддерживающими определение ме­ стоположения. Наилучшими будут приложения, которые повышают качество пользовательского взаимодействия путем

О

использования данных об их местонахождении.

Местоположение, местоположение... Знание того, где находятся ваши пользователи, дает возможность обеспечи­ вать для них более качественное взаимодействие: вы мож ете указывать им направление; советовать, куда бы они могли отправиться; дать им знать о том, кто еще, находящ ийся поблизости, интересуется, наприм ер, теми же м еро­ приятиям и, что и они. Существует бесчисленное множество путей использо­ вания и нф орм ации о местополож ении. С помощью HTML5 (и API-интерф ейса G eolocation на основе JavaScript) вы можете легко получать доступ к инф орм ации о м естополож ении на своих страницах. Однако есть вещи, о которы х вам необходимо знать, прежде чем мы приступим к работе. Д авайте рассмотрим их. Часто Задаваем ы е

BolJpocTbl

ъ-

• Я слышал, что Geolocation не является настоящим APIинтерфейсом. инте| Это так?

:

Geolocation не считается полноценным членом семейства 0 существующего стандарта HTML5, однако следует отметить, что он является стандартом W3C, который широко поддерживается, и многие относят Geolocation к числу важных API-интерфейсов в HTML5. И его наверняка можно назвать настоящим APIинтерфейсом JavaScript! API-интерфейс Geolocation и API-интерфейс Google Maps Maps — это не одно и то же?

5='Если мое устройство раскрывает мое местоположение, разве разв это не вторжение в частную жизнь?

О

, Спецификации API-интерфейса Geolocation определяют, что любой браузер должен получить от пользователя специальное разрешение на использование данных о его местоположе­ нии. Таким образом, если ваш код задействует API-интерфейс Geolocation, то первое, что сделает браузер, — это удостове­ рится в том, что пользователь согласен раскрыть информацию о своем местонахождении.

f t

Нет. Это абсолютно разные API-интерфейсы. Geolocation сосредоточен исключительно на получении информации о ме­ стоположении человека на поверхности Земли. API-интерфейс Google Maps — это JavaScript-библиотека от компании Google, которая обеспечивает доступ ко всей функциональности Google Maps. Если вам необходимо отображать местоположение своих пользователей на карте, то API-интерфейс от Google станет удобным инструментом.

0:

200

глава 5

=

Насколько хорошо поддерживается API-интерфейс Geolocation? Geoh

5

:

Очень хорошо. Фактически, он доступен почти в любом 0 современном браузере, включая настольный и мобильный сегменты. Только необходимо убедиться, что вы используете последнюю версию браузера. Если это так, скорее всего, ни­ каких проблем с поддержкой API-интерфейса Geolocation у вас не возникнет.


создание HTML-ст раниц с поддерж кой определения мест оположения

Широта и долгота... Ч тобы узнать, где вы находитесь, нотребуется система координат на новерхности Земли. К сча­ стью, у нас им еется такая штука, которая задействует ш ироту и долготу в качестве системы коор­ динат. Ш ирота онределяет северную /ю ж ную точку на новерхности Земли, а долгота — восточ­ ную / занадную точку. Ш ирота изм еряется от экватора, а и зм ерение долготы ведется от Гринвича, _ Англия. Задача API-интерф ейса G eolocation заклю чается в том, чтобы дать нам координаты на- *\ шего м естонолож ения в лю бой момент времени, иснользуя следующие координаты: О т Королевской

Координаты Си­ ликоновой долины: 3737, - г г г я г

Ш ирота — это расстояние на север или на юг от экватора.

Координаты Н ью -Й орка: 4 0 .7 7 , - 7 3 Я 2

обсерват ории в Г р и н в и ч е , ес ли

быть точными. Координат ы Гринвича, Англия: 5 1 .4 7 , О

Долгот а — это рас­ стояние на восток или на запад от Гринвича , Англия .

Координаты П о р т о -Ново, Тренин: (о.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


определение мест оположения

Как A PI-интерфейс Geolocation определяет местоположение пользователя Вам необязательно иметь новейш ий см артф он, чтобы онределять свое местонолож ение. Это нозволяют делать даже настольны е браузеры. У вас мож ет возникнуть вонрос о том, как настольны й браузер мож ет онределить ваше м естонолож ение, если у него нет GPS или другой снециальной технологии, даю щ ей возмож ность сделать это. Ч то ж, все браузеры (установленные в онерационны х системах мо­ бильны х устройств и настольны х комнью теров) иснользую т несколько снособов онределения м естопо­ лож ения, н ричем одни дают более точны й результат, чем другие. Д авайте взглянем н а них.

Я выиграла новейший смартфон со встроенной под­ держкой GPS и теперь могу с вы­ сокой точностью определять свои координаты!

GPS Глобальная система определения координат (Global Positioning System), поддерживаемая многими со­ временными мобильными устройствами, позволяет очень точно определять местоположение благода­ ря спутникам. Информация о местоположении мо­ жет включать данные о высоте, скорости и направ­ лении. Однако для того, чтобы пользоваться этой системой, вашему устройству необходимо «видеть» небо, при этом получение данных о местоположе­ нии иногда занимает много времени. GPS также может ускорить разрядку аккумуляторной батареи вашего устройства. 202

глава 5

1Р-адресс Для получения информации о местоположении пользова­ теля по его IP-адресу исполь­ зуется внешняя база данных, посредством которой 1Р-адрес соотносится с физическим ме­ стоположением пользователя. Преимущество данного под­ хода заключается в том, что он может работать везде; однако зачастую оказывается, что IPадреса принадлежат, напри­ мер, местному офису интернетпровайдера, обслуживающего пользователей. Данный способ можно считать надежным, если речь идет о городе ЫуЛ или его окрестностях.

ш


создание HTML-ст раниц с поддерж кой определения мест оположения

У меня мобильник устаревшей мо­ дели. В этом «малыше» нет GPS. Однако посредством триангуляции с использованием вышек сотовой связи мой телефон способен помочь определить мое местоположение с довольно большой точностью, чем может воспользоваться браузер.

Мобильный телефон

Я перемещаюсь из одного кафе в другое с ноутбуком и беспроводным подключением. Определить мое место­ положение можно посредством триангу­ ляции с использованием точек беспро­ водного доступа. Данный способ должен довольно хорошо работать.

Триангуляция с использованием вышек сотовой связи и мобиль­ ного телефона позволяет опре­ делить местоположение, взяв за основу расстояние, на котором его обладатель находится от од­ ной или более вышек (очевидно, что чем больше будет вышек, тем точнее окажется информация о местоположении). Данный способ может давать довольно точный ре­ зультат и работает в помещениях (в отличие от GPS); кроме того, иногда он позволяет намного быстрее получить итоговые данные, чем GPS. Однако если пользователь окажется в какой-нибудь глухомани, где есть только одна вышка сотовой связи, точность определения его местоположения будет невысокой.

При WiFi-позиционировании за­ действуется одна или более точек доступа WiFi, что позволяет вычислить местоположение пользователя. Данный способ может давать весьма точный ре­ зультат, является быстрым и рабо­ тает в помещениях. Очевидно, что он требует, чтобы пользователь оставался в некоторой степени не­ подвижным (например, сидел и пил чай со льдом в кафе).

дальш е ►

203


мет од определения м ест оположения

Здорово, что у нас есть так много способов опре­ делить свое местоположение. А как узнать, какой из них будет использовать мое устройство.

Никак. К раткий ответ на ваш вонрос —«никак», поскольку подход к онределению ме­ стополож ения зависит от реализации браузера. Однако есть и хорош ая но­ вость: браузер мож ет иснользовать лю­ бой из упоминавш ихся выше снособов определения местополож ения. Ф акти­ чески, если браузер достаточно умен, он сначала мож ет задействовать три ан ­ гуляцию с использованием вышек сото­ вой связи, если таковая достунна, для грубой оценки м естополож ения, а за­ тем выдать вам более точны й результат посредством WiFi или GPS. П озже вы увидите, что не стоит беснокоиться о том, как именно определяет­ ся м естонолож ение. Вместо этого мы сосредоточимся на точности опреде­ лен и я м естонолож ения. Исходя из точ­ ности результатов вы сможете реш ить, насколько нолезны ми окажутся для вас но лученные данные. Мы вернем ся к вонросу точности чуть нозже.

204

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

-Возьми в руку карандаш Задумайтесь об HTML-страницах и прилож ениях, которы е уже у вас имеются (или которые вы хотите создать); для чего может быть полезна включенная в них функция, позволяющая определять местоположение пользователей? |

|

Дать пользователям возможность отыскивать находящихся по­ близости других людей с аналогичными интересами.

|

|

Помогать пользователям находить местные развлекательные заведения или услуги.

|

|

Отслеживать, где именно пользователи что-то делают.

|

|

Указывать направление пользователям относительно той точки, где они находятся в текущий момент.

|

|

Использовать данные о местоположении для выяснения иной демографической информации о пользователях.

□ □ □ □

........................................................................................ ........................................................................................ ........................................................................................ ........................................................................................ Свои идеи напиш ите здесь!

дальш е ►

205


использование ар1-интерфейса geolocation

Так где Же Вы находитесь? К онечно же, ям знаете, где находитесь, однако давайте носмотрим, каково ваше м естонолож ение с точки зрен и я браузера. Д ля этого мы создадим небольшую HTM L-страницу.

< ! d o c ty p e

8 верхней части располагаются привычные вещи, включая ссылку на файл myLoc.js, в к о ­ т ором будет размещ ат ься наш JavaScript, и таблицу ст илей myLoc.css для придания приложению красивого внешнего вида.

h tm l>

< h tm l> <head> < m e ta

Наш геолокационный код будет р а з м е ­ щаться в myLoc.js.

c h a r s e t = " u t f - 8 M>

< title > W h e r e < s c r ip t C lin k

am

I? < / t it le >

s rc = "m y L o c . j s " X / s c r i p t >

r e l = Ms t y l e s h e e t 11 h r e f = Mm y L o c . c s s " >

< /h e a d > <body> < d iv

Данный э лем ент <div> будет использоваться для вывода информации о вашем местоположении.

id = " lo c a tio n " >

Your

lo c a t io n

w ill

go

h e re .

< /d iv > < /b o d y >

К ,

< /h tm l>

Весе» э т о т HTML необходимо п о м е ст и т ь в файл myLoc.html.

Тенерь создадим файл m yLoc. j s и наниш ем немного кода; сделаем это быстро, а чуть нозже вернемся к данному коду и проанализируем его. Д обавьте нриведенны й ниж е код в файл m yLoc. j s . Мы вызываем функцию getMyLocation, как только браузер заканчивает загрузку страницы.

w in d o w .o n lo a d

fu n c tio n i f

=

g e tM y L o c a tio n

g e tM y L o c a tio n

; f

() {

( n a v ig a to r .g e o lo c a tio n )

{

Проверяем, поддерживает ли браузер AP I-инт ерф ейс Geolocation; если объект navigator.geolocation п р и с у т с т в у е т , то все в порядке! Если поддержка имеется, вызываем мет од s- getCurrentPosition и передаем функцию обраI ботчика событий displayLocation. Мы р е а л и ­ Y зуе м ее через несколько мгновений.

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 t io n ) ;

функция 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

e ls e {

глава 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

va r

1 o n g i tu d e

va r

d iv

=

p o s it io n . c o o r d s . l a t it u d e ; =

П

Извлекаем ш и рот у и долготу вашего местоположения из объ­ екта position.coords.

p o s i t i o n . c o o rd s .1 o n g i tu d e ; \

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 re

a t

L a titu d e :

З а т е м извлекаем наш

<div> из HTML

"

+

la titu d e

+

L o n g itu d e :

"

+

lo n g itu d e ;

X

* 4 ваше * ... и задаем местоположение в качестве содержимого элем ент а <div> с использованием innerHTML.

Tecm-драйб местоположения Н аберите нриведенны й выше код и нроведите тест-драйв сво­ ей новой страницы. П ри нервом вы нолнении геолокационного веб-нрилож ения вы увидите в браузере окно с занросом на разреш ение иснользовать данны е о вашем м естонолож ении. Это нроверка систе­ мы защ иты браузера, и вы мож ете отказать браузеру в данном занросе. Поскольку нреднолагается, что вы хотите протести ­ ровать свое веб-нриложение, нужно будет нажать кнонку Allow (Разреш ить) или Yes (Да). П осле этого н рилож ение выдаст ко­ ординаты вашего м естонолож ения, как но казано ниже. &

f

О

О J

4

Q

□ Request P erm ission o n ly once

e v e ry 2 4 h o u rs

Запрос на разрешение может выглядеть п о-ра зн ом у в зависи­ м о ст и о т используемого вами браузера, но будет приб лизи­ тельно таким.

t

W h e r e a m [?

С? Л ® localhost/~Beth/i-L. Q s & | Ejj

£3 4* Л

You are at Latitude: 47.62485, Longitude: -122.52099

l И м ейт е в виду, что получение данных о м е ­ стоположении не всегда происходит мгновенно и может занят ь некоторое время...

А вот и ваши координаты! Ваше местоположение определенно будет отличаться от нашего (а если н е т , то мы будем волноваться за вас). Если ваше приложение не выдает к о ­ ординаты местоположения и вы дваж­ ды проверили код на наличие опечаток, то немного подождите, поскольку через несколько страниц вы познакомитесь с диагностическим т е ст о м , который поможет найти причину неполадок... дальш е ►

207


обзор кода geolocation Е с л и ваш браузер поддер­ живает A P I-интерфейс Geolocation, то вы обнаружите свойство geo location в объекте navigator

Что мы только что сделали... Тенерь, когда мы с вами создали и протестировали геолокационны й код (онять-таки, если данное н рилож ение не выдало вам координат, п отерпите немного, носкольку мы очень скоро ноговорим об отладочных методиках), давайте нройдем ся но коду более детально. А

Первое, что вам необходимо знать, если вы собираетесь написать геолокационный код, — это «поддерживает ли данный браузер API-интерфейс Geolocation?». Опирайтесь на тот факт, что свойство g e o l o c a t i o n присутствует в объекте n a v i g a t i o n браузера только в том случае, если он поддерживает API-интерфейс Geolocation. Таким образом, мы можем проверить, присутствует ли свойство g e o l o c a t i o n , и если оно имеется, то воспользуемся им; в проI тивном случае мы дадим пользователю знать об отсутствии под­ держки API-интерфейса Geolocation посредством вывода соответ­ ствующего сообщения в диалоговом окне a l e r t : Мы м ож ем выяснить, имеется ли в объекте свойство i f ( n a v ig a to r .g e o lo c a tio n ) { geolocation (если оно о т с у т с т в у е т , то р е зу л ь т а т о м S оценки navigator.geolocation окажется null, и значение Уe l s e { соот вет ст вую щ его условия будет false). a le r t ("O o p s ,

no

g e o lo c a tio n

s u p p o rt");

^

Е-сли свойство п р и с у т с т в у е т , то мы смо>келл использовать его, а если его н е т , то уведомляем пользователя посредством диалогового окна alert.

А

Если МЫ все же обнаружили свойство n a v i g a t o r . g e o l o c a t i o n , A P I -интерфейсы — можно воспользоваться им. Фактически, данное свойство представ- \ это просто объекты colocation. ^ со свойствами и м е т о ляет собой объект, содержащий весь API-интерфейс Geolocation дами! Теперь вы рады, Основной метод, поддерживаемый этим API-интерфейсом, назы­ что загодя прошли вается g e t c u r r e n t P o s i t i o n и занимается извлечением информа­ JavaScript-подготовку? ции о местоположении браузера. Более пристально взглянем на данный метод, обладающий тремя параметрами, два последних из которых являются опциональными: e r r o r H a n d l e r является другой ф у н к ц и ­ s u c c e s s H a n d l e r — ф ункция, которая вызывается, ей , которая вызывается, если ч т о - т о если браузер способен успешно определить ваше пойдет не т ак и браузер не сможет местоположение. определить ваше местоположение.

\ getcurrentPosition (successHandler,

с

errorHandler, options)

] 'ft ^ Параметр options позволяет сконф и­ Эти два пара м ет р а являются опциональ­ гурировать работу ными, что объясняет, почему они не т р е ­ API -инт ерф ейса бовались нам ранее. Qeolocation. 208

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

А сейчас взглянем на вызов метода g e t c u r r e n t P o s i t i o n . Мы передаем ар­ гумент в виде обработчика успешного исполнения для обработки удачной по­ пытки извлечения данных о местоположении браузера. Чуть позже мы рассмо­ трим ситуацию, когда браузеру не удается отыскать местоположение. Помните объединение в цепочку, о кот ором говорилось в главе 4 ? Мы используем объект navigator для п о л и чения доступа к объекту geolocation, который я в л я ется свойством объекта navigator.

/

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 объекта geolocation с использованием одного аргум ент а — обработчика успешного исполнения.

Когда АР [ - и н т е р ф е й с ' определит ваше м е ­ стоположение, он вы ­ зовет displayLocation.

ции? К ак передаем отмечалось здесь мы одну в главе 4, другой функции функцию ф ункявляются значениями, по эт ом у мы можем это делать.

Теперь взглянем на обработчик успешного исполнения 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

va r

1 o n g i tu d e

va r

d iv

=

{

= p o s it io n . с о o r d s T la t it u d e ; =

.объект coordinates, свою очередь, содержит ваши ш ирот у и долготу.

p o s i t i o n . со o r d s .1 o n g i tu d e ;

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 " ) ;

d i v . in n e rH T M L

=

"Y o u

a re

a t

L a titu d e :

"

+

la titu d e

+

L o n g itu d e :

"

+

lo n g itu d e ;

t

А эт а часть к настоящему м о м ен т у должна быть вам абсолютна ясна: мы просто берем информацию о коор­ динатах и отображаем ее в элемент е <div> страницы. дальш е ►

209


как работает получение т екущ ей позиции

Как бее это работает Теперь, когда мы прошлись по коду, давайте посмотрим, как все это работает во время выполнения.

Затем API-интерфейс 6eolocation запраши­ вает у пользователя разрешение. The w ebsite ,£http ://lo c a lh o s t" would like to use your current location.

Request p erm iss io n o n ly once every 2 4 hours D o n ’t A llo w

Браузер

С

( i [С И м аДНвц М а Ь /Н ... О

К

You are at LaMude: 47 .6 24 65 , Longitude: -1 2 2.5 20 99

Браузер 210

глава 5

**

*

3

(_

A llo w

)

Если пользователь дает разреше­ ние, то API-интерфейс Seolocation прикладывает максимум усилий для извлечения информации о ме­ стоположении браузера (посред­ ством GPS, триангуляции и т. д.).

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

И если API-интерфейсу 6eoloca+ion удается определить местоположение браузера, он вызывает обработчик успешного исполне­ ния и передает ему объект с координатами.


создание 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

не у д а е т с я о п р е д е л и т ь м е с т о п о л о ж е н и е .

n a v ig a t o r . g e o lo c a tio n .g e tc u r r e n tP o s itio n ( d is p la y L o c a tio n ,

d is p la y E r r o r ) ;

Теперь необходимо написать код обработчика ошибок. Для этого вам нужно знать, что 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. Бот о т личный способ ассоциировать сообщение об ошибке с соо т вет ст в ую щ и м кодом JavaScript:

_ va r

e rro rT y p e s 0:

"U n k n o w n

e rro r",

" P e r m is s io n " P o s itio n "R e q u e s t

d e n ie d

is

no t

tim e d

by

u s e r"

a v a ila b le " ,

o u t"

}; va r i f

(e rro r, code e rro rM e s s a g e

va r

=

e rro rM e s s a g e

d iv

=

e rro rT y p e s [e r r o r . co d e ]

== 0 | | =

— Создаем объект с несколькими свойст вами, им ею щ им и имена О, И, 2 и 3 соот вет ст венно. Эти свойства пр едст авляю т собой строки с соо§ще,ниями об ошибке, которые мы х о т и м ассоциировать с со о т вет ст вую щ и м кодом.

e r ro r, code

e rro rM e s s a g e

+

= 11 "

;

2) { +

e rro r

________ Используя свойство error. code} М Ы присваиваем одни из этих ст рок новой .m e s s a g e ; и Г ^ переменной errorMessage.

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 " ) ;

= e rro rM e s s a g e ; РЧ А за т е м добавляем сообщение к с т р а - ' нице для уведомления пользователя.

d i v . in n e r H T M L

3 случае с ошибками О и 2 иногда в свойстве error.message п р и с у т с т в у е т дополнительная инфор м ация, поэт ом у мы добавляем его в нашу ст року error.Message. дальше ►

211


П р е ж д е чем вы полнить тест, более пристально взглянем на типы о ш и б о к , ко то р ы е м о гу т вы водиться на экр ан .

va r

e rro rT y p e s = { "U n k n o w n

" P o s itio n "R e q u e s t

У'

J

e rro r"

" P e r m is s io n is

Это общая ошибка, которая выводится в с и т у а ­ циях, когда ни одна из остальных ошибок не подходит. О брат ит есь к свойству error message для получения дополнительной информации.

,

d e n ie d no t

tim e d

by

u s e r"

a v a ila b le

o u t"

\

И наконец, A P I -интерфейс Geolocation

,

Это означает, что пользователь от ка^ запросе на разрешение использовать информацию о местоположении. А это означает, что браузер попытался, но не смог определить ваше м ест оположение. О пят ь-т аки, для получения дополнительной информации обратитесь к свойству error.message,

предусматривает такую внутреннюю настройку, как время ожидания (timeout), г- . Л Л Л и если оно истекает до того, как будет Позже 6 этой главе вы Узнает е>как изменять определено местоположение, выводится значение tim eout, задаваемое по умолчанию данная ошибка. в случае API-интерфейса Geolocation. Набрав диагностический тест, запустите его. Если вы получите координаты местоположения, значит, все работает нормаль­ но, и никаких сообщений об ошибках выводиться не будет. Вы можете форсировать вывод сообщения об ошибке, отказав браузеру в его запросе на разрешение использовать инфор­ мацию о вашем местоположении. Либо вы можете проявить более творческий подход: например, войти в помещение со своим телефоном, поддерживающим GPS, что приведет к пропаданию GPS-сигнала от сети спутников.

*7®/ отв.*,,с ** O'

[(£>

Q

T im e d o u t

HOCtjf QHyLgmltm *■ -> С fl [Q

■■• G

- S

1

^

P e rm issio n d e n ie d by u s e r

В наихудшем случае, если вы долго ждете, но данные о ме­ стоположении так и не поступают и не выводится никаких сообщений об ошибке, то, скорее всего, для tim eout задано большое значение, то есть время ожидания будет продолжи­ тельным. Чуть позже в этой главе мы расскажем, как сократить длительность ожидания.

Укажите здесь результаты проведенной вами диагностики □ |

Я не давал разрешения использовать информацию о моем местоположении. |

□ □ □

Мое местоположение оказалось недоступно. Я получил сообщение о том, что время ожидания ответа на запрос истекло. Вообще ничего не произошло — я не получил ни координат местоположения, ни сообщения об ошибке. Нечто другое______________________________________


создание HTML-ст раниц с поддерж кой определения мест оположения

а

Част°

буд ьте o O H o j= > o JK H bi

ЧаДаВаеМые

Для тестирования своего геолокационного кода на мобильном устройстве вам потребуется сервер.

Если у вас нет средств загрузки своих HTML-, JavaScript- и CSS-файлов напря­ мую на мобильное устройство, то их будет проще всего протестировать, разместив на сервере (загляните в следующую главу, чтобы узнать, как установить свой собственный сервер в случае необходимости), и обра­ щаться к ним уже там. Если же у вас имеется сервер и вы решите именно так и поступить, мы полностью вас под­ держиваем. С другой стороны, если данный вариант вам не подходит, знайте, что мы разместили соответствующий код на серверах Wickedly Smart, так что вы сможете провести те­ стирование с использованием своих мобильных устройств. Мы также рекомендуем вам сначала протестировать код на своем настольном компьютере; если все будет нормально работать, переходите к его тестированию на мобильном устройстве, используя сервер (свой собственный или Wickedly Smart).

B oD poC fci

=

Значения широты и долготы моего местоположения, мест возвращаемые прило­ жени жением, не совсем точны. В чем же дело?

5

Существует масса методик, посред­ ством которых ваше устройство и поставщик услуг по определению местоположения вы­ числяют место, где вы находитесь; при этом одни из них дают более точный результат, чем другие. GPS зачастую позволяет полу­ чать самые точные показатели. Мы с вами рассмотрим способ определить уровень точ­ ности данных, возвращаемых локационной службой как часть объекта position, благо­ даря чему вы сможете понять, насколько точные данные о местоположении можно получить.

0:

При проведении первого тест-драйва (включая диагности­ рование ошибок) вводите на своем устройстве адрес http:// wickedlysmart.com/hfhtml5/chapter5/latlong/myLoc.html.

Раскрываем наше тайное убеЖище... Теперь, когда вы изучили осповы, сделаем кое-что более ин тереспое в плапе определепия м естополож епия. Как пасчет того, чтобы узпать, пасколько далеко вы паходитесь от пашего тайпого убежища — штаб-квартиры Wickedly Smart? Д ля этого пам потребую тся ко о р дипаты даппой ш таб-квартиры, а также зпапие того, как вы числяется расстояпие между двумя коор дипатами. Спачала добавим еще одип элемепт <div> в HTML: Координаты ш т а б квартиры Wickedly Sm art.

<body> < d iv

4 7 .6 Я 4 8 5 ,

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 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 х у п о т р е б л е н и е ; вы чи сл я е м р а с с т о я н и е _________________________

Вам когда-нибудь хотелось узнать, как вычисляется расстояние между двумя точками на поверхности планеты? Подробности этого процесса покажутся вам весьма любопытными, однако они лежат немного вне рамок данной главы. По­ этому мы заранее приготовили для вас код, который просто выполняет эту зада­ чу. Для вычисления расстояния между двумя координатами в большинстве слу­ чаев применяется формула гаверсинуса, реализация которой приведена ниже. Данная функция прини м ает две точки координат — начальную (startCoords) и конечную (destCoords) — и возвращает расстояние между ними в километрах. 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

va r

s ta rtL a tR a d s

=

,

d e s tC o o rd 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

=

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

va r

R a d iu s

va r

d is ta n c e

re tu rn

fu n c tio n va r

=

= =

6371;

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 ) ;

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 ) ;

/ /

радиус

Земли

в

кил о м е тр а х

= 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 ;

d is ta n c e ;

d e g r e e s T o R a d ia n s ( d e g r e e s ) r a d ia n s

re tu rn

=

(d e g re e s

*

{

3w y

M a th .P I)/1 8 0 ;

ф ун кц и ю

МЫ ещ е у в и д и м в г л а в е ,

посвященной элем ент у canvas.

r a d ia n s ;

} Добавьт е данный код в свой файл myLoc.js.

214

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

М ы хоидиМ вь1Иислиидь р а с с т о я н и е оил б а с

Написание кода для определения расстояния

до н а с то п р я м о й

Теперь, когда у пас имеется фупкция для вы числепия расстояпия между дву­ мя точками коордипат, определим паше (то есть пас, авторов) местополо­ ж ение —коордипаты ш таб-квартиры Wickedly Sm art (паберите и этот код):: var ourCoords =

{

latitude: longitude:

С

Определяем литеральный объект координат местоположения нашей ш т аб-кварт иры Wickedly S m art. Добавьт е его как глобаль­ ную переменную в верхнюю часть своего файла myLoc.js.

у для

47.624851, -122.52099

};

А теп ерь папиш ем код: все, что пам потребуется сделать, — это передать коордипаты вашего и паш его местополож епия фупкции 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

+ ",

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 ) ;

L o n g it u d e :

" + lo n g it u d e ;

Передаем координаты ваш е­ го и нашего местоположения функции 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";

А за т е м берем резу л ьт а т ы и обновляем со­ держимое элемент а <div> с id в виде distance.

Локационный тест-драйв П роведем тест-драйв пашего пового кода. Заверш ите добав­ ление кода в 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

Ваше местоположение и расстояние от ш т аб-кварт иры Wickedly S m a r t явно б у ­ дет отличаться в зависимости от т ого, в какой точке планеты вы находитесь. Проведите тестирование онлайн: h t t p : / / w ic k e d l y s m a r t.c o m / h f h t m l S / c h a p te r s/d is ta n c e /m y L o c .h tm l дальш е ►

215


добавление google maps Да, знать координа­ ты своего местоположения в виде 34.20472, -9 0 .5 7 5 2 8 — это, конечно, здорово, однако в данный момент как нельзя кстати пришлась бы карта!

Отображение Вашего местоположения на Как мы уже отмечали, API-иптерф ейс G eolocation довольпо п рост — оп позволяет вам определять (и, как вы еще увидите, отслеживать) то, где вы паходитесь, одпако пе преду­ см атривает пикаких ипструмептов для визуализации вашего местополож епия. Д ля это­ го пам придется обратиться к стороппему ипструмепту, и, как вы уже могли догадаться, Google Maps —паиболее популярпое средство для реш епия даппой задачи. Google Maps пе является частью специф икации HTML5, одпако мож ет отличпо взаимодействовать с HTM L5, поэтому мы пе прочь пемпого отклопяться кое-где от пашего марш рута и по­ казывать вам, как иптегрировать Google Maps с API-иптерф ейсом G eolocation. Н апри ­ мер, вы мож ете пачать с добавлепия приведеппого пиж е кода в <head> своего HTMLдокумепта, а чуть позже мы поговорим о том, как можпо добавить карту к страпице: < s c r ip t

s r c = Mh t t p : / / m a p s . g o o g l e . c o m / m a p s / a p i / j s ? s e n s o r = t r u e " X / s c r i p t >

^ Здесь находится A P I-инт ерф ейс JavaSciript Google Maps.

216

глава 5

^ Убедитесь, что вы набрали данный код точно, как ,д оказано здесь, включая п а р ам е т р за п р о са sens0r (API-инт ерф ейс не будет без него рабо­ тать). Мы указали sensor-true, поскольку наш код задейст вует ваше местоположение. Если бы мы просто использовали ка рт у без вашего м е с т о п о л о ­ жения, то напечатали бы sensor-false.


Ж^Отклоняемю

Как добаВить карту к странице

от маршрута

Теперь, когда вы указали ссылку па 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 й gu de т а р р а з м е р 4 0 0 на 4 0 0 п и к с е л о в и ч е р н у ю р а м к у .

,

1V < /b o d y > < /h tm l>

Подготовка к созданию к а р т ы ... Д ля создапия карты пам потребую тся ш ирота и долгота (а мы уже зпаем, как их извлечь), а также пабор парам етров, описывающ их, какой имеппо долж па быть паш а карта. Н ачпем с ш ироты и долготы. Мы зпаем, как извлекать их посредством API-иптерф ейса G eolocation. П ри этом следует отметить, что API-иптерф ейс Google Maps предпочитает, чтобы опи были «упаковапы» в его собствеппы й объект. Д ля создапия одпого из таких объектов мы можем воспользоваться копструктором, предусматриваемым API-иптерф ейсом Google Maps: va r

g o o g le L a tA n d lio n g

=

new

Не з а б ы в а й т е , ч т о и м е н а к о н с т р у к т о р о в

g o o g le .m a p s . L a t L n g ( l a

google.maps ст авит ся пеюед

^

должны начинаться с прописной буквы. t i t u d e , l o n g i t u d e ) ;_______ J ^

з

и м е н а м и всех м е т о д о в A P I - J

К о н с т р у к т о р , кот орый п р и н и м а ет ш и р о т у и долгот у

интерфейса Google Maps.

м в°звРаи4ает новь'й o5veKm’ где они

содержаться.

API-иптерф ейс Google Maps обеспечивает паличие парам етров, которы е мы можем задавать с целью коп троля итогового вида паш ей карты. Н априм ер, можпо указать, пасколько увеличеппым или умепьш еппым будет исходпое пред став лепие карты , какое м естополож епие будет отображ аться в ее цептре, какого типа будет карта (папример, ROADMAP), предусмотреть представлепие Satellite (Спутпик) и т. д. П арам етры задаются следующим образом:

va r

m a p O p tio n s zoom :

^ ---- Новый объект, который мы только что создали. Мы ко т им , g o o g l e L a t A n d L o n g , чтобы данное местоположение отображалось в центре карты.

10,

c e n te r:

m a p T y p e ld :

};

=

Д ля п ара м ет р а zoo m можно указывать значение о т О до 2-1. Поэкспе­ р и м е н т и р у й т е с ним: более высокие значения с о о т вет ст в ую т больше­ м у увеличению (то есть вы сможете р а ссм от рет ь больше деталей). Значение Ю подразумевает , т ак сказат ь, размер «с город».

g o o g l e .m a p s . М а р Т у р е I d . ROADMAP

Вы также МОЖете попробовать подст а ви т ь сюда SATELLITE или HYBRID. дальш е ►

217


код для от ображения карт ы

Отклоняемся

от маршрута

Отображение карты Соберем все воедипо в п овой фупкции с имепем showMap, которая прип им ает пабор коордипат и отображ ает карту па веб-страпице:

va r

Объявляем глобальную переменную т а р >которая будет содержать нашу к арт у Google после т ого, как мы ее создадим. Ч ут ь позже вы увидит е, как она используется.

ш ар;

fu n c tio n va r

_____

s h o w M a p (c o o rd s )

{

g o o g le L a tA n d L o n g

=

new

OL

g o o g le .m a p s . L a t L n g ( c o o r d s . l a t i t u d e

, ...и применяем их для создания объекта google, maps.LatLng.

c o o r d s . lo n g itu d e ) va r

m a p O p tio n s zoom :

=

{

1 0 ,-

c e n te r :

g o o g le L a tA n d L o n g

m ap T y p e I d :

Создаем объект mapOptions с п а р а м е т р а м и >которые х о ­ т и м задать для нашей карты.

f

g o o g l e . m a p s . M a p T y p e l d . ROADM AP

>; va r

m a p D iv =

m ap =

Задействуем ш ирот у и дол­ гот у из объекта coords...

new

И наконец, извлекаем т а р.Div из объектной модели документа (РОМ) и передаем его вмест е с mapOptions к онст рукт ору Мар с целью создания объекта google.maps.Map. Посредством него на нашей странице будет отображаться карта.

d o c u m e n t. g e tE le m e n t B y ld ( "m a p ") ;

g o o g l e . m a p s .M a p ( m a p D i v ,

m a p O p tio n s )

FT ' ^ Еще один конст рукт ор из API Присваиваем новый интерфейса Google Maps>к о т о объект Мар нашей рыи при ним ает элем ент и наши глобальной п е р е п а р а м е т р ы , после чего создает менной тар. и возвращает объект тар.

Добавьте даппы й код в пижпю ю часть своего JavaScript-файла. Затем остапется лиш ь присоединить его к уже имеющемуся у пас коду. Сделаем это путем редактирования фупкции d is p la y L o c a t io n : 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

va r

1 o n g i tu d e

va r

d iv

=

km =

va r

d iv

p o s it io n . c o o r d s . la t it u d e ; =

po s i t i o n . c o o rd s .1 o n g i tu d e ;

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

va r

=

=

"Y o u

a re

=

L a titu d e :

"

+

la titu d e

+

,

o u rC o o rd s ) ;

L o n g itu d e :

"

+

lo n g itu d e ;

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 " ) ; =

"Y o u

show M ap ( p o s i t i o n . c o o r d s ) ;

глава 5

a t

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

d i s t a n c e . in n e r H T M L

218

{

a re

"

+

km +

"

km

fro m

th e

W ic k e d ly S m a r t

H Q ";

Ъудем вызывать showMap из displayLocation после т ого, как обновим остальные <div> на странице.


Tecm-gpauB нашей новой карты У б ед и тесь, ч то вы д о б а в и л и весь повы й код с предыдущей страницы , а также элемент < d iv > с i d в виде тар в свой HTM L. Затем п ерезагрузите веб-страницу, и если браузеру удастся о п р ед ел и ть ваш е м естоп олож ен и е, вы увидите карту.

А вот и наша новая карта V/ Google

Здесь демонстрируется м ест о­ положение велосипедиста с коор­ динатами 3 4 .Я 0 4 7 Я , -<40.57522, вы, естественно, скорее всего оу дете находиться в другом месте.

Здорово! А есть ли способ увидеть мое точное местоположение на карте? Отмеченное, например, булавкой?

3t?i действительно х о т и т е , чтобы эта

штука валялась рядом с вашим велосипедом?

Проведите тестирование онлайн: h t t p : / /w ic k e d l y s m a r t.c o m / h f h t m l S / c h a p te r s / т а р / m yLoc.htm l дальш е ►

219


добавление маркера google

Отклоняемся

от маршрута

ПрикалыВаем булаВку на карту... Будет пампого лучше, если вы сможете увидеть па карте свое точпое м естополож епие. Если вам доводилось поль­ зоваться Google Maps, то вы, вероятпо, видели, что там ме­ стополож епие искомых ф изических объектов отмечается с помощью своего рода булавок. Н априм ер, если вы ищ е­ те башпю Space N eedle («Космический шпиль») в Сиэтле, ш тат Вашипгтоп, то система поиска выдаст вам карту, где рядом с этой баш пей в городе будет «приколота» булавка, щелкпув па которой вы увидите ипф орм ац иоп п ое окпо с подробностям и о даппом сооружепии. Эти булавки назы ­ ваю тся маркерами и являю тся одпой из мпогих возмож но­ стей, которы е предлагает АРI-иптерф ейс Google Maps.

Space Needle ;J 219 4th Avenue North Seattle, WA 98109 (206) 9Q&-21&Q

spaceneedlB.com

**** 28reviews

Directions Search nearby Save to map more Y

Д обавлепие м аркера с всплывающим ипф орм ациоппы м окпом потребует паписапия пекоторого кода, поскольку вам будет пеобходимо создать сам маркер, ипф орм ац иоп ­ пое окпо и обработчик собы тий click, инициируем ы е при щ елчке пользователя па даппом м аркере (что приводит к откры тию окпа). Поскольку мы отклопяемся от маршрута, па рассм отрение даппого аспекта потратим пе мпого времепи, тем более, что у вас уже имею тся все пеобходимы е зпапия, чтобы без особого труда во всем разобраться!

Если вы и щ е т е какой-либо объект в Google кM a p s , т о его местоположение на карт будет отмечено красным маркером.

<£> Начнем с создания новой функции a d d M a r k e r , после чего воспользуемся A P I-интерсрейсом Google Maps для создания маркера: функция addM arker п рини м ает т а р , latlong, title, для м а р ­ кера, а также co n te n t для информационного окна. J fu n c tio n va r

V

a d d M a rk e r(m a p , m a r k e r O p tio n s p o s it io n :

=

\

la tlo n g ,

la tlo n g ,

m ap,

t it le :

t it le ,

c lic k a b le :

'ч , c o n te n t)

{

{

4m ap:

t it le ,

tru e

Создаем объект markerOptions с latlong, m a p и title a макже указываем, к о т и м ли мы, чтобь/ пользова­ т ель имел возможность щ елкнут ь на маркере...

...задаем для clickable значение true, поскольку к от и м , чтобы пользователь мог щелчком на маркере выво' дить информационное окно. г

FZ >; va r

m a rk e r

^

220

глава 5

=

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.


Отклоняемся 0

П»р«ру»

(5 } Создадим информационное окно путем определения специфичных для него парамет­ ров, после чего сгенерируем новый объект InfoWindow с помощью A P I-интерфейса Google Maps. Добавьте приведенный ниже код в свою ф ункцию addMarker: fu n c tio n

a d d M a rk e r(m a p ,

;

la tlo n g ,

t it le ,

c o n te n t)

{

Млшостальной кодпо-преж нему здесь, мы просто экономим место...

va r

i n f o W in d o w O p tio n s

co n ten t:

=

{

co n ten t,

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 , i n f o W i n d o w . o p e n (m a p ) ;

}>;

/

Когда

f u n c t i o n ()

пользоват ель щ е л -

к а е т на м а р к е р е , п р о и с к о д и т вы зо в д а н н о й ф у н к ц и и ,

{

^

f

^

П е редае м с л у ш а т е л я Ф ункции, к о т о р а я

1 }

^

" c lic k " ,

вы зы вае т ся, когда

З а т е м мы и с п о л ь з у е м м е т о д a d d U ste n e r A PI-инт ерф ейса G o o g l e M a p s для добавления с л у -

пользоват ель щ е л к а -

ш а т е л я с о б ы т и и click. С л у ш а т е л ь

е т на м а р к е р е .

подобен о б р а б о т ч и к у со б ы т и и ( н а п р и м е р , o n lo a d или on chck),

и на к а р т е о т к р ы в а е т с я

с к о т о р ы м вы с т а л к и в а л и с ь р а не е.

и н ф о р м а ц и о н н о е окн о.

0

Осталось только вызвать функцию addMarker из showMap, убедившись, что мы пе­ редали все надлежащие аргументы для четырех параметров. Добавьте данный код В НИЖ НЮ Ю ЧаСТЬ СВОеЙ ф уН КЦ И И showMap!

va r

t it le

=

va r

c o n te n t

"Y o u r =

a d d M a rk e r(m a p ,

L o c a tio n " ;

"Y o u

a re

h e re :

"

+

c o o rd s . la titu d e

g o o g le L a tA n d L o n g ,

t it le ,

r

?

П ередаем объ ект ы m a p и g o o g le L a tA n d L o n g, создан-

+

",

"

+

c o o rd s . lo n g itu d e ;

c o n te n t);

< ,

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-драйВ маркера Щ

Добавьте весь код, касаю щ ийся addM arker, обповите showMap для вы зова addM arker и перезагрузите страпицу. П осле этого вы увидите карту с маркером, указывающ им ваше местополож епие. Щ елкпите па маркере кпопкой мыши. В результате этого по­ явится всплываю щ ее окпо, в котором будут отображ аться ш иро­ та и долгота вашего местополож епия.

«

► «

CO

ft I

1

I В

**

• ~ "■

Все это здорово, поскольку теперь вы мож ете точпо узпать, где паходитесь (паприм ер, если заблудились). Вот как будет выглядеть наша карта с м аркером и всплывающим окном.

г

Проведите тестирование онлайн: h t t p : / /w i c k e d l y s m a r t .c o m / k f k t m l s / c h a p t e r S / m a r k e r /m y L o c .h t m l

Прочие интересные Вещи, которые моЖно сделать с использованием A PI-интерфейса Google Maps Мы лиш ь поверхпостпо затропули то, что можпо сделать с помощью Google Maps, подробпое изу­ чепие даппого API-иптерф ейса выходит за рамки пастоящ ей кпиги. Но у вас пе возпикпет сложно­ стей, если вы захотите сделать это самостоятельпо. П риведем ряд вещ ей, для реализации которы х оп мож ет использоваться, а также пекоторы е подсказки для вас о том, с чего пачать. Элементы управления: ваша карта 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-интерфейс Geolocation. Сразу хочу отметить, что немного удив­ лен видеть Вас здесь. Geolocation: Почему же? Head First: Вы даже не являетесь «официальной» ча­

стью спецификации HTML5, однако стали первым API-интерфейсом, которому была отведена целая глава в данной книге! Чем это объясняется? Geolocation: Что ж, Вы правы в том, что я опреде­ лен в спецификации, отдельной от HTML5, однако являюсь официальным стандартом W3C. Оглянитесь вокруг: я уже реализован в браузерах, устанавливае­ мых на любом стоящем мобильном устройстве. Под этим я подразумеваю следующее: будет ли много пользы от мобильного веб-приложения, если оно не поддерживает меня? Head First: Какие приложения задействуют Вас? Geolocation: К их числу относится большинство приложений, которыми люди пользуются в дороге: начиная с приложений, позволяющих обновлять свой статус и включать геолокационную информа­ цию, и заканчивая приложениями для фотокамер, фиксирующими то, где были сделаны снимки, а так­ же социальными приложениями, дающими возмож­ ность отыскать местных друзей или отметиться в разных местах. Люди используют меня даже для фик­ сации того, где они ездили на велосипеде, бегали или останавливались перекусить, а также для того, чтобы добраться до нужного пункта назначения. Head First: Вы как API-интерфейс выглядите просто­ вато, то есть я хочу сказать, что у Вас в сумме имеется лишь несколько методов и свойств, ведь так? Geolocation: В компактности и простоте заключена мощь. Разве многие жалуются на меня? Нет. У меня есть то, что нужно всем разработчикам, которые каж­ дый день создают массу приложений с поддержкой определения местоположения. Кроме того, моя ком­ пактность означает, что меня можно быстро и легко освоить, не так ли? Может, в этом и заключается при­

чина, по которой я стал первым API-интерфейсом, которому была отведена отдельная глава? Head First: Давайте поговорим о поддержке. Geolocation: Тут не о чем особо говорить, посколь­ ку меня поддерживают почти все браузеры как в на­ стольном, так и в мобильном сегменте. Head First: Какая от Вас польза на устройствах, кото­ рые не поддерживают GPS? Geolocation: Это заблуждение, что я как-то зависим

от GPS. На сегодняшний день существует масса дру­ гих способов определять местоположение, напри­ мер посредством триангуляции с использованием вышек сотовой связи и мобильного телефона, по­ средством IP-адресов и т. д. Если в Вашем устройстве есть GPS, то это здорово, поскольку в этом случае я смогу быть для Вас еще более полезным; если же GPS отсутствует, то Вы всегда можете прибегнуть к массе других способов определения местоположения. Head First: Быть еще более полезным? Geolocation: Если у Вас достаточно хорошее мо­

бильное устройство, то я смогу сообщить Вам еще и высоту, направление, скорость, то есть все возмож­ ные показатели. Head First: Допустим, что ни один из этих способов не сработал —ни GPS, ни IP-адрес, ни триангуляция. Какой тогда от Вас толк? Geolocation: Что ж, я не всегда могу ручаться, что Вам обязательно удастся определить местоположе­ ние, однако есть и положительный момент — я даю возможность выяснить причину проблемы. Все, что Вам нужно сделать, —это дать мне обработчик оши­ бок, и я буду вызывать его в случае возникновения проблем. Head First: И это хорошо. Что ж, наше время истек­ ло. Благодарю Вас, API-интерфейс Geolocation, за то, что посетили нас. И поздравляю с обретением стату­ са настоящего стандарта W3C! дальш е ►

223


детали geolocation api

Возвращаясь к A PI-интерфейсу Geolocation... Мы с вами уже прош ли довольпо длиппы й путь, используя API-иптерф ейс Geolocation: мы определяли паше м естополо­ ж ение, вычисляли расстояпие до других объектов, обраба­ ты вали состояпия ошибки API-иптерф ейса и даже добавляли карту с помощью API-иптерф ейса Google Maps. Одпако от­ дыхать еще рапо, поскольку мы только подош ли к рассм отре­ нию иптереспы х особеппостей API-иптерф ейса G eolocation. Мы также приблизились к точке, которая отделяет человека, зпающего о даппом API-иптерф ейсе, от того, кто мастерски им владеет, поэтому пе будем останавливаться!

Geolocation

П реж де чем двипуться дальше, пам пеобходимо более приgetcurrentPosition стальпо взглянуть па сам этот API-иптерф ейс. Как уже отмеча­ watchPosition лось рапее, даппы й API-иптерф ейс довольпо п рост и вклю чает clearWatch лишь тр и метода: g e t c u r r e n t P o s i t i o n (о пем вам уже кое-что Aизвестпо), w a t c h P o s i t io n (подробпости о пем вы узпаете до­ вольпо скоро) и cle a r W a tc h (o n , как вы уже догадались, свяМетоды, являющиеся частью зап с w a t c h P o s i t io n ) . П еред тем как мы п ерей ти к этим двум API -инт ерф ейса Geoiocation. повы м методам, еще раз взгляпем па 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 in a te s . Вы от­ кроете для себя то, о чем рапы не пе зпали. Вызов errorHandler происходит, когда браузеру не удается определить м е с т о ­ положение пользователя. Как мы уже в и ­ дели, причин т о м у может быть немало.

getcurrentPosition(successHandler, errorHandler, positionOptions) Как вы можете пом н ит ь, successHandleru (или функция обратного вызова) вызыва­ ется, когда местоположение определено, и ем у передается объект position.

I

Position coords timestamp

Вы уже знаете о свойстве coords, однако в position также имеет ся свойство tim e s ta m p , содержащее значение времени создания объек­ та position. Оно позволяет узнат ь, насколько ст ары м является местоположение. 224

глава 5

У нас также имеется новый п а рам е т р, который мы еще не использовали, позволяющий н а с т р а и ­ вать поведение API -инт ерф ейса Geolocation.

Coordinates latitude longitude accuracy altitude altitudeAccuracy heading speed

Вам уже знакомы latitude и longitude, однако в объ­ екте coordinates имею т ся и другие свойства. Эти т ри гарант ирован_ но будут там: latitude, ongtitude и accuracy. Остальные м о гу т как s поддерживаться, так и не поддерживаться, — это зависит от и сп оль­ зуемого устройства.


создание HTML-ст раниц с поддерж кой определения мест оположения

МоЖем ли мы поговорить о точности? О пределение местополож епия пе является точпой паукой. В зависимо­ сти от методики, прим епяем ой вашим браузером, вы сможете узпать только штат, город и квартал города, в котором паходитесь. С другой сторопы , если устройство будет более продвинутым, то вы сможете определить собствеппое м естополож епие с точпостью до 1 0 метров, вклю чая показатели своей скорости, паправлепия и высоты. Так как же писать код, исходя из даппой ситуации? Разработчики APIи п тер ф ей са G eolocation заклю чили с пами пеболы ной договор: каждый раз, когда опи даю т пам коордипаты м естополож епия, опи также сооб­ щают пам их точпость в метрах в пределах 95%-пого уровпя достоверпости. Так, если бы мы пам сообщ или паше местополож епие с точпостью до 500 метров, то мы могли бы быть достаточпо уверепы в его достоверпости, если пе выходить за пределы этих 500 метров. В таком случае можпо, паприм ер, давать пользователям верпы е реком ендации отпосительпо города или его окрестпостей, по пе сообщ ать им подробпы й уличпый маршрут проезда. В любом случае очевидпо, что ваше прилож епие будет реш ать, как опо хочет использовать даппы е, касаю щ иеся точпости. Но хватит разговоров, давайте взгляпем па точпость в случае с вашим текущим местополож ени­ ем. Как вы уже зпаете, ипф орм ация, касаю щ аяся точпости, является частью объекта c o o r d i n a t e s . И звлечем ее, а затем используем в фупкции d i s p l a y L o c a t i o n . 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

va r

1 o n g i tu d e

va r

d iv

=

= =

=

d iv .in n e r H T M L

+=

km =

va r

d iv

p o s i t i o n . coo r d s .1 o n g i tu d e ;

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 " ) ;

d iv .in n e r H T M L

va r

{

p o s it io n . c o o r d s . l a t i t u d e ;

"Y o u "

a re

( w ith

a t "

L a titu d e : +

"

+

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 ,

=

la titu d e

o u rC o o rd s ) ;

d o c u m e n t . g e t E le m e n t B y ld ( " d is t a n c e "

d i s t a n c e . in n e r H T M L

=

"Y o u

a re

+

p o s it io n . c o o r d s . a c c u ra c y

"

+

km

+

"

km

); fro m

th e

", +

L o n g itu d e : "

m e te rs

"

+

lo n g itu d e ;

a c c u ra c y )" ;

' Используем свойство accuracy, которое добавляем в конец innerHTML элем ент а <div>. W ic k e d ly S m a rt H Q ";

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


от слеживание перемещ ения

«Wherever you go, there you are» И сточпик происхож депия ф разы из заголовка (одпо из ее зпачепий: «Куда бы ты пи шел —ты имеппо там», то есть в философ ском смысле здесь под­ разумевается, что от себя пе убежишь) горячо обсуждается. Н екоторы е утверждают, что опа впервы е упомипалась в фильме «Бакару Бапзай» (Buckaroo Banzai), в то врем я как другие полагают, что опа происходит из дзеп-буддийских текстов, а третьи ссылаю тся па различпы е кпиги, прочие кипоф ильм ы и популярпы е песпи. Н еваж по, что имеппо послужило ее ис­ точником, главпое — опа была увековечепа, и тем более сохрапится после даппой главы, потому что мы п ревратим ее в пеболы ное веб-приложепие с соответствующ им имепем. Одпако пам потребуется пемпого участия с ва­ ш ей читательской сторопы . Вам предстоит расш ирить свой текущий код таким образом, чтобы оп смог отслеж ивать ваше перем ещ епие в реальпом времепи. Д ля этого мы соберем все вместе, вклю чая два последпих метода, имею щ ихся в APIи п терф ей се G eolocation, и создадим п рилож епие, которое будет отслеж и­ вать ваше перем ещ епие в реж им е, близком к режиму реальпого времепи.

А к т о Лпо-ваш ем у, прав в дебатах по поводу источника происхождения дан­ ной фразы? Исходит она от веб-ресурса Banzai Institute или же берет свое нача­ ло в дзен-буддийской л и т ер а т ур е?

Как мы будем отслеживать ваше перемещение Вы уже зпаете, что 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 , по ведет себя пемпого по-другому: оп повторпо вы зы вает обработчик успешпого исполпепия каждый раз, когда изм епяется ваше м естополож епие. Д авайте посмотрим, как оп работает. / Т \ Ваше приложение вызывает метод

w a t c h P o s i t i o n , передавая ему функцию обработчика успешного выполнения.

Браузер

/^ Ч w a t c h P o s i t io 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

w a t c h P o s i t io n будет про­ должать отслеживать ваше местоположение (и доклады­ вать о нем обработчику успешного исполнения) до тех пор, пока вы не остановите отслеживание путем вызова clea r W a tc h .

©:

226

глава 5

При изменении вашего местоположения watchPosition вызывает функцию обработчика успешного исполнения для до­ клада ей о вашем новом место­ положении.


создание HTML-ст раниц с поддерж кой определения мест оположения

Приступаем к созданию приложения В качестве отправпой точки мы возьмем приводивш ийся рапее код; спачала добавим пару кпопок в HTML, чтобы можпо было запускать и останавливать отслеж ивапие вашего м естополож е­ ния. Зачем вообщ е нужпы кпопки? П режде всего пользователи пе хотят, чтобы их перем ещ епия отслеживались постояппо, и, как правило, хотят иметь коптроль пад этой процедурой. Но есть и вторая причипа: п остояппая проверка местополож епия па мобильпом устройстве п отребляет мпого электроэпергии, и если оставить ее активироваппой, это приведет к бы строй разрядке аккумулятора. Поэтому мы в первую очередь обповим HTM L с це­ лью добавить форму и две кпопки: одну для зануска отслеж ивапия вашего м естополож епия, а другую —для его остаповки. < ! d o с ty p e

h tm l>

<head> c h a r s e t = Mu t f - 8 M>

< t itle > W h e r e v e r < s c r ip t < lin k

you

go,

th e re

you

a r e < /title >

s rc = "m y L o c . j s " X / s c r i p t >

r e l = Ms t y l e s h e e t "

Г

Отслеживание местоположения пользователя в режиме реального времени может пагубно сказаться на уровне заряда аккумулятора. Убедитесь, что вы предост авля­ ет е пользователям информацию об отслеживании их м е с т о п о л о ­ жения', а также средства к о н т р о ­ ля над этой процедурой.

< h tm l>

< m e ta

-*

h r e f = Mm y L o c . c s s M>

< /h e a d > <body> < fo r m > < in p u t

ty p e = " b u tto n "

id = " w a tc h "

v a lu e = "W a tc h

< in p u t

ty p e = "b u tto n "

id = " c le a r W a tc h "

m e ">

v a lu e = " C le a r

< /fo rm > < 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

w a tc h " >

Мы добавляем э л е ­ м е н т form с двумя кнопками, одна из которы х, имеющая id в виде "watch", будет использоваться для запуска отслеживания, а вт орая, с id в виде "clearWatch", — для его остановки.

id = " m a p " >

Снова воспользуемся нашими прежними элем ент ам и <div> для сообщения информации о местоположении в режиме реального времени

< /d iv > < /b o d y > < /h tm l>

Ч уть позже мы вернемся и п о за ­ ботимся о карте Google...

дальш е ►

227


использование w atchposition

Дорабатываем наш старый код... Теперь пам пеобходимо добавить обработчики собы тий c l i c k , инициируем ы е при щ елчке па кпопке, для двух паш их кпопок. Мы будем добавлять их в фупкцию g e tM y L o c a tio n только п ри паличии под­ держ ки API-иптерф ейса G eolocation. И поскольку мы собираемся полпостью контролировать геолокациоппое отслеж ивапие посредством двух кпопок, удалим существующий вызов g e t c u r r e n t P o s i t i o n из g e tM y L o c a tio n . И так, удалим соответствующ ий код и добавим два обработчика: w a tc h L o c a tio n — для кпопки, используемой для зануска отслеж ивапия, и c le a rW a tc h — для кпопки, прим епяем ой для остаповки отслеживапия: с ^ „ ^ fu n c tio n i f

q/

{

g e tM y L o c a tio n ()

( n a v ig a to r .g e o lo c a tio n )

Е сли б р а у з е р п о д д е р ж и в а е т A P I - и н т е р ф е й с G e o lo c a tio n , т о м ы д о б а в л я е м о б р а б о т ч и к и с о б ы т и й click. В их д оба в ле нии не б у д е т с м ы с л а

в с л у ч а е о т с у т с т в и я т а к о й поддерж ки.

{

n a v i g a t o r . g e o l o e a f e i o n . g e fe C u g g e n fe P o s i f e i o n . ( d i a p l a y L o e a f e i o n , d i a p l a y E g g o g ) ; va r

w a tc h B u tto n

=

d o c u m e n t. g e tE le m e n t B y ld ( " w a t c h " ) ;

w a tc h B u tto n . o n c lic k va r

c le a r W a tc h B u tto n

=

w a t c h L o c a t io n ; =

d o c u m e n t. g e tE le m e n t B y ld ( " c le a r W a t c h " ) ;

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 ;

У e ls e

Ъудем вы зы ват ь w a tchL o ca tion для з а п у с к а о т с л е ж и в а н и я ,

{ a l e r t ("O o p s ,

no

g e o lo c a tio n

s u p p o rt") ;

c l e a r W a tc h новки.

й

для его о с т а -

}

Написание обработчике watchLocation В о т ч т о м ы попы таемся сделать: когда пользователь паж имает кпопку с i d в виде " w a tc h " , оп хочет пачать отслеж ивапие своего местополож епия. Поэтому мы воспользуемся методом g e o lo c a t io n . w a t c h p o s it io n для зануска отслеж ивапия его м естополож епия. М етод g e o l o c a t io n . w a t c h p o s it io n об­ ладает двумя парам етрам и — обработчиком успешпого исполпепия и обработчиком ошибок, так что мы сможем повторпо использовать обработчики, которы е у пас уже имеются. О п также возвращ ает w a tc h ld , что мож ет использоваться в лю бой момепт для отмепы отслеживающ его поведепия. Мы п ри ­ прячем w a t c h ld в глобальпой перем еппой, которую используем, когда будем писать обработчик собы­ ти й c l i c k для кпопки, прим епяем ой для остаповки отслеж ивапия. Вот код для фупкции w a t c h L o c a tio n и w a tc h ld , которы й вам пужпо добавить в m y L o c . j s: va r

w a tc h ld

fu n c tio n

= n u ll;

w a t c h L o c a t io n ()

w a tc h ld

=

£ ___________

Д о б а в ь т е w a t c h l d в в е р х н ю ю ч а с т ь своего ф а й л а к а к г л о б а л ь н у ю п е р е м е н н у ю . М ы и н и ц и а л и з и р у е м ее з н а ч е н и е м null. О н а п о т р е б у е т с я н а м позже для о с т а н о в к и о т с л е ж и в а н и я .

{

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-ст раниц с поддерж кой определения мест оположения

Написание обработчика clearlVatch Теперь паппш ем обработчик для остаповки отслеживапия. Д ля этого пам потребуется взять w a tc h ld и передать его методу g eo l o c a t i o n . clea r W a tc h .

fu n c tio n i f

c le a r W a t c h ()

( w a tc h ld )

{

Убеждаемся, что у нас имеется w atch ld, а затем...

{

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 ) ; w a tc h ld

=

^

n u ll;

}

^ ...вызываем м ет од geolocation. clearWatch, передав ему watchld. Это приведет к остановке отслеживания.

Еще необходимо внести небольшое обновление в displayLocation... Есть еще одпо пеболы ное обповлепие, которое пам нужпо вы полпить, и касается опо кода Google Maps, паписаппого рапее. В даппом коде мы вызы ваем showMap для отображ епия карты Google (showMap ге-

перирует повую карту па веб-страпице). П ри этом пам пеобходимо, чтобы даппая процедура осущест­ влялась только одип раз. Одпако, как вы мож ете помпить, при запуске отслеж ивапия вашего местопо­ лож епия посредством w a tc h P o s i t io n обработчик d is p l a y L o c a t io n будет вы зы ваться каждый раз, когда происходит обповлепие вашего местополож епия. Ч тобы гараптировать, что вызов showMap состоится только одип раз, спачала проверим , существует ли карта, и если опа отсутствует, то вы зовем showMap. В п ротивпом случае, если карта присутствует, это будет озпачать, что вызов фупкции showMap уже происходил, карта была сгеперировапа, поэтому пам пе пужпо вызы вать ее спова. 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

va r

1 o n g i tu d e

va r

d iv

=

=

p o s it io n . c o o r d s . l a t it u d e ; =

po s i t i o n . c o o rd s .1 o n g i tu d e ;

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 " ) ;

d iv .in n e r H T M L

=

d iv .in n e r H T M L

+=

va r

km =

va r

d is ta n c e

"Y o u "

a re

( w ith

a t "

L a titu d e :

=

+

(m a p = =

la titu d e

+

", +

L o n g itu d e : "

m e te rs

"

+

lo n g itu d e ;

a c c u ra c y )" ;

o u rC o o rd s );

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 " ) ;

n u ll)

=

"Y o u

a re

"

+

km +

"

km

fro m

th e

W ic k e d ly S m a r t

H Q ";

{

s h o w M a p ( p o s itio n .c o o r d s ) ;

}

"

+ p o s it io n . c o o r d s . a c c u ra c y

c o m p u te D is ta n c e ( p o s itio n .c o o r d s ,

d i s t a n c e . in n e r H T M L

i f

{

Если функция showMap еще не вызывалась, следует вызвать ее; в прот ивном случае ее не нужно будет вызывать при каждом вызове displayLocation. дальш е ►

229


т ест ирование от слеживания пользоват еля

Пора отправляться в путь! Убедитесь, что вы добавили весь п овы й код, и перезагрузите свою страпицу m y L oc.h tm l. Теперь, для того чтобы по-пастоящему п ротести ровать даппую веб-страпицу, вам потребуется перем еститься са­ мим, чтобы обповить свое м естополож епие. П оэтому отправляйтесь па прогулку, прокатитесь па вело­ сипеде или автомобиле либо воспользуйтесь любым другим видом трапспорта. С тоит ли говорить, что если вы будете тестировать даппое п рилож епие па своем пастольпом компью те­ ре, то опо покаж ется довольпо скучпым (так как вы пе сможете взять его с собой), поэтому вам следует проводить тестирование с использованием мобильпого устройства. А если вам потребуется доступ со своего мобильпого устройства к версии кода, разм ещ еппой оплайп, вы сможете пайти ее по адресу http: / / w ickedlysm art.com /hfhtm l5 / chapter5 / watchm e / myLoc.htm l.

В о т наш т е с т о в * .« лрогон...

Эти показатели будут обновляться по мере вашего перемещения.

Следует о т м е т и т ь , что на данный м о м е н т в центре карты будет отображаться ваше н а ­ чальное местоположение...

Проведите тестирование онлайн: h t t p : / /w i c k e d l y s m a r t .c o m / h f h tm ls / c h a p t e r S / w a t c h m e /m y L o c .h t m l 230

глава 5


Часш°

ЧаДаВаеМые В опросы Как я могу регулировать частоту обновления браузером моего местоположения при использовании watchPosition?

ваться (и, очевидно, их поддержка будет обеспечиваться только на

Q j Никак. Браузер сам определяет оптимальную частоту обнов­

удостовериться в том, что ваш код сможет справиться с отсутствием

ления и судит о том, когда именно произошло изменение вашего

их поддержки.

0 : Нет гарантий, что эти свойства обязательно будут поддержи­ мобильных устройствах высшего класса), поэтому вам потребуется

местоположения.

В

Что такое heading и speed?

Почему показатели моего местоположения изменяются по нескольку раз при первой загрузке страницы, даже несмотря на то что я сижу на месте не перемещаясь?

a

0 : Помните, мы говорили, что браузер может применять разные

томагистрали, а спидометр показывает 90 км/ч. Ваше направление

0 : h e a d in g — это направление, в котором вы двигаетесь, s p e e d — скорость, показывающая, насколько быстро вы это

делаете. Представьте, что вы едете в автомобиле на север по ав­

методики для определения вашего местоположения? В зависимости

в данном случае — на север, а скорость равна 90 км/ч. Если же вы

от методики (или методик), используемой браузером для выяснения

сидите в машине, стоящей на парковке, то ваша скорость равна О,

того, где вы находитесь, точность определения вашего местопо­

а направления у вас нет (поскольку вы не двигаетесь).

ложения со временем может изменяться. Как правило, точность

Когда я проверяю по карте расстояние от своего место­ положения до вашего, у меня получается намного больший результат, чем рапортует приложение. В чем причина?

улучшается, но иногда (например, если вы заехали в сельскую местность, где есть только одна вышка сотовой связи) может ухудшаться. Кроме того, вы всегда можете задействовать свойство accuracy в объекте position.coords, чтобы следить за точностью.

0 : Как вы можете помнить, функция

Могу ли я использовать свойства altitude и altitudeAccuracy объекта coordinates?

c o m p u te D is ta n c e вы­

числяет расстояние по прямой. Ваш картографический инструмент, скорее всего, выдает расстояние, которое придется проехать на автомобиле по извилистому пути.

Возьми в руку карандаш Ниже приведена альтернативная реализация для displayLocation. Сможете ли вы догадаться, что она делает? Взгляните на нее и напишите свой ответ в самом низу. Если в вас проснулась предприимчивость, то затем протестируйте данный код! d i a t a n e e . i n n e rH T M L — " Y o u i f

(k m <

0 .1 )

d is ta n c e .in n e r H T M L }

e ls e i f

п— I— fem—I— M k m

f r o m t h e W i e k e d l y D m a g t IIQ M ;

=

" Y o u 'r e

on

fir e !" ;

{ (p re v K m

<

km )

{

d is ta n c e .in n e r H T M L }

a re

{

e ls e

=

" Y o u 'r e

g e ttin g

h o tte r!";

=

" Y o u 'r e

g e ttin g

c o ld e r ..." ;

{

d is ta n c e .in n e r H T M L

} } 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 = {

enableHighAccuracy: false, timeout: Infinity, maximumAge: 0 } И наконец, с помощ ью п а ра м ет ра m a xim um A ge устанавливаем максимальный « во зр а ст » данных о местоположении, который они м о гу т и м е т ь до того, как браузеру пот ребует ся заново опре делит ь местоположение. По ум олчанию данный па р а м е т р и м е ет значение О, которое подраз­ ум евает , что браузеру придется всегда зано во определять местоположение пользователя (при каждом вызове getcurrentPosition).

Параметр tim e o u t позволяет конт роли ро ва т ь, как долго браузер сможет определять м е с т о ­ положение пользователя. По умолчанию для данного п ар ам ет ра задается значение Infinity, то есть браузер получит столько времени, сколько ему потребуется. Д л я данного пара м ет р а также можно задать значение в миллисекундах (например, ю ООО), то есть браузер по луч ит Ю секунд на о п р е ­ деление местоположения, в прот ивном случае будет вызван обработчик ошибок.

Нельзя ли сноба поговорить о т о ч н о с т и ? Вы уже видели, что все даппы е о м естополож епии, возвращ аемы е пам 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-ст раниц с поддерж кой определения мест оположения

Мир параметров timeout и maximumAge... Еще раз взгляпем па то, что представляю т собой парам етры tim e o u t и maximumAge.

timeout: сообщ ает браузеру, как д олго оп сможет определять место­ полож ение пользователя. Следует отметить, что если пользователю будет предложепо одобрить запрос па определепие местоположепия, то отсчет врем епи ож идапия пе пачпется до тех пор, пока оп пе даст своего согласия. Если браузеру пе удастся определить повое м естопо­ лож ение в течепие врем епи в миллисекупдах, указаппого в зпачепии t im e o u t , п р о и зой д ет вы зов об раб отчи ка ош ибок. Параметр timeout по умолчанию имеет значение Infinity. maximumAge: сообщает браузеру, пасколько у старевш и м и могут быть даппы е о м естоп олож еп ии . Таким образом , если у браузера им ею тся д ан ны е о м есто­ п олож ении, которое было определепо 60 секупд пазад, а для maximumAge при этом задано зп ачеп ие 9 0 0 0 0 (90 секупд), то вы зов g e t c u r r e n t P o s i t i o n п риведет к возврату уже имею щ ихся кэш ироваппы х даппы х о местополож епии (то есть браузер пе стапет пы таться определить повое ме­ стополож ение пользователя). Одпако если в даппой ситуации для maximumAge будет задапо зпачепие, равпое 30 секупдам, браузеру придется определять повое м естополож епие пользователя.

Таким образом, посредством maximumAge я могу устанавливать, насколько часто браузер будет пересчитывать или определять мое ме­ стоположение. Я понимаю, что это позволит сделать мое приложение более быстрым и энергоэффективным. А как насчет timeout? Как я могу использо­ вать данный параметр, чтобы сделать код лучше?

Вы правы в своих суждениях насчет maximumAge. Ч то касается t im e o u t, следует рассуждать так: при использовании maximumAge вы получаете стары е (кэш ированны е) данные, пока они остаю тся «моложе» значе­ ния, заданного для maximumAge, и это действительно помогает оптим и­ зировать производительность вашего прилож ения. Но что будет, ког­ да «возраст» данных о местополож ении превы сит значение, заданное для maximumAge? В таком случае браузер попы тается извлечь данные о новом местополож ении. Бы ть может, все это не будет слишком вас беспокоить, наприм ер, вас устроят данны е о новом местополож ении, если они есть у браузера, а если же их у него нет, то эти сведения не по­ требуются сию же минуту. Вы могли бы задать для tim eout значение 0, и если у браузера будут данны е о м естополож ении, которы е проходят «тест» maximumAge, то все отлично, в противном случае соответству­ ю щий вызов незамедлительно потерп ит неудачу и произойдет вызов обработчика ош ибок (с кодом ошибки TIM EO UT). Это лиш ь прим ер творческого подхода к использованию maximumAge и t im e o u t для пастройки поведепия вашего прилож епия. дальш е ►

233


упражнение на использование парамет ров geolocation

+КТ

9

И Н Т^»Б Л а т

1т ?

_____

Ниже приведены параметры, касающиеся API-интерфейса Geolocation. Ваша задача заключается в том, чтобы подобрать каждому параметру пару в виде соответствующего ему поведения.

{maximumAge:600000}

234

Мпе требую тся только кэш ироваппы е даппы е о м естополож ении, которы м мепыне 10 минут. П ри отсутствии таких даппы х я хочу получить даппы е о повом м естополож епии, по только в том случае, если па это уйдет 1 секупда или мепыне.

{timeout:1000 , maximumAge :б00000 }

Я буду использовать кэш ироваппы е дап­ пы е о м естополож епии, если таковы е будут иметься у браузера, и при этом им будет мепыне 10 минут; в противпом слу­ чае я хочу получить даппы е о повом ме­ стополож епии.

{timeout:0 , maximumAge :Infinity}

Мпе требую тся только даппы е о повом местополож епии. Браузер мож ет ис­ пользовать столько времепи па опреде­ ление м естополож епия, сколько ему по­ требуется.

{timeout:Infinity, maximumAge:0 }

Мпе требую тся только кэш ироваппы е даппы е о м естополож епии. М епя устро­ ят даппы е лю бого «возраста». Если кэ­ ш ироваппы е даппы е о м естополож епии будут полпостью отсутствовать, про­ изойдет вызов обработчика ошибок. Сведепия о повом местополож епии из­ влекаться пе будут! Д аппы е пастройки предпазпачепы для использования в си­ туациях, когда речь идет об автопом пой работе.

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

Как задавать параметры Одпа из зам ечательпы х особеппостей JavaScript заклю чается в том, что если пам потребуется задать целы й пабор парам етров в объекте, мы сможем сделать это, просто вставив литеральпы й объект прямо посередипе вы зова метода. Допустим, пам пеобходимо активировать высокую точпость, а также задать максимальпый «возраст» для даппы х о м естополож епии, равпы й 60 секупдам (60 ООО миллисекупд). П ерем еппая o p t i o n s создается следующим образом: 0 г ^ ^ г уже начали з а м е v a r o p t i o n s = { 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 } ; гj чат ь>Что JavaScript — . это n o -настоящ ему Затем мы можем передать o p t i o n s либо g e t Cur r e n t P o s i t i o n , n^ „ r круто? По крайней либо w a t c h P o s i t i o n , как показало далее: ' м е р е } мы считаем n a v ig a t o r . g e o lo c a tio n .g e tC u r r e n tP o s itio n ( именно так. © displayLocation,

Передаем наши параметр*.

КГ

o p tio n s ) ;

И ли мы могли бы просто добавить соответствую щ ий объект как встроеппы й: 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

<

Вы б у д е т е ч а с т о с т а л -

< литерального o o v екта прямо в вызов функции! Н е к о т о р ы е

киваться с использовас ч и т а ю т , что так 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 , d is p la y E r r o r ,

^

З ад ав для t i m e o u t значение SOOO м и л л и с е ­ кунд ( S секунд), вы с д е л а е т е т а к , ч т о д р а у ^ ^ S y d e m бесконечно долго п ы т а т ь с я

определит ь местополож ение. J Проведите т ест ирование, подставляя сюда разные значения. { t im e o u t : 5 0 0 0 }) ;

}

дальш е ►

235


г

И С П Ы Т А Й Т Е С Ь с д е л а т ь э т о д о м а

(КА К ЗАСТАВИТЬ GEOLOCATION РАБОТАТЬ НА ПРЕДЕЛЕ ВОЗМОЖНОСТЕЙ) Разве не интересно узнать, как быстро браузер сможет определить ваше местопо­ ложение? Мы усложним для него задачу, насколько это представляется возможным: ■ активируем высокую точность; ■ не позволим ему использовать кэшированные данные о местоположении (за­ дав для maximumAge значение 0); ■ ограничим его по времени, задав для tim e o u t значение 100, которое будем увеличивать после каждой неудачной попытки браузера определить местополо­ жение в течение заданного времени. Предупреждение: мы не знаем, как долго продержится аккумулятор того или иного устройства при определении местоположения на основе таких настроек, поэтому используйте их на свой страх и риск! Вот как будут выглядеть наши исходные параметры:

Mt?i начнем с этого... { e n a b le H ig h A c c u r a c y :

tru e

,

tim e o u t: 100 ,

m a x im u m A g e : 0 }

{ e n a b le H ig h A c c u r a c y :

tru e

,

tim e o u t: 20 0 ,

m a x im u m A g e : 0 }

{ e n a b le H ig h A c c u r a c y :

tru e ,

tim e o u t: 3 0 0 ,

m a x im u m A g e : 0 }

и если браузеру не удастся опреде­ лить мест ополо­ жение, дадим ему больше времени... ^

и т ак далее...

Теперь ознакомьтесь с кодом, приведенным на следующей странице, — он покажется вам довольно интересным. Наберите его (можете добавить его в свой JavaScript-файл m yLoc. j s ). Протестируйте данный код на различных устройствах, которые у вас имеются, а результаты запишите здесь:

ме\мь\ме yciMjpoutw о 3

д 3j ect? у КаЖите время

десь по На

местоположение было определено з а

миллисекунд

На.

местоположение было определено за

миллисекунд

На.

местоположение было определено з а _____ миллисекунд

На

местоположение было определено з а _____ миллисекунд

Тестирование онлайн: h t t p ://w ic k e d ly s m a r t.c o m /h fh tm ls /c h a p te r s /s p e e d te s t/s p e e d te s t.h tm l

236

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

var options = { enableHighAccuracy:

true, timeout: 100, maximumAge: 0 };

window.onload = getMyLocation;

Сначала мы инициализируем options при эт о м tim e o u t будет и м е т ь

function getMyLocation() { if

(navigator.geolocation)

{

значение Ю О , a m a X i m u m A g e

O,

navigator.geolocation.getcurrentPosition ( displayLocation, displayError ,

}

^ ^

Здесь по ст упаем как обычно : задей ст вуeM displayLocation и display Error в качестве соот вет ственно обработчика успешного исполнения и обработчика ошибок — и п е р е даем options в роли т р ет ьего параметра.

op i o ns), 4else { alert("Oops, no geolocation support");

} > function displayError(error)

Первым делом разбираемся с обработчиком ошибок.

var errorTypes = {

Э т от код будет т ак им же, как и прежде...

"Unknown e r r o r " , "Permission d enied", "Position is not available",

/

"Request timeout"

}; var errorMessage = errorTypes[error.c ode]; if

(error.code =

0 || error.code == 2)

{

errorMessage = errorMessage + " " + error.message;

} var div = document.getElementByld (" location" ) ; div.innerHTML = errorMessage; options .timeout += 100;

^ -- -

navigator.geolocation.getcurrentPosition ( di splayLocation, displayError, options);

8 случае, если браузеру не удастся определить м е с т о ­ положение, будем увеличивать значение tim e o u t на Ю О м и л ­ лисекунд и давать ему п о ­ вт орную попытку. Мы также уведомим пользователя о п о ­ вторении попытки.

div.innerHTML += " ... checking again with timeout=

+ options .timeout

} function displayLocation(position)

{

var latitude = position.coords.latitude; var longitude = position.coords.longitude; var div = document.getElementByld("location"); div.innerHTML = "You are at Latitude: ", Longitude:

" + latitude +

" + longitude;

div.innerHTML += " (found in " + options.timeout + " milliseconds)

}

7^ Когда браузеру удастся определить местоположение пользователял V. мы сооощим ему, сколько времени это заняло.

J 237


добавление п ут и на карт у

Шлифуем наше приложение! Е с л и откинуться па спипку стула и призадуматься, то мы с вами, используя пемпого HTM L и JavaScript, создали веб-приложепие, которое способпо пе толь­ ко определять ваше местополож епие, по также от­ слеж ивать и отображ ать его почти в режиме реального времени. Да, HTM L и вправду серьезпо подрос (как и ваши п авы ки !).

Одпако если вести речь о даппом прилож епии, пе ка­ ж ется ли вам, что опо нуждается в пеболы ной шли­ фовке с целью придапия ему заверш еппого вида? Н априм ер, мы могли бы сделать так, чтобы ваше ме­ стополож епие отображ алось па карте по ходу п ере­ мещения; кром е того, мы могли бы п ойти еще даль­ ше и показы вать места, где вы были, то есть па карте будет отображ аться ваш путь. Н апиш ем фупкцию для того, чтобы ваше м естополо­ ж епие продолжало отображ аться в ц еп тре карты по мере вашего передвиж епия. Будем добавлять повы й маркер, отмечая каждое повое местополож епие. будем вызывать данную ф ункцию и Iпередавать ей соот вет ст вую щ ие координаты. И т а к,

fu n c tio n va r

Данные координаты будут указы ват ь на ваше Г~ самое, последнее местоположение, которое мы ( Jy ст анем отображать в центре к ар т ы , а также о т м е т и м его м ар кер о м . s c r o llM a p T o P o s itio n ( c o o r d s ) { Сначала извлечем новые ш ирот у la titu d e = c o o rd s . la titu d e ; u долгот у и создадим для них объект google.maps.LatLng.

va r

lo n g itu d e

=

va r

la tlo n g

new

=

c o o rd s . lo n g itu d e ;

g o o g le .m a p s . L a t L n g ( l a t i t u d e ,

Метод panTo объекта m ap п риним ает объект LatLng и прокручивает карт у т ак им образом, чтобы ваше новое местоположение отображалось в ее центр.

m a p .p a n T o ( la tlo n g ) ;

a d d M a rk e r(m a p ,

la tlo n g ,

lo n g itu d e ) ;

"Y o u r

new

lo c a t io n " ,

la titu d e

+

",

"

"Y o u +

m oved

to :

lo n g itu d e ) ;

И наконец, добавляем м аркер для о т м е т к и вашего нового местоположения, используя ф ункцию addMarker, написанную нами ранее, которой передаем т ар, объект LatLng, заголовок и содержимое для нового маркера.

238

глава 5


создание HTML-ст раниц с поддерж кой определения мест оположения

интеграция нашей новой функции Н ам остапется лишь обповлять фупкцию d is p l a y L o c a t io n для вы зова s c r o llM a p T o P o s it io n каждый раз, когда изм епяется ваше местополож епие. Н е забы вайте, что при первом вызове d is p l a y L o c a t io n мы вызы ваем showMap для геп ери ровап ия кар­ ты и отображ епия маркера, отмечаю щ его ваше пачальпое место­ полож епие. Каждый раз после этого пам потребуется вызы вать s c r o llM a p T o P o s it io n для добавлепия пового м аркера и цептрир овап ия карты запово. Вот как будет выглядеть обповлеппы й код: function displayLocation(position)

{

var latitude = position.coords.latitude; var 1ongi tude = po s i ti o n .coo r d s .1ongi tude; var div = document.getElementByld("location"); div.innerHTML = "You are at Latitude: + ", Longitude:

" + latitude

" + longitude;

div.innerHTML += " (with " + position.coords.accuracy +

meters accuracy)";

var k m = computeDistance(position.coords, ourCoords); var distance = document.getElementByld("distance") ; distance.innerHTML = "You are " + k m +

if (map == null)

{

showMap(position.coords) ;

km from the WickedlySmart HQ" ;

При первом вызове displayLocation нам необ­ ходимо сгенерировать и отобразить к а р т у , а также добавить первый маркер.

} else { scrollMapToPosition(position.coords);

U еще раз...

После этого останется лишь добавлять новые маркеры на имею щ уюся карту.

о®

П ерезагрузите свою страпицу и пачпите движепие... Ну как, вы черчивается па карте ваш нуть? Вы должпы увидеть дорожку из маркеров, добавляемы х па карту по мере вашего передвиж епия (если, копечпо, вы пе сидите за пастольпым компью тером!). Таким образом, даппое прилож епие мы представля­ ем как твердое доказательство того, что «куда бы ты пи шел —ты имеппо там» (в паш ем случае под этой ф илософ ской ф разой попимается, что вас можпо будет пайти).

г *

/\орожка из м а р к е ­ ров, показывающая наш недавний п у т ь от ш т аб-кварт иры Wickedly S m a r t до тайного подземно­ го логова... Ой, зря мы проболтались об этом...

Тестирование онлайн: h ttp ://w ic k e d ly s m a r t . c o m / h f h t m l s / c h a p t e r s / w a t c h m e p a n / т у Loc.html дальш е ►

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) if

240

глава 5

( > ) { scrollMapToPosition(position.coords);

* 1000;


создание HTML-страниц с поддержкой определения местоположения

КЛЮЧЕВЫЕ — МОМЕНТЫ Я ■ API-интерфейс Geolocation не является «официаль­ ной» частью спецификации HTML5, но считается ча­ стью семейства технологий HTML5. ■

Можно использовать разные методики определения своего местоположения в зависимости от устройства, которое у вас имеется. GPS позволяет получать более точные данные о ме­ стоположении, чем триангуляция с использованием вышек сотовой связи и мобильного телефона или методика на основе применения 1Р-адресов.

При вызове g e t C u r r e n t P o s i t i o n ВЭШ браузер должен удостовериться, что вы дали разрешение на использование информации о вашем местоположении. ■

w atc h P o sitio n —

ЭТО МвТОД объекта

geo l o c a t i o n ,

который отслеживает ваше местоположение и вызыва­ ет обработчик успешного исполнения при изменении вашего местоположения. ■

Как И у 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 имеется один обязательный параметр — обработчик успешного исполнения и два опциональных — обра­ ботчик ошибок И o p t i o n s .

В случае с мобильными устройствами, не поддержива­ ющими GPS, для определения местоположения можно прибегнуть к триангуляции с использованием вышек сотовой связи и мобильного телефона.

Основным методом в API-интерфейсе Geolocation является g e t C u r r e n t P o s i t i o n — МвТОД объекта

будет разряжаться быстрее. ■

У g e t C u r r e n t P o s i t i o n имеется один обязательный

контроля над поведением API-интерфейса Geolocation. ■

параметр — обработчик успешного исполнения, и два

Объект p o s i t i o n передается обработчику успешного исполнения наряду с информацией о местоположении пользователя, включая широту и долготу.

Свойство m a x im u m A g e устанавливает, будет ЛИ

g e tC u rre n tP o sitio n

опциональных — обработчик ошибок И o p t i o n s .

Третий параметр методов 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 с именем o p t i o n s представляет со­ бой объект со свойствами, которые вы задаете с целью

n a v i g a to r . g eo lo catio n . ■

При использовании w a t c h P o s i t i o n энергопотребле­ ние устройства возрастает, поэтому его аккумулятор

■ API-интерфейс Geolocation включает три метода и не­ сколько свойств. ■

c l e a r W a t c h используется для остановки отслеживания местоположения пользователя.

ИСПОЛЬЗОВЭТЬ КЭШИрОВЭННЫе

данные о местоположении, и если да, то насколько устаревшими смогут быть эти данные, прежде чем потребуется определять новое местоположение. ■

Свойство t i m e o u t устанавливает, сколько времени будет у 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 , кото­ рое является объектом c o o r d i n a t e s .

вого местоположения, прежде чем произойдет вызов обработчика ошибок.

Объект c o o r d i n a t e s обладает свойствами, включая l a t i t u d e , lo n g itu d e Иaccuracy.

СВОЙСТВО

en ab leH ig h A ccu racy

Н ам екает устр ой-

ствам на то, что им следует затрачивать больше усилий

Некоторые устройства могут поддерживать и дру­ гие свойства объекта c o o r d i n a t e s : a l t i t u d e , a l titu d e A c c u r a c y , h e a d in g И speed.

Свойство a c c u r a c y используется для определения точности местоположения в метрах.

на определение точного местоположения, если это представляется возможным. ■

Вы можете использовать API-интерфейс Geolocation в сочетании с API-интерфейсом Google Maps для ото­ бражения своего местоположения на карте.

дальше ►

241


кроссворд

1 Л Щ , 5 - К Г °ссК°Г Д Вы проделали довольпо длиппы й путь в этой главе, используя свой п ервы й API-иптерф ейс JavaScript. Закреп и те изучеппы й материал, реш ив даппы й кроссворд.

По горизонтали

По вертикали

3. Измерение долготы ведется о т _______________, Англия.

1. В случае применения устройств без поддержки GPS опре­

4. Точность определения местоположения имеет опреде­

делить ваше местоположение можно будет посредством

ленный подтекст в случае с веб-приложениями, который

_______________ с использованием вышек сотовой связи.

заключается в том, что она может сказываться на уровне

2. Для вычисления расстояния между двумя точками ко­

заряда аккумуляторной_______________ устройства. 7. Не давайте кому-либо рекомендаций насчет направления

ординат можно использовать формулу_______________. 5. Вы никогда не получите кэшированных данных о место­

движения, если ваши координаты не будут обладать до­

положении, если для параметра_______________ задано

статочной _______________.

значение 0.

9. Фраза «Куда бы ты ни шел — ты уже там» упоминалась

6. Центрирование карты заново осуществляется с исполь­

в ф ильме__________________________ . 10. Если вы откажете браузеру в его запросе на разреше­ ние использовать данные о вашем местоположении, это приведет к вызову обработчика ошибок с кодом _______________ в виде 1. 11. Тайное местоположение штаб-квартиры______________ имеет координаты 47.62485, -12 2.52099.

242

глава 5

зованием м етод а_______________. 8.

Место, где располагается город_____________ , имеет широту и долготу соответственно 40.77, -73 .9 8.


создание HTML-страниц с поддержкой определения местоположения

Развлечения с магнитами, решение Ваша задача заключается в том, чтобы заполнить пробелы в приведенном ниже коде, благодаря которо­ му новый маркер будет отображаться только в том случае, если вы пройдете более 20 метров от места, отмеченного предыдущим маркером. Для заполнения пробелов в коде используйте соответствующие магнитные таблички. Будьте внимательны, поскольку некоторые из них придется использовать более одного раза! Приведем решение этого задания. p re v C o o rd s = n u l l ; function displayLocation(position)

{

var latitude = position.coords.latitude; var 1ongi tude = po si ti o n .c oords.1ongi tud e ; var div = document .getElementByld ("location") ; div.innerHTML = "You are at Latitude:

" + latitude + ", Longitude:

" + longitude;

div.innerHTML += " (with " + position.coords.accuracy + " meters accuracy)"; var k m = computeDistance(position.coords, ourCoords); var distance = document.getElementByld("distance") ; distance.innerHTML = "You are " + k m + " k m from the WickedlySmart HQ"; if (map == null)

{

showMap(position.coords); prevCoords =

posi t i o n .coords

} else { var meters =

coirputeDistance \ (position.coords, prevCoords)

> -L i°

I

* 1000;

<

scrollMapToPosition (position, coords) ; prevCoords

p o s i t i o n .c o o r d s ^ j ;

r * Так намного лучше!

Проведите тестирование онлайн: h t t p : / /w ic k e d ly s m a r t.c o m /h fh tm l 5 / c h a p t e r ^ / final/ m yLoc.htm l дальше ►

243


решение упражнения

^.Возьми в руку карандаш Решение

Ниже приведена альтернативная реализация для d i s p l a y L o c a t i o n . Сможете ли вы догадаться, что она делает? Взгляните на нее и напишите свой ответ в самом низу. Если в вас проснулась предприимчивость, про­ тестируйте данный код!

distance .innerHTML = "You are 11— I— km I — 11 km from the Wickedly Omar t IIQ" ; if

(km < 0 . 1 )

{

distance.innerHTML = "You’re on fire!"; } else { if (prevKm < km)

{

distance.innerHTML = "You're getting hotter!"; } else { distance.innerHTML = "You're getting colder...";

} prevKm = km;

дел а е т весь э т о т код.

,

Данный код превращает наше приложение в игру «Горя­ чо/холодно». Он выводит сообщение “You're getting hotter!" ("Теплее!"), если вы подходите ближе к штаб-квартире Wickedly Smart, либо “You're getting colder!" ("Холоднее!"), если вы уходите все дальше от нее. Когда вы окажетесь fi километра от штаб-квартиры Wickedly Sm art, появится сообщение "You're on fire!" ("Очень горячо!")

Мы прот ест ировали данный код, и вот что у нас получилось!!

244

глава 5


создание HTML-страниц с поддержкой определения местоположения

+

+

КТ9 И

Ниже приведены параметры, касающиеся API-интерфейса Geolocation. Ваша задача заключается в том, чтобы подобрать каждому параметру пару в виде соответствующего ему поведения.

{maximumAge:600000 }

Мпе требую тся только кэш ироваппы е даппы е о м естополож епии, которы м мепьше 10 мипут. П ри отсутствии таких даппых я хочу получить даппы е о повом м естополож епии, по только в том случае, если па это уйдет 1 секупда или мепьше.

{timeout:1000, maximumAge:600000}

Я буду использовать кэш ироваппы е дапны е о местополож епии, если таковы е будут иметься у браузера, и при этом им будет мепьше 1 0 мипут; в противпом слу­ чае я хочу получить даппы е о повом ме­ стополож епии.

{timeout:0 , maximumAge :Infinity}

Мпе требую тся только даппы е о повом местополож епии. Браузер мож ет ис­ пользовать столько времепи па опреде­ ление м естополож епия, сколько ему по­ требуется.

{timeout:Inf ini t y , maximumAge:0 }

Мпе требую тся только кэш ироваппы е даппы е о местополож епии. М епя устро­ ят даппы е любого «возраста». Если кэ­ ш ироваппы е даппы е о местополож епии будут полпостью отсутствовать, п ро­ изойдет вызов обработчика ошибок. С ведепия о повом местополож епии из­ влекаться пе будут! Д аппы е пастройки предпазпачепы для использования в си­ туациях, когда речь идет об автопом пой работе.

дальше ►

245


решение упражнения

Д

246

глава 5

Н

г

Ш М Ь 5 _ к Г оссБоР л - f e ffleHue


6

оё>1Ц 0Н ие

с

В0ё>— с л у ж б а м и

Приложения-экстраверты —

Ес л и бы я только знала, что обращение к веб­

службам и взаимодействие с ними м ожет быть настолько увлекательным...

Что-то вы слишком засиделись на своей странице. Настало время пообщаться с веб-службами с целью сбора данных и последующего возврата этой информации, что позволяет создавать более эффективные веб-ресурсы, которые объединяют собираемые данные. Это важный момент в написании современных НТМ1_5-приложений, а чтобы успешно этим заниматься, вам необходимо знать, как происходит общение с веб-службами. Кроме того, вы научитесь внедрять данные от веб-служб в свои страницы. Усвоив изложен­ ный здесь материал, вы сможете взаимодействовать с любой веб-службой. Мы даже расскажем вам о новомодном жаргоне, которым следует пользоваться при общении с веб-службами. Вы познакомитесь с некоторыми новыми APIинтерфейсами — так называемыми коммуникационными API-интерфейсами.


приложение mighty gumball

Компании Mighty Gumball требуется Веб-прилоЖение Свежая п о в о с т ь : и пповациоппая ком папия Mighty Gum ball, Inc., которая п роизводит и уста­ навливает настоящие автоматы для продажи же­ вательной резинки в виде шариков, связалась с нами и попросила помочь. Если вы еще не знаете, то эта ком пания недавно стала оснащ ать свои то р ­ говые автоматы возможностью подклю чения к Интернету, чтобы отслеживать уровни продаж п очти в реж им е реального времени. С тоит ли говорить, что в Mighty G um ball рабо­ таю т те, кто знает толк в автоматах для продажи ж евательной резинки, а не разработчики п ро­ граммного обеспечения, поэтому они и обрати­ лись к нам за помощью и попросили написать п рилож ение, которое позволит отслеживать уровни продаж данной ж евательной резинки.

Ознакомьтесь с нашей новой моделью автомата для продажи жевательной резинки М62200, поддерживающей подключение к Интернету. Он произведет настоящую рево­ люцию в бизнесе.

Вы можете пом н ит ь э т у компанию по нашей книге «И зучаем шаб­ лоны п ро ект иро ва­ ния» (Head First Design Patterns), где мы п о м о ­ гали им разрабатывать код на стороне сервера.

Исполнительный директор Mighty Gumball

Вот что они нам прислали: Б л а г о д а р и м , ч т о с о г л а с и л и с ь п о м о ч ь ! В о т к а к , на на ш в з г л я д , долж ен р а б о т а т ь и н с т р у м е н т д л я о т с л е ж и в а н и я продаж ж е в а т е л ь н о й р е з и н к и и з а в т о м а т о в , и м ы н а д е е м с я , ч т о вы см о ж е т е его д ля нас р е а л и з о в а т ь ! Miehty Gumball Inc. Там, где автомат для продажи жевательной резинки никогда не пуст наполовину

М о б и ль н ы е и наст оль­ ны е у с т р о й ­ ст ва будут получат ь св е д ен и я о продаж ах о т сервера реально­ го в р е м е н и с пом ощ ью веб -служ б ы .

248

глава 6

О б р а щ а й т е с ь , ес ли у вас в о з н и к н у т к а к и е - л и б о в о п р о сы ! К р о м е т о г о , м ы в с к о р е в ы ш л е м в а м сп е ц и ф и к а ц и и , к а с а ю щ и е с я в е б ­ служ бы.

— —к о м п а н и и M ig h ty C jum ball И нж енеры

кг

'я Н а м н е о б х о д и м о , чт о б ы вы н а п и с а л и э т у ч а с т ь , ест ест вен н о , используя

HTMLSH

Н аш и н т е р н е т -

сервер

Все наши а вт ом ат ы для п р о ­ дажи жевательной резинки будут о т п равлят ь отчеты на центральный сервер.


общение с веб-службами

Г

Прежде чем мы п р и с т у п и м , п о т р а т ь т е немного времени и подумайте, как бы вы подошли к разработке приложения, которое извлекает дан­ ные, предоставляемые веб-службой, и использует их для обновления веб­ страницы. Не беспокойтесь, если вы еще не знаете, как извлекать данные, просто обдумайте высокоуровневый дизайн приложения. Сделайте наброски, пом ет ки, напиш ите псевдокод для любого кода, который вам может п о ­ требоваться. С чит айте это разминкой для мозга...

---------------

Заметки по разработке MieMyOumballlncТам, где автомат для продажи жевательной резинки никогда не пуст наполовину

Как мы будем извлекать данные, предоставляемые UX веб-службой, и направлят ь к нашей веб-странице?

Как мы будем обновлять ст раницу после того, как извлечем данные?

Какие проблемы у нас м о г у т возникнуть с получением дан­ ных о т удаленного сервера?

дальше ►

249


обзор системы mighty gumball

Подробнее о системе Mighty Gumball В ероятпо, вам пеобходимо более подробпо разобраться во всей этой системе, чем было описапо в краткой записке от ипж еперов из Mighty Gum ball. И так, вот как обстоит дело: во-первых, у даппой ком папии есть автоматы для продаж и ж евательпой резипки, которы е располагаю тся по всей страпе и отправляю т отчеты па сервер Mighty Gum ball, которы й, в свою очередь, собирает все эти отчеты и делает их доступпыми с помощью веб-службы. Во-вторых, пас просят создать веб-приложепие, отобра­ жающее показатели продаж в браузере для группы сбы та Mighty Gum ball. К роме того, опи, скорее все­ го, захотят, чтобы даппая отчетпость обповлялась по мере изм епепия уровпя продаж по прош ествии времепи. Вот как все это будет выглядеть паглядпо в общих чертах:

Всем спасибо, я принял ваши отчеты об уровне продаж и соберу их все вместе.

о

250

)О J

Торговые автоматы Mighty Gumball установлены по всей стране и отправляют отчеты об уровне про­ даж на центральный сервер дан­ ной компании. Затем центральный сервер собирает все отчеты вместе и делает их доступными с помо­ щью веб-службы. глава 6

0

Л

Сервер Mighty Gumball


общение с веб-службами

Браузер загружает веб­ приложение Mighty 6umball( включая HTML-разметку, CSS и JavaScript.

Приложение отправляет веб-запрос с целью извлечения собранных вме­ сте данных об уровне продаж с сер­ вера Mighty Gumball.

Приложение изучает данные, после чего обновляет объектную модель документа (DOM) стра­ ницы для того, чтобы отразить новые данные об уровне продаж.

/Ж 1 М Т Т \0 Обратно приложение получает данные с сервера Mighty feumball.

V Приложение возвраща­ ется к шагу 3 и постоян­ но запрашивает новые данные. В результате этого страница обнов­ ляется почти в режиме реального времени.

Браузер обновляет страницу на основе DOM, в результа­ те чего пользователи могут увидеть результаты.

дальше ►

251


подготовка разметки

Приступаем к созданию приложения... П ока мы ждем специф икаций от и пж еперов из Mighty G um ball, займемся HTM L-разметкой. Н аверпяка вы уже сообразили, что пам пе попадобится больш ой объем HTM L-разметки, чтобы успешпо пачать создавать паше веб-приложепие. Все, что пам требуется, — это место для разм ещ епия отче­ тов об уровпе продаж по мере их поступлепия, а все остальпое мы доверим сделать JavaScript. Н абери­ те приведеппую пиж е разметку, после чего мы взгляпем па то, как извлекать даппы е с веб-сервера по протоколу HTTP.

<! d o cty p e

И сп о льзуем ст а н д а р т ­ ны е H T M L S - э л е м е н т ы

h tm l>

<head> и <body>.

<html lang="en"> <head> < title > M ig h ty < m e ta

G u m b a ll

Заранее размещаем ссылку на JavaScript-ф айл , зная , что вскоре напишем соответству­ ющий JavaScript-код!

(J S O N )< /title >

c h a r se t= " u tf-8 " >

< s c r ip t < lin k

sr c = " m ig h ty g u m b a ll. j s " X / s c r i p t >

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 " >

< /h e a d >

(hr

<body> < h l> M ig h tY < d iv

G u m b a ll

S a le s < /h l>

i d = Hs a l e s " >

< /d iv > < /b o d y > < /h tm l>

з а д е й с т в у е м C S S д ля e m u л и з а ц и и о т ч е т а о продаж ах M ig h ty G u m b a ll, ч т о б ы его вн еьи н и й ви д п о н р а в и л с я и с п о л н и т е л ь ном у директ ору. Т<якже

Сюда мы будем помещать дан­ ные об уровне продаж. Каждый элемент данных об уровне продаж будет добавляться сюда как <div>.

Забодите двигатель для тест-драйба Н абрав приведеппы й выше код, загрузите его в своем лю­ бимом браузере и протестируйте, прежде чем двипетесь дальше. И пе забы вайте, что загрузить CSS (и п рочи й код, использоваппы й в этой главе) вы сможете со страпицы http: / / wickedlysm art.com /h f h tm l 5 .

252

глава 6


общение с веб-службами

Как Выполняются запросы, адресованные Веб-слуЖбам? Д авайте пемпого приторм озим ... Вы уже зпаете, как браузер запраш ивает страпицу с веб-сервера — оп отправляет H TT P-запрос серверу, а тот возвращ ает соответствующую страпицу паряду с дополпительпыми метадаппыми, которы е (обы чпо) «видит» только браузер. Одпако, возможпо, вы пе зпаете, что браузер способеп апалогичпы м образом извлекать данные с веб-сервера по протоколу HTTP. Вот как это происходит:

Браузеры могут\ запра -

собРаннЫе

ПР° А0Ж Ж В°4^

Сервер, ожидающий запросов от браузеров п р и л о ж

— ^ в а т ь данные ^прилож е­ ний на сервере, н а п р и м е р от

е н и я

Sb

Веб-сервер

M ' 3 ^ t y G u m b a ll,

которое соби«Конечно, вот они»

Рае^\ данные об уровн£ ^

К Сервер возвращает ЗАПРОС: используется протокол НТТР1.1 для извлечения ресурса из « / gumballsales» (наше прило­ жение на сервере).

запрошенные

данные

П олезпо взгляпуть пемпого пристальпее па запрос, отправля поступает. Запрос сообщ ает браузеру, какие даппы е пас ипт которы й пас иптересует), а ответ будет содерж ать метадапп мацию, запрош еппую пами:

первым идет заголовок про­ ZOO — ОТВЕТ: код ответа токола HTTP сервера, означаю­ 1.1; здесь сообщается , чтовсе дляпро передачи данного ис­ щийj что - —? H TTP/1.1 200ответа ок Content-length 756 пользовался протокол HTTPj а также шло нормально. ^ Content-type: application/json приводится код ответа. [{"name":"C AMPBELL", Метаданные: мы получили " tim e " : 1302212903099, содержимое, которое и м е- "sales": "3"}, ет длину 7 5 6 байт и т и п {"name": "FRESNO", " t i m e " : 13 022 12 9 0 31 0 0, application/json... "sales"; 2}, Метаданные: мы ...при этом запрос исходит от бра­ отправляем запрос у зересовм ест им ого с Mozilla 5.0 на хост gumball. (данный пользовательский агент wickedlysmart.com... используется в случае с Safari , Chrome и другими браузерами).

17 ...а вот данные, к о т о р ы е мы запрашивали!

Примечание: данный шаблон извлечения данных с использованием XMLHttpRequest обычно называется Ajax или XHR.

дальше ►

253


использование xmlhttprequest

Как выполнять запросы из JavaScript Итак, теперь мы зпаем, что можпо извлекать даппы е по протоколу HTTP, по как имеппо? Н апиш ем пеболы ной код для геп ери ровап ия пастоящ его H TTP-запроса, после чего п опросим браузер соверш ить запрос от пашего имепи. Выполпив даппы й запрос, браузер передаст пам даппы е, которы е получит в ответ. П ош агово рассм отрим соверш епие НТТР-запроса. Начнем с URL. Ведь, в конце концов, нужно же нам как-то ска зать браузеру, где искать данные, которые нас интересуют: Вот наш URL -адрес someserver.com

"js<m" о зн а ч а е т ф о р ­ м а т о б м ен а д а н н ы м и (к н е м у м ы в е р н е м с я н е м н о го позж е).

V var url = "http://someserver.com/data.j son11

T Сохраним URL-адрес в переменной u rl, кот орую будем использовать далее.

О

Теперь создадим объект r e q u e s t следующим образом:

var request = new XMLHttpRequest();

1

А Присваиваем объект request переменной request.

Используем конст рукт ор Х М LHttpRequest для создания нового объекта request. О XM L в данном имени мы поговорим чуть позже

Далее нам необходимо сообщить объекту r e q u e s t , какой URL ему нуж­ но найти и какого рода запрос он должен использовать (мы задействуем стандартный HTTP-запрос GET так же, как на предыдущей странице). Для этого воспользуемся методом open объекта r e q u e s t . Может показаться, что, судя по имени o p e n , данный метод может не только задавать соответ­ ствующие значения в объекте r e q u e s t , но и открывать новое соедине­ ние и извлекать данные. На самом деле это не так. Несмотря на имя, метод o p e n лишь задает URL для объекта r e q u e s t , а также сообщает ему, какого рода запрос следует использовать, чтобы XMLHttpRequest смог произве­ сти верификацию соединения. Вызов метода o p e n осуществляется следу­ ющим образом:

request.open ("GET11, url) ; Настраиваем объект request задействуя Н Т Т Р -запрос ^ который является ст андарт ­ а м средством извлечения данных по протоколу HTTP. 254

глава 6

Т

Настраиваем объект request на использование URL -адреса, сохраненного в переменной url.

Совершенно новый объект XMLHttpRequest.

О б н о вл ен н ы й о б ъ ­ е к т Х М L H ttp R e q u e st, к о т о р ы й « з н а е т » не о бхо д и м ы й URL -а д р ес .


общение с веб-службами

Итак, мы подошли к важной части и особенностям работы X M L H t t p R e q u e s t : когда мы, наконец, попросим объект X M L H t t p R e q u e s t извлечь данные, он приступит к работе и извлечет требуемую информацию. Это может занять 90 миллисекунд (что довольно много по компьютерным меркам), а порой даже 10 секунд (целая вечность по компьютерным меркам). Вместо того чтобы просто дожидаться данных, мы предусмотрим обработчик событий, который будет вызываться при их поступлении (эта процедура в некоторой степени уже должна быть вам знакома): Наш объект request r e q u e s t , o n lo a d = f u n c t i o n () if

a l e r t ( " D a ta r e c e i v e d ! 11) ; } у.

method: SET URL: "h ttp ://..." onload:

Когда браузер получит о т в ет от удаленной веб-

{

( r e q u e s t , s t a t u s == 2 0 0 )

XMLHttpRequest

{

request.onload = function!) { if (request.status = 200) {

службы, он вызовет данную функцию.

alert("Data received!");

};

}

/ Сначала обработчику необходимо п р о ве р и т ь, является ли кодом от вет а ' сервера значение ZOO, то есть все ли в порядке, после чего он сможет ч т о - т о сделать с данными. На данный м о м е н т мы просто будем выво­ дить для пользователя диалоговое окно alert с сообщением>что данные пост упили. Вскоре мы пр им еним здесь более выразительный код.

Остался последний шаг: нам все еще нужно сказать объекту r e q u e s t , чтобы он извлек данные, для чего воспользуемся методом s e n d : Благодаря эт о м у происходит отправка запроса на сервер. re q u e s t, send ( n u ll) ; nep e$aeM n u /ij если не от правляем какие-либо данные удаленной службе (чего мы как раз и не делаем). Давайте еще раз пройдемся по всему процессу: мы создаем объект X M L H t t p R e q u e s t , снабжаем его URL-адресом и HTTP-запросом наряду с обработчиком. Затем мы отправляем запрос и дожидаемся по­ ступления данных. Когда данные поступают, происходит вызов обработчика.

- —

ь Запрос

Данные

Веб-служба дальше ►

255


как получить доступ к http-omeemy

Я так ничего и не услышал о том, как из­ влекать данные, полученные с помощью H T T P -вызова. Я вижу ф ункцию onload, но где код для доступа к этим данным? И ли я что-то пропустил?

Мы просто еще не дошли до рассм отрения дан­ ного аспекта. И нф ормацию , полученную посред­ ством H T T P-запроса GET, можно найти в свойстве responseText объекта request. Таким образом, мы можем написать код вроде следующего: Вызов данной ф у н к ­ ции происходитj когда объект request request.onload = function() { получает ответ. if

(request.status =

200)

{

alert(request.responseText);

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 (_

{

);

Чувствуете, что вам сегодня повезет? Х отите

Разместит е со­ от вет с т ву ю щ и е таблички с кодом в нужных местах!

быть в этом уверены? Т о г­ да воспользуйтесь нашей службой!

} f u n c t i o n d i s p la y L u c k ( lu c k )

{

v a r p = d o c u m e n t.________ P

}

in n e rH T M L

( " lu c k " ) ;

= "T o d a y y o u a r e " + l u c k ;

У-

request.onload = function() |

m yLuckyText^^""^^"*"^™ "*™ ^"™ "^^ r e q u e s t . s t a t u s == 200

new XMLHttpRequest() g e tE le m e n tB y ld

дальше ►

257


решение упражнения

развлечения с магнитами, решение Новая веб-служба 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 ) в определенный день. Нам требуется ваша помощь в создании показательной реализации, чтобы продемонстрировать другим, как они могут включить ее в свои сайты. Ниже приведен скелет кода; помогите нам за­ полнить пробелы в нем, используя магнитные таблички. Будьте внимательны, поскольку здесь есть лишние таблички. Вот наше решение этого упражнения.

window.onload = function () { var url = "http://wickedlysmart.com/i feel lucky today" ; var request =

n e w X M L H t t p R e q u e s t ();

r e q u e s t . o n l o a d = f u n c t i o n () if

(_

1

[{

r e q u e s t .status == 200 1) {

di s p 1 a y L u c k ( r e q u e s t .responseText

);

Чувствуете, что вам сегодня повезет? Хотите быть в этом уверены? Т о г­ да воспользуйтесь нашей службой!

request.o p e n ("GET", url) ; L request.send(null) ; |

I

function displayLuck(luck)

Размест ит е со­ о т вет ст вую щ ие таблички с кодом в нужных местах!

{

var p = document. I ^etElementById l("luck"); p.

innerHTML 1 =

"Today you are " + luck;

Лишние таблички

request.create("GET", url) myLuckyText

258

глава 6


общение с веб-службами

Интервью недели: Признания объекта XMLHttpRequest Head First: Д обро ножаловать, X M LH ttpR equest, мы рады, что вы смогли вы кроить для нас время в своем нлотном граф ике. Расскажите, как Вы внисываетесь в нроцесс создания веб-нриложений.

ционны е данны е о том, что раснолож ено но бли­ зости... П очти любые данные, которы е вы только можете себе нредставить, нонадают во Всемирную наутину в форме, с которой я могу работать.

XMLHttpRequest: Я нолож ил начало целому тренду но нривнесению внеш них данны х в веб­ страницы. Слышали о Google Maps? О GMail? Это все я. Без меня все это было бы невозможным.

Head First: Это же ведь все исклю чительно XMLданны е, не так ли? Я имею в виду, что в Вашем име­ ни присутствует часть XML.

Head First: В каком смысле? XMLHttpRequest: До моего ноявления люди гене­ рировали веб-страницы на стороне сервера, нри этом в них закладывались сразу все данные. Я же нозволяю нолучать данны е после того, как страни­ ца сгенерирована. Всномните Google Maps: дан­ ная служба обновляет то, что им еется на страни­ це, каждый раз, когда нроисходит корректи ровка вашего м естонолож ения на карте, без необходи­ мости перезагрузки страницы целиком. Head First: Вы нользуетесь уснехом. В чем ваш се­ крет? XMLHttpRequest: В моей ненритязательности и нростоте. Д айте мне URL-адрес, и я отнравлю сь но нему и извлеку необходимы е вам данные. Н е более того.

XMLHttpRequest: Неужели? П озвольте ответить нрямо. Н есомненно, было время, когда я, главным образом, занимался извлечением XML-данных, од­ нако мир не стоит на месте. В настоящ ее врем я я могу извлекать всевозмож ны е данные. Естествен­ но, н екоторы е из них являю тся XML-данными, однако я нолучаю все больше занросов на извлече­ ние JSO N -данных. Head First: В самом деле? А что такое JSON и н е­ чему он набирает такую нонулярность? XMLHttpRequest: JSO N — это сокращ ение от JavaScript O bject N otation (нотация JavaScriptобъектов). У этого ф орм ата им еется ряд преиму­ ществ: разм ер, удобочитаемость, а также тот факт, что он является «родным» для наиболее нонулярного язы ка програм м ирования, иснользуемого нри создании веб-нрилож ений, которы м, конечно же, выстунает м ой друг 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

Подвинься, XML: встречайте JSON Как вы мож ете номнить (а мож ете и не ном нить), XML собирался стать наш им всеобщ им снасителем, — это ф орм ат данных, которы й удобочитаем для человека и мож ет быть нодвергнут разбору маш иной, н ри этом он был готов п реврати ться в универсальны й ф орм ат для обмена данны ми во всем мире. Д ей­ ствительно, с ноявлением XMLHttp Re quest XML стал форматом, с номощью которого мы все обменива­ лись данны ми (отсюда и часть XML в им ени XMLHttpRequest). Однако но ходу дела XML, но-видимому, «носкользнулся на банановой кож уре», которую ему нодбросил JSON. Ч то такое JSON? Это наиболее соврем енны й и отличны й ф орм ат данных, рож денны й JavaScript, которы й обретает ноддержку в сф ере И н терн ета —в браузерах и на стороне сервера. И нтересно, удаст­ ся ли ему быстро стать предпочтительным форматом для НТМ Ьб-нриложений? Так что же такого зам ечательного в JSON? Это внолне удобочитаемый для человека формат, данны е в котором могут быть легко и быстро разобраны и нреобразованы нрямо в JavaScript-значения и объекты. В отличие от XML, он такой классный и симнатичны й... так или иначе, разве мож но носле всего этого сказать, что он нравится нам лиш ь чуть-чуть? Вы много раз будете сталкиваться с JSO N далее в книге. Мы будем иснользовать его для обмена JavaScript-данными через И нтернет, для сохранения данны х в localStorage с нрим енением API-интерф ейса Web Storage, а также как часть еще одного нодхода к нолучению достуна к веб-данным (вскоре мы ноговорим об этом нодробнее). Постойте-ка, ф орм аты обмена данными ч ерез И нтернет... ф орм аты хранения... все это так сложно, не нравда ли? Н е беснокойтесь, носкольку н а п ротяж ении следующих десяти страниц мы будем превра­ щать вас в эксперта вы уже знаете нрактически все необходимое о JSON. Ч тобы иснользовать JSON, вам потребуется лиш ь нонимание JavaScript-объектов (а эти знания у вас уже есть), а также два нросты х вы зова методов. ф

Q У нас имеется JavaScript-объект, мы хотим обменяться им или сохранить его, поэтому вызываем метод J S O N . s t r i n g i f y и пере­ даем ему этот объект в качестве аргумента.

Результатом будет строка, представ­ ляющая объект. Мы можем сохранить данную строку, передать ее функции, отправить через Интернет и т. п.

ляОТЯ. s tr : ingifY<®ovie)

M

О VI в

{"title":"Plan 9 from Outer Space","genre":"Cult Classic" ,"rating":5,"showtimes":["3:0 0pm" ,"7:00pm" ,"11:00pm" ]}

1

string)

JSO N.parse (jso n!

ф Q

260

Результатом будет копия на­ шего оригинального объекта.

глава 6

Когда мы будем готовы преобразо­ вать строку обратно в объект, мы пе­ редадим ее методу J S O N . p a r s e .


общение с веб-службами

Краткий пример е использованием JS0N ©

Ha самом деле есть еще ряд ограничений, "однако мы не с т а ­ нем беспокоиться о ник сейчас.

Рассмотрим н рим ер н реобразования объекта в строковы й ф орм ат JSON. Н ачнем с объекта, которы й будет вам нонятен, — m o v ie из главы 4. Однако не все можно нреобразовать в данны й ф орм ат (нанрим ер, методы ), зато ноддерж иваю тся все базовые тины , такие как n u m b e r, s t r i n g , а также массивы. Д авайте создадим объект, а затем нередадим его методу JS O N . s t r i n g i f у:

var plan9Movie = new Movie ("Plan 9 from Outer Space" ,"Cult Classic" , 2, ["3:00pm" , "7:00pm" , "11:00pm" ]);

Наил объект movie>« ук о м п л е к т о ва нный» ст р о ка м и , числами и массивом.

-% "

Раснолагая объектом, мы можем нреобразовать его в строко­ вы й ф орм ат JSON с номощью метода JS O N . s t r i n g i f y . П о­ смотрим, как это нроисходит... (вы мож ете вернуться к коду m o v ie из главы 4 и добавить нриведенны й далее код в ниж ­ нюю часть своего сценария):

var jsonString = JSON. stringify (plan9Movie) ; alert(jsonString);

{“title":"Plan 9 from Outer Space",“genre CUss iс“.Vat ing': 5 .“showt ime s*: P3:OOpmV7:OOpmVn:OOpni-|J

А вот р езульт ат : строковая версия объект а, отображаемая в диалоговом окне alert.

Тенерь у нас имеется строка JSO N , нредставляю щ ая объект m o v ie . Н а данны й момент мы можем взять эту строку и, нанрим ер, отнравить ее но нротоколу H TTP на сервер. Мы так­ JavaScript же можем нолучать строку JSON с другого сервера. Донустим, JSON Movie is Plan 9 from Outer Space сервер нрислал нам данную строку; как нреобразовать ее об­ ратно в объект, с которы м мы сможем что-нибудь сделать? Для 1 этого нужно нросто воспользоваться «сестрой» метода JS O N . s t r i n g i f y — J S O N .p a r s e . Д елается это так: Ax da, т еперь мы используем var jsoriMovieObject = JSON.parse(jsonString); < это как настоящий о б ъ е к т , alert("JSON Movie is " + jsonMovieObject.title); обращаясь к его свойствам.

ok

ШTVPM Введите данный URL-адрес. Что вы видите? h t t p ://search.twitter.сот/search.j son?q=hfhtml5

Примечание: браузер FirefoK предложит вам о т кры т ь либо сокранить файл. Д л я от кры т ия можете использо­ ват ь TeKtEditj Блокнот или любой другой базовый т е к ­ стовый редактор.

У

меня

новость !

Только что прибыли специф икации! П еревер­ ните страницу!

")


обзор спецификаций mightygumball

Спецификации только что прибыли!

Т

Спецификации сервера 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 }

Название города; на данный м о м е н т ^ ы т е с т и р у е м свои т орговы е а в т о м а т ы в Калифорнии-

Количество проданной жвачки с м о м е н т а последнего от чет а.

Вт орой город, Фресно. ]

Непре­ менно сдел ш т е это

А здесь будут другие города...

Введите данный URL-адрес в своем б р а у зер е , чтобы у в и д е т ь , как в о т в е т п о с т у п а ю т значения. На экране должен появиться один объект или более в массиве. Вы также можете добавить п а р а м е т р la str e p o rttim e в конец URL-адреса, чтобы извлечь т олько о т ч е т ы , кот орые п о с т у ­ пили начиная с указанного врем ени . Например: h t t p :/ / д ш п Ь а И .wickedlysmart.com/?lastreporttime=1302212903099

У нас сотни а в т о м а т о в по продаже жевательной резинки,

кот орые присы лаю т от чет ы прямо сейчас, п о эт о м у вы должны у в и д е т ь , что обновление от чет ност и происходит в среднем каждые S - 8 секунд. У ч т и т е , что эт о наш п р о и з ­ водственный с е р в е р , п о эт о м у мы просим вас п р е д в а р и т е л ь ­ но проводит ь локальное т ест ирование своего кода! б ла го д а р и м , что согласились нам помочь! И п о м н и т е , что, как говорит наш исполнительный директ ор, « а в т о м а т для продажи жевательной резинки никогда не п у с т наполовину».

- Инженеры компании M ighty Gum ball 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 » . Соединим все и наниш ем код.

Написание функции обработчика событий onload У верены, что в данной нроцедуре для вас не будет ничего нового, однако мы собираемся нанисать обработчик собы тий o n l o a d , ко­ то р ы й станет вы зы ваться носле н олной загрузки HTML; мы также предусмотрим ини ц ии рован ие Н ТТР-занроса для и звлечения дан­ ных об уровне нродаж. Когда данны е будут возвращ ены , мы нонросим XMLHttpRe q u e s t вызвать функцию u p d a t e s a l e s (нанисанием которой займемся чуть нозже): window.onload = function() {

Сначала проведем тестирова Hue с использованием л о к а л ь­ ного файла (как и просили нас инженеры из Mighty Gumball!), чтобы убедиться, что все работает. Подробнее об эт ом поговорим немного позже...

var url = "http://localhost/sales.json" ; var request = new XMLHttpRequest(); request.o p e n ("GET" f u r l ); request.onload = function() { if (request.status == 200)

^

---------

{

^

ф орм ируем XM LHttpRequest п у т е м создания объект а, вызова метода open с испо льзованием нашего URL -адреса и последую щ е­ го присваивания свойства onload функции.

updatesales(request.responseText);

>;

^ ---

request.send(null);

Ь б уд ьте o O H o j= > oJK H bi

Наконец, от правляем запрос.

' Проверяем, все ли в порядке, а з а т е м ... ...когда загрузка данных б у ­ дет завершена, произойдет вызов этой функции.

Е с л и в ы используете Opera либо Internet Explorer 8 (или ниже), рекомендуем вам проводить тестиро­ вание с применением другого браузера. Об особен­ ностях поддержки Opera и старых версий Internet Explorer мы поговорим позже.

дальше ►

263


как проводить тестирование локально

Отображение данных об уровне продаЖ Жвачки Тенерь нам необходимо нанисать обработчик u p d a te s a le s . О блегчим задачу и нрибегнем к наиболее нростой реализации из возможных, носкольку всегда сможем улучшить ее нозже: Извлечем элем ент <div>, ко­ торый уже помещен в HTML, и будем использовать его для function updateSales(responseText) { размещения данных. var salesDiv = document.getElementByld("sales") salesDiv.innerHTML = responseText;

< }

Внимание, впереди объезд!

^

8 качестве содержимого <div> задаем ст року responseText. О разборе этого содержимого мы вскоре поговорим... А сна­ чала давайте проведем т е ­ стирование.

П риш ло врем я нровести н овы й тест-драйв, однако сначала нам необ­ ходимо сделать, так сказать, небольш ой крю к но объездному нути. И н­ ж енеры из комнании Mighty G um ball нонросили нас нровести тести­ рование локально, нреж де чем задействовать их производственны й сервер, что является разумной идеей. Однако для этого нам потребу­ ется, чтобы данны е располагались на сервере, благодаря чему X M L H t t p R e q u e s t сможет иснользовать нротокол H TTP для их извлечения. О тносительно серверов у вас есть несколько альтернатив: ■ если ваша ком нания раснолагает серверами, достунными для тестирования, то иснользуйте именно их; ■ либо вы м ож ете нрибегнуть к но мощ и хостинговы х сервисов вроде GoDaddy, D ream host или одной из множества других комнаний, предлагаю щ их услуги хостинга; ■ наконец, вы мож ете установить сервер нрямо на своем компью тере. В этом случае ваши URL-адреса будут выглядеть нрим ерно так: 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

файлы также м о гу т располагаться в подкаталоге: н а п р и м ер , h ttp ://lo c a lh o s t/g u m b a ll/mightygumball.html Н еобходимые советы и указатели вы найдете на следующей странице. И м ейте в виду, что хостинговы е окруж ения довольно сильно отлича­ ю тся друг от друга, ноэтому мы не можем нривести здесь общее руко­ водство для всех них. И если у вас не окаж ется легкого доступа к тому или иному серверу, установка собственного сервера локально на своем ком нью тере мож ет оказаться наилучшим выходом! 264

глава 6


общение с веб-службами

Как установить собственный веб-сервер Установка собственного локального сервера на своем ком нью тере будет зависеть от тина иснользуемой вами онерац и онн ой системы. Н иж е нриведены советы но установке сервера в онерационны х системах OS X (также назы ваем ой Mac OS X), Windows и Linux. П рочие варианты вы найдете на следующей странице.

Mac OS X У становка в еб -сер в ер а в о п е р а ц и о н н о й си ­ ст ем е OS X осущ ествл яется д о в о л ь н о п р о с т о . Щ ел к н и те > System P r eferen ces (Н а с т р о й ­ ки си ст ем ы ), п о сл е ч е г о в ы б ер и т е S h a rin g (С ов м ест н ы й д о ст у п ). Н а п а н ел и слева п р о ­ верьте, устан ов л ен ли ф л аж ок W eb S h a rin g (С ов м ест н ы й веб-доступ):

Zi

Web S haring

А к ти ви ров ав п а р а м етр W eb S h a rin g (С о в м ест ­ ны й веб-доступ ) (л и б о о н уж е м о ж е т бы ть ак­ ти в и р о в а н н ы м ), вы у ви ди те и н ф о р м а ц и ю о том , как пол учить д о ст у п к своем у л окал ьн ом у серверу. Вы дол ж н ы и м еть в о зм о ж н о с т ь и с­ п ол ь зовать l o c a l h o s t в м ест о IP-адр еса (к о­ т о р ы й и м е е т т е н д е н ц и ю и зм ен я ться п р и и с ­ п о л ь зо в а н и и D H C P -м ар ш р ути затор а, в силу ч ег о l o c a l h o s t лучш е п о д о й д е т в ваш ем сл учае). П о ум ол ч ан и ю ваш и ф айлы будут за ­ груж аться из Ь и р ://1 о с а Ш о 8 1 /~ И М Я _ П О Л Ь З О В А Т Е Л Я /, куда о н и в св о ю о ч е р е д ь загру­ ж аю тся и з папки И М Я _ П О Л Ь З О В А Т Е Л Я / Sites, п о эт о м у вы, в е р о я т н о , за х о т и т е со зд а т ь там подк атал ог для M ighty G u m b all.

Windows И н стал л яц и я с о б с т в е н н о г о в еб -сер в ер а в о п е р а ­ ц и о н н о й си ст ем е W in d o w s стала п р о щ е, чем э т о бы л о р аньш е, бл агодар я установщ ик у M icrosoft W eb P latform In staller (такж е назы в аем ом у W eb P I). Текущая в ер си я п о д д е р ж и в а е т с я о п е р а ц и о н ­ ны м и си ст ем а м и W in d ow s 7, V ista SP2, Х Р SP3+, Server 2 0 0 3 SP2+, Server 2 0 0 8 и Server 2 0 0 8 R2 и д о ст у п н а для загрузки п о а д р есу h t t p : // w w w . m ic r o so ft.c o m / w eb / d o w n lo a d s / p la tfo rm .a sp x . В качестве альтернативы м о ж н о уст а н о в и т ь п р о ­ грам м у с откры ты м и сх о д н ы м кодом W am pServer, к о то р а я п оста в л я ется вм есте с A p a c h e , Р Н Р и M ySQL для р а зр а б о т к и в еб -п р и л о ж е н и й . О н а л е г ­ ка в и н ста л л я ц и и и уп р а в л ен и и . З а гр у зи ть W am pServer на св о й к о м п ь ю т ер м о ж н о с сайта h t t p : / /w w w .w a m p se r v e r .c o m /е п / . С ущ ествую т такж е др уги е д о ст у п н ы е р еш ен и я с откры ты м и сх о д н ы м к одом , п о эт о м у у вас будет б о л ь ш о й вы бор .

ф а и а т с к и о дистрибутивы 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

Q Q

5

3

chapterl chapt*f2

п chapter3 Вы можете прибегнуть к Т Р -п р о гр а м м е (н а п р и ­ м е р j Transit, Cyberduck или VJinSCP), для вы груз­ ки своих ф айлов, если не х о т и т е использовать FTP командной строки.

Р~1 chapter4

D chapters r~| Chapters р-i chapter7 f~ | chapters p i chapter9

p~| chapter10

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 и вклю чен в код, иснользуемый в этой книге и достунный в И н терн ете (вы мож ете и самостоятельно набрать его, если вам нравится этот нроцесс): Ъудем использовать sales.json для проведения тестирования, прежде чем обратимся к настоящему производствен­ ному серверу с данными об уровне продаж, п о ­ ст упаю щ их в режиме реального времени.

ARTE S I A " , "t i me":1308774240669,"sales":8},

[ { " паш е":

{ " п а ш е " : LOS ANGELES","time": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales": 2 ) , { " п а ш е " : PASADENA","time": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales":8},

^

STOCKTON","time": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales": 2 ) ,

{ "паш е":

{ " п а ш е " : FRE S N O " ,"t ime": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales":2},

SPRING VALLEY","time": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales" :9},

{ "паш е":

{ " п а ш е " : E L V E R T A " t i m e " : 1 3 0 8 7 7 4 2 4 0 6 6 9 sales":5}, { "паш е":

SACRAMENTO" / ’t i me": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales":7},

{ "паш е":

SAN M A T E O " ,"time": 1 3 0 8 7 7 4 2 4 0 6 6 9 sales":1}]

Разместите данны й файл на своем сервере, носле чего не забудьте обновить свой JavaScript, указав в нем URLадрес этого файла. В наш ем случае он будет выглядеть как

Г/f

<

ANGE L E S ' - M - » . . - . , , _________

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 () ; request.open ("GET" , u rl ) ; request.onload = function() { if (request.status == 200)

{

fib*

V_ Убедитесь, что здесь указан правильный URL-adpec.

updateSales(request.responseText);

} }; reques t .s e n d (nul1);

дальше ►

267


тестирование приложения mighty gumball версии 1

Давайте, наконец, проведем тестирование!

jО.) |J», ijg

I

M ighty Gum ha]] Sales

Мы нроделали долгий нуть и, наконец, готовы нереходить к тестированию нашего кода!

|{*naxne*:*AJ:t TliSlA*t*tan!e*:lJ0Sn43406691pi*jej.*;S} <'] A ^G a^\4m w ":J3087742«406& 9iT" iik s':2 } ,

<

<глга": ТЗГПХ:ЛТ1>?У‘."faint':

Убедитесь, что ваши ф айлы HTM L, JavaScript, JSON — и не забудьте о CSS — разм ещ ены на иснользуемом вами сервере. Введите URL-адрес ва­ шего HTM L-файла в браузере (в нашем случае это h ttp : / /lo c a l h o s t / g u m b a ll /m ig h ty g u m b a ll.h tm l), носле чего нажмите Назад...

VUQS

ТАЗАРРЛ'А'Лтте';13OT7742*P669,^iirat

VALLEY W i 1Ш7НЭШ№,<и»’Я).

^

--2}‘ Гпате*«swung “

i{ ’furftc": ’E L V E K T А’ *&ССИПI ЭОГГМВ Д В Д ,’nun’ J J ,

* ■ ' “SACRAMENTO",^rae'.' 1ШТ7^иоШ:±±\&'\7\ rrfiinier.’VA\

MATEO".'tijuc’.J ЭСЩ7743дабе9,'||1кл':] }|

t

Оформлено не слиш ком красиво, зато видны требуемые данные.

Т 7

П омнит е, что мы от правляли HTTP -запрос для извлечения данных, содержащихся в sales.json, которые за т е м просто сбросили в элем ент <div> Похожеj все работает!

'

Если у вас возникнут п р о­ блемы, проверьте каждый файл отдельно с исполь­ зованием браузера и уб е­ дитесь., что они доступны Зат ем дважды проверьте свои URL-адреса.

Здорово! Да, пришлось потрудиться. Нам потребовалось разобраться, как совер­

шать HTTP-запросы и устанавливать соб­ ственный сервер, но в итоге все получилось! Я уже задумываюсь об отличных приложе­ ниях, которые смогу создать для использо­ вания всевозможных веб-служб, общаться с которыми я теперь умею.

268

глава 6


общение с веб-службами

Производим впечатление на клиента... Мы нрилож или массу усилий, чтобы в итоге нолучить работаю щ ее нрилож ение. Это зам ечательно, од­ нако наш клиент Mighty G um ball будет более внечатлен, если данное нрилож ение будет еще и выглядеть хорош о. Н иж е ноказано, какого именно результата мы собираем ся добиться.

Что мы имеем Л А О

jo] 1^] II I

Mighty Gumball

jnrypu-ng.

Mighty Gumball Sales [{ ’name’ :’ARTESIAVtime":1308774240G69t*sa]es*:8}r{*name*:’LOS ANGELES"/time*: 1308774240669,*sales":2}, {"nan*":*PASADENA\*time":1308774240669,*sales":8}, {*tiame":’STOCKTON*.*lLme":1308774240669,“sales*:2}r { "name": ’FRESNO* ."time*: 1308774240669,*sales*:2},{ "name*:"SPRING VALLEY" .time*: 1308774240669.*sales*:9>. { *name*:*ELVERTA’ ."time": 1308774240669,*sa3es*:3}, { "name":"SACRAMENTO* ."time*: 1308774240669,*sales":7},{ "name*: "SAN MATEO" ,*time*:1308774240669 .’sales’ : 1>]

Чего мы хотим |7Т7];о 1;^[88][ 4- |0hnp://lre*llw«/9um(Mll/roflftr!flyu^iMll.hEiT

6 | (О.- Cooglt

Mighty Gumball Sales ARTESIA sold 8 gum baits LOS ANGELES sold 2 gum balls PASADENA sold 8 gum balls STOCKTON sold 2 gum balls FRESNO sold 2 gum balls SPRING VALLEY sold 0 gum balls ELVERTA sold 5 gum balls SACRAMENTO sold 7 gum balls SAN m a te o sold l gum balls

т Пока мы просто сбрасываем J S O N -массив п р я ­ мо в браузер. В некоторой степени э ф ф е к т и в ­ но, но р е з у л ь т а т получается не очень красивым. Какая жалость, ведь есть целая с т р у к т у р а данных, которая только и ждет более э ф ф е к ­ тивного подхода к ее использованию!

С

Здесь мы использовали JSON -массив и преврат или его в красиво от обра­ жаемые данные.

Вот что тр е б у ется , чтобы о б е с п ечи ть более кр а си в о е о то б р аж е н и е д ан н ы х:

©

Сначала нам нужно взять данные, полученные от объекта XMLHttpRequest (которые представляют собой простую JSONстроку), и преобразовать их в подлинный JavaScript-объект.

(2) Затем мы сможем пройтись по результирующему массиву и до­ бавить новые элементы в объектную модель документа (ЬОМ) — по одному в случае с каждым элементом данных об уровне про­ даж в массиве. дальше ►

269


добавление поддержки json

Дорабатываем код с целью использования JS0N В ыполним описанные выше два шага и откорректируем наш код необходимым образом:

©

Сначала нам нужно взять данные, полученные от объекта X M L H ttp R e q u e s t (кото­ рые представляют собой простую JS O N -строку), и преобразовать их в подлинный JavaScript-объект. Чтобы это сделать, обновим функцию u p d a t e S a l e s , первым делом удалив строку кода, которая задает для < d i v > содержимое в виде строки r e s p o n s e T e x t , и преоб­ разуем r e s p o n s e T e x t из строки в ее JavaScript-эквиволент с помощью j s o n . p a r s e . function updateSales(responseText)

{

var salesDiv = document.getElementByld("sales");

aaleaDiv. innerUQML - reaponaeTexte; &

Эта строка нам больше не нужна.

var sales = JSON.parse(responseText);

} Здесь мы б ерем о т в е т и и с п о л ь з у е м JSO N .p arse для преобразования его в J a v a S c r i p t -о б ъ е к т (в данном случае э т о б удет м ассив) и п р и с ва и ва е м его п е р е м е н н о й sales.

Теперь пройдемся по результирующему массиву и добавим новые элементы в объ­ ектную модель документа (DO M ) — по одному в случае с каждым элементом дан­ ных об уровне продаж в массиве. В нашем случае мы создадим новый < d i v > для каждого элемента данных: function updateSales(responseText)

{

var salesDiv = document.getElementByld("sales");

Совершаем ит ерацию no каждо­ м у э лем ент у данных в массиве. for (var i = 0; i < s a les.length; i++) { Д ля каждого элем ент а данных var sale = sales[i]; мы создаем <div> и присваива­ var div = document.createElement ("div") ем ему класс « sa leltem » (ис' пользуемый CSS). div. setAttribute ("class" , "saleltem") ;

var sales = JSON.parse(responseText);

div.innerHTML = sale.name + salesDiv. appendChild (div) ;

270

глава 6

+ sale.sales +

gumballs";

Задаем содержимое для элем ент а <div> с помощ ью innerHTML, после чего добав­ ляем его в качестве дочернего элемент а по отношению к salesDiv.


общение с веб-службами

Заключительный этап...

u_iJjo] ГаНГЩггтнгг-—^ УСи,Ы и"

В ы уж е зн аете , к а к будет в ы гл я д е ть к о н е ч н ы й результат, н о в се -та ки в н е с и т е о п и с а н н ы е в ы ш е и з м е н е н и я в с в о й ко д . В з гл я н и т е более п р и с т а л ь н о на к о д , п р и в е д е н н ы й н а п р е д ы д у щ е й с т р а н и ц е , и уб е д и те сь, ч т о в ы п о л н о с т ь ю в н е м р а зо б р а л и с ь. З а те м п е р е за гр у з и те в е б -с тр а н и ц у M ig h ty G u m b a ll.

Как видите, конечный р е з у л ь т а т получился т а к и м j как мы вам и говорили!

^

Тестирование прошло удачно, и теперь вы, ребята, готовы перейти к использо­ ванию действующего производственного сервера Mighty Gumball. Удачи!

Переходим к использованию действующего сервера И н ж е н е р ы и з M ig h ty G u m b a ll п р о с и л и на с п р е д в а р и т е л ь н о п р о в е с т и т е с т и ­ р о в а н и е л о к а л ь н о , ч т о м ы и сделали. Т е пе р ь м ы г о т о в ы п е р е х о д и т ь к т е с т и ­ р о в а н и ю с и с п о л ь з о в а н и е м р е а л ь н о го се р ве р а M ig h ty G u m b a ll. Н а э т о т раз в м е сто и з в л е ч е н и я с т а т и ч е с к о го J S O N -ф айла д а н н ы х будем и з в л е ка ть J S O N ф айл, к о т о р ы й д и н а м и ч е с к и ге н е р и р у е т с я с е р в е р о м M ig h ty G u m b a ll. Н а м п о тр е б у е тс я о б н о в и т ь U R L -адрес, и с п о л ь з у е м ы й о б ъ е к т о м X M L H ttpR e quest, и и з м е н и т ь е го т а к и м о б р а зо м , ч т о б ы о н вел к се р в е р у M ig h ty G u m b a ll.

Д авайте сделаем это:

URL-адрес сервера Mighty Gumball. Замените прежний URL-адрес э т и м и сохраните. \

win d ow .onload = f u nction() {

у_)

var url = "h t t p ://gumball.wickedlysmart.com" ; var request = new XMLHttpRequest(); request.o p e n ("GET", url); request.onload = function() { if

(request.status =

200)

{

updateSales(request.responseText);

} }; Эйджей, к о н т р о ­ лер качества

request.send(null);

дальше ►

271


проблема с mighty gumball

Тест-драйв с применением действующего сервера. У б е д и те сь , ч т о в ы с о х р а н и л и и з м е н е н и я , ка с а ю щ и е с я U R L -адреса, в своем ф айле m i g h t y g u m b a l l . j s на с е р ве р е , если х о т и т е п р о д о л ж а т ь и з в л е ка ть H T M L оттуда, л и б о л о ка л ь н о на ж е с т к о м д и с ке , если и с п о л ь зу е те lo c a lh o s t. В ы уж е зн а ете , ч т о делать дальш е: у к а ж и т е своем у б р а ­ узер у п уть к с о о тв е т с тв у ю щ е м у H T M L -файлу, п о сл е ч е го у в и д и те , к а к будут п о с т у п а т ь о п е р а т и в н ы е , к р а с и в о о ф о р м л е н н ы е , н а с т о я щ и е д а н н ы е о т т о р г о в ы х а в то м а ­ то в M ig h ty G u m b a ll п о всему м и р у !

Хьюстон, у нас проблема! Идите скорее сюда, мы вообще не можем получить какие-либо данные об уровне продаж после того, как перешли к исполь­ зованию действующего сервера Mighty Gumball!

Это еще что?! Мь/ не видим вообще никаких данных!

Ой! А все вы гл яд ело т а к х о р о ш о ; м ы уж е п р е д с та в л я л и себе, к а к будем п о т я ­ ги в а ть м и н е р а л ьн ую воду « P e rrie r» и о тм е ч а ть у с п е ш н о е за в е р ш е н и е еще о д н о г о п р о е к т а с M ig h ty G u m b a ll. А т е п е р ь все м о ж е т п о й т и н а с м а р ­ ку. Л а д н о , н е б уде м и з л и ш н е д р а ­ м а ти зи р о в а ть си туа ц и ю , но в чем ж е в с е -т а ки дело? Ведь все д о л ж н о р а б о та ть ! С делайте гл у б о к и й вдох. Т ом у есть л о г и ч е с к о е о б ъ я с н е н и е ...

Эйджей, расстроенный контролер качества

272

глава 6

л Примечание для редактора: вообще-то мы представляли себеj как будем обналичивать Жирный чек и от пр а в л ят ь вам э т у книгу! А вм ест о этого нам т еперь придется допи­ сывать ее, рассказывая о т о м , как найти выход из очередной непростой ситуации!


с веб-службами

Неожиданный поворот событий! Мы вообщ е не в и д и м каких-либо данны х на странице M ighty Gum ball. Все нрекрасно работало, но ка мы не нереш ли к иснользованию действующего сер­ вера... Удастся ли нам найти нричину нроблемы? Удастся ли нам устранить ее? О ставайтесь с нами... мы ответим на эти вонросы, а также... Между тем ноны тайтесь самостоятельно разобраться в том, что именно нош ло не так и как это можно исправить.

КЛЮЧЕВЫЕ МОМЕНТЫ

Для извлечения HTML-файлов или данных с сервера браузер отправляет НТТР-запрос.

HTTP-ответ включает код ответа, который позволяет

XMLHttpRequest Level 2 является самой последней

нении запроса.

версией X M L H ttpR equest, однако данный стандарт

Код 2 0 0 в HTTP-ответе означает, что при выполнении

Для отправки HTTP-запроса из JavaScript используется

Объект X M LH ttpR equest. ■

все еще находится в разработке. Чтобы использовать XMLH ttpRequest, СООТВвТСТВующие файлы необходимо разместить на сервере, с которого и будут запрашиваться данные. Вы можете установить локальный сервер на своем компьютере

Обработчик событий o n l o a d объекта XMLHttpRequest

для проведения тестирования либо воспользоваться

обрабатывает получение ответа от сервера.

хостинговыми сервисами.

JSON-ответ на X MLHttpRequest помещается в свой­

Свойство o n l o a d объекта X M L H t t p R e q u e s t не

ство r e s p o n s e T e x t объекта r e q u e s t .

поддерживается старыми версиями браузеров, такими

Для преобразования строки r e s p o n s e T e x t В JS0N используется метод J S O N . p a r s e .

всевозможного текстового содержимого (например, XML, JS0N и др.).

узнать, произошли ли какие-либо ошибки при выпол­

запроса не произошло никаких ошибок. ■

XMLHttpRequest может применяться для извлечения

как Internet Explorer 8 и ниже, а также Opera 10 и ниже. В этом случае вы можете написать код для проверки версии браузера и обеспечения альтернативы.

X M L H t t p R e q u e s t задействуется в приложениях для обновления содержимого, (например, карт или электронной почты) без необходимости перезагрузки страницы.

дальше ►

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


общение с веб-службами

Свойство onload объекта XMLHttpRequest не поддер­ живается устаревшими версиями браузеров, однако из этой ситуации есть простой выход.

]}удьше оС 1 Ц о |Э о Ж Н ь х

Мы использовали request, onload для определения функции, вызываемой, когда завер­ шается извлечение запрошенных данных с сервера. Это возможность XMLHttpRequest Level 2 (считайте ее «версией 2»). Версия XMLHttpRequest Level 2 остается все еще до­ вольно новой, то есть многие пользователи могут до сих пор использовать браузеры, которые ее не поддерживают. В частности, Internet Explorer 8 (и ниже), а также Opera 10 (и ниже) поддерживают только XMLHttpRequest Level 1. Хорошая новость заключается в том, что новые возможности ХМ LHttpRequest Level 2 являются расширениями, поэтому вы сможете без проблем продолжить использовать именно возможности версии 1 во всех браузерах; это всего лишь означает, что ваш код не будет отличаться особой элегант­ ностью. Вот код для использования XMLHttpRequest Level 1:

Большая часть кода для использования X M L H ttp R e q u e s t Level 3является такой же, как и раньше... function i n i t () var url

...Однако в ХМ LHttp Request Level П нет свойства request.onload, п о ­ э т о м у вместо него вам п р и ­ дется использовать свойство onreadystatechange.

"h t t p ://localhost/gumball/sales.jison" г

var request = new XMLHttpRequest(); request.onreadystatechange = function() { if

(request.readyState == 4 && request.status == 200) updateSales(request.responseText);

}; request.o p e n ("GET", url) request.send(null);

f

See остальное, no большей част и, является т аким же, как и раньше.

{

З а т е м проверьте readyState, чтобы убедиться, что з а ­ грузка данных за в ер ­ шилась. Если значением readyState является 4, то вы будете знат ь, что загрузка закончена.

Вы также можете проводить проверку на предм ет других зн а ­ чений readyState и status с и,елы-о выявления р а з ­ личных ошибок.

дальше ►

275


выяснение, что пошло не так

Помните, как мы столкнулись с неожиданным поворотом событий? Неполадки с приложением Наш к о д нрекрасно работал, когда мы иснользовали свой локальны й сервер, но как только мы нереш лн на действую щий сервер Mighty G um ball в И н терн ете, с наш им нрилож ением возникли неноладки! Чего мы оЖцдали: Я О П

Ч т о мы подучили: n o n

Mighty Gumbtl

•«j*■ О

S3

+ !^hWp://kKalta*t/»uft*all/mi9MY0umha«-htrr,

С ](Q r

Googlf

Mighty Gumball Sales

■*j

Mighty Gumball

0

9 ]

SS

+

j^Mrp://kxaltatf/0uir*aU/mightyi0umba«-htrr,

Oooglf

Mighty Gumball Sales

ARTESIA sold 8 gum balls LOS ANGELES sold 2 gumballs PASADENA sold 8 gumballs STOCKTON sold 2 gumballs FRESNO sold 2 gumballs SPRING VALLEY sold 9 gumballs ELVERTA sold 5 gumballs SACRAMENTO sold 7 gumballs SAN MATEO sold 1 gumballs

В о т как в итоге выглядит наша страница но еле того, как мы вы нолнили код и из­ влекли данны е об уровне нродаж со сво­ его локального сервера, иснользуя адрес http: / /lo c a lh o st / gum ball / sales.json.

А вот как в итоге выглядит наш а стра­ ниц а но еле того, как мы вы нолнили код и извлекли данны е об уровне нродаж с сервера Mighty Gum ball, используя адрес http: / / gum ball.wickedlysm art.com .

Что Же делать дальше?! Пожалуй, дальше мы будем делать то же, что и всегда, — соберем всех членов ко­ манды и быстро все обсудим. Мы уверены, что все вместе (включая вымыш ленны х нерсонаж ей) мы сможем вы яснить нричину нроблемы! Фрэнк? Джим? Джо? Где вы все? А, вот где —н а следующей странице...

276

глава 6

Эйджей, довольно сильно расстроенный контролер качества


общение с веб-службами

Д ж им: URL-адрес правильный? Ф рэнк: Да, правильны й, я уже вводил его в браузере, чтобы убедиться в том, что увижу ожидаемые нами данные об уровне продаж, и все нормально работало. Не понимаю... Д ж о: Я заглянул в консоль JavaScript в браузере C hrom e и увидел что-то об управлении доступом и ис­ точниках или доменах. Ф рэнк: Хм? f

сДж им

Ребята, где вы были, когда мы занимались проектом S+arbuzz \ Coffee? Если помните, у нас была проблема 1 с аналогичным поведением. Держу пари, что на

этот раз вы столкнулись с междоменными пробле мами, поскольку запрашиваете данные с сервера, отличного от того, с которого исходит ваша страни ца. Браузер рассматривает все это как проблему безопасности. /

Хм, а нельзя ли освежить в нашей памяти то, как браузер подходит к вопросам безопасности?

Джуды

дальше ►

277


обзор браузерной политики безопасности

Что за браузерная политика безопасности? Да, с наш ей стороны было стыдно налететь на такую «корягу», — достаточно лишь нодумать о том, в какое нолож ение нри этом мы ставим вас, читателей, —но Джуди нрава, браузер задействует нолитику безонасности в случае с НТТР-занросами с ис­ пользованием X M L H ttpR e quest, которая мож ет вызы вать нроблемы. Так что это за нолитика такая? Это браузерная нолитика, которая подразумевает, что вы не сможете извлечь данны е из домена, отличного от домена, из которого стра­ ниц а загружается как таковая. Донустим, вы создали сайт DaddyW arBucksBank. com и кто-то взломал вашу систему и внедрил JavaScript-код, которы й собира­ ет персональны е данны е пользователей и делает с ним и всевозмож ны е инте­ ресны е вещ и, установив соединение с сервером HackersN eedM oreM oney.com . Звучит скверно, не так ли? Ч тобы номеш ать нодобным вещам, браузеры п реп ят­ ствуют соверш ению с иснользованием X M L H ttpR e quest НТТР-занросов в домены, отличные от исходного домена, из которого загружается ваша страница. П осмотрим , какое новедение можно считать нриемлемы м в случае с JavaScriptкодом, а какое нет. Приемлемое поведение 6 случае J a v a S c r i p t - кода Сначала пользователь (посредством браузера) совершает запрос HTML-страницы (и, конечно же, любых ассоциированных с ней JavaScript- и CSS-файлов): Сервер успешно возвращает запраш ива­ ем ую вами страницу.

Ваш браузер о т ­ правляет запрос страницы из doodD om ain.com .

GoodDomain.com

Браузер

Странице требуются некоторые данные из GoodDomain.com, поэтому она запрашивает их с использованием XMLHttpRequest:

располагаются в одном и т ом же^домене.

jf-fc

Сервер успешно воз­ вращает запрошенные данные.

Г

Браузер 278

глава 6

GoodDomain.com


общение с веб-службами

Неприемлемое поведение 6 случае JavaS cript-kog a: Тенерь носмотрим, что нроизойдет, когда ваша страница, располагаю щ аяся в G oodD om ain.com , ноны тается занросить данны е с использованием X M L H ttpR eq uest из BadD om ain.com . Как и ранее, браузер совершает запрос страницы, которая располагается в GoodDomain.com. Сюда могут входить JavaScript- и CSS-файлы, также располагающиеся в GoodDomain.com.

Сервер успешно возвращает запраш ива­ ем ую вами страницу.

Ваш браузер о т ­ правляет запрос страницы из QoodDomain.com.

GoodDomain.com

Браузер

Однако на этот раз у нас имеется код, которому требуются данные из другого источника, то есть из BadDomain.com. Посмотрим, что произойдет, когда страница запросит эти данные с использо­ ванием XMLHttpRequest:: Браузер видит, что Ваша с т р а н и ­ это запрос в домен, ца использует отличный от т ого , XMLHttpRequest в кот ором р асп о­ для попытки лагается ст раница, и п р е п я т с т в у е т его запроса данных, располагающихся совершению. То есть в BadPomain.com в запросе будет о т ­ казано.

Браузер

Сервер BadPomain.com т ак и не увидит запрос; полит ика безопас­ ности вашего браузера во с п р еп ят ­ с т ву е т его совершению прежде, чем это могло бы случиться.

GoodDomain.com

BadDomain.com

дальше ►

279


обзор имеющихся вариантов

Да уж, славно потрудились — написали столько кода, а он так и не будет работать? Л нельзя ли просто скопировать наши —i файлы на сервер Mighty Gumball?

Обычно ответ на подобный вопрос бывает утвердительным. Допустим, вы являетесь раз­ работчиком, работаю щ им над кодом для Mighty G um ball, а в этом случае у вас, скорее всего, будет доступ к серверу данной компании (или к людям, которы е могут произвести разверты вание ф ай ­ лов на соответствующ ем сервере за вас), где вы сможете разм естить все свои файлы и избежать лю бых междоменных проблем. Однако в данном случае (хоть нам и н еп риятно разруш ать вашу По крайней мере веру в правдоподобность излагаемой ситуации) не в рамках Ь\од вы на самом деле поработаете на Mighty Gumball, жета, выделенного а являетесь читателями книги, и мы не можем нам редактором! дать возмож ность ты сячам людей заниматься копированием своих файлов на сервер Mighty Gumball. Так к чему же мы приш ли? К тупиковой ситуации? Нет, у нас есть несколько вариантов, как можно ностунить в данном случае. Взглянем на них...


общение с веб-службами

Какие у нас варианты? Будем честны: все это время мы знали, что м еж источниковы й занрос X M L H ttpR e quest н отерн ит неудачу. Однако, как уже отмечалось ранее, нри создании н рилож ений вы зачастую будете раснолагать достуном к соответствующему серверу, так что это не станет нроблем ой (а нри создании нрилож ений, в зна­ чительной стенени зависящ их от ваших собственных данных, иснользование X M L H ttpR e quest обычно оказы вается онтимальны м выбором). Однако в данны й момент мы можем услышать от вас следующее: «Все это, конечно, здорово, но как, на­ конец, заставить наш код работать?». Ч то ж, есть два снособа сделать этот Способ 1: использовать уже размещенные нами на сервере файлы. Мы уже разм естили для вас файлы на нашем сервере но адресу: h t t p : //g u m b a ll .w ic k e d ly s m a r t. с о т / g u m b a ll/g u m b a ll .h tm l

П роведите тестирование, введя данны й URL в своем браузере, что но зв о лит увидеть в действии код, которы й вы набирали до сих нор. Способ 2: использовать другой подход к извлечению данных. 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

Д ж о: Н епременно! А что это такое? Д ж им : Похоже, что другой нодход к но лучению данных от веб-служб для нередачи в наши нрилож ения. Фрэнк: О т меня здесь не будет толку, носкольку я всего лишь дизайнер. Д ж им : Фрэнк, я думаю, что все не так уж и плохо. Я бы­ стро п роверил с номощью Google, что такое JSONP, и уз­ нал, что это, по сути, снособ заставить тег <script> вынолнять работу по извлечению данных. Джо: А разве так можно? Джим: К онечно можно — многие крунные сервисы ноддерж иваю т такой нодход, нанрим ер Twitter. Фрэик: Все это нохож е на какой-то халтурны й нри ем. Джо: Да, и я о том же. Я имею в виду, как иснользование тега <script> м ож ет быть нриемлемы м нодходом к извле­ чению данных? Я даже нонять не могу, как он вообщ е сра­ ботает. Джим: Я сам еще далеко не нолностью в этом разобрался. Но здесь можно рассуждать так: когда мы иснользуем эле­ мент <script>, он извлекает код для нас, ведь так? Джо: Да, это так... Джим: А что, если мы номестим данны е в этот код? Джо: П роцесс ношел, все закрутилось-завертелось... Фрэик: Да, можно сказать, как хомяки в колесе...

282

глава 6


общение с веб-службами

Присаживайся, Кузнечик. Зачастую то, чему я учу, ты уже, в сущ­ ности, знаешь...

Гуру HTML5: ...и этот как раз один из таких случаев. Кузнечик, взгляни на этот код: Что он делает?

Данным код ра спо­ лагается по э т о ­ м у URLГуру: Да, верно. Создай свой собственный простой HTML- адресу. файл и помести в него < s c r i p t > , расположив данный элемент в <body>, как показано далее:

Веб-разработчик: Если произвести его оценку, предполагая при этом, что он выполняется в браузере, то данный код выведет диа­ логовое ОКНО a l e r t С ТеКС ТО М "woof".

< s c r i p t s r c = " h t t p : / / w i c k e d l y s m a r t . c o m / h f h t m l 5 / c h a p t e r б/ d o g . j s "> < /sc rip t>

Гуру: Что он делает? Веб-разработчик: Загружает страницу, которая загружает с сервера wickedlysmart.com JavaScript-код, содержащийся в файле d o g . j s и вызывающий функцию a l e r t , в результате чего браузер выводит диалоговое окно alert с текстом "w oof". Гуру: Получается, что JavaScript-фойл, загружаемый из другого домена, может вызывать функцию в твоем браузере? Веб-разработчик: Теперь, когда вы так выразились, да, Гуру, я полагаю, что именно так все и происходит. Как только файл d o g . j s , находящийся на сервере wickedlysmart.com, подвергается извлечению, он вызывает функцию a l e r t в моем браузере. Гуру: По адресу http://wickedlysmart.com/hfhtml5/chapter5/ dog2.js располагается еще один файл со следующим JavaScript-кодом: anim alsays("dog",

"w oof");

Гуру: Что он делает?

дальше

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 , и посмотри, что будет. a n i m a l S a y s ( " c a t " , "m eow ");

Веб-разработчик: На экране появилось диалоговое окно a l e r t с сообщением " c a t s a y s m e o w ". Гуру: Получается, что JavaScript-файл, загружаемый из другого домена, может не только вызывать любую функцию в твоем коде, какая ему будет необходима, но и передавать нам любые данные, какие ему потребуется? Веб-разработчик: Вообще-то я не вижу никаких данных, только два аргумента. Гуру: А разве аргументы не являются данными? Что, если внести изменение, в результате чего аргументы станут выглядеть так: v a r anim al = { " ty p e " : an im alS a y s(a n im a l);

"cat",

"sound":

"meow"};

cat 3.js

Веб-разработчик: Теперь функции a n i m a ls a y s передается один аргумент, который является объ­ ектом. Хм, несомненно, в моих глазах этот объект начинает становиться похожим на данные. Гуру: Ты можешь переписать функцию объект? Веб-разработчик: Попробую... 284

глава 6

a n i m a ls a y s

таким образом, чтобы она использовала новый


общение с веб-службами

Веб-разработчик: Вот так? fu n c tio n anim alsay s(an im al) { a l e r t ( a n i m a l . type + " says " + a n im a l. so u n d );

}

Гуру: Очень хорошо. Измени ссылку на http://wickedlysmart.com/hf html5/chapter6/dog3.js и про­ веди тест. Сделай то же самое с использованием http://wickedlysmart.com/hf html5/chapter6/cat3.js. Веб-разработчик: Да, оба варианта работают, как и ожидалось в случае с моей новой функцией. Гуру: А что, если изменить имя animalSays на updateSales? Веб-разработчик: Гуру, я не понимаю, какая может быть связь между животными и уровнями про­ даж жевательной резинки? Гуру: Давай поработаем сообща. Что, если мы переименуем dog3.js, присвоив ему имя sales.js, и перепишем код следующим образом: 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) ;

Веб-разработчик: Кажется, я начинаю понимать. Мы передаем данные посредством JavaScript-файла, HO КОТОрыЙ ССЫЛаеМСЯ, ВМеСТО ТОГО, Ч Т О б ы СаМИМ ИЗВЛекаТЬ И Х С ИСПОЛЬЗОВаНИеМ X M L H t t p R e q u e s t .

Гуру: Да. Однако ты должен уметь видеть главное за массой второстепенных деталей. Разве при этом их извлечение осуществляется не из другого домена? А это 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> оау^

URL веб-службы, кото­ рая будет обеспечивать для нас J S O N -данные об уровне продаж жева­ тельной резинки.

< h l > M i g h t y Gumball Sales</ < d i v id*" sales ••>

</diV>

,/ V, U Wickedlysmart.com/" X <script src="h t t p ://gumball.wicke

/ script

</body> </html>

_____ ____

( Т \ ТJ S O N -ответ посту­ пает в форме строки, которую браузер разбирает и интерпретирует. Л ю ­

Когда браузер сталкивается с элементом <script> на странице, он отправ­ ляет HTTP-запрос по URL-адресу источника.

бые типы данных преоб­ разуются в подлинный JavaScript-объект и значе­ ния, а любой код подвер­ гается выполнению.

Помнит е, что на данный * м о м е н т это всего лишь строковое представление объекта*

286

глава 6

/ j N Сервер воспринимает данный запрос как HTTP-запрос и отправ­ ляет в ответ на него JS O N .

Веб-служба


общение с веб-службами

Что означает буква Р в аббревиатуре JS0NP? П ервое, что вам необходимо знать о JSONP, —это то, что у него глуное и не очень нонятное имя: JSON with P adding (JSONP с нодкладкой). Если бы мы давали ему имя, то назы вали бы его как-то вроде JSON with Callback (JSONP с функцией обратного вы зова), либо «извлеки мне JSO N -данные и вы нолни код, когда вернеш ь их», либо нросто как-то но-другому вместо JSO N with Padding. Однако все, что здесь подразумевается нод Padding, —это оберты вание JSO N -данных в вызов функции, нрежде чем они ностунают в ответ н а занрос. Вот как все это работает: Браузер

& по о

/ 7 \ Как и ранее, мы включили элемент

-—

<«.doctype html>

< s c r i p t > . Источником

Chtml lang="en">

для этого элемента выступает URL веб­ службы, которая будет

<body> <hl>Mighty Gumball Sales</h > <div id="sales">

обеспечивать для нас J S O N -данные . </body>

Как и раньше, ког-

/ Т \ На этот раз, когда J S O N ответ подвергается разбору и интерпретации, он уже обернут в вызов функции. Поэтому про­ исходит вызов данной функции

да браузер стал­ кивается с элементом < s c r i p t > на странице, он отправляет НТТРзапрос по URL-адресу источника.

и создание объекта из J S O N строки, которая ей была передана.

На э т о т раз J S O N данные будут обернуты в вызов функции.

Л/

updateSales f o \ Как и ранее, сервер воспринимает данный запрос как обычный запрос и отправляет в ответ на него J S O N -строку, о дн ако ... здесь имеется небольшое отличие. Прежде чем сервер отправляет обратно J S O N строку, он предварительно обертывает ее в вызов функции, например в вызов функции

Веб-служба

u p d ateS ale s.

дальше ►

287


разбираемся с функциями обратного вызова

Я понимаю, как использовать тег <script> для того, чтобы заставить браузер извлекать JavaScript, и как сервер может по­ мещать свои данные в этот JavaScript. Но как быть с именем функции? Откуда веб-служба знает имя нужной функции? Напри­

О

мер, откуда веб-службе Mighty Gumball известно, что необходимо вызывать именно updateSales? Вдруг у меня имеется другая служба и я хочу вызывать, допустим, функцию updateScore, или a lert, или какую-то другую?

Веб-службы позволяют указывать имя требуемой функции обратного вызова. О бы чно веб-службы позволяю т указывать имя необходимой вам функции. Хоть мы и не говорили этого, но Mighty G um ball нредоставляет такую возможность. Когда вы будете указывать со­ ответствующ ий URL-адрес, добавьте в его конец параметр, как показано дальше: h t t p ://gumball.wickedlysmart.com/?callback=updateSales

------u , n, л Ооычныи URL -адрес. который мы уже и с ­ пользовали раньше.

А здесь мы добавили URLпа р а м е т р c a l l b a c k который указывает, что при генериро­ вании JavaScript должна исп оль­ зоваться функция updateSales.

В результате Mighty G um ball будет иснользовать u p d a t e S a l e s для оберты вания объекта в ф орм ате JSO N до того, как отнравлять его обратно вам. В случае с веб-службами данны й нара­ метр обычно назы вается c a l l b a c k , однако для нодстраховки вам все же следует изучить документацию к иснользуемой вами веб-службе.

ШТУРМ Введите данные 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 h t t p ://search.twi tter.com/search.j son?q=hfhtml5&callback=updateTweets

Примечание: браузер Firefox предложит вам от к ры т ь либо сохранить файл. Д л я от кры т ия вы можете использовать T extEdit, Блокнот или любой другой базовый текстовый редактор.

288

глава 6


общение с веб-службами

Ребята, у нас все получилось. Нам при­ шлось немного повозиться, чтобы разобраться с использованием элемента < s c r i p t > при обращении к веб-службе, однако теперь такой подход кажет­ ся едва ли не более простым, чем использование XMLHttpRequest.

Д ж им : Ч то ж, почти. Д ж о: Думаю, это дает нам возмож ность избавиться от части кода. Ф рэнк: Я готов придать веб-нриложению красивы й внеш ний вид, когда вы закончите. Д ж им : Д ж о, а что ты думаешь? Д ж о: В случае с 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> .

Джим: Как раз это меня и интересовало. Где мы его разместим? Джо: Браузер будет онределять, когда он будет загружаться, а нам необходимо, чтобы сначала загружалась страница, чтобы мы могли обновить объектную модель документа (DOM) н ри вы зо­ ве u p d a t e s a l e s . Единственны й выход, как мне кажется, в данном случае заклю чается в разм ещ ении < s c r i p t > в ниж ней части стра­ ницы , в <body> HTM L-документа. Джим: Да, нохоже, это здравая мысль. Н ам следует но дробнее на н ей остановиться. Но сначала давайте нроверим ее н а нрактике. Джо: Я хочу, чтобы наш код, наконец, заработал! Д авайте им зай­ мемся! Ф рэи к: Ребята, вам лучше носнеш ить, но скольку, готов снорить, Джуди уже наш ла свой снособ заставить все работать. дальше ►

289


план повторной реализации

Обновление кода Веб-прилоЖения Mighty Gumball П ора обновить к о д нашего н рилож ени я Mighty G um ball с использовани­ ем JSONP. Помимо удаления существующего кода, связанного с вы зовом X M L H ttpR eq uest, все остальные изм енения будут незначительны м и.

Вот что нам потребуется сделать: Удалить КОД X M L H ttp R e q u e st. (2 )

Удостовериться, ЧТО функция u p d a t e S a l e s будет готова к приему объекта, а не строки (как было В случае С X M L H ttp R e q u e st). Добавить элемент < s c r i p t > для выполне­ ния работы по извлечению данных.

^

Весь код в нашей функции o n l o a d является связанным с X M L H ttp R e q u e st, поэтому мы можем просто удалить его. Сохраним функцию o n l o a d на слу­ чай, если она пригодится нам немного позже. А пока она ничего не будет делать. Откройте свой файл m i g h t y g u m b a i i . j s и внесите следующие из­ менения: 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 " т var request = new XMLIIttpRequest () ; reque st.open (ивВФм , url); reque st.onload = function ()— fif— (reque st.status == 200)— {updateflales(request.responseText); t

reques t .sen d (nul1);

290

глава 6

g данный МОЛЛент бяМ HCofixoдимо просто удалит ь весь код, имеющийся в этой функции.


общение с веб-службами

(2 )

Как вы помните, когда мм используем элемент < s c r i p t > , мм говорим браузе­ ру, что нужно извлечь JavaScript, в результате чего браузер извлекает его, а за­ тем проводит его разбор и оценку. Это означает, что к моменту, когда он дойдет до вашей функции u p d a t e S a l e s , JS O N будет представлять собой уже не стро­ ку, а полноценнмй JavaScript-объект. Когда мм использовали X M L H ttp R e q u e s t, даннме возвращались в форме строки. На даннмй момент функция u p d a t e S a l e s предполагает, что будет получать строку, поэтому давайте внесем здесь измене­ ние, чтобм она обрабатмвала объект, а не строку: Удаляем responseText и п е р е ­ писываем ст року с использо­ ванием парам ет ра sales.

function up date Oale s(resp onseText) function updateSales(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) ;

}

t

А вот и р езульт ат : т еперь у нас имеет ся функция, готовая к обработке наших данных.

И наконец, добавляем элемент < s c r i p t > для вмполнения работм по извле­ чению даннмх. < !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 "> < 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 > < 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 " > < /h e a d > <body> < h l> M ig h ty G um ball S a le s < /h l>

Это ссылка на веб-службу Mighty Gumball. Мы исп оль­ зуем п а рам ет р callback и указываем имя нашей ф у н к ­ ции updateSales, в силу чего веб-служба будет оберт ы ­ вать J S O N -данные в вызов функции 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

Тест-драйв нового кода с JS0NP Когда вы внесете все изм енения, настунит время нровести тест-драйв. П ерезагрузите m ig h ty g u m b all. htm l в своем браузере. Тенерь вы загружаете данны е об уровне нродаж ж евательной рези н ки автоматами Mighty Gum ball, иснользуя свое веб-нриложение и JSONP. Внешне страница долж на но лучиться такой же, как и нри извлечении данных об уровне продаж из локального ф ай­ ла, но вы будете знать, что в данном n n n Mightycumbaii Случае используется соверш енно Дру- f ^ I II + гой способ извлечения и нф орм ации. , „

* F

Mighty Gumball Sales IMPERIAL sold 4 gumballs

в о т что вы увидите при перезагрузке страницы Mighty Gumball Вы будете наблюдать разные города и уровни продаж, посколь­ ку на экран с т а н у т выво­ диться реальные данные.

SAN FRANCISCO sold 5 gumballs CHINO HILLS sold 8 gumballs STANFORD sold 3 gumballs CARSON sold 9 gumballs GOLETA sold 6 gumballs BRADLEY sold 5 gumballs CAPAY sold 7 gumballs LANCASTER sold 8 gumballs SAN QUENTIN sold 5 gumballs

Да! Исполнительному ди­ ректору Mighty Gumball это должно понравиться! Теперь можно и отдохнуть.

292

глава 6


А мне кажется, что JSONP является одной большой бре­ шью в безопасности!

Данный подход не менее безопасен, чем использо­ вание <script> для загрузки JavaScript. Это нравда: если вы соверш аете JSO N P-запрос, обращ а­ ясь к вредоносной веб-службе, то ответ мож ет содерж ать JavaScript-код, которого вы не ожидаете, и браузер вынолнит его. Все это ничем не отличается от добавления JavaScript нутем связы вания с библиотеками, размещ аемыми на других серверах. Всякий раз, когда вы осущ ествляете связы вание с JavaScript-библиотекой (например, с от­ носящ ейся к <head> вашего документа) либо используе­ те JSONP, вам необходимо быть уверенными в том, что вы доверяете данной службе. А если вы пиш ете вебнрилож ение, которое станет задействовать аутентиф и­ кацию н ри реш ении вопроса о том, давать ли доступ кон­ кретному нользователю к чувствительным данным, то наилучшим выходом для вас, вероятно, будет вообщ е не иснользовать сторон н ие библиотеки или JSO N -данные, размещ аемы е на других серверах. Поэтому осторож но нодходите к выбору веб-служб, к ко­ торы м собираетесь подклю чаться. Если вы иснользуете API-интерф ейс, такой как Google, Twitter, Facebook, или одну из множ ества других ш ироко известны х веб-служб, то мож ете быть уверены в их безонасности. В н ротивном случае рекомендуется нроявлять осторож ность. В нашем случае мы знакомы с инж енерам и из ком нании Mighty G um ball и знаем, что они никогда не стали бы внедрять что-либо вредоносное в свои JSO N -данные, в силу чего вы мож ете быть уверенны м и в их безонасности.


Беседау камина У ч а с т н и к и : X M L H ttp R e q u e st an d JS O N P Сегодня мы станем свидетелями разговора двух популярных способов извлечения данных в случае с браузерами.

X M L H ttp R e q u e st: Н е хочу Вас обидеть, но не являетесь ли вы халтурным приемом? Я имею в виду, что Ваше назначение заклю­ чается в извлечении кода, а люди используют Вас для соверш ения запросов данных.

Н о все, что Вы делаете, —это вбрасы вание данны х вме­ сте с кодом. И вообщ е вы никак не позволяете со в ер ­ шать запросы напрямую из JavaScript-кода; Вы вынуж­ даете лю дей использовать HTM L-элемент < s c r i p t > . Э то приводит Ваших пользователей в замеш ательство.

Э й, XML по-прежнему ш ироко используется, и не сто­ ит умалять его значение. А извлекать JSO N -данные мож но и с помощью меня без проблем .

JSO N P :

Халтурным? Я бы назвал себя замечательным. Ведь я могу использоваться для извлечения как кода, так и данны х. Какая н еобходим ость в том, чтобы делать все это двумя разными способами?

Э й, но ведь такой п о д х о д р а б о т ает и дает людям в о з­ можность писать код, который позволяет получать JSO N данные от сервисов вроде Twitter, G oogle и других. Как та­ кое возм ож но при использовании Вас, XM LH ttpRequest, учитывая налагаемые Вами огр ан и чен и я с целью о б е ­ спечения безопасности? Я имею в виду, что Вы все еще цепляетесь за прош лое, за XML

К онечно м ож но, если кому-то нравится постоян но за­ ниматься п р еобр азованием результатов с помощью Я позволяю контролировать, какие им енно данны е будут подвергаться р азбору и преобразованию в JavaScript-объекты. А в случае с Вами это п р ои сходи т в отнош ении всех данных.

Что ж, мож но воспользоваться халтурным прием ом вроде JSO N with P ad d in g (ну и глупое ж е название) либо правильным сп особом , то есть X M LH ttpR equest, и «расти» вместе с ним по м ере его эволю ции. В конце концов, люди работаю т над тем, чтобы сделать меня бол ее гибким, но в то ж е время безопасны м .

294

глава 6

JS O N .parse.

А в этом как раз и заключается преимущ ество — к мо­ менту, когда данны е дойдут до м оих пользователей, все они будут разобраны и преобразованы . П ой м ите, я Вас очень уважаю, Вы стояли у истоков целого подхода к написанию прилож ени й, но проблем а в том, что Вы навязываете слишком много ограничений. В совр ем ен ­ ном мире веб-служб людям требуется возм ож ность со ­ вершать запросы и в другие дом ены .

Л ю ди, н есом н ен н о, работаю т над вашим улучшением, однако у м оих пользователей имею тся реальные п о­ т р ебн ости уже сегодня, — они не могут ждать, пока бу­ дут устранены все ваши м еж дом енны е проблемы .


общение с веб-службами

X M L H ttp R e q u e st:

JSO N P : И ничего глупого в слове P adding в названии JSONP нет, поскольку он о всего лишь означает, что когда пользователь соверш ает запрос веб-службы, он при этом также просит ее добавить небольш ой преф икс, наприм ер, " u p d a t e S a l e s ()", к результату. А Вас как иногда называют? Ajax? Разве это не название средства чистки для ванн?

У меня нет ничего общ его с названием Ajax, поэтом у не надо задавать мне такие вопросы ! К стати, Вы ни разу не говорили о том, насколько Вы безопасны .

Я могу лишь сказать, что если вам не требуется извле­ кать чужие данны е, которы е м ож ет дать, наприм ер, Twitter или G oogle, и вы создаете свою собственную веб-службу и клиента, то вы бирайте меня. Я о б е с п е ­ чиваю бол ее высокий уровень б езоп асн ости и бол ее прост в использовании.

Программистам постоянно приходится проявлять о ст о­ р ож ность. Если вы извлекаете код с другого сервера, то долж ны знать, что дел аете. Н о ответ в данном случае не д о л ж ен н р о ст о ограничиваться ф р а зо й «этого не следует делать».

Алло? Никто не создает службы, которы е не исполь­ зуют внеш ние данны е. Слышали когда-нибудь термин «мэшап»?

Да, да, знаю я об этом смеш ивании данны х, извлекае­ мых с различны х сто р о н н и х веб-ресурсов. Э й, я, по крайней м ере, обладаю стабильной пов се­ м естной поддерж кой и терпеть не могу, когда п р и хо­ дится писать код X M L H ttpR equ est, которы й см ож ет работать в стары х браузерах. Да ладно, не так уж и много кода нужно, чтобы о б е ­ спечить поддерж ку меня версиями вплоть до Internet Explorer 5. Ха-ха, а в случае со м ной для этого вообщ е не потребу­ ется НИ К АК О ГО кода. Лишь п р остой HTM L-тег. Что ж, однако, это ещ е не все. П робовали ли Вы когда-нибудь делать нечто повторяю щ ееся, то есть когда требуется извлекать что-либо снова и снова? В каче­ стве прим ера мож но привести пр ил ож ени е Mighty G um ball, над которы м сейчас идет работа. Как разра­ ботчики смогут обесп еч и ть такую функциональность, используя Вас?

М не кажется, Ваши читатели, услышав только что ска­ занн ое Вами, переспросят: «Что, простите?»

Э й, все не настолько плохо. Нужно просто добавить новы й элем ент < s c r i p t > в объектную модель доку­ мента (DOM ) для соверш ения ещ е одного запроса.

H E A D F IR S T : Благодарю , ребята! Боюсь, наше врем я истекло!

дальше ►

295


jsonp-упражнение для ума

Вы немного не доработали приложение. Я думал, что увижу постоянно обновляющийся поток данных об уровне продаж, поступающий от наших автоматов для продажи жевательной резинки. Конечно, я могу нажать кнопку Refresh (Обновить) в браузере, но ведь получается, что я смогу увидеть самые свежие отчеты только в том случае, если сам вручную нажму кнопку обновления. Это не то, чего я хотел!

М 9 *Г 9 *9 Й

ШТУРМ Он прав, нам необходимо подкорректировать приложение, чтобы оно обновляло отображаемые данные, используя новые сведения об уровне продаж, через регу­ лярные интервалы времени (например, каждые 10 секунд). На данный момент у нас в странице имеется элемент <script>, который инициирует отправку запроса на сервер только один раз. Вы можете придумать какой-нибудь способ так исполь­ зовать JSON, чтобы обеспечивалось непрерывное извлечение отчетов с новыми данными об уровне продаж?

Подсказка: используя объектную модель документа (РОМ), мы можем вставить новый элемент <script> в страницу. Поможет ли это?

296

глава 6


общение с веб-службами Ребята, как я только что узнала, исполнительный директор Mighty Gumball не совсем доволен вашей первой версией приложения?

Джим: Да, он хочет, чтобы отображ аемы е на странице данны е обнов­ лялись ненреры вно. Джуди: В этом есть смысл. Я имею в виду, что большим преимуще­ ством веб-нрилож ения является то, что его не нужно обновлять с номощью кнонки Refresh (О бновить) как обычную веб-страницу. Джо: Внолне справедливое требование. К роме того, мы уже знаем, как зам енять старые данны е об уровне нродаж новы ми на странице, иснользуя DO М. Но мы нока не уверены в том, как именно следует об­ рабаты вать JSO N P-часть. Джуди: Н е забы вайте, что вы также мож ете иснользовать объектную модель документа в сочетании с элементом <script>. Другими слова­ ми, вы мож ете создавать новы й элемент <script> в DOM всякий раз, когда необходимо извлечь дополнительны е данные. Джим: Что-то я не очень нонял. Н ельзя ли новторить? Джо: Кажется, я разобрался. Н а данны й момент мы статически раз­ мещаем элемент <script> в HTM L-разметке, нросто набрав его там. Вместо этого мы могли бы создавать новы й элемент <script> с исполь­ зованием JavaScript-кода и добавлять его в DOM. Единственное, в чем я здесь не уверен, — станет ли браузер еще раз извлекать данны е, ког­ да мы создадим новы й элемент <script>? Джуди: К онечно, станет. Джим: Ясно, то есть мы будем создавать новы й элемент <script> каж­ ды й раз, когда нам будет необходимо, чтобы браузер вы нолнил для нас JSO N P-онерацию. Джуди: Правильно! П охоже, что и ты во всем разобрался. А знает ли кто-нибудь из вас, как сделать так, чтобы это происходило снова и снова? Джим: Мы еще не дошли до этого, мы нока что размыш ляем о JSONP. Джуди: Вам уже все известно о функциях обработчиков собы тий вроде onload или onclick. Вы мож ете установить тайм ер для вызова функции обработчика через заданны й интервал врем ени с использо­ ванием метода setlnterval в JavaScript. Джо: Д авайте именно так и ностуним и сделаем JSO N P динам иче­ ским, чтобы как можно скорее нредставить исполнительному дирек­ тору Mighty G um ball долж ны м образом работаю щ ее нрилож ение. Джим: О, это все, что нотребуется сделать? Тогда не будем медлить! дальше ►

297


делаем jso np динамическим

ДорабатыВаем приложение Mighty Gumball Как видите, нам нридется вы нолнить немного дополнительной работы , однако она не будет слишком сложной. По сути, мы нанисали нервую версию нашего н рилож ения таким образом, что оно извлекает отчеты об уровне нродаж с сервера Mighty G um ball и отображ ает их только один раз. Это наше унущ ение, носкольку ночти все соврем енны е веб-нрилож ения долж ны ненреры вно осуществлять м онито­ ринг данны х и обновлять отображ аемы е на странице сведения (ночти) в реж име реального времени.

Вот что нам потребуется сделать:

©

М м удалим JSONP-элемент < s c r i p t > из HTM L-страницм Mighty Gumball, поскольку больше не будем его использовать.

©

Нам потребуется задать обработчик для обработки совершения JSO NP-запроса каждме несколько секунд. Прислушаемся к со­ вету Джуди и воспользуемся JavaScript-методом s e t i n t e r v a l .

©

Затем необходимо реализовать наш JSONP-код в обработчике, чтобм каждмй раз, когда будет происходить его вмзов, он со­ вершал запрос с целью извлечения отчетов с самими свежими данными об уровне продаж с сервера Mighty Gumball.

Шаг 1: удаляем элемент < script> . . . Мы собираем ся иснользовать новы й н о д х о д к инициированию JSONPзанросов, ноэтому давайте удалим элемент < s c r ip t> из HTM L-разметки.

<! doc type html> <h tml 1 ang=11e n 11> <head> <title>Mighty Gumball</title> <meta charset="utf-8"> < script src="mightygumball.j s " X / s c r i p t > <link rel="stylesheet" href="mightyguinball.css"> </head> ^ S L i g h t y

Gumball Sales</hl>

<div id="sales">

^

У д а л и т е данны й эл е м е н т

из своего

H T M L -ф а й л а .

</div> T <script src="http://gumball.wickedlysmart.com/?callback=update 3ale s 11></script> </body> </html>

298

глава 6


общение с веб-службами

Шаг 2: Время для установки таймера И так, мы стремимся к тому, чтобы вместо и звлечения отчетов об уровне н ро­ даж только один раз эта нроцедура осуществлялась врем я от врем ени, скажем, каждые 3 секунды. Это мож ет оказаться слишком часто или редко в зависимо­ сти от конкретного нрилож ения, однако в случае с Mighty G um ball мы начнем с интервала 3 секунды. Н ам нотребуется функция, которую мы сможем вы зы вать каждые 3 секун­ ды. И, как говорила Джуди, для этого мы мож ем воснользоваться методом setlnterval, которы й имеется в объекте window:

s e tln te r v a l(h a n d le R e fr e s h ,

s e tln te r v a l приним ает одраб о т ч и к и зн а ч е н и е и нт ер ва ла врем ени. М етод

3000);

г

Наше значение интервала вр е м е ­ ни, выраженное в миллисекундах. 3 ООО миллисекунд = 3 секунды.

Наила функция обра­ ботчика, кот орую мы определим чут ь позже.

Таким образом, каждые 3000 миллисекунд JavaScript будет вызы вать обработчик —в данном случае функцию h a n d l e R e f r e s h . Д авайте наниш ем нростой обработчик и протестируем его:

function handleRefresh() { alert("I’m alive");

При каждом вызове данного обработчика (а происходить это будет каждые 3 се­ кунды) на экран будет выводиться диалоговое окно alert с сообщением «I'm alive».

Тенерь нам нотребуется код для задания вы зова s e t l n t e r v a l , которы й мы добавим в функ­ цию o n l o a d , чтобы он нроисходил сразу но еле того, как страница нолностью загрузится: window.onload = function() { setlnterval (handleRefresh, 3000) ;

)

Это наша прежняя функция onload, в которой ничего не осталось после того, как МЫ удалили из нее код X M L H ttp R e q u e s t.

't

! е ш Г ° 7 М Н&0бК0диМ0 с Э е л а ^ -

эт о

д о б а в и т ь н а ш вы зов

к о т о р ы й в КТ о Т Т вЬ'П° Л н е н ш ^ з а п у с т и т т айм ер к о т о р ы й , в сво ю о ч е р ед ь, с т а н е т и н и ц и и р о в а т ь с я кажды, ч а « в ы зы в а т ь н а ш у ф у НКЦию h a n d le R e fr e s h

П роведем тест-драйв, а затем, когда убедимся, что все работает (то есть когда мы увидим, что обработчик вы зы вается каждые 3 секунды), реализуем JSO N P-код.

дальше ►

299


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.