+ All Categories
Home > Documents > Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First...

Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First...

Date post: 03-Jan-2016
Category:
Upload: marcoci-valeriu
View: 260 times
Download: 11 times
Share this document with a friend
508
Transcript
Page 1: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 2: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

О других книгах серии Head First

«В книге „Изучаем объектно-ориентированный анализ и проектирование“ используется новый подход к теме ООАП. Эта книга отличается от других тем, что она ориентирована на об-учение. Авторы сделали материал ООАП доступным и полезным для программиста-прак-тика».

— Айвар Джейкобсон, Ivar Jacobson Consulting

«Я только что закончил читать „Изучаем объектно-ориентированный анализ и проектирование“ и остался в полном восторге! Больше всего мне понравилось то, что книга ориентирована на необходимость применения ООАП для написания хороших программ».

— Кайл Браун, заслуженный инженер, IBM

«За смешными картинками и вычурными шрифтами скрывается серьезное, разумное, ис-ключительно качественно проработанное изложение объектно-ориентированного анали-за и проектирования. Во время чтения книги мне казалось, что я стою за спиной опытного проектировщика, который объясняет мне, какие аспекты важны на каждом этапе проек-тирования, и почему».

— Эдвард Сьоре, адьюнкт-профессор, факультет компьютерных технологий, Бостонский колледж

«В целом „Управление разработкой ПО“ представляет собой замечательный источник инфор-мации для всех, кто хочет привести в порядок свои навыки программирования — причем подход к изложению материала постоянно привлекает внимание читателя на многих уров-нях».

— Энди Хадсон, Linux Format

«Программистам-новичкам „Управление разработкой ПО“ поможет сразу встать на правиль-ный путь. Да и опытные разработчики найдут здесь для себя немало полезного».

— Томас Дафф, Duffbert’s Random Musings

«Вместо изложения материала в стиле традиционных учебников „Программируем для iPhone и iPad“ предлагает читателю живую, увлекательную и даже приятную методику обуче-ния программированию для iOS. Материал подобран умело и качественно: в книге рас-сматриваются многие ключевые технологии, включая Core Data, и даже такие важные аспекты, как проектирование интерфейса. И где еще можно прочитать, как UIWebView и UITextField беседуют у камина?»

— Шон Мерфи, проектировщик и разработчик приложений для iOS

Page 3: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

О других книгах серии Head First

«Книга „Программируем для iPhone и iPad“ объясняет принципы разработки приложений iOS с самого начала. Основные изменения по сравнению с первым изданием относятся к iOS 4, Xcode 4 и написанием приложений для iPad. Благодаря пошаговым описаниям с визуаль-ным стилем изложения материала эта книга становится отличным средством изучения программирования для iPhone и iPad во всех аспектах, от простейших до нетривиальных».

— Рич Розен, программист и соавтор книги Mac OS X for Unix Geeks

«Главное достоинство книги — простые, пошаговые описания. Она не пытается научить читателя всему сразу, а знакомит его с построением приложений для iOS на уровне друже-ственного, разговорного общения. Эта книга идеально подходит для людей, которые уже умеют программировать и хотят поскорее заняться построением приложений для iOS».

— Эрик Шеферд, владелец Syndicomm

«Книга „Программируем для iPhone и iPad“ написана специально для того, чтобы научить вас создавать приложения, изучать и использовать технологии iOS без предварительного опыта работы со средствами разработки на Macintosh».

— Джо Хек, основатель Seattle Xcoders

«Эта книга способна вывести из себя! Некоторым из нас пришлось изучать программиро-вание для iOS „классическим“ способом, а теперь вдруг выясняется, что все мучения были излишними».

— Майк Моррисон, основатель Stalefish Labs

«Книга „Программируем для iPhone и iPad“ продолжает нарастающую тенденцию к изложе-нию сложных технических тем на доступном уровне, но без ущерба для глубины и мас-штабности материала. Программирование для iOS в любом случае придется покорять, как горную вершину, но с книгой „Программируем для iPhone и iPad“ вы будете взбираться на эту „гору“ по заранее проложенным маршрутам, со страховкой и в компании опытного проводника! Я рекомендую эту книгу каждому, кто хочет быстро освоить программирова-ние для этой непростой и интересной платформы».

— Крис Пилсор, snogboggin.com

Page 4: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 5: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 6: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

ББК 32.973.2-018.1 УДК 004.434 Б41

Бенедетти Р., Крэнли Р. Б41 Изучаем работу с jQuery. — СПб.: Питер, 2012. — 528 с.: ил.

ISBN 978-5-459-00896-8

Хотите добавить интерактивности своему интернет-сайту? Узнайте, как jQuery позволит вам создать целый набор скриптов, используя всего несколько строчек кода! С помощью этого издания вы максимально быстро научитесь ра-ботать с jQuery — этой удивительной библиотекой JavaScript, использование которой сегодня стало необходимостью для разработки современных веб-сайтов и RIA-приложений. jQuery помогает легко получать доступ к любому эле-менту DOM, обращаться к атрибутам и содержимому элементов DOM, а также предоставляет богатые возможности по взаимодействию с AJAX. Особенностью данного издания является уникальный способ подачи материала, выделяющий серию «Head First» издательства O’Reilly в ряду множества скучных книг, посвященных программированию.

ББК 32.973.2-018.1 УДК 004.434

Права на издание получены по соглашению с O’Reilly. Все права защищены. Никакая часть данной книги не может быть воспроиз-ведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.

ISBN 978-1449393212 англ. © Authorized Russian translation of the English edition of titled Head First jQuery, 1st Edition (ISBN 9781449393212) © 2011, Ryan Benedetti and Ronan Cranley. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to

publish and sell the same. ISBN 978-5-459-00896-8 © Перевод на русский язык ООО Издательство «Питер», 2012

© Издание на русском языке, оформление ООО Издательство «Питер», 2012

Page 7: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Мы посвящаем эту книгу магистрам JavaScript: Джону Рези-гу (создателю и ведущему разработчику библиотеки jQuery), Дугласу Крокфорду, Дэвиду Фленагану и Брэндону Эйку.

Моим трем феям: Джози, Вин и Шонне.

— Райан

Кейтлин и Боно: спасибо вам за все!

— Ронан

Page 8: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

8

об авторах

Райан Бенедетти — обладатель степени ма-гистра искусств в области писательского ма-стерства (университет Монтаны); работает веб-разработчиком и специалистом по мульти-медиа в университете Портленда. В своей рабо-те использует jQuery, Flash, ActionScript, Adobe Creative Suite, Liferay Portal, Apache Jakarta Velocity и Drupal.

В течение семи лет Райан руководил факуль-тетом информационных и компьютерных технологий в колледже Салиш-Кутени. До этого он работал редактором и специалистом по информационным системам в программе исследования рек, ручьев и сильно увлажнен-ных земель в школе лесоводства при универ-ситете Монтаны.

Стихотворения Райана опубликованы в по-этических сборниках. В свободное время занимается рисованием, играет на губной гармошке и практикует сидячую медитацию. Свои лучшие моменты жизни Райан прово-дит с дочерью, сыном и своей любимой Шон-ной в Портленде, штат Орегон. Также любит выбираться на природу со своими четверо-ногими друзьями: Роки, Манчем, Фестером и Тазом.

Ронан Крэнли работал в университете Порт-ленда с момента своего переезда из Дубли-на, Ирландия, в 2006 году — с должности веб-разработчика до старшего веб-разработчика/инженера-системотехника и заместителя дирек-тора по веб-системам и администрированию.

Ронан получил степень бакалавра в области компьютерных технологий в технологиче-ском институте Дублина, который он закон-чил с отличием в 2003 году. Во время учебы, а также на своей предыдущей должности в ESB International (Дублин) и текущей в университе-те Портленда Ронан работал над разнообраз-ными проектами на языках PHP, VB.NET, C# и Java. Среди этих проектов была клиентская система GIS, система управления контентом, система календарного планирования и гибрид-ное приложение jQuery/Google Maps.

Помимо проектирования и построения веб-приложений, Ронан также занимается адми-нистрированием баз данных SQL Server. Сво-бодное время Ронан проводит на футбольном поле, на площадке для гольфа, а также со сво-ей женой Кейтлин и английским бульдогом Боно, наслаждаясь всей полнотой жизни на северо-западном Тихоокеанском побережье.

Райан

РонанРонан

Page 9: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

9

содержание

Содержание (сводка)

Содержание (настоящее)

Ваш мозг думает о jQuery. Вы сидите за книгой и пытаетесь что-нибудь выучить, но ваш мозг считает, что вся эта писанина не нужна. Ваш мозг говорит: «Выгляни в окно! На свете есть более важные вещи, например сноуборд». Как заставить мозг думать, что ваша жизнь действительно зависит от jQuery?

Введение

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

Метапознание: наука о мышлении 27

Что можете сделать ВЫ, чтобы заставть свой мозгповиноваться 29

Примите к сведению 30

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

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

Введение 23

1 Знакомство с jQuery. Живые веб-страницы 37

2 Селекторы и методы. Хватай и действуй 69

3 События и функции jQuery. Страница в центре событий 109

4 Операции со структурой страниц в jQuery. Изменение DOM 157

5 jQuery эффекты и анимация. Плавно и изящно 209

6 jQuery и JavaScript. Люк jQuery, я твой отец! 247

7 Пользовательские функции для пользовательских эффектов. Что будем делать? 285

8 jQuery и Ajax. Пожалуйста, передайте данные 321

9 Данные JSON. Клиент встречается с сервером 355

10 jQuery UI. Переработка форм 399

11 jQuery и APIs. Объекты, сплошные объекты 439

I Остатки. Десять важных вещей (которые мы не рассмотрели) 473

II Настройка среды разработки. Готовимся к великим свершениям 487

Page 10: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

10

содержание

1 Живые веб-страницыВы хотите расширить возможности своих веб-страниц. Вы уже знаете HTML и CSS и хотите включить в свой арсенал сценарное программирование, но вам совершенно не хочется про-водить свою жизнь за написанием сотен строк кода. Нужна библио-тека сценариев, которая позволяла бы изменять веб-страницы «на ходу». И если на то пошло, как насчет поддержки AJAX и PHP? И чтобы в трех строках кода можно было сделать то, для чего в большинстве клиентских языков потребуется 15? Пустые мечты, скажете вы... А вот и нет! На помощь приходит jQuery.

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

$( )

jQuery( )

$( )

Новые возможности веб-страниц 38

HTML и CSS — это, конечно, хорошо, но… 39…без сценариев не обойтись 40

Знакомьтесь: jQuery (и JavaScript)! 41

Что происходит в браузере 43

Скрытая структура веб-страницы 44

jQuery упрощает работу с DOM 45

Функция jQuery (и ее сокращенная запись) 48

jQuery выбирает элементы по тем же правилам,что и CSS 49

Селекторы: стили и сценарии 50

Использование селекторов jQuery 51

jQuery в переводе 52

Ваш первый проект с jQuery 56

Подготовка файлов HTML и CSS 60

Поехали… 62Эффекты изменения прозрачности 63

И это все? 64

Пушистые Друзья спасены 66

Ваш инструментарий jQuery 67Пользователь щелкнул мышью Эй, браузер, обнови для

меня этот элемент img!

Page 11: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

11

содержание

2 Хватай и действуйjQuery помогает выбирать элементы веб-страниц и выпол-нять с ними всевозможные операции. В этой главе более подроб-но рассмотрены селекторы и методы jQuery. Селекторы jQuery выбирают элементы страницы, а методы выполняют операции с этими элементами. Библиотека jQuery, словно сборник магических заклинаний, позволяет изменять окружающую реальность. Вы можете заставить изображение исчезнуть или появиться из ниоткуда или же выбрать фрагмент текста и анимировать изменение его размера шрифта... Но довольно разгово-ров — хватайте элементы веб-страниц и действуйте!

Селекторы и методы

Подруга просит тебя помочь оформить сайт 70

Что требуется от проекта? 71

Начинаем с div 73

Событие click под увеличительным стеклом 76

Включение метода click в страницу 79

Выражайтесь точнее 81

Назначение классов 82

Идентификаторы элементов 83

Три уровня веб-страницы 86

Возвращаемся к списку 89

Выделение памяти для хранения данных 90

Конкатенация и слияние данных 91

Возвращаемся к программному коду… 92Вставка сообщения 93

Все отлично работает, но… 95Дайте мне $(this) 97

Использование $(this) 98

Скатертью дорога! Метод remove 100

Селекторы потомков 101

Ваша очередь прыгать от радости 107

Ваш инструментарий jQuery 108

Page 12: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

12

содержание

Ни минуты покоя 110

В словах бухгалтера есть резон... 111

Реакция на события 113

За кулисами слушателя событий 114

Связывание события 115

Срабатывание событий 116

Удаление событий 120

Перебор элементов 124

Структура проекта 130

Использование функций 134

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

Анонимная функция 136

Именованные функции как обработчики событий 137

Передача переменных функциям 140

Функция также может возвращать значения 141

Условные конструкции и принятие решений 143

Но это еще не все 147

Методы могут изменять CSS 149

Добавление события hover 151

Еще немного... 153

Ваш инструментарий jQuery 156

3 Страница в центре событийjQuery позволяет легко включить в любую веб-страницу поддержку действий и интерактивности. В этой главе вы узнаете, как заставить вашу страницу реагировать на действия, выполняемые пользователем. Возможность выполнения кода в ответ на действия пользователя поднимает сайт на совершенно новый уровень. Также в этой главе рассказано, как создавать функ-ции, чтобы однократно написанный код можно было использовать много раз.

События и функции jQuery

Слушатель события, связанный с элементом, «слышит» событие click и сообщает интерпрета-тору JavaScript...

...Интерпретатор JavaScript

выполняет функцию, задан-

ную в слушателе события.

Page 13: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

13

содержание

4 Изменение DOM

Операции со структурой страниц в jQuery

Завершение загрузки страницы еще не означает, что ее структура останется неизменной. В главе 1 было показано, как в процессе загрузки страницы строится модель DOM, опреде-ляющая ее структуру. В этой главе вы научитесь перемещаться по дереву DOM, работать с иерархией элементов и отношениями «родитель/потомок» для изменения структуры страницы «на ходу» средствами jQuery.

Интерактивное меню 158

Вегетарианцы, вперед! 159

Назначение классов элементам 164

Создание кнопок 167

Что дальше? 169

Перемещение по дереву DOM 174

Методы обхода дерева DOM 175

Сцепленные вызовы методов 176

В переменных также могут храниться элементы 183

И снова знак $... 184

Хранение данных в массивах 185

Хранение элементов в массиве 186

Изменение элементов методом replaceWith 188

Чем поможет replaceWith? 189

Не торопитесь с replaceWith 191

Когда replaceWith не подходит 192

Вставка HTML в DOM 193

Фильтры (часть 1) 195

Фильтры (часть 2) 196

Верните гамбургер на место 199

И где же мясо? 200

Массив отсоединенных элементов 201

Метод each и перебор массивов 202

Вроде… все? 205

Ваш инструментарий jQuery 208

Вашэлемент

Page 14: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

14

содержание

5 Плавно и изящно

jQuery эффекты и анимация

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

Новый заказ 210

Проект «Собери монстра» 211

Макет и позиционирование 212

Еще немного структуры и стиля 215

Проработка интерфейса 216

Эффект молнии 221

Как jQuery выполняет анимацию элементов? 222

Эффекты изменения прозрачности изменяютсвойство CSS opacity 223

Эффект скольжения 224

Как работают эффекты изменения прозрачности 226

Комбинированные эффекты 227

Задержка при использовании эффектов 228

Включение функций в сценарий 231

Самодельные эффекты и animate 233

Что можно анимировать? 234

Метод animate изменяет стилевое оформление 236

Откуда и куда? 239

Абсолютные и относительные перемещения элементов 240

Включение вызовов animate в сценарный код 243

Смотри, мама! Работает без Flash! 245

Ваш инструментарий jQuery 246

Page 15: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

15

содержание

6 Люк jQuery, я твой отец!

jQuery и JavaScript

Силы jQuery небезграничны. Хотя эта библиотека написана на JavaScript, к сожалению, она позволяет сделать не все, на что способен язык-родитель. В этой главе мы рассмотрим некоторые возможности JavaScript, необходимые для создания современных сайтов, и их применение в jQuery для создания пользовательских списков и объектов, а также средства перебора списков и объектов, которые существенно упростят вашу работу.

1 2 3 4 2 3 4... ... ... ... ... ... ...

Программируем блэкджек 248

Объекты и хранение данных 250

Построение собственных объектов 251

Создание объектов для повторного использования 252

Взаимодействие с объектами 253

Подготовка страницы 254

И снова массивы 257

Обращение к ячейкам массива 258

Добавление и обновление ячеек 259

Повторение операций 261

Поиск иголки в стоге сена 264

Пора принимать решение... снова! 271

Операторы сравнения и логические операторы 272

Стирание информации в jQuery 278

Чтобы было красивее 282

Ваш инструментарий jQuery и JavaScript 284

Page 16: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

16

содержание

7 Что будем делать?

Пользовательские функции для пользовательских эффектов

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

Надвигается буря 286

Мы создали монстра... функцию-монстра 287

Управление временными эффектами 288

Обработка событий браузера в onblur и onfocus 291

Методы работы с таймером определяют времявыполнения функций 295

Пишем функции stopLightning и goLightning 298

Новая просьба 306

Случайные монстры 307

Мы уже знаем текущую позицию... 308

...и функция getRandom уже готова 308

Перемещение относительно текущей позиции 312

«Собери монстра-2» — настоящий хит! 319

Ваш инструментарий jQuery 320

Конечно, зубы — главное,что есть у монстра,

но остаться без лицакак-то не хочется!

Page 17: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

17

содержание

8 Пожалуйста, передайте данные

jQuery и Ajax

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

li

$(“li”).find(“ul”)

Ежегодные Ежегодные соревнованиясоревнования

В этом году марафон проходит на Мауи,

заказывайте билеты заблаговременно!

Бегом к современным технологиям 322

Прошлогодняя страница 323

Даешь динамику! 326

СТАРЫЕ и НОВЫЕ веб-технологии 327

Структура Ajax 328

Что такое Ajax? 328

Фактор «X» 329

Получение данных методом ajax 334

Разбор данных XML 336

Планирование событий 340

Самоактивизируемые функции 341

Сервер нам поможет 344

Который час? 345

Отключение планирования событий на странице 350

Ваш инструментарий jQuery/Ajax 354

Page 18: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

18

содержание

9 Клиент встречается с сервером

Данные JSON

Возможность чтения данных из файлов XML безусловно по-лезна, но иногда этого оказывается недостаточно. Другой, более эффективный формат передачи данных JSON (JavaScript Object Notation) упрощает получение данных со стороны сервера. Кроме того, данные JSON проще генерируются и читаются, чем данные XML. При помощи jQuery, PHP и SQL можно создать базу данных для хранения информации, которая позднее читается с использованием JSON и отображается на экра-не средствами jQuery. Вот она, истинная мощь веб-приложений!

В отделе маркетинга MegaCorp никто не знает XML 356

Ошибки в XML 357

Ввод данных на веб-странице 358

Что делать с данными 361

Форматирование данных перед отправкой 362

Отправка данных серверу 363

Хранение информации в базе данных MySQL 365

Создание базы данных для информации об участниках 366

Строение команды insert 368

Использование PHP для работы с данными 371

Обработка данных POST на сервере 372

Подключение к базе данных из кода PHP 373

Чтение из базы данных 375

Доступ к данным в коде PHP 377

На помощь приходит JSON! 380

jQuery + JSON = потрясающе 381

Несколько правил PHP... 382

Правила PHP (еще немного)... 383

Форматирование вывода средствами PHP 384

Работа с данными в объекте JSON 391

Проверка и чистка данных в PHP 394

Ваш инструментарий jQuery/Ajax/PHP/MySQL 397

Page 19: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

19

содержание

Переработка форм

jQuery UI

10 Пользователи и их данные — жизнь и смерть веб-приложений. Ввод данных пользователем — серьезная задача, которая может отнять много времени у веб-разработчика. Вы уже видели, как jQuery упрощает построение веб-приложений, использующих Ajax, PHP и MySQL. Теперь давайте посмотрим, как jQuery упрощает построение пользовательского интерфейса форм для ввода данных пользователем. Заодно вы узнаете много полезного о jQuery UI — официальной библиотеке пользователь-ского интерфейса для jQuery.

??

Cryptozoologists.org нуждается в переработке 400

Новая форма HTML 401

jQuery UI экономит время и силы 404

Содержимое пакета jQuery UI 408

Построение календаря 409

Незаметное вмешательство jQuery UI 410

Изменение параметров виджета 411

Стильные кнопки 414

Ограничение ввода числовых данных 418

Создание цвета по трем составляющим 427

Функция refreshSwatch 430

И последнее... 434

Ваш инструментарий jQuery 438

Тоже мне, удружили!Теперь не будетни минуты покоя!

Page 20: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

20

содержание

Объекты, сплошные объекты

jQuery и APIs

11 Даже самый талантливый разработчик не сможет сделать всю работу в одиночку... Мы уже видели, как включать расширения jQuery (такие как jQuery UI или вкладки) для повышения уровня функцио-нальности приложения. Чтобы поднять наше приложение на следующий уровень — использовать Интернет и информацию из крупных информа-ционных систем типа Google, Twitter или Yahoo! — понадобится... нечто большее. Эти компании предоставляют вам программные интерфейсы (API, Application Programming Interface). В этой главе мы рассмотрим ос-новы работы с API, а также используем очень распространенный сервис Google Maps API.

Привет! Я маркер. Раз познакомиться. Мы ведь уже встречались на картах

Google, не так ли?

Где видели снежного человека? 440

Google Maps API 442

В API используются объекты 443

Включение карт Google в страницу 445

Чтение данных JSON средствами SQL и PHP 448

Точки на карте — маркеры 452

Список задач для отображения нескольких существ 456

Прослушивание событий карты 466

Получилось!!! 470

Ваш инструментарий jQuery API 471

Пара слов на прощание… 472

Page 21: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

21

содержание

I Десять важных вещей(которые мы не рассмотрели)Даже после всего сказанного многое осталось «за кадром». Существует масса других полезных возможностей jQuery и JavaScript, которые нам не удалось вместить в книгу. Было бы неправильно даже не упомянуть о них. Мы хотим, чтобы вы были готовы к любому аспек-ту jQuery, с которым вы можете столкнуться во время самостоятель-ных исследований.

Остатки

1. Все, что есть в библиотеке jQuery 474

2. jQuery CDN 477

3. Пространство имен jQuery: метод noConflict 478

4. Отладка кода jQuery 479

5. Расширенная анимация и очереди 480

6. Проверка форм 481

7. Эффекты jQuery UI 482

8. Создание собственных модулей расширения jQuery 483

9. Замыкания 484

10. Шаблоны 485

Page 22: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

содержание

II Готовимся к великим свершениямВам понадобится среда, в которой вы сможете потренировать свои навыки PHP, но так, чтобы ваши данные не стали уязви-мыми для внешних атак. Разработку приложений PHP всегда жела-тельно начинать с безопасной среды и только потом открывать доступ для внешнего мира. В этом приложении приведены инструкции по установке веб-сервера, MySQL и PHP. После их выполнения в вашем распоряжении появится безопасная среда для работы и экспериментов.

Настройка среды разработки

Создание среды разработки PHP 488

Что у вас уже есть? 488

У вас установлен веб-сервер? 489

У вас установлена поддержка PHP? Какая версия? 489

У вас установлен MySQL? Какая версия? 490

Начнем с веб-сервера 491

Установка Apache... завершение 492

Установка PHP 492

Действия по установке PHP 493

Действия по установке PHP... завершение 494

Установка MySQL 494

Установка MySQL в системе Windows 495

Включение поддержки PHP в Mac OS X 500

Установка MySQL в Mac OS X 500

Page 23: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Как пользоваться этой книгой

ВведениеНе могу поверить, что они включили такое

в книгу о jQuery!

В этом разделе мы ответим на насущный вопрос:

«Так почему они включили ТАКОЕ в книгу о jQuery?»

Вам нравится?Книга стоит денег, которые вы заплатили за нее, и станет лучшим подарком.

Page 24: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

24 введение

как пользоваться этой книгой

1

2

3

Äëÿ êîãî íàïèñàíà ýòà êíèãà?

Êîìó ýòà êíèãà íå ïîäîéäåò?

Если вы ответите «да» на все следующие вопросы:

Если вы ответите «да» на любой из следующих вопросов:

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

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

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

У вас уже имеется опыт веб-разработки или веб-дизайна?

Вы хотите изучить, запомнить, понять и научиться применять важнейшие концепции jQuery и JavaScript, чтобы сделать ваши страницы более интерактивными и интересными?

Вы предпочитаете оживленную беседу сухим, скуч-ным академическим лекциям?

1

2

3

Вы абсолютно не разбираетесь в веб-программировании?

Вы уже занимаетесь разработкой веб-приложений, и ищете справочник по jQuery?

Вы боитесь попробовать что-нибудь новое? Скорее пойдете к зубному врачу, чем наденете по-лосатое с клетчатым? Считаете, что техническая книга со снежным человеком серьезной быть не может?

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

Обратитесь к книге «Изучаем HTML, XHTML и CSS» (Питер, 2012) — в ней приведен отличный вводный курс веб-программирования. А потом воз-вращайтесь к нам!

Page 25: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 25

введение

Замечательно. Еще 487 сухих,

скучных страниц.

Ìû çíàåì, î ÷åì âû äóìàåòå

È ìû çíàåì, î ÷åì äóìàåò âàø ìîçã

«Разве серьезные книги по программированию такие?»

«И почему здесь столько рисунков?»

«Можно ли так чему-нибудь научиться?»

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

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

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

Активизируются нейроны. Вспыхивают эмоции. Происходят химические реакции. И тогда ваш мозг понимает...

Конечно, это важно! Не забывать!А теперь представьте, что вы находитесь дома или в библио-теке, в теплом, уютном месте, где тигры не водятся. Вы учи-тесь — готовитесь к экзамену. Или пытаетесь освоить слож-ную техническую тему, на которую вам выделили неделю... максимум десять дней.

И тут возникает проблема: ваш мозг пытается оказать вам услугу. Он старается сделать так, чтобы на эту очевид-но несущественную информацию не тратились драгоцен-ные ресурсы. Их лучше потратить на что-нибудь важное. На тигров, например. Или на то, что к огню лучше не при-касаться. Или что на лыжах не стоит кататься в футболке и шортах.

Нет простого способа сказать своему мозгу: «Послушай, мозг, я тебе, конечно, благодарен, но какой бы скучной ни была эта книга и пусть мой датчик эмоций сейчас на нуле, я хочу запомнить то, что здесь написано».

Ваш мозг считает, что ЭТО важно.

Ваш мозг пола-

гает, что ЭТО

можно не запо-

минать.

Page 26: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

26 введение

как пользоваться этой книгойкак пользоваться этой я книгой

Как мы что-то узнаем? Сначала нужно это «что-то» понять, а потом не забыть. Затол-

кать в голову побольше фактов недостаточно. Согласно новейшим исследованиям в об-

ласти когнитивистики, нейробиологии и психологии обучения, для усвоения матери-

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

ваш мозг работать.

Основные принципы серии Head First:

Наглядность. Графика запоминается гораздо луч-

ше, чем обычный текст, и значительно повышает

эффективность восприятия информации (до

89 % по данным исследований). Кроме того,

материал становится более понятным. Текст

размещается на рисунках, к которым он отно-

сится, а не под ними или на соседней странице.

Разговорный стиль изложения. Недавние исследо-

вания показали, что при разговорном стиле изложения матери-

ала (вместо формальных лекций) улучшение результатов на

итоговом тестировании достигает 40 %. Рассказывайте историю, вместо того чтобы

читать лекцию. Не относитесь к себе слишком серьезно. Что привлечет ваше внимание:

занимательная беседа за столом или лекция?

Активное участие читателя. Пока вы не начнете напрягать извилины, в вашей

голове ничего не произойдет. Читатель должен быть заинтересован в результате; он

должен решать задачи, формулировать выводы и овладевать новыми знаниями. А для

этого необходимы упражнения и каверзные вопросы, в решении которых задействова-

ны оба полушария мозга и разные чувства.

Привлечение (и сохранение) внимания читателя.

Ситуация, знакомая каждому: «Я очень хочу изучить это, но за-

сыпаю на первой странице». Мозг обращает внимание на интересное, странное,

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

быть скучным. Интересное узнается намного быстрее.

Обращение к эмоциям. Известно, что наша способность запоминать

в значительной мере зависит от эмоционального сопереживания. Мы запо-

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

Нет, сентименты здесь ни при чем: речь идет о таких эмоциях, как удивление,

любопытство, интерес, и чувстве «Да я крут!» при решении задачи, которую

окружающие считают сложной, — или когда вы понимаете, что разбираетесь

в теме лучше, чем всезнайка-Боб из технического отдела.

Эта книга для тех, кто хочет учиться.

$( )

jQuery( )

$( ) Вы можете замедлить дви-

жение и заставить картинку

исчезнуть?

ПриСитусыпаприбыт

Обв мНл

Ежегодные Ежегодные

соревнованиясоревнования

В этом году марафон

проходит на Мауи,

заказывайте билеты

заблаговременно!

Page 27: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 27

введение

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

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

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

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

Ìåòàïîçíàíèå: íàóêà î ìûøëåíèè

Как бы теперь заставить мой мозг все это запомнить...

Как же УБЕДИТЬ мозг, что программирование для jQuery не менее важно, чем тигр?Есть способ медленный и скучный, а есть быстрый и эффек-тивный. Первый основан на тупом повторении. Всем известно, что даже самую скучную информацию можно запомнить, если повторять ее снова и снова. При достаточном количестве повторений ваш мозг прикиды-вает: «Вроде бы несущественно, но раз одно и то же повторяется столько раз... Ладно, уговорил».

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

Разговорный стиль тоже важен: обычно люди проявляют больше внимания, когда они участвуют в разговоре, так как им приходится следить за ходом бе-седы и высказывать свое мнение. Причем мозг совершенно не интересует, что вы «разговариваете» с книгой! С другой стороны, если текст сух и фор-мален, то мозг чувствует то же, что чувствуете вы на скучной лекции в роли пассивного участника. Его клонит в сон.

Но рисунки и разговорный стиль — это только начало.

Page 28: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

28 введение

как пользоваться этой книгой

Âîò ÷òî ñäåëàëè ÌÛ:Мы использовали рисунки, потому что мозг лучше приспособлен для воспри-ятия графики, чем текста. С точки зрения мозга рисунок действительно стоит тысячи слов. А когда текст комбинируется с графикой, мы внедряем текст пря-мо в рисунки, потому что мозг при этом работает эффективнее.

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

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

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

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

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

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

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

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

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

Беседа у камина

Тест-драйв

Page 29: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 29

введение

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

1

2

3

4

5 Пейте воду. И побольше.Мозг лучше всего работает в условиях высо-кой влажности. Дегидратация (которая может наступить еще до того, как вы почувствуете жажду) снижает когнитивные функции.

Не читайте другие книги после этойперед сном.

6

7

9 Творите!Попробуйте применить новые знания в своей повседневной работе. Просто сделайте хоть что-нибудь, чтобы приобрести практический опыт за рамками упражнений. Все, что для этого нужно — это карандаш и подходящая задача... задача, в которой изучаемые методы и инструменты могут принести пользу.

Прислушивайтесь к своему мозгу.

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

Следите за тем, когда ваш мозг начинает уста-вать. Если вы начинаете поверхностно вос-принимать материал или забываете только что прочитанное — пора сделать перерыв. С определенного момента попытки «затол-кать» в мозг дополнительную информацию не только не ускоряют обучение, а скорее идут во вред ему.

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

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

Читайте врезки.Это значит: читайте все. Врезки — часть основно-го материала! Не пропускайте их.

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

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

Вырежьте и прикрепите на холодильник.

×òî ìîæåòå ñäåëàòü ÂÛ, ÷òîáû

çàñòàâèòü ñâîé ìîçã ïîâèíîâàòüñÿ

Page 30: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

30 введение

как пользоваться этой книгой

Ïðèìèòå ê ñâåäåíèþ

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

Предполагается, что вы уже знаете HTML и CSS.

Если вы еще не знаете HTML и CSS, то для начала найдите книгу Head First HTML with CSS & XHTML. В этой книге мы напомним вам, как работают селекторы CSS, но не ждите, что здесь будет рассказано все, что необходимо знать о CSS.

От вас не требуется знание JavaScript.

Знаем, знаем — кто-то с нами не согласится, но мы считаем, что jQuery можно изучать без пред-варительного изучения JavaScript. Конечно, для написания кода jQuery необходимо знать не-которые концепции JavaScript, но мы представим их одновременно с описанием кода jQuery. Мы глубоко и искренне верим в девиз jQuery: Меньше Кода, Больше Дела.

Мы рекомендуем использовать разные браузеры.

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

Эта книга не о браузерных средствах разработчика…

...но предполагается, что вы умеете пользоваться ими. Мы настоятельно рекомендуем исполь-зовать браузер Google Chrome, который можно загрузить по адресу http://www.google.com/chrome. Информация о браузерах и их средствах разработчика представлена на следующих сайтах:

Google Chrome http://code.google.com/chrome/devtools/docs/overview.html

Firefox Firebug http://getfirebug.com/wiki/index.php/FAQ

Safari http://www.apple.com/safari/features.html#developer

Internet Explorer 8 http://msdn.microsoft.com/en-us/library/dd565628(v=vs.85).aspx

Internet Explorer 9 http://msdn.microsoft.com/en-us/ie/aa740478

Opera Dragonfly http://www.opera.com/dragonfly/

Мы надеемся, что вы не ограничитесь чтением книги.

Лучшее, что можно сделать при изучении чего-то нового — присоединиться к сообществу изучаю-щих. Мы считаем, что сообщество jQuery — одно из лучших, самых активных сообществ в мире со-временных технологий. Дополнительная информация приводится на сайте http://www.jquery.com.

Page 31: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 31

введение

Упражнения ОБЯЗАТЕЛЬНЫ.

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

Повторение применяется намеренно.

У книг этой серии есть одна принципиальная особенность: мы хотим, чтобы вы действительно хорошо усвоили материал. И чтобы вы запомнили все, что узнали. Большинство справочников не ставит своей целью успешное запоминание, но это не справочник, а учебник, поэтому некоторые концепции излагаются в книге по не-скольку раз.

Упражнения «Мозговой штурм» не имеют ответов.

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

Òðåáîâàíèÿ ê ïðîãðàììíîìó îáåñïå÷åíèþ

Для написания кода jQuery вам понадобится текстовый редактор, браузер, веб-сервер (он может работать локально на вашем персональном настольном компьюте-ре) и библиотека jQuery.

В системе Windows мы рекомендуем использовать редакторы PSPad, TextPad и EditPlus (хотя при желании можно работать и в Блокноте). Для Mac можно вос-пользоваться редактором TextWrangler. В системе Linux имеется много встроенных текстовых редакторов; вероятно, пользователям этой системы не нужно рассказы-вать про них.

Для разработки веб-приложений понадобится веб-сервер. Для последних глав книги (9, 10 и 11) вам стоит обратиться к приложению с описанием установки PHP, MySQL и веб-сервера (Apache или IIS) и выполнить приведенные там инструкции. Сделайте это прямо сейчас. Нет, серьезно — откройте приложение, выполните инструкции и возвращайтесь, когда все необходимое будет установлено.

Вам также понадобится браузер и средства разработчика (см. предыдущую страни-цу). Научитесь пользоваться консолью JavaScript в Google Chrome Dev Tools — вы не пожалеете о потраченном времени. Считайте, что это домашнее задание, которое вы должны выполнить самостоятельно.

Наконец, вам понадобится сама библиотека jQuery; о том, где ее взять, рассказано на следующей странице.

Page 32: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

32 введение

как пользоваться этой книгой

Çàãðóçêà jQuery

Пора браться за дело. Откройте сайт jQuery и загрузите ко-пию библиотеки, которую вы будете использовать в книге.

Шаг 1:

Шаг 2:

Запустите браузер и введите в нем адрес http://www.jquery.com.

Шаг 3:

Найдите раздел «Grab the Latest Version» и установите флажок рядом со строкой «Production».

Шаг 4:

Щелкните на кнопке «Download jQuery».

Открывается следующая страница, которая выглядит примерно так.

Сохраните ее в папке с именем scripts.

scripts

jquery-1.6.2.min.js

Рабочая версия оптимизирована для максимальной скорости выпол-нения на веб-сервере. Версия для разработчика предназначена для изучения внутреннего строения библиотеки jQuery. Если вы любите «покопаться во внутренностях» библиотек, загрузите обе версии.

Чем рабочая (Production) версия отличается от версии для разработчика (Development)?

Page 33: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 33

введение

Ñòðóêòóðà ïàïîê

В папке каждой главы присутствует пап-ка begin, в которой хранится начальный вариант кода этой главы.

После загрузки и распаковки кода с сайта Head First Labs (http://www.headfirstlabs.com/books/hfjquery) вы увидите, что для каждой главы книги в структуре кода создана отдельная папка. Для примера возь-мем папку ch03:

Папка end в папке каждой главы содержит итоговую версию кода этой главы. Используйте папку end только для того, чтобы сверить ее с вашей версией кода.

В папке styles находится файл my_style.css, в кото-ром хранится начальная версия стилей для этой главы.

В папке scripts находится

только что загруженная

вами библиотека jQuery.

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

Файл my_scripts.js содержит

код, который вы напишете

в этой книге. Постарайтесь

не заглядывать в него без

крайней необходимости.

Файл index.htmlсодержит размет-ку веб-приложений.

Page 34: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

34 введение

Íàó÷íûå ðåäàêòîðû

группа рецензирования

Пол БарриЛиндси Скурас

Джим Доран работает программистом в университете Джона Хопкинса в Балтиморе, штат Мэриленд. Он преподает JavaScript в муниципальном колледже округа Балтимор, а также выступает с лекциями о jQuery на веб-конференциях. В остальное время Джим ведет блог по адресу http://jimdoran.net и катается на роликовых коньках.

Билл Мителски был научным редактором нескольких книг из серии Head First. В настоящее время он работает программистом в крупном национальном медицинском центре в окрестностях Чикаго, где занимается биостатистическими исследованиями. Когда он не занят сбором и обработкой данных, его можно найти на поле для гольфа, где он гоняет маленький белый мячик.

Линдси Скурас — юрист из Вашингтона. Она самостоятельно научилась программировать в свободное время по книгам серии Head First. Ее другие увлечения — чтение, рукоделие, посещение музеев и про-ведение свободного времени с мужем и собаками.

Пол Барри читает лекции по компьютерным дисциплинам в технологическом институте Карлоу (Ир-ландия). Пол пишет для журнала Linux Journal, а также опубликовал несколько технических книг. Он является автором Head First Python и соавтором Head First Programming. В свободное время Пол консуль-тирует малые и средние предприятия, а также начинающие фирмы по ведению программных проектов.

Билл Мителски

Джим Доран

Page 35: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 35

введение

Áëàãîäàðíîñòè

Кортни НэшККортни Н

Лу Барр

Группе O’Reilly:

Спасибо Лу Барр за быструю, превосходную и просто волшебную работу. Благода-ря ей эта книга приняла свою окончательную форму и стала такой красивой.

Спасибо Лори Петрики за то, что она дала «зеленый свет» нашему проекту. Рай-ан сохранил теплые воспоминания о программе обучения авторов HF в Бостоне и никогда не забудет классной, семейной атмосферы, которую здесь создала Лори.

Спасибо Карен Шанер. Спасибо всем специалистам из группы технического ре-цензирования.

Райан никогда не забудет тот день, когда он обнаружил первую книгу серии Head First в книжном магазине. Спасибо Кэти Сьерра и Берту Бэйтсу за то, что они по-могли расшевелить нейроны умников по всему миру. Спасибо Берту за то, что он слушал наши жалобы, помогал избавиться от нашей ограниченности и сохранять объективный взгляд на мир ; )

Спасибо Тиму О’Рейли за лучшее издательство технической литературы!

Друзьям и семье Ронана:

Я особенно благодарен своей жене Кейтлин — ее фантастические способности к дизайну и знание всех тонкостей Adobe позволили этой книге воплотиться в жизни. А еще спасибо за ее терпение — без тебя у меня бы ничего не получилось! Огромное спасибо всем, кто поддерживал нас в этой работе: моим соседям, моим коллегам по университету Портленда, моей футбольной команде и товарищам по гольфу. Спасибо моей ирландской семье за под-держку и помощь. И самое главное — спасибо Райану Бенедетти, моему замечательному со-автору, коллеге и другу. Спасибо, что вывел меня в этот путь. Это было незабываемо!

Нашему редактору:

Спасибо (и наши поздравления!) Кортни Нэш, которая заставила нас выложиться «на полную» в работе над книгой. Она справи-лась с огромным потоком сообщений, вопросов, жалоб и наших капризов. Она постоянно была рядом с нами и доверяла нам — а мы, естественно, доверяли ей.

Друзьям и семье Райана:

Спасибо моей дочери Джози, моему сыну Винни и моей невесте Шонне — они верили в меня и ежедневно поддерживали в работе над книгой. Ti amo, i miei tre miracoli. Я люблю вас всех, вы мои три чуда!

Спасибо маме и папе; моему брату Джеффу; моим племянницам Клэр и Квинн. Спасибо моим коллегам и группе WAS из университета Портленда — а именно Дженни Уолш, Джейкобу Кани-пароли и «вторниковой» технической группе (сами знаете, о ком я). Спасибо Кейтлин Пирс-Крэнли за ее выдающиеся навыки дизайна. Спасибо моему приятелю «ирландскому ниндзя» (также известному как Ронан Крэнли) за его мастерство программирования jQuery, JavaScript и PHP; его чувство юмора и невероятную трудовую дисциплину в работе над книгой.

Page 36: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 37: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Может, здесь найдется что-нибудь для улучшения

интерактивности моихвеб-страниц...

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

Живые веб-страницы

Вы хотите расширить возможности своих веб-страниц. Вы уже знаете HTML и CSS и хотите включить в свой арсенал сценарное програм-мирование, но вам совершенно не хочется проводить свою жизнь за написа-нием сотен строк кода. Нужна библиотека сценариев, которая позволяла бы изменять веб-страницы «на ходу». И если на то пошло, как насчет поддержки AJAX и PHP? И чтобы в трех строках кода можно было сделать то, для чего в большинстве клиентских языков потребуется 15? Пустые мечты, скажете вы... А вот и нет! На помощь приходит jQuery.

Page 38: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

38 глава 1

страницы в движении

Íîâûå âîçìîæíîñòè âåá-ñòðàíèö

Вы уже умеете строить замечательные веб-страницы из чистого, синтаксически правильного кода HTML и CSS. Но статические веб-страницы сегодня никому не нужны — пользователи требуют динамики, анимации, интерактивности и современных эффектов.

Клиентам нравится дизайн моих веб-страниц, но они

требуют большей интерактив-ности. У нашей компании такой скучный сайт... Мы

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

Хотите управлять своими веб-страницами и сделать их более удобными

для посетителей? Отметьте все нужные пункты в следующем списке.

Динамическое включение элементов в веб-страницу без ее полной перезагрузки.

Изменение элементов меню при наведении на них указателя мыши.

Оповещение пользователя о незаполненных полях формы.

Поддержка движения и переходов в тексте и графике.

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

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

Page 39: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 39

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

Когда пользователь вводит веб-адрес в адресной строке, браузер запрашива-ет веб-страницу у сервера.

1

Сервер находит запрашива-емый файл (или файлы) и отправляет его браузеру.

2

Браузер отображает страницу HTML на основа-нии файла, полученного от сервера.

3

HTML è CSS — ýòî, êîíå÷íî, õîðîøî, íî…

index.htmlБраузер загружает страницу и отображает ее для пользователя.

Старые добрые технологии HTML и CSS определяют структуру и стилевое оформ-ление веб-страницы. Готовая страница прекрасно отображается в браузере, но она остается статической.

А если понадобится изменить ее внешний вид, что-то добавить или удалить? При-ходится либо идти на немыслимые выкрутасы с CSS, либо просто загружать новую страницу. Оба варианта оставляют желать лучшего. Почему? Да потому что HTML и CSS предназначены для управления внешним видом страницы.

Веб-сервер

Мне, пожалуйста, файл index.html.

Вот, держи.

index.html

Page 40: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

40 глава 1

действуй по сценарию

…áåç ñöåíàðèåâ íå îáîéòèñü

Чтобы изменять веб-страницы «на ходу», без полной переза-грузки, необходимо отдать соответствующую команду браузе-ру. Как это сделать? При помощи тега HTML < script>.

index.html

<script>

Тег <script> сообщает брау-зеру, что он должен выпол-нить некоторые действия.

Тег <script> включа-

ется в файл HTML.

Ага, вижу тег <script>... Слушаю и повинуюсь.

</script>Браузер, будь другом,

выполни для меня пару операций.

Но как объяснить браузеру, что он должен сделать? Это

как-то непривычно...

Хороший вопрос. Напомним, что HTML — язык разметки, который определяет структуру документа.А каскадные таблицы стилей (CSS) опреде-ляют внешний вид и расположение этих элементов. Таким образом, в коде HTML и CSS можно описать, как веб-страница долж-на строиться и отображаться, но добавить новое поведение в нем не удастся. Для этого вам понадобится язык сценариев. Для этого вам понадобится jQuery.

Page 41: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 41

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

jQuery — библиотека

JavaScript, предназначенная

для изменения документов

веб-страниц «на ходу».

Çíàêîìüòåñü: jQuery (è JavaScript)!

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

Чтобы передать инструкции интерпретатору, необходимо знать JavaScript. Не беспокойтесь! jQuery вам в этом поможет. jQuery — библиотека JavaScript, предназначенная для изменения доку-ментов веб-страниц «на ходу». Рассмотрим при-мер использования jQuery.

Интерпретатор JavaScript отслежива-

ет («прослушивает»)

события, происходящие

со страницей, — такие

как щелчок мышью.

Интерпретатор JavaScript тоже мо-жет отдавать брау-зеру команды.

Эй, браузер, обнови для меня этот элемент img!

Пользователь щелкнул мышью!

<script> $(document).ready(function(){ Когда документ веб-страницы будет готов,

выполнить следующие действия. $("button").click(function(){ $("h1").hide("slow");

$("h2").show("fast"); $("img").slideUp(); }); }); </script>

Возьми в руку карандаш Следующий сценарий динамически изменяет веб-страницу. Прочитайте каждую строку

и  попробуйте предположить, что она делает, руководствуясь своими знаниями HTML и

CSS. Затем запишите краткое описание каждой строки справа. Если в чем-то не уверены  —

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

Page 42: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

42 глава 1

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

Хороший вопрос. Чудеса какие-то, верно?Давайте взглянем на веб-страницу с точки зрения браузера. Итак, как же jQuery может изменять страницу из браузера?

Следующий сценарий динамически изменяет веб-страницу. Прочитайте каждую строку

и попробуйте предположить, что она делает, руководствуясь своими знаниями HTML и CSS.

Затем запишите краткое описание каждой строки справа. Если в чем-то не уверены  —

попытайтесь угадать, это абсолютно нормально. Ниже приведено наше решение.

<script> $(document).ready(function(){ Когда документ веб-страницы будет готов,

выполнить следующие действия. $("button").click(function(){ При щелчке на любой кнопке сделать следую-

щее: $("h1").hide("slow"); Все элементы h1 медленно исчезают со стра-

ницы. $("h2").show("fast"); Все элементы h2 медленно появляются на

странице. $("img").slideUp(); Все элементы img скользят вверх и исчезают. }); Конец функции click.}); Конец функции ready.</script>

Но если я не обновляю страницу, как браузер узнает, что элемент нужно

скрыть или переместить вверх?

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

Page 43: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 43

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

×òî ïðîèñõîäèò â áðàóçåðå

Пора разобраться, что же в действительности происходит в браузере при отображении веб-страницы. Ваш браузер использует модель HTML DOM (Document Object Model) для преобразования простой разметки HTML и кода CSS в полноценную страницу с текстом, графикой, видеороликами и прочим замечательным контентом, который мы с таким удовольствием просматриваем.

index.html

Ядро визуализации браузера анализирует HTML и CSS для построения «документа» на базе HTML DOM (Document Object Model).

2

Браузер загружает файл HTML,полученный от сервера.

1

Браузер отображает построенную страни-цу в окне просмотра браузера.

3

Интерпретатор JS обращается к структу-ре DOM для внесения изменений в веб-страницу без ее перезагрузки.

4

index.html Версия страницы в формате DOM

Окно просмотра (viewport) — глав-ное окно браузера.

Все это происходит внутри браузера.

Интерпретатор JavaScript

Версия страницы в формате DOM

Page 44: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

44 глава 1

строение DOM

Долгие годы структура DOM помогала HTML, CSS и JavaScript эффективно работать в сочетании друг с другом. DOM образует стандартный «скелет» страницы, который используется всеми современными браузерами для повы-шения эффективности просмотра. Структуру DOM часто сравнивают с дере-вом: у нее тоже есть корень и ветви, завершающиеся узлами. Или, если хотите, DOM напоминает рентгеновский снимок построенной страницы.

Ñêðûòàÿ ñòðóêòóðà âåá-ñòðàíèöû

На рентгеновском снимке врач видит скрытую структуру человеческого тела. Аналогичным образом DOM пред-ставляет скрытую структуру веб-страницы. Но в отличие от рентгенограмм JavaScript и jQuery могут использовать DOM для изменения структуры страницы.

html

head body

Тег <html> — «корень»

документа.

title div ul

«DOM Bones»

«Dem Bones»

li li li p img

Кроме узлов элемен-

тов, в структуру

DOM также входят

текстовые узлы.

Части DOM назы-ваются «узлами».

Внутренние узлы иерархии <html> называются «уз-лами элементов».

«Toe bone connected to your foot bone»

«Foot bone connected to your ankle bone»

«Ankle bone connected to yourleg bone»

Page 45: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 45

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

На первый взгляд может показаться, что операции с DOM слишком сложны, но, к счастью, использование jQuery сильно упрощает их. Не забудьте: опе-рации jQuery тоже выполняются из кода JavaScript, но в куда более удобном виде. Предположим, вы хотите изменить код HTML, содержащийся в един-ственном элементе абзаца на странице.

Одно из главных преимуществ jQuery заключается в том, что библиотека позволяет работать с DOM, почти ничего не зная об этой структуре. Всю «черную работу» вы-полняет код библиотеки. В этой книге вы научитесь использовать JavaScript в соче-тании с jQuery. В главе 6 отношения между jQuery и JavaScript будут рассмотрены бо-лее подробно, а заодно вы повысите свою квалификацию в области JavaScript. А до этого момента все операции с DOM будут выполняться средствами jQuery.

jQuery óïðîùàåò ðàáîòó ñ DOM

document.getElementsByTagName("p")[0].innerHTML = "Change the page.";

for (i = 0; i <= 4; i++){ document.getElementsByTagName("p")[i].innerHTML="Change the page";}

$("p").html("Change the page.");

 îáû÷íîì êîäå JavaScript  jQuery

В jQuery используется «ме-

ханизм селекторов»; таким

образом, для получения эле-

ментов можно использовать

селекторы, как это делается

в CSS.

Операция выполняется

с основным документом.Получить эле-мент абзаца.

Заменить код HTML этого элемента значением в круглых скобках.

Получить все элементы с име-нем тега «p».

Выбрать нуле-вой элемент. Записать в код HTML этого элемента...

...это значение.

А сейчас пришло время опробовать jQuery и DOM в действии...

Или допустим, вы хотите изменить код HTML в пяти элементах абзацев нашей страницы:

$("p").html("Change the page.");

В цикле перебираем элементы,

которые требуется изменить.

Так как в jQuery использу-ются селекторы CSS, эта операция выполняется так же, как и предыдущая.

Получить теку-щий элемент.

Page 46: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

46 глава 1

готовый код

<!DOCTYPE html><html><head> <title>jQuery goes to DOM-ville</title><style> #change_me { position: absolute; top: 100px; left: 400px; font: 24px arial;}

#move_up #move_down #color #disappear { padding: 5px;}</style><script src="scripts/jquery-1.6.2.min.js"></script></head><body> <button id="move_up">Move Up</button> <button id="move_down">Move Down</button> <button id="color">Change Color</button> <button id="disappear">Disappear/Re-appear</button>

<div id="change_me">Make Me Do Stuff!</div> <script> $(document).ready(function() { $("#move_up").click( function() { $("#change_me").animate({top:30},200); });//end move_up $("#move_down").click( function() { $("#change_me").animate({top:500},2000); });//end move_down $("#color").click( function() { $("#change_me").css("color", "purple"); });//end color $("#disappear").click( function() { $("#change_me").toggle("slow"); });//end disappear });//end doc ready </script></body></html>

Введите следующий код в текстовом редакторе. Сохраните его, откройте в браузере и проверьте, как работает каждая кнопка. (И раз уж на то пошло, просмотрите код и попробуйте разо-браться, как он работает...)

index.html

Готово к употреблению

Page 47: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 47

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

Манипуляции jQuery со страницей выглядят довольно впечатляюще, верно? Важ-но помнить, что при нажатии кнопок исходный код HTML и CSS остается неиз-менным. Как же jQuery творит все эти чудеса? Взгляните на схему.

Êàê ýòî ðàáîòàåò?

Интерпретатор JavaScript не изменяет ис-

ходные файлы HTML и CSS. Он вносит изме-

нения в представление страницы в формате

DOM, хранящееся в памяти браузера.

Обнаружено нажатие кнопки.

Пользователь нажимает кнопку.1

Интерпретатор JavaScript

Интерпретатор JavaScript об-наруживает событие щелчка и запускает функцию, связанную с этим событием.

2

Интерпретатор JavaScript изменяет представление страницы в структуре DOM.

3

Пользователь ви-дит, как элемент перемещается вверх по странице.

4

Версия страницы в формате DOM

Это вы видите в браузере

Понятно — просто скажи, что

нужно сделать.

Засценой

Переместить элемент вверх.

Page 48: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

48 глава 1

функции jquery

Если разместить здесь селектор CSS, то jQuery вернет набор элементов, соответствующих этому селектору.Это самый распространенный вари-ант использования функции.

$( )

А для чего нужны знаки $ в коде?

jQuery( )

Ôóíêöèÿ jQuery (è åå ñîêðàùåííàÿ çàïèñü)

Знак доллара со скобками — это сокращенная запись функ-ции jQuery. Мы используем ее вместо записи «jQuery()», когда хотим обозначить функцию jQuery (ее также назы-вают «оберткой»).

Знак доллара ($) показывает, сколько денег вы сможете за-рабатывать со своими новыми навыками jQuery... Шутка — однако знак $ играет очень важную роль в мире jQuery.

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

$( )

Функция jQuery возвраща-

ет элементы, определяе-

мые условиями в круглых

скобках.

Сокращенная запись для jQuery. Вместо шести символов, образующих имя «jQuery», до-статочно ввести всего один символ.

Если в скобках заклю-чена строка HTML, то вы сможете добав-лять элементы DOM в страницу «на ходу».

На этот вариант пока не обращай-те внимания. Он будет рассмотрен в следующих главах.

Page 49: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 49

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

jQuery âûáèðàåò ýëåìåíòû ïî òåì æå ïðàâèëàì, ÷òî è CSS

Вы уже знаете о jQuery больше, чем может показаться на первый взгляд. Для выбора элементов в jQuery используются селекторы — те же, кото-рые вы использовали в CSS. Если вы подзабыли, как работают селекто-ры CSS, краткая сводка поможет вам освежить память.

Это селектор элементов (он же — селектор тегов). Он выбирает все элементы h1 в документе HTML.

h1 { text-align: left;}

.my_class { position: absolute;}

Все это пра-вила CSS. Селектор классов позволяет

выбрать сгруппированные элементы.

Это свойство CSS… …а это его значение.

Обозначение

класса CSS всег-

да начинается

с точки.

#my_id { color: #3300FF;}

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

Идентификатор CSS всегда начина-ется с «решетки» (знак #).

Page 50: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

50 глава 1

похоже на стили

Селектор элементов jQuery

Метод

Метод

$("h1").hide();

$(".my_class").slideUp();

$("#my_id").fadeOut();

Метод

В jQuery селекторы, используемые в CSS для стилевого оформления стра-ницы, используются для выполнения операций с элементами страницы.

Селектор элементов

h1 { text-align: left;}

.my_class{ position: absolute;}

#my_id { color: #3300FF;};

Селектор идентифи-каторов jQuery

Селектор классов

Селектор идентификаторов

Ñåëåêòîðû: ñòèëè è ñöåíàðèè

Ñåëåêòîð CSS Ñåëåêòîð jQuery

Скрывает все элементы h1 на странице.

Сдвигает вверх

все элементы,

входящие в класс

CSS my_class.

Команда «раство-ряет» элемент с идентификатором CSS my_id до тех пор, пока он не станет невидимым.

Селектор классов jQuery

Селекторы CSS выбирают элементы для при-

менения стилей; селекторы jQuery выбирают

элементы для добавления нового поведения.В главе 2 (и в остальных гла-вах) мы продолжим объединять селекторы с методами.

Page 51: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 51

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

img{ float:left; height:350px; text-align:center; border: solid #000 5px;}

Èñïîëüçîâàíèå ñåëåêòîðîâ jQuery

$("img")

img

" "

$( )

В этом примере ис-пользуется элемент img, но с таким же успехом его можно заменить другими элементами.

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

Селекторы передаются функции jQuery в сокращенной записи.

Библиотека jQuery за-прашивает элементы средствами JavaScript…

Эй, jQuery, ты можешь вернуть мне все элементы

img на странице?

Как подсказывает само название, библиотека jQuery предназначена для создания запросов (querying). Вы что-то описываете при помощи селектора, а интерпретатор JavaScript запраши-вает это «что-то» у структуры DOM. Если запрашиваемый элемент содержит вложенные элемен-ты, то jQuery вернет и их. Давайте рассмотрим селектор jQuery, чтобы вы лучше поняли, как он работает.

Это селектор. Для выбора элементов в библиотеке jQuery используется способ, знакомый нам по CSS. Селектор CSS

Интерпретатор JavaScript

Версия страницы в формате DOM

DOM, верни мне все элементы img

на странице.

…и возвращает их.

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

Держи.

Page 52: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

52 глава 1

вы говорите на jquery?

jQuery â ïåðåâîäå

$("button").click(function(){} });

...вы должны кое-что сделать для меня.

...когда поль-зователь щелкнет на вас...

Слушайте, элементы button...

Чтобы показать вам, как легко пользоваться jQuery, мы разберем несколько выражений на языке jQuery, которые могли бы вам при-годиться в ваших путешествиях по стране DOM.

$("p").hide;

...станьте невидимыми.

Каждая команда jQuery

должна завершаться

символом «точка с за-

пятой».

Эй, элементы p (т. е. элементы абзацев)...

$("#myTop").css({" background-color":"blue"});

…цвет фона… …синий.

…задай для себя правило CSS…

Элемент с идентифика-тором myTop…

<p> Poof!</p>

<div id="myTop”></div>

Текст, заключенный в элементах абза-

цев, исчезает.

Когда пользо-ватель щелкает на мне, я выполняю все коман-ды jQuery в фигурных

скобках.

>>>>>>>>>>>>>> PPPPPPPPPPPPPPPooooooooooooooooooooooooooofffffffffffffff!!!!!!!!!!!!!!

Окрашивается в синий цвет.

Page 53: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 53

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

СТАНЬ браузеромПредставьте себя на месте браузера. Обведите

кружком элементы HTML (справа), на которые

повлияет выполнение команды jQuery (слева).

<p>Проснувшись однажды утром после беспокойного сна. . .</p>

<p>Грегор Замза обнаружил, что он у себя в постели превратился в страшное насекомое.</p>

<p>Лежа на панцирнотвердой спине, он видел, стоило ему приподнять голову. . . </p>

$("p").hide();

Команда jQuery Элементы HTML

<p id="mytext">Проснувшись однажды утром после беспокойного сна. . .</p>

<p id="mytext">Грегор Замза обнаружил, что он у себя в постели превратился в страшное насекомое.</p>

<p>Лежа на панцирнотвердой спине, он видел, стоило ему приподнять голову. . . </p>

$("p#mytext").show();

<span class="Italian">Nel Mezzo del cammin di nostra vita</span>

<span class="English">In the middle of this road called "our life"</span> <span class="Italian">mi ritrovai per una selva oscura</span>

$("span.Italian").toggle();

Page 54: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

54 глава 1

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

СТАНЬ браузером — решениеПредставьте себя на месте браузера. Обведите

кружком элементы HTML (справа), на которые

повлияет выполнение команды jQuery (слева).

<p>Проснувшись однажды утром после беспокойного сна. . .</p>

<p>Грегор Замза обнаружил, что он у себя в постели превратился в страшное насекомое.</p>

<p>Лежа на панцирнотвердой спине, он видел, стоило ему приподнять голову. . . </p>

$("p").hide();

Команда jQuery Элементы HTML

<p id="mytext">Проснувшись однажды утром после беспокойного сна. . .</p>

<p id="mytext">Грегор Замза обнаружил, что он у себя в постели превратился в страшное насекомое.</p>

<p>Лежа на панцирнотвердой спине, он видел, стоило ему приподнять голову. . . </p>

$("p#mytext").show();

<span class="Italian">Nel Mezzo del cammin di nostra vita</span>

<span class="English">In the middle of this road called "our life"</span> <span class="Italian">mi ritrovai per una selva oscura</span>

$("span.Italian").toggle();

Page 55: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 55

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

В: Зачем было создавать jQuery, если библиотека только использует JavaScript? Разве одного JavaScript недостаточно?

О: JavaScript хорошо подходит для многих задач (и особенно для манипуляций с DOM), но решение получается довольно сложным. Низкоуровневые операции с DOM — дело в лучшем случае не-простое. Именно здесь на помощь приходит jQuery: библиотека скры-вает многие сложности, связанные с операциями с DOM, и благодаря ей самые впечатляющие эффекты создаются на удивление просто. (Библиотеку jQuery создал Джон Резиг; дополнительная инфор-мация об авторе доступна по по адресу http://ejohn.org/about).

В: Зачем нужны все эти знаки доллара?

О: Это просто сокращенное обозначение, чтобы вам не при-ходилось снова и снова вводить «jQuery»! Впрочем, если вы ра-

ботаете с другими языками на стороне клиента, полная запись jQuery() поможет избежать конфликтов имен.

В: Ранее вы уже упоминали о «клиентских сценариях». Что это такое?

О: Веб-разработчики часто назы-вают браузер клиентом, потому что он использует данные, полу-ченные с (веб-)сервера. Клиентский язык сценариев управляет работой браузера, тогда как серверные язы-ки отдают инструкции серверу. Эта тема более подробно рассматрива-ется в главах 8 и 9.

В: Как появилась модель DOM?

О : Хороший вопрос. Веб-дизайнеры и разработчики устали от несовместимости браузеров и решили, что им необходим стан-дартный механизм добавления по-ведения и взаимодействия со стра-ницами в любом браузере. Комитет W3C (World Wide Web Consortium)

разработал стандарт DOM при уча-стии многочисленных заинтересо-ванных групп. За дополнительной информацией обра щайтесь по адресу http://w3.org/dom.

В: Загрузка jQuery доступна в двух вариантах: рабочая вер-сия и версия для разработчи-ков. Чем они отличаются друг от друга?

О: Рабочая версия более компак-тна, из нее удалены избыточные символы и пробелы. Она оптими-зирована для достижения макси-мального быстродействия в ходе реальной эксплуатации, но в ней труднее разобраться. В версии для разработчиков расставлены удобные пробелы, она лучше чи-тается. Эта версия предназначена для программистов, которые хотят покопаться в коде jQuery с целью его изменения и даже расширения (раз уж это проект с открытым ис-ходным кодом!).

частоЗадаваемые

вопросы

Page 56: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

56 глава 1

jquery приходит на помощь

Âàø ïåðâûé ïðîåêò ñ jQuery

Вы только что поступили на должность веб-разработчика в Фонд спасения домашних пи-томцев. Группа маркетинга хочет запустить ежегодную кампанию по привлечению средств, в которой должна быть задействована переработанная версия прошлогодней веб-страницы «Поможем нашим пушистым друзьям». Вам выдали снимок экрана из прошлогодней кампании с подробными инструкциями по поводу того, что должна делать страница.

Джош из отдела марке-тинга требует улучшения интерактивности.

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

Прошлогоднюю страницу нужно доработать. Сейчас по-сетитель щелкает на кнопке, и на экране появляется временная картинка — но она не остается на странице. Мы хотим, чтобы при первом щелчке на кнопке изображение появлялось, а при

повторном — исчезало со страницы.

Когда посетитель Когда посетитель щелкает здесь . . .щелкает здесь . . .

. . . эта секция стано-. . . эта секция стано-вится видимой и уве-вится видимой и уве-личивается до размеров личивается до размеров изображения.изображения.

Примечание:Примечание:И все это должно происходить И все это должно происходить внутри страницы (то есть внутри страницы (то есть кнопка не должна открывать кнопка не должна открывать новую страницу HTML).новую страницу HTML).

Показать «пуши-стого друга»

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

постепенно?

А его начальнику нужны визуальные эффекты.

Page 57: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 57

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

a:link img, a:visited img {

display:none;

}

a:hover img, a:active img {

display:block;

}

a{

text-decoration:none;

color: #000;

}

<!DOCTYPE html><html> <head>

<title>Furry Friends Campaign: jQuery Proof-of-Concept</title>

<link rel="stylesheet" type="text/css" href="styles/my_style.css">

</head>

<body>

<div id="showfriend">

<a href="#">Our Furry Friends Need Your Help

<img src="images/furry_friend.jpg">

</a>

</div>

У якорного тега имеются состояния «hover» и «active», заданные в CSS.Пользователь наводит указатель мыши на ссылку — изображение появляется.

index.html

my_style.css

Возьми в руку карандашПрежде чем разбираться с тем, как включить в страницу функциональность

jQuery, стоит посмотреть, как выглядел код HTML и CSS предыдущей версии.

Ниже приведено содержимое файла из прошлогодней кампании. Найдите

элементы, которые, по вашему мнению, понадобятся вам в реализации.

Напишите рядом с каждым элементом, что необходимо сделать для выполнения

требований отдела маркетинга. Первое описание мы заполнили за вас.

Page 58: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

58 глава 1

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

Прежде чем разбираться с тем, как включить в страницу функциональность

jQuery, стоит посмотреть, как выглядел код HTML и CSS предыдущей версии.

Ниже приведено содержимое файла из прошлогодней кампании. Найдите

элементы, которые, по вашему мнению, понадобятся вам в реализации.

Напишите рядом с каждым элементом, что необходимо сделать для

выполнения требований отдела маркетинга. Не беспокойтесь, если ваши

ответы где-то отличаются от наших.

a:link img, a:visited img {

display:none;

}

a:hover img, a:active img {

display:block;

}

a{

text-decoration:none;

color: #000;

}

о

<!DOCTYPE html><html> <head>

<title>Furry Friends Campaign: jQuery Proof-of-Concept</title>

<link rel="stylesheet" type="text/css" href="styles/my_style.css">

</head>

<body>

<div id="showfriend">

<a href="#">Our Furry Friends Need Your Help

<img src="images/furry_friend.jpg">

</a>

</div>

У якорного тега имеются состоя-ния «hover» и «active», заданные в CSS. Пользователь наводит указатель мыши на ссылку — изображение появляется.

index.html

my_style.css

Изображение встроено в якорный тег. Оно не должно отображаться до тех пор, пока пользователь не щелкнет на ссылке якорного тега.

Этот селектор CSS задает свойству display вложенного изображения значение «none», чтобы оно оставалось скры-тым при загрузке страницы.

Когда пользователь наводит указатель мыши или щелкает на якорном теге, свойство display элемента img при-нимает значение «block». Изображение мгновенно появляется на экране.

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

Page 59: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 59

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

Преобразуем в область div с отслеживанием щелчков.

Изображение тоже оформ-ляется в виде области div, которая изначально нахо-дится в скрытом состоянии.

Мы присвоим этой области идентификатор picframe.

Можно, но сначала нужно подготовиться. Прежде чем использовать jQuery для реализации всех эффектов, которые желает видеть отдел марке-тинга, мы должны убедиться в том, что у jQuery есть все необходимое для работы. Как вы уже знаете, одна из главных задач jQuery — манипуляции с элементами HTML, поэтому нам понадобится хорошая структура. Для выбора элементов jQuery использует те же селек-торы, что и CSS; следовательно, нам также понадо-бятся хорошо определенные стили.

Âåðíåìñÿ ê òðåáîâàíèÿì

Размышляя о структуре, всегда полезно вернуться на шаг назад и понять, что же вы, собственно, пытаетесь построить. Отдел маркетинга хочет, чтобы изображе-ние опускалось и проявлялось при щелчке в области страницы «Show Me the Furry Friend of the Day». Какие изменения в HTML и CSS для этого нужно внести?

Пора браться за дело? Пишем код jQuery для всей нужной

функциональности?!

Page 60: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

60 глава 1

наводим порядок

<!DOCTYPE html><html><head> <title>Furry Friends Campaign</title> <link rel="stylesheet" type="text/css" href="styles/my_style.css"> </head> <body> <div id="clickMe">Show Me the Furry Friend of the Day</div> <div id="picframe"> <img src="images/furry_friend.jpg"> </div> <script src="scripts/jquery-1.6.2.min.js"></script> <script> $(document).ready(function(){ $("#clickMe").click(function() { }); }); </script> </body></html>

#clickMe { background: #D8B36E; padding: 20px; text-align: center; width: 205px; display: block; border: 2px solid #000;}

#picframe { background: #D8B36E; padding: 20px; width: 205px; display: none; border: 2px solid #000;}

Ïîäãîòîâêà ôàéëîâ HTML è CSS

Прежде чем браться за написание команд jQuery, следует подумать, какие изменения необходимо внести в файлы HTML и CSS. Откройте файлы jQuery главы 1 (если вы еще не загрузили их, обращайтесь к разделу «Как работать с книгой» во Введении). Найдите среди файлов главы 1 папку Begin. Включите в файлы код, выделенный ниже жирным шрифтом.

Этот фрагмент создает область div, отслежи-вающую щелчки мышью. Приме-ним к области стилевое оформ-ление в файле CSS, чтобы она по внешнему виду не отличалась от области div с идентификато-ром picframe.

Область div с идентифика-тором будет «скользить», открывая скры-тое изображе-ние.

Изображение furry_friend.jpg вложено в элемент picframe.

В селекторе picframe за-дается значение «display: none», чтобы картинка не отображалась при за-грузке страницы.

Этот фрагмент определяет

оформление области clickMe,

чтобы она не отличалась по

виду от области div с иденти-

фикатором picframe.

index.html

my_style.css

Задание!

Page 61: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 61

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

Итак, файлы HTML и CSS готовы. Пора повнимательнее присмотреться к коду, заключенному в теги <script>.

$(document).ready(function(){ $("#clickMe").click(function() {

});});

Точка отделяет селектор от метода.

Точка с запятой завершает конструкцию jQuery click.

Селектор идентификаторов для области clickMe.

Кнопка с идентификатором clickMe связывается с событием click. После этого кнопка начина-ет отслеживать щелчки мышью.

Код, который должен выполняться при нажатии кнопки, заключается в фигурные скобки («блок кода»).

DOM

…сделай кое-что

для меня.Эй, DOM…

…когда загрузка за-вершится и все будет готово к работе…

А эта точка с запятой завершает функцию jQuery ready.

При первой же возможности я начну выполнять код в фигур-

ных скобках!

В описании встречается много новых терминов.

Вскоре все эти события, методы и функции будут рассмотрены бо-лее подробно.

Код под увеличительным стеклом

Р А СС Л А Б Ь Т Е С Ь

Page 62: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

62 глава 1

добавление эффектов

Но наша страница пока еще не делает

ничего нового!

Верно. Разметка HTML и код CSS готовы; пора переходить к jQuery.Вместо мгновенного появления содержи-мое picframe должно разворачиваться и и постепенно проявляться на странице. К счастью, создатели jQuery предусмотре-ли эффекты для управления обоими визу-альными действиями. Эффектам jQuery в книге посвящена целая глава (глава 5), так что не старайтесь запомнить все сейчас. Начнем с эффекта скольжения.

$("div").slideToggle();

Метод slideUp изменяет свойство height элемента, пока оно не станет рав-ным 0, после чего скрывает элемент.

Действие slideToggle означа-ет: «Если элемент свер-нут, развернуть его, а если развернут — свернуть».

Ïîåõàëè…Начнем с эффекта скольжения, которого от нас требует начальник группы маркетин-га. Существуют три варианта реализации скольжения:

$("div").slideUp(); $("div").slideDown();

Метод slideDown изменя-ет свойство height эле-мента от 0 до значения, заданного в стиле CSS.

Page 63: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 63

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

$("img").fadeIn();

То, что должно проявляться на странице: в данном случае элемент img.

Проявляющийся элемент постепенно переходит из состояния полной прозрач-ности в состояние полной непрозрачности.

Ýôôåêòû èçìåíåíèÿ ïðîçðà÷íîñòè

Мы также хотим, чтобы изображение плавно переходило от полной прозрачности к полной видимости. И для этой категории эффектов в jQuery тоже существуют специальные методы. Имена этих мето-дов очень похожи на имена методов скольжения: FadeIn, FadeOut, FadeTo и FadeToggle. В нашем примере будет использоваться метод FadeIn, управляющий прозрачностью элементов HTML.

Как вы думаете, сколько команд jQuery потребуется для достижения нужного эффекта?

Запишите эти команды на листке бумаги. Если не уверены, хотя бы попробуйте сформулировать их суть словами; постепенно мы научим вас мыслить понятиями jQuery.

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

Мозговой

штурм

Page 64: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

64 глава 1

проще некуда

È ýòî âñå?

Невероятно, но для реализации этих эффектов доста-точно написать всего две строки кода jQuery. Теперь вы понимаете, почему у jQuery так много поклонников? Включите фрагмент, выделенный жирным шрифтом, в файл index.html — вот и все!

<!DOCTYPE html>

<html>

<head>

<title>Furry Friends Campaign</title>

<link rel="stylesheet" type="text/css" href="styles/my_style.css">

</head>

<body>

<div id="clickMe">Show me the Furry Friend of the Day</div>

<div id="picframe">

<img src="images/furry_friend.jpg">

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script>

$(document).ready(function(){

$("#clickMe").click(function() {

$("img").fadeIn(1000);

$("#picframe"). slideToggle("slow");

});

});

</script>

</body>

</html>

index.html

В jQuery важно выстроить эффекты в такой по-следовательности, чтобы они не мешали друг другу. Позднее мы еще вернемся к этой проблеме.

Значения в круглых скобках обеспечивают дополнитель-ную настройку эффектов. За подробностями обращай-тесь к главе 5.

Сначала к изобра-

жению применяется

эффект проявления.

Задание!

Page 65: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 65

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

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

Щелкните здесь.

Изображение постепенно проявляется и разворачива-ется на стра-нице.

Тест-драйв

Будьте осторожны!

Проверьте в разных браузерах.

Да, jQuery одинаково работает во всех браузерах — но это не означает, что во всех браузерах будут одинаково работать стили, определенные в файле CSS, или динамические стили, примененные к элемен-там страницы!

Page 66: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

66 глава 1

друг животных

Ïóøèñòûå Äðóçüÿ ñïàñåíû

Потрясающе смотрится — и ты справился так быстро!

Вы успешно справились с поставленной задачей — для этого было достаточно слегка изменить HTML и CSS и добавить пару строчек jQuery. Благодарные зверюшки вас не забудут…

Новая кампания приносит хоро-шие результаты. А это значит, что

у нас будет больше денег для спасения животных. Спасибо!

Page 67: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 67

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

Âàø èíñòðóìåíòàðèé jQuery

Глава 1 осталась позади, а ваш творческий инстру-ментарий расширился: в него добавилась основная функция jQuery, селекторы, события click и эффекты изменения прозрачности.

Функция jQuery

Используется для выбора элементов

страницы HTML, с которыми выпол-

няется операция.

Сокращенная запись $ избавляет

вас

от необходимости снова и снова на

-

бирать «jQuery».

Функции jQuery могут передаваться

селекторы, код HTML и даже объек-

ты JavaScript.

Эффекты изменения прозрач-

ности

К выбранному элементу можно при-

менять различные эффекты изменения

прозрачности с использованием мето-

дов FadeIn, FadeOut, FadeTo и FadeToggle.

Эффекты изменения прозрачности мо-

гут применяться к любым элементам:

тексту, графике и т. д.

Чтобы управлять скоростью изменения,

укажите время (в миллисекундах) в кру-

глых скобках в конце команды.

Селектор В jQuery, как и в CSS, для выбора элементов используются селек-торы.

Селекторы jQuery позволяют идентифицировать практически любые элементы HTML.

ГЛА

ВА 1

Page 68: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 69: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

2 Селекторы и методы

Хватай и действуй

jQuery помогает выбирать элементы веб-страниц и выполнять с ними всевозможные операции. В этой главе более подробно рассмотре-ны селекторы и методы jQuery. Селекторы jQuery выбирают элементы страницы, а методы выполняют операции с этими элементами. Библиотека jQuery, словно сборник магических заклинаний, позволяет изменять окружающую реальность. Вы можете заставить изображение исчезнуть или появиться из ниоткуда или же выбрать фрагмент текста и анимировать изменение размера его шрифта... Но довольно разговоров — хватайте элементы веб-страниц и действуйте!

Крошка, мои селекто-ры и методы способны

творить настоящие чудеса с элементами твоих

веб-страниц...

Page 70: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

70 глава 2

репутация растет

От: ЭмилиТема: Рекламная акция «Прыгаем от радости»!

Привет,

Читала у тебя в Твиттере, что ты занялся интерактивным веб-программированием.

Надеюсь, ты поможешь мне с реализацией некоторых интерактивных возможно-

стей для рекламной акции «Прыгаем от радости» на моем сайте. Я хочу, чтобы

посетители могли получить скидку перед оформлением своего заказа. Так поль-

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

(и хочется надеяться, будут больше покупать!).

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

ний в каждой. Когда пользователь щелкает в одной из областей, под изображе-

нием в этой области появляется сообщение «Размер вашей скидки:» и случайное

значение (от 5 до 10 процентов). Если пользователь щелкает снова, то старое

сообщение исчезает и появляется новое.

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

Сможешь помочь??

--Эмили

Ïîäðóãà ïðîñèò òåáÿ ïîìî÷ü îôîðìèòü ñàéò

Вы получили сообщение от своей подруги — профессионального фотогра-фа-портретиста. Она хочет провести рекламную акцию «Прыгаем от радо-сти» по получению скидок, и ей нужна ваша помощь в оформлении сайта.

Page 71: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 71

селекторы и методы

Список задач:

1.

2.

3.

4.

5.

×òî òðåáóåòñÿ îò ïðîåêòà?

Эмили — хороший фотограф, но ее запрос выглядит довольно туманно. Давайте повнимательнее присмотримся к сообщению и попробуем понять, чего же она, собственно, хочет. Прежде чем браться за написание кода jQuery, необходимо предельно четко выяснить, что же требуется от проекта (и от пользователя).

Выделите из сообщения список конкретных задач, которые долж-

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

в том, что наше веб-приложение отвечает потребностям заказчика.

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

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

Page 72: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

72 глава 2

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

Список задач:

1.

2.

3.

4.

5.

Выделите из сообщения список конкретных задач, которые должно

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

том, что наше веб-приложение отвечает потребностям заказчика.

Приводим наше решение.

Страница должна состоять из четырех областей. Каждая область содержит одно изображение.

Области должны реагировать на щелчки мышью.

Нам понадобится сообщение, состоящее из текста («Размер ва-шей скидки:») и случайного значения (от 5 до 10 процентов).

Когда пользователь щелкает в одной из областей, под изображе-нием в этой области должно появляться сообщение.

Если пользователь щелкает снова, то старое сообщение исчезает и появляется новое.

Отлично, с требованиями разобрались — давайте уже браться за jQuery!

Стоп! Не надо торопиться!Начинать работу над каждым проектом jQuery с про-работки требований — безусловно полезная при-вычка. Но прежде чем приступать к написанию кода jQuery, необходимо немного поработать над струк-турой и стилями. Мы сделали это в главе 1, а теперь перед переходом к jQuery придется потрудиться еще основательнее.

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

Page 73: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 73

селекторы и методы

Íà÷èíàåì ñ div

На странице должны находиться четыре области, реагирующие на щелчки мышью; начнем с создания этих областей. Самый полезный и универсальный элемент HTML для наших целей — тег <div>. Он очень хорошо подходит для определения струк-туры, так как является блочным элементом. Кроме того, внешний вид и поведение элементов div удобно определяется посредством применения стилей.

Тег для включения библиотеки jQuery, версия 1.6.2.Тег <div> с идентификатором header.Тег <div> с идентификатором main.Разместите в каждом из четырех элементов div, вложенных в main, от-дельное изображение (графические файлы можно загрузить по адресу www.thinkjquery.com/chapter02/images.zip).

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<h2>Jump for Joy Sale</h2>

</div>

<div><img src="images/jump1.jpg"/></div>

<div> </div>

<div> </div>

<div> </div>

</div>

<script > </script> </body>

</html>

index.html

div{

float:left;

height:245px;

text-align:left;

border: solid #000 3px;

}

#header{

width:100%;

border: 0px;

height:50px;

}

#main{

background-color: grey;

height: 500px;

}

my_style.css

УпражнениеОткройте свой любимый текстовый редактор и создайте необходимые файлы HTML и CSS. В приведенной ниже заготовке кода отсутствуют некоторые ключевые элементы. Включите в страницу пункты следующего списка, вычеркивая их по мере выполнения.

Page 74: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

74 глава 2

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

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<h2>Jump for Joy Sale</h2>

</div>

<div><img src="images/jump1.jpg"/></div>

<div> </div>

<div> </div>

<div> </div>

</div>

<script > </script> </body>

</html>

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

Тег для включения библиотеки jQuery, версия 1.6.2.Тег <div> с идентификатором header.Тег <div> с идентификатором main.Разместите в каждом из четырех элементов div, вложенных в main, отдельное изображение.

index.html

div{

float:left;

height:245px;

text-align:left;

border: solid #000 3px;

}

#header{

width:100%;

border: 0px;

height:50px;

}

#main{

background-color: grey;

height: 500px;

}

my_style.css

<div id="header">

<div id="main">

<img src="images/jump2.jpg">

<img src="images/jump3.jpg">

<img src="images/jump4.jpg">

<script src="scripts/jquery-1.6.2.min.js"></script>

Ваши файлы HTML и CSS

должны выглядеть так.

Элемент div с иден-

тификатором header

Элемент div c иден-тификатором main

Включение библиотеки jQuery.

Элементы div для изображений.

Page 75: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 75

селекторы и методы

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

Страница содержит четыре области с изображе-ниями. Как заставить эти области реагировать на щелчки мышью?

Элемент div с иденти-фикатором header.

Элемент div с идентифи-катором main содержит… …четыре элемента

div с изображениями.

Тест-драйв

Мозговой

штурм

Page 76: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

76 глава 2

событие click

$("p").click( function() {

alert("You rang?");

});

Как мы уже знаете, организовать отслеживание события click элементом в jQuery совсем не сложно.

При щелчке на элементе страницы происходит событие, которое может привести к выполнению функций. Позднее события и функции будут рассмотрены более подробно, а пока давайте посмотрим, как событие click работает с те-гами абзацев (или тегами <div>).

Ñîáûòèå click ïîä óâåëè÷èòåëüíûì ñòåêëîì

Элемент, с которым

связывается событие

click.

Функция объединяет опе-

рации, которые должны

выполняться при обнару-

жении события.

Здесь мы сообщаем интерпретатору JS, что элементы абзацев должны что-то делать, когда пользователь щелкает на них мышью.

Закрывающая фигур-ная скобка завершает «блок» кода.

Открывающая фигурная скобка начинает «блок» программного кода. Блок можно сравнить с абзацем текста: абзац состоит из строк текста, блок состоит из строк кода.

Так как функция заключена в кру-глые скобки, отно-сящиеся к событию click, она будет выполняться при выполнении поль-зователем щелчка мышью.

Команда alert помо-жет нам убедиться в том, что функция была вызвана правильно.

Текст, заключенный в кавычки, появится в новом окне.

Page 77: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 77

селекторы и методы

Сложите из магнитов фрагмент кода, после выполнения которого

элементы div станут реагировать на щелчки мышью. При щелч-

ке на div функция JavaScript alert должна выводить текст «You

clicked me». Мы уже расставили несколько магнитов по местам.

("click(

function()

</script>

$(document)

.ready(

{

{

");

").

function()

alert

});

div

$("

});

<script>

You clicked me.

Развлечения с магнитами

Page 78: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

78 глава 2

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

("

click( function()

</script>

$(document) .ready( {

{

");

").

function()

alert

});

div$("

});

<script>

"You clicked me.

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

Выводим окно сообщения,

чтобы проверить, как ра-

ботает функция click.

Закрываем click для элемента div.

Закрываем ready.

Закрываем тег <script>.

Связываем с тегами <div>

событие click.

Открываем тег

<script>.

Сложите из магнитов фрагмент кода, после выполнения которого

элементы div станут реагировать на щелчки мышью. При щелч-

ке на div функция JavaScript alert должна выводить текст «You

clicked me».

Развлечения с магнитами

Page 79: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 79

селекторы и методы

Используя код из решения с магнитами на предыдущей странице, включите этот сценарий в свой файл HTML. Не забудьте, что он должен быть заключен в тег <script>!

Âêëþ÷åíèå ìåòîäà click â ñòðàíèöó

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<div id="header">

<h2>Jump for Joy Sale</h2>

</div>

<div id="main">

<div><img src="images/jump1.jpg"/></div>

<div><img src="images/jump2.jpg"/></div>

<div><img src="images/jump3.jpg"/></div>

<div><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script > $(document).ready(function() {

$("div").click(function() {

alert("You clicked me.");

});//end click function

});//end doc ready

</script>

</body>

</html>

index.html

Функция alert от-крывает в браузере окно с сообщением. Мы будем использо-вать ее для проверки результатов вклю-чения в код новых переменных, функций и т. д.

Добавьте эти строки между те-гами <script>, чтобы

области div реаги-ровали на щелчки мышью.

Некоторые программисты добавляют

комментарии, которые помогают опреде-

лить, к какой команде относятся фигурные

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

комментариев — вопрос стиля программи-

рования, и выбор исключительно за вами.

Задание!

Page 80: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

80 глава 2

тест-драйв

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

Окно сообщения, добавленное

нами в программу. Как видите,

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

Интерпретатор JS дела-

ет в точности то, что

мы требуем. Он выбирает

все области div… …и связывает каждую область

с методом click.

$("div").click( );

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

Да, но сообщение появляется всегда, где бы я ни щелкала. Почему

так происходит?

Чтобы получить сообщение, необязательно даже щелкать на изо-бражениях. В структуре нашей страницы используются элементы div, вложенные в другие элементы div; при щелчке на них браузер думает, что вы щелкнули на обоих элементах, и вы можете полу-чить сразу два сообщения. Похоже, необходимо более конкретно объяснить jQuery, чего мы хотим…

Тест-драйв

Page 81: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 81

селекторы и методы

div

div div div div

Проблема в том, что мы слишком расплывчато сформулировали правило выбора элементов. Так как же отобрать четыре вложенных области div без вмещающего элемента div? Вспомните, о чем говорилось в главе 1: селек-торы jQuery используют классы и идентификаторы CSS. Вы всегда можете уточнить, с какими элементами должна выполняться операция, назначая этим элементам классы и идентификаторы.

Этот элемент div не должен

реагировать на щелчки мы-шью. Он используется только

для отображения информации.

Âûðàæàéòåñü òî÷íåå

Что лучше использовать для определения элементов div в на-шем примере — только классы CSS, только идентификаторы или их сочетание? Какой способ лучше подойдет и почему?

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

Мозговой

штурм

Page 82: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

82 глава 2

классы элементов

$(".nav").click( function(){

alert("You clicked me!");

});

В CSS классы используются для группировки элементов и назна-чения им общих стилевых атрибутов. Страница может содержать один или несколько элементов, относящихся к одному классу. В jQuery можно использовать селектор классов, чтобы действие методов jQuery распространялось на определенную группу элемен-тов. И в CSS, и в jQuery для обозначения классов используется сим-вол «.», поэтому присвоить класс элементу проще простого.

Íàçíà÷åíèå êëàññîâ

Селекторы клас-сов отбирают все элементы, входящие в заданный класс.

body

html

div

div class="nav" p id="my_blurb"div class="nav"

Древовидная структура DOM для веб-страницы.

Дерево DOM.

.nav { display: block; border: solid #00f 1px; width: 100%;}

Код CSS Код jQuery

Page 83: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 83

селекторы и методы

Èäåíòèôèêàòîðû ýëåìåíòîâ

Селектор идентификаторов предназначен для выбора одного конкретного элемента страницы. В jQuery, как и в CSS, селекторы идентификаторов обозначаются символом #. Они особенно хорошо подходят для максимально точного определения элемента стра-ницы, а также для определения элементов, заведомо существующих только в одном эк-земпляре (например, заголовка или завершителя страницы).

Класс

Однозначно определяет уникальный элемент страницы

Укажите, для каких целей могут использоваться классы и идентифи-каторы, сделав пометку в соответствующем столбце. Не забывайте, что класс и идентификатор иногда могут делать одно и то же!

Идентификатор

Определяет один или несколько элементов страницы

Может использоваться одним методом JavaScript

для кросс-браузерной идентификации элемента

Может использоваться в CSS для применения стилей

к элементам

Может многократно назначаться одному элементу

Селекторы идентификаторов опре-деляют один конкретный элемент.

$("#my_blurb").slideToggle("slow");#my_blurb { display: block; border: 0px; height: 50%;}

Код jQuery

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

Код CSS

Page 84: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

84 глава 2

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

В: Что такое блочный элемент?

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

В: Почему тег <script> размеща-ется в конце страницы перед те-гом </body>? Мне казалось, что он должен находиться в тегах <head> </head>?

О: Да, когда-то это считалось правильным (а кое-кто продолжает так считать). Однако

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

В: Для чего нужны окна сообще-ний JavaScript?

О: Окна сообщений не блещут красо-той, но приносят немалую пользу. По сути функция alert отображает простое окно с текстом, указанным в круглых скобках при ее вызове. Если вы хотите вывести строку текста, заключите ее в кавычки. Чтобы

вывести значение переменной, укажите имя переменной без кавычек. Значения переменных также можно объединять со строками при помощи знака +. Наверняка вы уже встречались с окнами сообщений, даже если не обращали на них особого внимания — например, когда забывали заполнить обязательное поле на форме. В нашем случае окно сообщения исполь-зуется в целях тестирования и отладки. Ко-нечно, существуют и более совершенные средства вывода отладочной информации; они будут представлены в следующих главах книги.

Укажите, для каких целей могут использоваться классы и идентифи-каторы, сделав пометку в соответствующем столбце. Не забывайте, что класс и идентификатор иногда могут делать одно и то же!

Однозначно определяет уникальный элемент страницы

Определяет один или несколько элементов страницы

Может использоваться одним методом JavaScript

для кросс-браузерной идентификации элемента

Может использоваться в CSS для применения стилей

к элементам

Может многократно назначаться одному элементу

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

решение

Класс Идентификатор

частоЗадаваемые

вопросы

Page 85: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 85

селекторы и методы

Áåñåäà ó êàìèíà: ñåëåêòîðû CSS è jQuery îáñóæäàþò ñâîè ðàçëè÷èÿ.

Ñåëåêòîð CSS:

Привет, Селектор jQuery. Хорошо, что ты здесь — так окружающие скорее поймут, что своим суще-ствованием ты обязан исключительно мне.

Да уж, стиля мне не занимать — но кто сказал, что я ничего не делаю? Я могу моментально изменить внешний вид многих объектов на странице.

И что же можешь сделать ты, чего не могу я?

Началось, технический жаргон... Что это значит «возвращаешь» элементы?

Но я тоже могу влиять на все выбранные элемен-ты — cкажем, назначить им всем розовый цвет фона. И не забывай, что вся твоя функциональ-ность обеспечивается моими механизмами.

Да, пожалуй, это впечатляет.

Ñåëåêòîð jQuery:

А, да, спасибо... Конечно, моя сила во многом обу-словлена твоими способностями к выбору эле-ментов. Однако я ориентируюсь на поведение, а не на стилевое оформление. Твое дело — про-стое украшение страницы, а благодаря мне вы-полняется серьезная работа.

Не спорю, польза от тебя есть. У тебя своя рабо-та — изменение внешнего вида элементов, а у меня своя — совершенно другая.

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

Допустим, кто-то использует меня для выбора всех элементов абзацев на странице. Я отбираю все абзацы и передаю их методу jQuery для даль-нейшей обработки.

Верно, твой механизм селекторов лежит в основе части моих возможностей, но другую часть пре-доставляет JavaScript. Не забудь о слове «запрос» (Query) в моем имени. Я запрашиваю у браузера элемент и передаю его методу jQuery, а метод за-ставляет этот элемент летать по странице или даже раствориться в воздухе.

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

Беседа у камина

Page 86: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

86 глава 2

три уровня

Òðè óðîâíÿ âåá-ñòðàíèöû

Стилевое оформление =

CSS

Структура = HTML

Сценарный код = jQuery (и JavaScript)

Классы и идентификаторы закладывают основу для трех уровней веб-страницы, рассмотрен-ных нами в главе 1: структуры, стилевого оформления и сценарного кода. Селекторы связывают эти уровни, позволяя им взаимодействовать друг с другом. HTML предоставляет «строитель-ный материал» (элементы, атрибуты и т. д.), или структуру веб-страницы. CSS предоставля-ет стилевое оформление, то есть описание представления и размещения этих элементов. JavaScript и jQuery предоставляют сценарный код, управляющий поведением (функциональ-ностью) этих элементов.

Допустим, элементу img, для которого должен выполняться метод slideUp, назначен класс slideshow:

<img class="slideshow" />

.slideshow{

float: left;

height: 100;

}

$(".slideshow").slideUp()

Элементу img назнача-ется класс slideshow.

Таблица стилей за-дает параметры представления и позиционирования класса slideshow с использованием селектора.

Сценарная библиотека jQuery выбирает элемент и задает его поведение.

Page 87: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 87

селекторы и методы

Измените структуру, стилевое оформление и сценарный код

страницы, чтобы на щелчки реагировали только четыре обла-

сти div. В файле CSS создайте класс CSS (с именем guess_box)

и примените его в тегах html и script. Кажется, один из эле-

ментов div также потерял свой атрибут id. Удастся ли вам опре-

делить отсутствующее значение и вернуть его на место?

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<div id="header">

<h2>Jump for Joy Sale</h2>

</div>

<div >

<div ><img src="images/jump1.jpg"/></div>

<div <img src="images/jump2.jpg"/></div>

<div ><img src="images/jump3.jpg"/></div>

<div ><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script>

$(document).ready(function() {

$(" ").click(function() {

alert("You clicked me.");

});

});

</script>

</body>

</html>

index.html

div{

float:left;

height:245px;

text-align:left;

border: solid #000 3px;

}

#header{

width:100%;

border: 0px;

height:50px;

}

#main{

background-color: grey;

height: 500px;

}

height 245px;

my_style.css

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

Page 88: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

88 глава 2

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

Здесь определяется

класс для четырех

областей div. Зна-

чение height соот-

ветствует высоте

используемых изо-

бражений, так что

вся графика сохра-

няет нормальное

выравнивание.

Всем элементам div, в которых будет скрываться код скид-

ки, назначается класс guess_box. Также измените селек-

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

в файл CSS. Атрибут id пропал у главного элемента div.

З

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<div id="header">

<h2>Jump for Joy Sale</h2>

</div>

<div >

<div ><img src="images/jump1.jpg"/></div>

<div ><img src="images/jump2.jpg"/></div>

<div ><img src="images/jump3.jpg"/></div>

<div ><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script>

$(document).ready(function() {

$(" ").click(function() {

alert("You clicked me.");

});

});

</script>

</body>

</html>

index.html

div{

float:left;

height:245px;

text-align:left;

border: solid #000 3px;

}

#header{

width:100%;

border: 0px;

height:50px;

}

#main{

background-color: grey;

height: 500px;

}

height 245px;

my_style.css

.guess_box

id="main"

class="guess_box"class="guess_box"

class="guess_box"

class="guess_box"

}

Метод click связыва-ется только с классом guess_box, а не со всеми элементами div.

.guess_box{

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

Page 89: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 89

селекторы и методы

Вернемся к списку задач и посмотрим, что же мы выполнили из пожеланий Эмили.

Области должны реагировать на щелчки мышью.

Страница должна состоять из четырех областей. Каждая об-ласть содержит одно изображение.

Нам понадобится сообщение, состоящее из текста («Размер вашей скидки:») и случайного значения (от 5 до 10 процентов).

Когда пользователь щелкает в одной из областей, под изобра-жением в этой области должно появляться сообщение.

Если пользователь щелкает снова, то старое сообщение исче-зает и появляется новое.

Âîçâðàùàåìñÿ ê ñïèñêó

Необходимо создать сообщение и где-то сохранить его для вывода. Как вы думаете, как это лучше сделать?

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

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

Мозговой

штурм

Page 90: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

90 глава 2

хранение данных

Âûäåëåíèå ïàìÿòè äëÿ õðàíåíèÿ äàííûõ

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

var pts = 250;

Ключевое слово var

объявляет переменную.

За ключевым словом var указывается имя переменной. Так значение переменной за-

дается в программном коде.

При объявлении переменной интерпретатор JavaScript выделяет блок памяти браузера, в котором будут храниться ваши данные.

pts

Переменной присваи-вается имя, по кото-рому вы будете позд-нее обращаться к ней в своем сценарии.

pts

=250

Значение, сохраня-емое в переменной, указывается после знака равенства.

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

Если вы захотите больше узнать о переменных JavaScript и мате-матических функциях, найдите книгу М. Моррисона «Изучаем JavaScript» (Питер, 2012)!

Page 91: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 91

селекторы и методы

var discount = Math.floor((Math.random()*5) + 5);

Следующий фрагмент кода JavaScript создает переменную с именем discount, в которой хранится случайное число от 5 до 10. Напишите код создания переменной discount_msg, содержащей текст сообщения и случайное число. Позаботьтесь о том, чтобы сообщение содержалось в элементе абзаца.

var msg = "High score: <strong>"+pts+"</strong>"

"High score: <strong>"

pts

"</strong>"

Символ «+» использу-ется для конкатенации (объединения) текста, чисел, переменных и т. д.

Теги HTML тоже могут храниться в переменных!

Êîíêàòåíàöèÿ è ñëèÿíèå äàííûõ

В разных сценариях jQuery нам придется сохранять разные типы данных: числа, текст, логические признаки «истина/ложь». Достаточно часто (особенно когда потребуется выводить разные сообщения для пользователей) разметка HTML будет смешиваться с другими данными. Как же переменные объединяются с другими значениями? Посред-ством конкатенации. Допустим, в вашей видеоигре переменная с именем pts использу-ется для хранения рекорда, и вы хотите вывести ее значение.

Нужно объединить три фрагмента:

Текст и фрагменты кода HTML заключа-ются в кавычки.

При обращении к пере-менной указывается ее имя без кавычек.

Получается следующее:

Упражнение

Page 92: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

92 глава 2

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

<script>

$(document).ready(function() {

$(".guess_box").click( function() {

var discount = Math.floor((Math.random()*5) + 5);

var discount_msg = "<p>Your Discount is "+ discount +"%</p>";

alert(discount);

});

});

</script>

index.html

Математические операции и функция random рассматри-ваются в главе 3.

Итак, теперь у нас есть переменная, в которой хранится объединенное сообщение о скидке. Остается лишь обно-вить фрагмент, заключенный в теги <script>.

Âîçâðàùàåìñÿ ê ïðîãðàììíîìó êîäó…

Мы передаем переменную discount функции alert, чтобы убедиться в том, что она содержит нужный текст.

Создаем новые переменные JavaScript.

var discount = Math.floor((Math.random()*5) + 5);

Следующий фрагмент кода JavaScript создает переменную с именем discount, в которой хранится случайное число от 5 до 10. Напишите код создания переменной discount_msg, содержащей текст сообщения и случайное число. Позаботьтесь о том, чтобы сообщение содержалось в элементе абзаца.

var discount_msg = "<p>Your Discount is "+ discount +"%</p>";

Задание!

Page 93: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 93

селекторы и методы

$("p").append(" <strong>Like me, for instance.</strong>");

Âñòàâêà ñîîáùåíèÿ

Сообщение готово, но как вывести его на странице под изображением, на котором был сделан щелчок? По сути, речь идет о вставке нового содержимого в страницу. В jQuery предусмотрено несколько способов вставки содержимого в существую-щие элементы. Самые полезные способы будут подробно рассмотрены в главе 4, а пока мы воспользуемся действием append.

jQuery lets me add stuff onto my web page without having to reload it. Like me, for instance.

Если выполнить эту команду в секции сценарного кода, то на странице появится текст, выделенный жирным шрифтом.

Эта команда jQuery приказывает интерпретатору JS присоединить

содержимое, заданное в круглых скобках, ко всем элементам абзацев.

Итоговый код HTML в модели DOM.

Используя то, что вы уже знаете о селекторах, а также только что описанный метод append, напишите код присоединения переменной discount к элементу guess_box.

<p>jQuery lets me add stuff onto my web pagewithout having to reload it.</p>

<p>jQuery lets me add stuff onto my web page without having to reload it.</p> <strong>Like me,for instance.</strong>

Упражнение

Page 94: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

94 глава 2

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

$(".guess_box").append(discount_msg);

Как видите, включить новое сообщение в веб-страницу совсем несложно!

append — метод jQuery. Методы

используются в jQuery для выпол-

нения различных операций.

частоЗадаваемые

вопросы

В: Существуют ли ограничения для имен классов?

О: Имя класса должно начинаться с символа под-черкивания (_), дефиса (-) или буквы латинского алфавита (a–z), за которыми может следовать любое количество дефисов, символов подчерки-вания, букв или цифр. Правда, есть еще правило: если первым символом является дефис, то вторым символом должна быть буква или символ под-черкивания, а имя должно содержать не менее двух символов.

В: Существуют ли ограничения для имен переменных?

О: Да! Имена переменных не могут начинаться с цифр. Кроме того, они не могут содержать знаки математических операторов (+ * - ^ / ! \), пробелы или знаки препинания. При этом допускается ис-пользование символов подчеркивания. Имена переменных не могут совпадать с ключевыми словами JavaScript (например, window, open, array, string, location), и в них учитыва-ется регистр символов.

В: Сколько классов можно назначить элементу?

О: Согласно стандартам, четко определенного максимума не существует, но в условиях реального использования ограничение составляет около 2000 классов на элемент.

В: Можно ли выбрать все элементы страницы?

О: Да! Для получения всех элементов достаточно передать jQuery селектор “*”.

В: Если я присваиваю элементам класс или идентификатор, не опреде-ляя для него стилевого оформления, повлияет ли это на их внешний вид в браузере?

О: Нет, в браузерах не существует оформления по умолчанию для классов или идентификаторов. Некоторые браузеры используют несколько иную процедуру обработки таких элементов, но наличие класса или идентификатора, к которому не приме-нено оформление CSS, не отразится на внешнем виде элементов.

Page 95: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 95

селекторы и методы

Âñå îòëè÷íî ðàáîòàåò, íî…Переменная discount генерирует случайное число, а сообщение присоединяется к стра-нице так, как и ожидалось, но мы сталкиваемся с неожиданным побочным эффектом: ин-формация о скидке выводится во всех областях div. Это не совсем то, чего мы добивались. Что же пошло не так?

<script> $(document).ready(function() { $(".guess_box").click( function() { var discount = Math.floor((Math.random()*5) + 5); var discount_msg = "<p>Your Discount is "+discount+"%</p>"; alert(discount_msg); $(".guess_box").append(discount_msg); }); });</script>

Селектор работает на уровне класса,

так что операция распространяется на

все элементы div, принадлежащие классу.

Здесь элемент связывается с методом click, чтобы все элементы класса guess_box ре-

агировали на щелчки мышью.

Сообщение о скидке должно выводиться только в той отдельной области div, на которой щелкает пользователь. Как же выбрать только ту область, в которой был сделан щелчок, и присоединить содержимое discount только к этой области?

Просто для про-верки значения переменной.

Откройте страницу в своем любимом браузере и убедитесь в том, что все работает. Обратите особое внимание на вызов alert — убедитесь в том, что значение перемен-ной discount успешно сохраняется.

При каждом щелчке сообщение о скидке включается

в каждый элемент div, принадлежащий классу guess_box.

Тест-драйв

Page 96: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

96 глава 2

в идеальном мире

А как было бы замечательно, если бы в jQuery можно было легко определить эле-мент div, на котором щелкнул пользователь?

Но это, конечно, всего лишь мечты...

Page 97: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 97

селекторы и методы

Äàéòå ìíå $(this)

В этой главе рассматривались селекторы jQuery и их использование для выбора элементов, с которыми работают методы jQuery. Довольно ча-сто мы хотим предельно конкретно указать, какой элемент требуется выбрать. В подобных ситуациях часто используется простейший селек-тор $(this), обозначающий текущий элемент.

Помните, что смысл конструкции $(this)зависит от контекста. Иначе говоря, смысл $(this) изменяется в зависимости от того, где и как вы используете эту конструкцию. В частности, ее уместно использовать вну-три функции, выполняемой при вызове метода jQuery:

$("#myImg").click( function(){ $(this).slideUp();});

$(this)

$( )

this Ключевое слово «this» обозначает текущий элемент, с которым мы работаем.

Функция, выпол-няемая при вызове метода.

Вызов метода jQuery.Селектор для обраще-ния к элементу.

Метод jQuery будет при-менен только к текущему элементу.

Как и прежде, используем обертку jQuery.

И click, и slideUp являются

методами jQuery. Мето-

ды и функции легко узнать

по круглым скобкам.

Для любознательных

Обращение к текущему элементу (#myImg в данном

случае) внутри функции.

this è $(this)

В JavaScript ключевое слово «this» обозначает элемент DOM, с ко-торым мы работаем в своем коде. Добавление $( ) (в результа-те чего получается $(this)) позволяет нам взаимодействовать с элементом DOM с использованием методов jQuery.

Page 98: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

98 глава 2

Тест-драйв

$(this) в действии

Давайте посмотрим, как $(this) поможет справиться с возникшей пробле-мой. Измените программный код так, чтобы в нем использовалась конструкция $(this); ниже соответствующий фрагмент выделен жирным шрифтом.

Сообщение о скидке присоединя-ется только к тому элементу класса guess_box, на котором щелкнул пользователь.

Èñïîëüçîâàíèå $(this)

Откройте страницу в своем любимом браузере и убедитесь в том, что все работает. Обратите особое внимание на вызов alert — убедитесь в том, что значение переменной discount успешно сохраняется. Щелкните несколько раз в разных местах; проверьте правильность вывода случайного числа, присо-единенного к текстовому сообщению.

Задание!

Сообщение о скидке присоединя-ется только к тому элементу класса guess_box, на котором щелкнул пользователь.

<script type="text/javascript">

$(document).ready(function() {

$(".guess_box").click( function() {

var discount = Math.floor((Math.random()*5) + 5);

var discount_msg = "<p>Your Discount is "+ discount +"%</p>";

alert(discount_msg);

$(this).append(discount_msg);

});

});//end doc ready

</script>

index.html

Page 99: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 99

селекторы и методы

Хороший вопрос!Мы подошли к последнему пункту нашего списка задач.

Области должны реагировать на щелчки мышью.

Страница должна состоять из четырех областей. Каждая область содержит одно изображение.

Нам понадобится сообщение, состоящее из текста («Размер вашей скидки:») и случайного значения (от 5 до 10 процентов).

Когда пользователь щелкает в одной из областей, под изо-бражением в этой области должно появляться сообщение.

Если пользователь щелкает снова, то старое сообщение исчезает и появляется новое.

$(this) прекрасно работает! Но теперь при повторных щелчках на стра-

нице появляются лишние сообщения. Можно ли от них избавиться?

Как вы думаете, как удалить со страницы послед-нее сообщение?

Мозговой

штурм

Page 100: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

100 глава 2

удаление элементов

Ñêàòåðòüþ äîðîãà! Ìåòîä remove

Как удалить последнее сообщение и создать новое? Используйте метод remove. Этот метод предназначен для удаления со страницы отдельного элемента или группы элементов. Взгляните на очень простую страницу со списком и кнопкой.

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

Слева показано, как страница выглядит в браузере, а справа приведена разметка HTML для ее создания.

1

А это код кнопки, удаляющей все пункты из списка:2

Посмотрите на страницу в браузере и на HTML после выполнения кода jQuery: все пункты списка исчезли, их нет даже в HTML!

3

$("#btnRemove").click(function(){

$("li").remove();

});

 áðàóçåðå

 áðàóçåðå

 ðàçìåòêå HTML

 ðàçìåòêå HTML

<div>My To Do List</div>

<ol>

<li>Learn jQuery</li>

<li>Ask the Boss for a raise</li>

<li>Tweet about my raise</li>

</ol>

<button id="btnRemove">

<div>My To Do List</div>

<ol>

</ol>

<button id="btnRemove">

remove — еще один метод jQuery. Мето-ды jQuery определяют действия, выполняе-мые с веб-страницей.

Мозговой

штурм

Page 101: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 101

селекторы и методы

$("div div div div pp")$("div p")

Ñåëåêòîðû ïîòîìêîâ

Селекторы потомков — еще одна разновидность селекторов, которая может использо-ваться в jQuery. Оказывается, они идеально подходят для нашей ситуации. Селекторы потомков позволяют определять отношения между элементами: вы можете выбирать родительские, дочерние или сестринские (одноранговые) элементы.

Справа указывается селектор потомка.

Слева указыва-ется селектор родителя.

Имена родителя и потомка разде-ляются пробелом.

А так выбира-ется «потомок потомка».

$("div div")

$("div div img")

$("div p#my_blurb")

$("div p")

Объединение селекторов классов и иден-тификаторов с селекторами потомков позволяет очень точно определить выби-раемые элементы, что особенно важно при работе со сложными веб-страницами.

Выбор всех элемен-тов p, родителями которых являются элементы div.

Выбор всех элементов img, которые являются потомками потомков элементов div.

Селектор возвраща-ет все элементы div, родителем которых является элемент div. body

html

div

div p id="my_blurb"div

p img

(«Внучатые» элементы?)

Возьми в руку карандашНапишите команду, которая будет удалять последнее сообщение в модели DOM из нашего примера с использованием селектора потомков.

Page 102: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

102 глава 2

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

Начните с селектора классов .guess_box, за ним укажите селектор

потомков p для обращения к добавленному элементу абзаца. Затем

вызовите метод remove, чтобы удалить из страницы все элементы p,

родитель которых принадлежит к классу guess_box.

$(".guess_box p").remove();

Итак, теперь я могу присоединять и удалять фрагменты страницы по своему

усмотрению. Важно ли, где и когда это происходит?

Да, порядок добавления и удаления элементов важен.

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

Если пользователь щелкает во второй раз, мы удаляем присоединенный элемент аб-заца, после чего присоединяем новый элемент абзаца.

Когда пользователь щелкает на этом элементе, к нему присоединяется эле-мент абзаца.

p

body

html

div id="header"

div id="main"

h2div class=

"guess_box"div class="guess_box"

div class="guess_box"

div class=

"guess_box"

img img img img

p

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

Page 103: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 103

селекторы и методы

Решите, где должна находиться команда remove. Запишите ее в одной

из строк 1, 2 или 3 и объясните, почему разместили ее именно в этой

строке. Подумайте, когда должен удаляться абзац, и методом исключе-

ния выберите правильное место для выполнения этой операции.

Почему я считаю, что команда должна находиться именно здесь:

<script>

$(document).ready(function() {

$(".guess_box").click( function() {

var discount = Math.floor((Math.random()*5) + 5);

var discount_msg = "<p>Your Discount is "+ discount +"%</p>";

alert(discount_msg);

$(this).append(discount_msg);

});

});

</script>

1.

2.

3.

index.html

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

Page 104: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

104 глава 2

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

Команда remove не может находиться в строке 1, потому что эта строка находится за пределами функции click класса guess_box. Она также не может находиться в строке 3, потому что в этом случае она будет удалять только что присоединенный фрагмент. Последнее сообщение о скидке должно удаляться перед генерированием нового, поэтому мы размещаем remove в первой строке блока кода (в фигурных скобках) функции click класса guess_box.

Очень важно, чтобы методы jQuery вызывались в правиль-ном порядке и в правильный момент.

Причем это особенно важно тогда, когда вы выводите важную информацию для своих посетителей, а потом удаляете ее снова. Мы еще вернемся к теме последовательности и свое-временности применения эффектов в главе 5.

Решите, где должна находиться команда remove. Запишите ее в одной

из строк 1, 2 или 3 и объясните, почему разместили ее именно в этой

строке. Подумайте, когда должен удаляться абзац, и методом исключе-

ния выберите правильное место для выполнения этой операции.

Почему я считаю, что команда должна находиться именно здесь:

<script>

$(document).ready(function() {

$(".guess_box").click( function() {

var discount = Math.floor((Math.random()*5) + 5);

var discount_msg = "<p>Your Discount is "+ discount +"%</p>";

alert(discount_msg);

$(this).append(discount_msg);

});

});

</script>

1.

2.

3.

index.html

$(".guess_box p").remove();

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

Будьте осторожны!

Page 105: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 105

селекторы и методы

В: Иногда после вызова метода remove элементы, удаленные из разметки, остаются на странице. Почему это происходит?

О: Часто при использовании команды получения исходного кода страницы браузер обращается к серверу с новым вы-зовом. Инспекторы DOM (например, Chrome Developer Tools или Firebug для Firefox) покажут вам содержимое DOM для текущего состояния страницы.

В: Что делают методы Math.floor и Math.random?

О: Метод floor округляет число вниз до ближайшего целого и возвращает результат. Метод random возвра-щает случайное число от 0 до 1. При умножении его на другое число мы получаем случайное число в интервале от 0 до числа-множителя.

В: Откуда взялось ключевое слово this?

О: Во многих объектно-ориентированных языках ключевым словом this (или self) в методах экземпляров обознача-ется объект, для которого был вызван метод, выполняемый в настоящий момент.

В: Значит, я могу выводить сообщение о скид-ке тогда, когда пользователь щелкает на одном из изображений, и удалять ее при щелчке на другом изображении. Но ведь для реально-го приложения этого было бы недостаточно, верно?

О: Вы абсолютно правы. Это всего лишь первая часть головоломки. Этот код должен передать информацию о предоставленной скидке в тот момент, когда пользователь переходит к оформлению заказа. Чтобы скидка была учтена при расчете, ее необходимо передать серверу для обработки. Такая функциональность более подробно рассматривается в главах 8–10.

частоЗадаваемые

вопросы

Page 106: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

106 глава 2

тест-драйв

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

Тест-драйв

Page 107: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше� 107

селекторы и методы

Âàøà î÷åðåäü ïðûãàòü îò ðàäîñòè

Поздравляем! Вы справились со всеми требованиями, и рекламная акция теперь заработает.

Области должны реагировать на щелчки мышью.

Страница должна состоять из четырех областей. Каждая область содержит одно изображение.

Нам понадобится сообщение, состоящее из текста («Размер вашей скидки:») и случайного значения (от 5 до 10 процентов).

Когда пользователь щелкает в одной из областей, под изо-бражением в этой области должно появляться сообщение.

Если пользователь щелкает снова, то старое сообщение исчезает и появляется новое.

От: ЭмилиТема: Re: Рекламная акция «Прыгаем от радости!»

Спасибо за то, что ты сделал для меня! Мой сайт стал гораздо лучше.

Надеюсь, посетители будут в таком же восторге от моих фотографий,

как я — от новой страницы!

--Эмили

> PS. Прилагаю свой автопортрет — так я выглядела, когда увидела новую

веб-страницу... Надеюсь, не нужно объяснять, что я делаю?

Page 108: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

108 глава 2

ваш инструментарий jquery

Âàø èíñòðóìåíòàðèé jQuery

Глава 2 осталась позади, а ваш творче-ский инструментарий дополнился основ-ными принципами работы с селекторами и некоторыми методами jQuery.

$(this)

Выбирает «текущий» элемент.

Смысл $(this) изменяется в зависи-

мости от того, где находится эта

конструкция.

Селекторы

$(this) — выбирает текущий элемент.

$("div") — выбирает все элементы div

на странице.

$("div p") — выбирает все элементы p,

вложенные непосредственно в элемен-

ты div.

$(".my_class") — выбирает все элемен-

ты класса my_class.

$("div.my_class") — выбирает толь-

ко те элементы, которым назначен

класс my_class. (Разные типы эле-

ментов могут относиться к одному

классу.)

$("#my_id") — выбирает элемент

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

Методы jQuery

Метод jQuery представляет собой

фрагмент кода, определенный в библи-

отеке jQuery и предназначенный для

многократного использования. Методы

используются для выполнения раз-

личных операций в jQuery и JavaScript.

Считайте, что метод — своего рода

команда, выполняющая некоторые

операции с веб-страницей.

.append — вставляет заданное содер-

жимое в DOM. Данные присоединяют-

ся к элементу, для которого вызыва-

ется метод.

.remove — удаляет элемент из DOM.

ГЛА

ВА 2

Page 109: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Нет, я непременно докопаюсь до сути...

События и функции jQuery3

Страница в центре событий

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

Page 110: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

110 глава 3

дела финансовые

Эмили довольна вашей работой для рекламной акции «Прыгаем от радости», но после встречи с бухгалтером она хочет внести на сайте некоторые изменения.

Íè ìèíóòû ïîêîÿ

От: ЭмилиТема: RE: Прыгаем от радости

Привет,

Ты отлично справился с поддержкой нашей рекламной акции! Я встречалась

с нашим бухгалтером, и мы обсудили некоторые показатели успеха нашей

рекламной акции.

Бухгалтер предложил внести в приложение некоторые изменения, которые

должны повысить уровень продаж.

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

Однако на этот раз величина скидки остается постоянной. Бухгалтер рекомен-

дует установить величину в 20% от объема заказа, такая высокая скидка будет

для них более привлекательной.

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

каждом посещении скрывается под случайно выбранным изображением. Если

посетитель находит код скидки, щелкнув на изображении, то код появляется на

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

была спрятана скидка.

Удастся ли тебе справиться с этой задачей так же хорошо, как и с первой?

--Эмили Сондерсjumpforjoyphotos.hg

Эмили приложила фотографии своего бухгалтера — тот явно не собирается прыгать от радости. Может, после внесения изменений на сайте дело пойдет на лад?

Page 111: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 111

события и функции jquery

 ñëîâàõ áóõãàëòåðà åñòü ðåçîí...

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

Щелк!Щелк!

Щелк!Щелк!Щелк!Щелк!

Щелк!Щелк!Щелк!Щелк!

Требования:

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

делать: просмотрите сообщение Эмили и выберите все новые возмож-

ности приложения, которые она хочет видеть на своем сайте. Опишите

простыми словами, как должно работать новое решение.

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

Page 112: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

112 глава 3

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

Вы знаете, как включить в страницу функцию click. Но как убедиться в том, что посетитель использует ее только один раз?В предыдущих главах вы узнали, как организовать выполнение кода при вызове click. Нельзя ли использовать эту информацию в реализации нового решения?

Êàê íàøå ðåøåíèå ðàáîòàåò ñåé÷àñ Êàê îíî äîëæíî ðàáîòàòü

Щелкай на здоровье! Чем больше — тем лучше!

Требования:

У тебя только одна попытка!

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

• После того как посетитель выбрал изображение и щелкнул на нем, следует со-общить о результате. Если изображение было выбрано правильно, нужно вывести величину скидки.

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

• Вместо случайной скидки будет использоваться постоянная скидка 20 %. Таким образом, вместо процента в сообщении следует вывести код скидки.

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

делать: просмотрите сообщение Эмили и выберите все новые возмож-

ности приложения, которые она хочет видеть на своем сайте. Опишите

простыми словами, как должно работать новое решение.

Мозговой

штурм

Page 113: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 113

события и функции jquery

Submit

Submit

$("#btnSubmit").click( function(){

// Код jQuery!

$("div").toggle();

});

Ðåàêöèÿ íà ñîáûòèÿ

Работа приложения «Прыгаем от радости» основана на щелчках мышью. В jQuery и JavaScript щелчок называется событием (существует много других событий, но нас пока интересуют только щелчки). Механизм событий позволяет вам выполнять код, когда со страницей что-то происходит (например, пользователь щелкает на кнопке). Выполняемый код оформлен в виде функции — а как говорилось ранее, функции делают код jQuery более эффективным и пригодным для повторного использования. Вскоре функции будут рассмотрены более подробно, а пока давайте посмотрим, как же на са-мом деле работает событие click.

С кнопкой HTML проис-ходит событие click.

Кнопка HTML

Слушатель (обработчик) Слушатель (обработчик) события обнаруживает события обнаруживает его и передает...его и передает...

Обратите внимание на до-полнительный этап, которого не было в главе 1.

…и выполняет код, изме-няющий страницу.

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

Щелк!Щелк!

А что это за «слушатель со-бытия»? Раньше его не было.

Что именно он делает?

Хороший вопрос.Слушатели событий являются частью модели DOM. Их мож-но включить в любую страни-цу, чтобы операции со страни-цей могли выполняться и без участия пользователя, щелка-ющего на ссылках и кнопках. Давайте разберемся поглубже.

Page 114: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

114 глава 3

свет, камера, события

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

jQuery предоставляет очень простые механизмы связывания слушателей событий с любым элементом страницы, так что пользователям не приходится долго кликать по ссылкам и кнопкам!

Çà êóëèñàìè ñëóøàòåëÿ ñîáûòèé

Что вы видите в браузере

Я слышу щелчок.

Я должен вывести окно сообщения!

Пользователь щелкнул на элементе.1

Интерпретатор JavaScript

Слушатель события, связанный с элементом, «слышит» событие click и сообщает интерпретато-ру JavaScript, какой код связан с этим событием.

2

Интерпретатор JavaScript выполняет функцию, задан-ную в слушателе события.

3

Пользователь видит, как на странице что-то про-исходит.

4

Слушатель события

$("#showMessage").click(function() {

alert('You Clicked Me!');

});

Элемент с иден-тификатором showMessage.

Добавляется событие click.

Выполняется этот код.

Щелк!Щелк!

За

сценой

Page 115: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 115

события и функции jquery

Ñâÿçûâàíèå ñîáûòèÿ

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

Есть два способа связывания событий с элементами.

Способ 1 — всего лишь сокращенная форма способа 2, но он может использоваться только в том случае, если элементы DOM уже суще-ствуют.

В jQuery много таких сокращенных вариантов записи, которые упроща-ют программный код. Они существуют исключительно для удобства — однако у них есть свои ограничения. Способ 2 следует использовать для добавления событий к новым элементам DOM, созданным в вашем коде

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

Этот способ используется для связывания событий с элементами при загрузке страницы. Такая форма записи часто называется «сокращенной».

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

Оба способа добавляют слуша-теля события click к элементу с идентификатором myElement.

Ñïîñîá 1

Ñïîñîá 2

$("#myElement").click( function() {

alert($(this).text());

});

$("#myElement").bind('click', function() {

alert($(this).text());

});

Будьте осторожны!

Page 116: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

116 глава 3

как появляются события

Ñðàáàòûâàíèå ñîáûòèé

События могут срабатывать при выполнении разно-образных операций со страницей. Более того, опе-рации, выполняемые с самим браузером, тоже могут стать источниками событий!

click mousedown mouseout toggledblclick mouseenter mouseoverfocusin mouseleave mouseup

focusout mousemovehover

События мышиkeydownkeypress

keyup

События клавиатуры

События форм

blurchangefocusselectsubmit

События браузера

errorresizescroll

Загрузкадокумента

loadready

unload

События

События

Page 117: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 117

события и функции jquery

function () { [блок кода, в котором что-то делается]}

Селектор + Событие + Функция = Сложное взаимодействие

В: А что это за функции в собы-тиях?

О: Они называются обработчика-ми. Функция-обработчик выполняется при каждом срабатывании события. Функции будут более подробно рас-смотрены позднее в этой главе.

В: Где можно узнать о разных ви-дах событий?

О: На сайте jquery.com, в разделе «Documentation → Events».

В: Сколько существует разных ка-тегорий событий?

О: В jQuery события делятся на пять категорий: события браузера, события загрузки документа, события форм, со-бытия клавиатуры и события мыши.

В: А сколько вообще существует разных событий?

О: Около 30 разных типов во всех категориях.

В: Что может привести к срабаты-ванию события на странице?

О: Большинство типов событий сра-батывает от операций с устройствами ввода (клавиатура, мышь). Тем не ме-нее браузер, документ страницы, код jQuery и даже форма HTML на странице тоже могут быть источниками событий.

Ñîáûòèå ñðàáîòàëî

Âûïîëíÿåòñÿ ôóíêöèÿ

Интерпретатор JavaScript

Слушатель события

частоЗадаваемые

вопросы

Page 118: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

118 глава 3

откровенно о событиях

HeadFirst: Добрый вечер, Событие, мы очень рады встрече.

Событие: Да, и я тоже.

HeadFirst: Так кто же вы? Что собой пред-ставляет настоящее Событие?

Событие: Я — объект, помогающий людям взаимодействовать с веб-страницей. В наши дни я уже твердо стою на ногах, но до появ-ления jQuery мое существование было... как бы это выразиться... немного рассеянным.

HeadFirst: Как интересно. Мы еще вернемся к этой теме, но почему вы говорите о рассеян-ности? Откуда вы вообще появились?

Событие: Это долгая история. В середи-не 1990-х годов фирма Netscape выпустила Navigator 2.0. Какие были времена... Моя модель тогда была очень простой. DOM, JavaScript и я — все мы только-только появи-лись. Существовал стандарт W3C, в котором говорилось, как браузеры должны реализо-вать нас!

HeadFirst: Но это было давно. С тех пор вы сильно изменились.

Событие: Да, все мы изменились. Попутно мы даже ввязались в «войну браузеров» между Microsoft Internet Explorer и Netscape. Обе компании пытались обойти друг друга при помощи всяких классных штучек, которые не входили в стандарт, но поддерживались только в браузере этой компании. В конеч-ном итоге победа досталась Microsoft.

HeadFirst: Похоже, непростое было время.

Событие: Да, но сейчас дела налаживаются. В 1997 году Netscape и Microsoft выпустили

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

HeadFirst: И что произошло?

Событие: Ситуация вышла из-под контроля. Браузер Netscape был преобразован в проект с открытым кодом и позднее превратился в Mozilla Firefox. Но какое-то время браузер Netscape продолжал существовать, причем в нем и в Internet Explorer использовались разные модели событий. Многие решения работали только в одном браузере, а это силь-но раздражало пользователей, заходивших на сайт в другом браузере. В конечном итоге Netscape не стало, но на сцене появилось не-сколько новых браузеров.

HeadFirst: Тогда почему вы говорите, что дела налаживаются?

Событие: Полной совместимости между браузерами по-прежнему нет. Набор собы-тий, поддерживаемых Internet Explorer, от-личается от наборов событий Firefox, Google Chrome, Apple Safari и Opera. Однако ситу-ация меняется к лучшему с выходом каждой новой версии. Браузеры постепенно начи-нают лучше соответствовать стандартам. Но самое замечательное, что jQuery решает эти проблемы за веб-разработчика.

HeadFirst: Правда? Вот здорово! А как? И что это за объект, которым, как вы говорите, вы являетесь?

Событие: jQuery выбирает способ обработ-ки событий в зависимости от того, какой браузер используется посетителем ваших

Интервью недели:Чем так замечательны события?

откровенно

о событиях

Page 119: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 119

события и функции jquery

сайтов. А что касается объекта, то здесь нет ничего сложного. В сущности, объект — это всего лишь переменные и функции, объеди-ненные в одну структуру.

HeadFirst: И где можно побольше узнать об этих переменных и функциях?

Событие: Вы найдете информацию обо мне в официальной документации jQuery:http://api.jquery.com/category/events/event-object/.

HeadFirst: Спасибо! Непременно почитаю. А что нужно сделать, чтобы использовать вас на странице?

Событие: Для начала меня нужно с чем-то связать — ведь слушатель событий должен знать, что на меня следует обращать вни-мание. Затем какое-то условие должно при-водить к моему срабатыванию, и тогда при возникновении события будет выполняться нужный код.

HeadFirst: Хорошо, но как узнать, какой именно код должен выполняться?

Событие: Этот код определяется при моем связывании с элементом. При этом можно задать практически любой набор операций — поэтому события и считаются такими полез-ными. Кроме того, меня можно отсоединить от элемента. Когда это происходит, слуша-тель перестает обнаруживать события для этого элемента, и тот код, который должен выполняться при моем срабатывании, вы-полняться уже не будет.

HeadFirst: Беседа получилась очень инте-ресной, но наше время на исходе. Где я могу подробнее узнать о вас и о типах событий, которые могут происходить со страницами?

Событие: Уже упоминавшаяся ссылка объ-ясняет, как работает объект. Дополнитель-ную информацию обо мне и о разных типах событий можно найти в разделе докумен-тации на сайте jQuery. Спасибо за пригла-шение!

HeadFirst: И вам спасибо, что пришли. До встреч в программном коде!

Функции и переменные более подробно рассматриваются в этой главе.

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

Р А СС Л А Б Ь Т Е С Ь

Page 120: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

120 глава 3

довольно событий

$("#myElement").bind ('focus', function() {

alert("I've got focus");

});

$("#myElement").click(function(){

alert('You clicked me.');

});

$("#myElement").unbind();

$("#myElement").bind ('click', function() {

alert($(this).text());

});

$("#myElement").unbind('click');

Óäàëåíèå ñîáûòèé

Наряду со связыванием событий с элементами также часто возникает необходимость удаления событий из элементов — например, когда вы не хотите, чтобы пользователи могли повторно щелкнуть на форме или же какая-либо операция со страницей должна выполняться только один раз. Именно такая ситуация встретилась нам в новых требо-ваниях рекламной акции «Прыгаем от радости».

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

Код, который выполняется при щелчке на myElement:

К элементу с иденти-фикатором myElement добавляется слушатель события click.

Событие click отсоединяется от myElement.

Команда unbind приказывает браузеру прекратить прослу-шивать заданное событие конкретного элемента.

К элементу с иденти-фикатором myElement добавляется слушатель события focus.

К элементу с иден-тификатором myElement добав-ляется слушатель события click.

Браузер переста-ет прослушивать события элемента myElement.

Äëÿ óäàëåíèÿ îäíîãî ñîáûòèÿ:

Äëÿ óäàëåíèÿ âñåõ ñîáûòèé:

Page 121: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 121

события и функции jquery

Итак, слушатель события работает в браузере,присоединяется к элементам, ждет возникновения событий

и приказывает интерпретатору JavaScript что-то сделать при обнаружении события, верно?

Да! Именно так.Посмотрим, как события помогут нам в реализации первого требования.

Не разрешайте пользователю

повторный поиск скидки!

Используя то, что вы уже знаете о $(this), и то, что вы узнали

о событиях, измените код из предыдущей главы — включите в него

команду удаления события click из областей div.

$(".guess_box").click( function() {

$(".guess_box p").remove();

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append(discount);

});

index.html

• После загрузки страницы посетителю предоставляется

только одна возможность найти скидку. Следовательно,

если первая попытка оказалась неудачной, то дальнейшие

щелчки необходимо заблокировать.

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

Page 122: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

122 глава 3

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

Измените файл index.html и сохраните его. Пощелкайте на странице и убедитесь в том, что она работает именно так, как нужно.

Используя то, что вы уже знаете о $(this), и то, что вы узна-

ли о  событиях, измените код из предыдущей главы  — включите

в него команду удаления события click из областей div.

$(".guess_box").click( function() {

$(".guess_box p").remove();

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append(discount);

});

index.html

$(this).unbind(″click″);

Приказываем браузеру остано-

вить прослушивание событий

из текущего элемента.

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

Тест-драйв

Page 123: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 123

события и функции jquery

Верно, слушатель события click удаляет-ся не из всех областей.Событие click удаляется только из той области div, на которой был сделан щелчок. На других областях по-прежнему можно щелкать. Как бы удалить слуша-теля события click из всех остальных элементов…

Как бы вы удалили событие click из всех областей после того, как посетитель щелкнет на одной области? Нужно ли для этого перебирать все элементы один за другим?

Наверное, то же, что и у меня. А это совсем не то, о чем говорится

в требованиях...

А вы пробовали пощелкать А вы пробовали пощелкать на странице во время пробно-на странице во время пробно-

го запуска? И что произошло?го запуска? И что произошло?

Мозговой

штурм

Page 124: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

124 глава 3

а теперь повторите!

Ïåðåáîð ýëåìåíòîâ

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

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

$(".nav_item").each(function(){

$(this).hide();

});

Перебор всех элементов, соответ-

ствующих заданному селектору.Выполняемаяфункция-обработчик

Код выполняется для каждого элемента, соответствующего селектору.

Селектор jQuery.

Итератор .each берет группу эле-

ментов и последовательно выполняет

операцию с каждым элементом группы.

Мы еще вернемся к этой теме,особенно в следующей главе...

Перебор будет более подробно рассмотрен позднее в книге.

Page 125: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 125

события и функции jquery

Напишите код, использующий перебор для удаления слушателя события

click из всех областей div, реагирующих на щелчки в странице «Прыгаем

от радости». Внимательно прочитайте свой код и проверьте — может,

какие-то из его фрагментов стали лишними?

В: Могу ли я инициировать события в своем коде?

О: Да! Этот прием используется относительно часто — например, при отправке форм для проверки данных или закрытии модальных временных окон.

В: И как это делается?

О: События инициируются методом .trigger в сочета-нии с селектором — например, $("button:first").trigger('click'); или $("form").trigger('submit');.

В: Могу ли я работать с событиями в веб-странице без ис-пользования jQuery?

О: Да, можете. jQuery всего лишь упрощает связывание событий с элементами, потому что библиотека обеспечивает межбраузерную совместимость и использует для связывания событий с элементами простые, легко запоминающиеся функции.

В: Как работает .each?

О:.each использует селектор, от которого исходит вызов, и создает массив элементов, соответствующих данному селектору. Затем в цикле происходит последовательный перебор элементов массива. Не беспокойтесь, вскоре массивы и циклы будут рассмо-трены более подробно!

В: Итак, я могу создавать элементы средствами jQuery после загрузки страницы. Могут ли эти элементы получать события?

О: Да, могут. После того как элемент будет создан, вы можете воспользоваться методом.bind для связывания его со слуша-телем событий. Кроме того, если вам заранее известно, что ваш элемент будет вести себя как другие, уже созданные элементы, вы можете воспользоваться методом .live. Это приведет к тому, что обработчик события будет связываться со всеми элементами, соответствующими текущему селектору, сейчас и в будущем. Это решение подходит даже для элементов, которые еще не были включены в DOM.

$(".guess_box").click( function() {

$(".guess_box p").remove();

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append(discount);

$(this).unbind('click');

});

index.html

частоЗадаваемые

вопросы

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

Page 126: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

126 глава 3

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

$(".guess_box").click( function(){

$(".guess_box p").remove();

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>"

$(this).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

});

index.html

Перебираем элементы

.guess_box и удаляем из них

событие click.

Вызов метода .each для класса .guess_box перебирает все эле-

менты этого класса, чтобы вы могли последовательно отсоединить

метод click от каждого элемента. Команда с вызовом .remove стала

лишней; так как посетители всего равно смогут щелкнуть всего один

раз, удалять старое сообщение не нужно.Так как пользователям

разрешается щелкать

только один раз, удалять

старое сообщение уже не-

обязательно!

Стоп!Вы не находите, что в файле

HTML стало слишком много сце-нарного кода? Прежде чем дви-

гаться дальше, хорошо бы придать ему стройности...

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

Page 127: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 127

события и функции jquery

Хорошая мысль. Вообще-то существует не-сколько причин для хранения кода jQuery в отдельном файле.

Вы уже знаете, как включить в HTML файлы CSS и библиотеку jQuery. Включение отдельного файла, содержащего ваш сценарный код JavaScript/jQuery, происходит практически так же!

В корневом веб-каталоге уже должна существовать папка scripts (где вы разместили библиотеку jQuery).

<script src="scripts/my_scripts.js"></script>

Так давайте создадим файл сценариев отдельно от файла HTML? Мы уже делали это с CSS...

Файл можно включать в разные страницы (повторное использование кода).

1

Страница будет загружаться быстрее.2

Код HTML станет более стройным и удобочитаемым.3

В своем любимом текстовом редакторе создайте файл с именем my_scripts.js и сохраните его в папке scripts.

1

Создайте ссылку на файл в странице HTML. Для этого перед закры-вающим тегом </body> размещается следующая строка:

3

Перенесите весь код JavaScript и jQuery из файла index.html в новый файл. Переносить теги <script> и </script> необязательно.

2

Упражнение

Page 128: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

128 глава 3

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

Теперь этот файл можно включать во все

файлы HTML, входящие в проект, — и все

они смогут пользоваться вашим кодом

jQuery. Вам уже не придется повторять

этот код в каждом файле.

Вы уже знаете, как включить в HTML файлы CSS и библиотеку jQuery. Включение отдельного файла, содержащего ваш сценарный код JavaScript/jQuery, происходит практически так же!

В своем любимом текстовом редакторе создайте файл с именем my_scripts.js и сохраните его в папке scripts.

1

Перенесите весь код JavaScript и jQuery из файла index.html в новый файл. Переносить теги <script> и </script> необязательно.

2

$(document).ready(function() {

$(".guess_box").click( function() {

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

});

});

my_scripts.js

Page 129: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 129

события и функции jquery

<!DOCTYPE html>

<html>

<head>

<title>Jump for Joy</title>

<link href="styles/styles.css" rel="stylesheet">

</head>

<body>

<div id="header">

<h2>Jump for Joy Sale</h2>

</div>

<div id="main ">

<div class="guess_box"><img src="images/jump1.jpg"/></div>

<div class="guess_box"><img src="images/jump2.jpg"/></div>

<div class="guess_box"><img src="images/jump3.jpg"/></div>

<div class="guess_box"><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/jquery.1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

</body>

<html>

index.html

Да, это уже лучше.Сделано красиво и аккуратно.

Проходите...

Создайте ссылку на файл в странице HTML. Для этого перед закры-вающим тегом </body> размещается следующая строка:

3

Page 130: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

130 глава 3

так гораздо лучше

Ñòðóêòóðà ïðîåêòà

Мы только что внесли важные изменения в структуру файлов проекта. Давайте посмотрим, что же получилось в итоге.

В: Почему наш файл имеет рас-ширение .js?

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

В: Как отделение сценарного кода ускоряет загрузку страницы?

О: Если ваш файл .js включен в несколько файлов HTML, то брау-зер запросит его только один раз. Полученный файл сохраняется в кэше браузера, чтобы ему не прихо-дилось заново обращаться к серверу для каждой страницы HTML, содер-жащей ссылку на ваш файл.

В: Почему теги <script>и </script> необязательны в файле my_scripts.js?

О: Потому что это теги HTML. Так как наш код уже включается в страницу как файл JavaScript, брау-зер уже знает тип его содержимого.

images

scripts

styles

root

jump1.jpg

jump2.jpg

jump3.jpg

jump4.jpg

jquery-1.6.2.min.js

my_scripts.js

my_style.css

index.html

частоЗадаваемые

вопросы

Page 131: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 131

события и функции jquery

jquery-1.6.2.min.js

".guess_box"

class="guess_box"

class="guess_box"

script

});

</div>

this

<body>

my_num

<head>

"

<!DOCTYPE html>

<html>

<title>Jump for Joy</title>

<link href="styles/styles.css" rel="stylesheet">

</head>

<div id="header">

<h2>Jump for Joy Sale</h2>

<div id="main">

<div ><img src="images/jump1.jpg"/></div>

<div class="guess_box"><img src="images/jump2.jpg"/></div>

<div class="guess_box"><img src="images/jump3.jpg"/></div>

<div ><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/ "></script>

< src="scripts/my_scripts.js"></script>

</body>

<html>

$(document).ready(function() {

$( ).click( function() {

var = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$( ).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

});

index.html

my_scripts.js

Разложите магниты в соответствии со структурой файлов проекта.

Убедитесь в том, что вы знаете, как правильно организовать разде-

ление кода HTML, CSS и jQuery. В будущем вы должны безошибочно

справляться с этой задачей.

Развлечения с магнитами

Page 132: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

132 глава 3

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

<!DOCTYPE html>

<html>

<title>Jump for Joy</title>

<link href="styles/styles.css" rel="stylesheet">

</head>

<div id="header">

<h2>Jump for Joy Sale</h2>

<div id="main">

<div ><img src="images/jump1.jpg"/></div>

<div class="guess_box"><img src="images/jump2.jpg"/></div>

<div class="guess_box"><img src="images/jump3.jpg"/></div>

<div ><img src="images/jump4.jpg"/></div>

</div>

<script src="scripts/ "></script>

< src="scripts/my_scripts.js"></script>

</body>

<html>

$(document).ready(function() {

$( ).click( function() {

var = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$( ).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

});

index.html

my_scripts.js

"

pts/my scripts.js"></scrip

jquery-1.6.2.min.js

cument).ready(func

)

var = Ma

".guess_box"

ain >

v >

v class="guess_box"><im

class="guess_box"

v class guess_box ><im

v >

>

class="guess_box"

p

< sr

body>script

});

});

});

p

<div id="maid= ma</div>

) this

/

<div id="h

<body>

discount =

=

g _

my_num

tml>

<title>Jump

<head>

Разложите магниты в соответствии со структурой файлов проекта.

Убедитесь в том, что вы знаете, как правильно организовать разде-

ление кода HTML, CSS и jQuery. В будущем вы должны безошибочно

справляться с этой задачей.

Развлечения с магнитами – решение

Page 133: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 133

события и функции jquery

А как было бы замечательно, если бы единожды написанный код jQuery можно

было использовать снова и снова?Но это, конечно, всего лишь мечты...

Page 134: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

134 глава 3

повторное использование кода

$(document).ready(function(){

$("#clickMe").click(function(){

//...

});

$(".guess_box").click(function(){

//...

});

});

Èñïîëüçîâàíèå ôóíêöèé

От добавления и удаления событий на страницах мы переходим к другой полезной возможности, которая повысит эффективность использования jQuery на наших сайтах: функциям.

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

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

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

Смотрите: функции!

Вспомните: эти блоки уже использовались в нашем коде!

В сущности, пользовательская

функция — это фрагмент кода

jQuery, которому присвоено имя

для удобства использования.

Page 135: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 135

события и функции jquery

Êàê óñòðîåíà ôóíêöèÿ

Определение функции связывает имя с выполняемым кодом. Синтаксис большинства базовых функций JavaScript выгля-дит так:

Имена функций? Но ведь у функций, которые мы ис-

пользовали прежде, имен не было. Почему же теперь мы стали присваивать имена?

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

function name ()

}

{

run this code

Все начинает-ся с ключевого слова function.

Имя функции

По круглым скобкам

можно сразу опреде-

лить, что перед нами

функция.

Открываю-щая фигур-ная скобка

Функция заверша-ется закрывающей фигурной скобкой.

В теле функции размещается вы-полняемый код.

function myFunc1(){

$("div").hide();

}

var myFunc2 = function() {

$("div").show();

}

Èìåíà ôóíêöèé

Îáúÿâëåíèå ôóíêöèè

Ôóíêöèîíàëüíîå âûðàæåíèå

Имя функции

Функция присваивается специальной переменной.

Присвоить имя функции можно двумя способами.

В именованном функциональном выражении функ-ция определяется как часть внешней конструкции (чаще всего команды присваивания):

Первый способ — объявление функции — опреде-ляет именованную функциональную перемен-ную без присваивания. Объявления начинаются с ключевого слова function:

Page 136: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

136 глава 3

что в имени тебе моем?

В: Чем объявление функции отличается от именован-ного функционального выражения?

О: Прежде всего временем использования. Хотя обе фор-мы делают одно и то же, функция, определяемая в форме именованного функционального выражения, может использоваться в коде только после выполнения команды, содержащей выражение. С другой стороны, функция, опре-деляемая в форме объявления функции, может вызы-ваться в любом месте страницы (даже в обработчике onload).

В: Существуют ли ограничения для имен, присваи-ваемых функциям?

О: Да. Имена функций не могут начинаться с цифр, в них не допускается использование математических операторов и знаков препинания, хотя допускается символ подчерки-вания (_). Кроме того, имя функции не может содержать пробелы, и в именах функций и переменных учитывается регистр символов.

Àíîíèìíàÿ ôóíêöèÿ

Анонимные функции определяются без имени и выполняются непосредственно при определении в коде. Все переменные, объ-явленные в таких функциях, доступны только во время выполнения функции.

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

$(document).ready(function() {

$(".guess_box").click( function() {

var my_num = Math.floor((Math.random()*5) + 5);

var discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

});

});

my_scripts.js

Эта функция не будет вызы-ваться в других местах кода.

переменные

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

Будьте осторожны!

частоЗадаваемые

вопросы

Page 137: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 137

события и функции jquery

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

Разложите магниты так, чтобы код, проверяющий скидку, был выделен

в именованную функцию checkForCode, которая используется в каче-

стве обработчика события click для областей div.

click

append

discount

"+my_num+"

checkForCode

function

{

)

()

var

}

(

myFunc1();

$("#myElement").click(myFunc2);

Это означает, что после щелчка на myElement области div будут видны.

Области div скрыва-ются в соответствии с объявлением функции.

Функция вызывается

в программном коде.Здесь нужны круглые скобки.

Когда функция вызывается как обработчик со-бытия, круглые скобки не нужны.

Имена функций

Функция вызыва-

ется как обра-

ботчик события.

function myFunc1(){

$("div").hide();

}

var myFunc2 = function() {

$("div").show();

}

Îáúÿâëåíèå ôóíêöèè

Ôóíêöèîíàëüíîå âûðàæåíèå

$(document).ready(function() {

$(".guess_box").click( checkForCode );

var my_num = Math.floor((Math.random()*5) + 5);

discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append( );

$(".guess_box").each( function(){

$(this).unbind(' ');

});

});

my_scripts.js

Èìåíîâàííûå ôóíêöèè êàê îáðàáîò÷èêè ñîáûòèé

Развлечения с магнитами

Page 138: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

138 глава 3

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

)

Объявление функции

Разложите магниты так, чтобы код, проверяющий скидку, был выделен

в именованную функцию checkForCode, которая используется в каче-

стве обработчика события click для областей div.

Лишние магниты

Отличная работа! Внесите эти изменения в файл с кодом. Поздравляем, вы создали свою первую функцию и исполь-зовали ее как функцию-обработчик события click.

$(document).ready(function() {

$(".guess_box").click( checkForCode );

var my_num = Math.floor((Math.random()*5) + 5);

discount = "<p>Your Discount is "+my_num+"%</p>";

$(this).append( );

$(".guess_box").each( function(){

$(this).unbind(' ');

});

});

my_scripts.js

()

);

}

ndom()d

{

y_

d

$(this)

var

ch( functio

click

p

)discount

) (

Math floor((Mathth

checkForCode

( g _

var my num = M

)

= M

function

append

)

ap"+my_num+"

d

(

Наша именованная

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

Команда завершается символом «;».

Генератор случай-

ных чисел (использо-

вался в главе 2)

Вывод сообщения

о скидке на экран

Удаление события click из всех областей, как было показано ранее в этой главе.

Задание !

Как бы вы написали функцию, скрывающую сообщение о скидке в случайной области div, и другую функцию, генерирующую случайное число для самого сообщения о скидке? Подсказка: генератор случайных

чисел может использоваться

как в существующей функции

checkForCode, так и в функции

вывода сообщения о скидке в слу-

чайной области div.

Развлечения с магнитами. Решение

Мозговой

штурм

Page 139: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 139

события и функции jquery

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

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

ласти div щелкнул пользователь...Как бы это сделать?

var pts = 250;

Ключевое слово var

объявляет переменную.

За ключевым словом var указывается имя переменной. Так значение переменной за-

дается в программном коде.

При объявлении пере-менной интерпретатор JavaScript выделяет блок памяти браузера, в ко-тором будут храниться ваши данные.

pts

Переменной присваивается имя, по которому вы бу-дете позднее обращаться к ней в своем сценарии.

pts

=250Значение, сохраняемое в переменной, указывается после знака равенства.

А ведь мы уже использовали пере-менные в своем коде, помните? var my_num = Math.floor((Math.random()*5) + 5);

var discount = "Your Discount is "+my_num+"%";

Page 140: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

140 глава 3

пожалуйста, передайте переменную

Ïåðåäà÷à ïåðåìåííûõ ôóíêöèÿì

Переменные, передаваемые функциям, называются аргументами. (Иногда также их называют параметрами.) Давайте разберемся, как же происходит передача аргументов функциям.

Нашей функции не нужно знать, какие данные хранятся в переменной; она просто выводит ее текущее содержимое. Таким образом, для измене-ния результата работы функции достаточно изменить передаваемую пере-менную (вместо изменения кода самой функции, что безусловно усложнит ее повторное использование!).

function welcome (name) {

alert ("Hello"+ name);

}

// Вызов нашей функции

welcome("John");

Имя функции

Аргумент используется в вычислениях.

Имя аргумента

function name (

}

{

выполняемый код

)аргументы

Аргументы перечисля-

ются в круглых скобках.

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

Однако вы можете рассматривать свою функцию как рецепт — допустим, рецепт коктейля. Набор

простых, легко повторяемых действий для создания коктейля (порцию того, немного этого, перемешать и т. д.) является аналогом функции, а ингредиен-ты — аналогами передаваемых переменных. Кто-нибудь желает джин-тоник?

Р А СС Л А Б Ь Т Е С Ь

Page 141: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 141

события и функции jquery

Ôóíêöèÿ òàêæå ìîæåò âîçâðàùàòü çíà÷åíèÿ

Функция возвращает результат своей работы при помощи команды, состоящей из ключевого слова return и возвра-щаемого значения. Результат передается в точку вызова функции для дальнейшего использования. Возвращаемое значение

может быть числом, строкой

текста и даже элементом

DOM (объектом).function multiply (num1, num2) {

var result = num1*num2;

return result;

}

// Call our function

var total = multiply (6, 7);

alert (total);

Имя функции

Операции с аргу-

ментами

Имена аргументов

Возвращаемое значение

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

в файл my_scripts.js новую функцию, которая получает один аргумент

(с именем num) и возвращает случайное число в интервале от 0 до пе-

реданного числа. Присвойте функции имя getRandom.

my_scripts.jsПодсказка: Вспомните код, который мы использовали для гене- рирования случайных чисел. Подумайте, как оформить его в виде функции.

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

Page 142: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

142 глава 3

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

function getRandom(num){

var my_num = Math.floor(Math.random()*num);

return my_num;

}

my_scripts.js

ДжимФрэнк Джо

Джим: Кроме новой функции getRandom, нам понадобится еще одна функция.

Фрэнк: Точно — для включения кода скидки в случайное выбран-ное изображение... Кстати, в ней можно использовать функцию getRandom.

Джо: Логично. После щелчка мы проверяем, правильно ли поль-зователь выбрал изображение.

Джим: Погодите-ка, что? Как проверить, правильно ли выбрано изображение?

Фрэнк: Условная конструкция!

Джим: Что?

Фрэнк: Условные конструкции позволяют проверить некоторое условие и выполнить код в зависимости от результата проверки.

Джо: Например, можно проверить, что переменная имеет опре-деленное значение или что два значения равны?

Фрэнк: Точно! Мы даже можем проверить, находится ли элемент внутри другого элемента... Думаю, здесь нам это пригодится.

Имя функции Имя аргумента

Функция возвращает случайное число.

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

в файл my_scripts.js новую функцию, которая получает один аргумент

(с именем num) и возвращает случайное число в интервале от 0 до  пе-

реданного числа. Присвойте функции имя getRandom.

Функции и аргументы — это, конечно, хорошо, но насколько мы приблизились к завершению кода страницы «Прыгаем

от радости»?Выглядит неплохо! Но это

только начало — посмо-

трим, что ваша группа

скажет о выборе «правиль-

ного» изображения…

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

Page 143: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 143

события и функции jquery

Óñëîâíûå êîíñòðóêöèè è ïðèíÿòèå ðåøåíèé

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

if( myBool == true ){

// Здесь что-то делаем!

}else{

// Иначе делаем что-то другое!

}

Проверяемое условие

Оператор проверки

равенства

Начало условной команды if

Переменная JavaScript

Код, который должен выполняться, если условие истинно.

Код, который должен выпол-няться, если усло-

вие ложно.

Примечание: команда if может и не содержать секции else, но вреда от нее не будет.

Расставьте магниты так, чтобы создать именованную функцию hideCode, которая при

помощи условной конструкции прячет новый элемент span с идентификатором has_discount в случайно выбранном элементе div класса .guess_box.

span

".guess_box"

has_discount

getRandom

hideCode

});

var = function (){

var numRand = (4);

$( ).each(function(index, value) {

if(numRand == index){

$(this).append("<span id=' '></ >");

return false;

}

}

{

)

()

}(

my_scripts.js

Развлечения с магнитами

Page 144: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

144 глава 3

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

var = function (){

var numRand = (4);

$( ).each(function(index, value) {

if(numRand == index){

$(this).append("<span id=' '></ >");

return false;

}

}

my_scripts.js

Расставьте магниты так, чтобы создать именованную функцию hideCode, которая при помощи

условной конструкции прячет новый элемент span с идентификатором has_discount в слу-

чайно выбранном элементе div класса .guess_box. Далее приводится наше решение.

Индекс элемента списка обозначает его текущую позицию в списке.

Индексы элементов всегда начинаются с 0.

Таким образом, индекс первого элемента равен 0, индекс второго — 1, и т. д. Мы еще вернемся к теме индексирования при рассмотрении массивов и цик-лов в главе 6.

>"span

)

if( R d i d

".guess_box"

'>has_discount

(getRandom

var numRand

hideCode

}

});

Условная кон-струкция срав-нивает текущую позицию списка со случайным

числом.

Наша именованная функция

Вызов функции, генериру-

ющей случайное число

Выход из цикла .each() Элемент discount до-

бавляется в элемент

класса .guess_box.

Развлечения с магнитами. Решение

Будьте осторожны!

Page 145: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 145

события и функции jquery

Потрясающе! Скидка каждый раз прячется в новом изображении. Да эти

функции действительно полезны!

function checkForCode(){

var discount;

if($.contains(this, document.getElementById("has_discount") ) )

{

var my_num = getRandom(5);

discount = "<p>Your Discount is "+my_num+"%</p>";

}else{

discount = "<p>Sorry, no discount this time!</p>" ;

}

$(this).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

}

my_scripts.js

Фрэнк: Да, безусловно. Нам удалось спрятать скидку, но как те-перь мы ее найдем?

Джим: Эээ... хороший вопрос. Я не знаю.

Джо: Полагаю, мы снова воспользуемся волшебными условными конструкциями?

Фрэнк: Точно. Вместо того чтобы выбирать случайный индекс в списке элементов .guess_box, мы переберем элементы и по-следовательно проверим, содержат ли они спрятанный элемент has_discount.

Джо: «Содержат?» Фрэнк, а ведь в этом что-то есть.

Фрэнк: Угу. Давайте посмотрим, чем нам поможет jQuery.

Задание!

Включите в функцию checkForCode но-вый код, основанный на идеях Джима, Фрэнка и Джо.Условная кон-

струкция про-веряет, нашел ли пользователь элемент div со скидкой.

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

discount

Этот метод jQuery проверя-ет, содержит ли первый пара-метр то, что определяется вторым пара-метром.

Текущий элемент —т. е. элемент,вызвавший функцию.

Поиск элемента DOM с идентификатором has_discount.

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

Page 146: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

146 глава 3

пользовательские функции

Пришло время написать несколько функций: первая гене-рирует случайное число, вторая прячет признак скидки, а третья проверяет наличие спрятанного признака.

$(document).ready(function() {

$(".guess_box").click( checkForCode );

function getRandom(num){

var my_num = Math.floor(Math.random()*num);

return my_num;

}

var hideCode = function(){

var numRand = getRandom(4);

$(".guess_box").each(function(index, value) {

if(numRand == index){

$(this).append("<span id='has_discount'></span>");

return false;

}

});

}

hideCode();

function checkForCode(){

var discount;

if($.contains(this, document.getElementById("has_discount") ) )

{

var my_num = getRandom(5);

discount = "<p>Your Discount is "+my_num+"%</p>" ;

}else{

discount = "<p>Sorry, no discount this time!</p>" ;

}

$(this).append(discount);

$(".guess_box").each( function(){

$(this).unbind('click');

});

}

}); //End document.ready()

my_scripts.js

Функция вызывается при щелчке на элементе, принад-лежащем классу .guess_box.

Именованная функция, скрывающая признак скидки

А эта функция проверя-

ет и сообщает размер

скидки.

Вызов именованной функции

Функция, генерирую-

щая случайное число

Задание!

Page 147: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 147

события и функции jquery

Íî ýòî åùå íå âñå

Только вы решили, что работа над рекламной акцией «Прыгаем от радости» завершена, как у Эмили появились новые требования…

От: ЭмилиТема: RE: Рекламная акция «Прыгаем от радости»

Привет,

Спасибо за все, что ты для нас сделал.

Я подумала, а нельзя ли «подсветить» изображение перед щелчком?

Пользователь будет точно знать, на каком изображении он щелкает, а это

поможет избежать недоразумений.

Кроме того, нельзя ли вывести сообщение о скидке в удобной текстовой

области под изображениями на экране? Допустим, код скидки будет состо-

ять из текста и числа? Я подумала, что это будет удобно... Да, и нельзя ли,

чтобы число было больше 10? Скажем, в диапазоне от 1 до 100?

Напиши, сможешь ли ты внести эти небольшие изменения.

--Эмили Сондерсjumpforjoyphotos.hg

Требования:

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

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

Page 148: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

148 глава 3

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

Требования:

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

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

• Вывести код скидки в специальной области страницы. Код должен состоять из текста и числа от 1 до 100.

Как показать пользователю, на какой области он собирается щелкнуть, до выполнения щелчка?

В: Обязательно ли указывать возвра-щаемое значение во всех функциях?

О: Формально необязательно. Все функции возвращают значение независимо от того, ука-зали вы его или нет. Если возвращаемое зна-чение не указано, то функция возвращает не-определенное значение undefined. Если ваш код не может обработать undefined, это приведет к ошибке. Следовательно, воз-вращаемое значение все же лучше указывать, даже в простейшем виде return false;.

В: Существуют ли ограничения для аргументов или параметров, передава-емых функции?

О: Нет, функции можно передать любой объект, элемент, переменную или значение. Также можно передать большее количество параметров, чем ожидает ваша функция. Лишние параметры игнорируются. Если передать слишком мало параметров, то недостающим параметрам автоматически присваивается undefined.

В: Что делает метод $.contains?

О: Это статический метод библиотеки jQuery, который получает два параметра. Он проверяет все дочерние элементы пер-вого параметра, ищет среди них второй па-раметр и возвращает true или false в зависимости от результата. В нашем примере выражение $.contains(document.body, document.getElementById"header")) истинно; с другой стороны, выражение $.contains(document.getElementById("header"), document.body) будет ложно.

В: Что такое «статический метод» jQuery?

О: Это означает, что функция связана с библиотекой jQuery, а не с конкретным объектом. Для вызова таких методов не нужен селектор, достаточно указать имя jQuery или его сокращенную форму ($).

В: Что делают index и value в нашей функции-обработчике . each?

О: index обозначает текущую итерацию цикла (начиная с 0 для первого элемен-та массива, возвращаемого селектором). value обозначает текущий объект, это аналог $(this) в цикле .each.

В: Почему наш цикл .each в функции hideCode возвращает false?

О: Команда return false в цикле .each приказывает прервать цикл и продолжить выполнение кода. При возвращении любого значения, отличного от false, цикл пере-ходит к следующему элементу в списке. В нашем примере скидка уже спрятана, поэтому остальные элементы перебирать необязательно.

Мозговой

штурм

частоЗадаваемые

вопросы

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

Page 149: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 149

события и функции jquery

<html>

<head>

<link href="styles/test_style.css" rel="stylesheet">

</head>

<body>

<div id="header" class="no_hover"><h1>Header</h1></div>

<button type="button" id="btn1">Click to Add</button>

<button type="button" id="btn2">Click to Remove</button>

<script src="scripts/jquery.1.6.2.js"></script>

<script src="scripts/my_test_scripts.js"></script>

</body>

</html>

class_test.html

Ìåòîäû ìîãóò èçìåíÿòü CSS

Следующая задача — «подсветить» область, на которую наведен указа-тель мыши, перед щелчком. Для изменения внешнего вида элемента проще всего воспользоваться CSS и классами CSS.

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

Создайте новые файлы отдельно от существующих и проследите за тем, как работают новые методы. Это поможет вам понять, как происходит «под-светка» области перед щелчком.

$(document).ready(function() {

$("#btn1").click( function(){

$("#header").addClass("hover");

$("#header").removeClass("no_hover");

});

$("#btn2").click( function(){

$("#header").removeClass("hover");

$("#header").addClass("no_hover");

});

});

.hover{

border: solid #f00 3px;

}

.no_hover{

border: solid #000 3px;

}

my_test_scripts.js

test_style.css

Помните по главам 1 и 2?

Готово к употреблению

Page 150: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

150 глава 3

тест-драйв

Äî ùåë÷êà

Ïîñëå ùåë÷êà

Здорово! Если бы все было так просто... А изменение CSS может срабатывать по другим причинам, кроме события click?

Да, может. И ничуть не сложнее...Переключение CSS может происходить по событию любого типа, но для нашего решения нужен вполне определенный тип события. Вернитесь к списку на с. 116 и попробуйте определить, какое событие следует использовать в нашем примере.

Ä ê

Ï

Откройте только что созданный файл class_test.html в браузере. При щелчке на кнопке Add класс применяется к области div с идентификатором header. Кнопка Remove снова удаляет назначенный класс!

Тест-драйв

Page 151: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 151

события и функции jquery

Äîáàâëåíèå ñîáûòèÿ hover

В параметрах события hover могут передаваться две функции-обработчика для событий mouseenter и mouseleave. Эти функции могут быть как именованными, так и анонимными. Внимательно просмотрите код тестового сценария и подумай-те, как использовать событие hover для изменения внешнего вида элемента при наведении на него указателя мыши.

$(".guess_box").hover(

function () {

// Обработчик события mouseenter

.

},

function () {

// Обработчик события mouseleave

});

Метод jQuery addClass назна-

чает элементу класс CSS. Он

не влияет на другие классы CSS,

уже назначенные элементу.

Метод jQuery removeClass отменяет класс CSS, на-значенный элементу.

Измените файлы my_style.css и my_scripts.js так, чтобы изображения визуально выде-лялись при наведении на них указателя мыши. Вам понадобится новый класс CSS и две функции-обработчика (после функции checkForCode), использующие ме-тоды addClass и removeClass для назначения/отмены класса CSS. Мы уже на-писали заготовки этих функций; вам остается лишь заполнить пропуски.

my_scripts.js

my_style.cssmy_style.css

Упражнение

Метод jQuery addClass назна-

чает элементу класс CSS. Он

не влияет на другие классы CSS,

уже назначенные элементу.

Метод jQuery removeClass отменяет класс CSS, на-значенный элементу.

$(document).ready(function() {

$("#btn1").click( function(){

$("#header").addClass("hover");

$("#header").removeClass("no_hover");

});

$("#btn2").click( function(){

$("#header").removeClass("hover");

$("#header").addClass("no_hover");

});

});

my_test_scripts.js

Page 152: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

152 глава 3

Тест-драйв

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

3

Откройте в браузере файл index.html, который включает ваш новый файл my_scripts.js. Наведите мышь на изображение и посмотрите, изменится ли внешний вид рамки.

Хмм... Рамка Хмм... Рамка изображения изображения меняет цвет, меняет цвет, но работа еще но работа еще не закончена...не закончена...

Это новый класс.

$(".guess_box").hover(

function () {

// this is the mouseenter event handler

$(this).addClass("my_hover");

},

function () {

// this is the mouseleave event handler

$(this).removeClass("my_hover");

});

.my_hover{

border: solid #00f 3px;

}

my_scripts.js

my_style.cssmy_style.cssНазначает класс CSS элементу, на который пользователь наводит ука-затель мыши, при помощи анонимной функции-об-работчика для события mouseenter.

Метод jQuery addClass назначает эле-менту класс CSS. Он не влияет на другие

классы, назначенные элементу ранее.

Метод jQuery removeClass отменяет назначение класса CSS элементу.

Анонимная функция-обработчик

для события mouseleave.

У нас есть класс CSS, для управления которым используется событие hover.

Page 153: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 153

события и функции jquery

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

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

Это требование еще из первого сообщения!

Измените код checkForCode так, чтобы функция:

1) выводила код скидки в специальной области страницы;

2) создавала код в виде комбинации из букв и числа в интер-вале от 1 до 100;

3) показывала посетителю, где был спрятан код, если попытка оказалась неудачной.

Чтобы упростить вашу задачу, мы создали классы CSS. Включите их в файл my_styles.css для обозначения того, правильно ли было вы-брано изображение.Заодно разместите под четырьмя изображения-ми элемент span с идентификатором result, в котором будет выводиться код скидки.

.discount{

border: solid #0f0 3px;

}

.no_discount{

border: solid #f00 3px;

}

my_style.cssmy_style.css

Åùå íåìíîãî...

• Визуально выделить область перед щелчком, чтобы пользователь точно знал, какой вариант он выбирает.

• Вывести код скидки в специальной области страницы. Код должен состоять из текста и числа от 1 до 100.

Упражнение

Page 154: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

154 глава 3

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

Функция checkForCode дополнена всеми необходимыми составляющими: отдельным местом на экране для вывода кода скидки; самим кодом скидки, состоящим из текста и чис-ла от 1 до 100; и выводом информации о местонахождении скидки после щелчка.

function checkForCode(){

var discount;

if($.contains(this, document.getElementById("has_discount") ) )

{

var my_num = getRandom(100);

discount = "<p>Your Code: CODE"+my_num+"</p> ;

}else{

discount = "<p>Sorry, no discount this time!</p>" ;

}

$(".guess_box").each(function() {

if($.contains(this, document.getElementById("has_discount")))

{

$(this).addClass("discount");

}else{

$(this).addClass("no_discount");

}

$(this).unbind();

});

$("#result").append(discount);

} // End checkForCode function

my_scripts.js

Проверяем, со-держит ли те-кущая область код скидки, с использова-нием функции jQuery contains.

...а если не уга-дал — исполь-зуем другое оформление.

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

Сообщение выводится на стра-

нице в специальной области.

Используем функцию getRandom для расширения числовой состав-ляющей кода до 100.

Выбираем выводимое сообщение в зависи-мости от того, нашел пользова-тель скидку или нет.

Page 155: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 155

события и функции jquery

Итак, функция checkForCode была успешно изменена. Проверьте, как рабо-тают новые возможности сайта. (Файл с окончательной версией кода можно загрузить по адресу http://thinkjquery.com/chapter03/end/scripts/my_scripts.js.)

Çàãðóæåííàÿ ñòðàíèöà

Ñêèäêè íåò

Êîä ñêèäêè

Отличная работа! Совсем другое дело. Рекламная акция повысит популярность

сайта, а Эмили сможет заработать!

Тест-драйв

Page 156: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

156 глава 3

инструментарий jQuery

Âàø èíñòðóìåíòàðèé jQuery

Глава 3 осталась позади, а ваш творческий инструментарий расширился: в нем появи-лись события, пользовательские функции и условные конструкции.

Функции

Фрагменты кода, которые мо-

гут использоваться в других

местах…

…но только в том случае,

если

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

Безымянные функции выпол-

няются только в точке свое

го

определения и не могут исполь-

зоваться в других местах.

Функции могут получать пере-

менные (называемые аргумента-

ми или параметрами), а также

могут возвращать результаты

своей работы.

Условные конструкцииПроверка логических условий (if XYZ = true) перед выпол-нением каких-либо операций.Часто содержат секцию else

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

События

Объекты, которые упроща-

ют взаимодействие пользо-

вателя с веб-страницей.

Всего существует около

30 типов событий. Практи-

чески все, что происходит

в браузере, может стать

источником события.

ГЛА

ВА 3

Page 157: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Операции со структурой страниц в jQuery4

Изменение DOM

Завершение загрузки страницы еще не означает, что ее структура останется неизменной. В главе 1 было показано, как в процессе загрузки страницы строится модель DOM, определяющая ее структуру. В этой главе вы научитесь перемещаться по дереву DOM, работать с иерархией эле-ментов и отношениями «родитель/потомок» для изменения структуры страницы «на ходу» средствами jQuery.

Родители у насобщие, но мы-товсе равно разные!

Page 158: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

158 глава 4

одна страница свяжет их воедино

У Александры, шеф-повара небольшого кафе в городке Интернет-виль, есть для вас работа. Ей приходится вести разные веб-страницы для двух разных версий своего меню: обычной и вегетарианской. Александра хочет создать одну страницу, которая бы при необходи-мости могла изменить меню для клиентов-вегетарианцев.

Мы разместили меню в Сети несколько лет назад, и клиентам это понравилось! Я хочу

добавить к нему кнопки, позволяющие клиентам изменять веб-меню «на ходу».

Èíòåðàêòèâíîå ìåíþ

Page 159: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 159

операции со структурой страниц в jQuery

Âåãåòàðèàíöû, âïåðåä!

Прежде чем браться за код jQuery, давайте посмотрим, какие файлы HTML и CSS нам прислал веб-дизайнер и насколько хороши их стиль и структура.

Нам нужна кнопка вегетарианского меню, которая

автоматически подставляет вегетарианские аналоги

в веб-меню.

Замена осуществляется по следующим правилам:

— у рыбных блюд аналогов нет, они просто удаля-

ются из меню;

— гамбургеры заменяются гигантскими шампиньо-

нами;

— мясные ингредиенты (кроме гамбургеров) и яйца

заменяются тофу.

Нам также понадобится вторая кнопка, восстанавли-

вающая меню в исходном состоянии.

P. S. И еще хотелось бы, чтобы замененные вегета-

рианские блюда в меню были помечены — например

зеленым листом.

Веб-дизайнер пришлет файлы текущего меню,

чтобы ты мог приступить к работе.

Вот чего хочет Александра:

ГГГррраааннн--ккаа

фее ИИИннтттеернннееетттвввииилляя

На этот раз отдельного упражнения с записью требо-ваний не будет (хотя, наверное, вы уже к ним привыкли?). Тем не менее обязательно изложите суть требований своими слова-ми — это поможет вам четко представлять, что именно мы здесь строим.

Page 160: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

160 глава 4

построение дерева DOM

body

h4

li

li

li

ul class="menu_list"

li

li

li li

li

li

li

li

li

lili

li

ul class="menu_list"

ul class="menu_list"

ul class="menu_entrees"

div class="left_col"

div class="menu_wrapper"

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

модели DOM. Ниже вы найдете все магниты с элементами, необходимыми для

заполнения всех пропусков. Достройте дерево, используя фрагмент разметки

HTML на следующей странице. Позиции для размещения магнитов обозначены

кружочками. Мы уже разместили несколько элементов за вас.

Развлечения с магнитами

Page 161: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 161

операции со структурой страниц в jQuery

Фрагмент реальной страницы HTML

<body> <div id="menu_wrapper"> <div class="left_col"> <h4>Dinner Entrees</h4> <ul class="menu_entrees"> <li>Thai-style Halibut <ul class="menu_list"> <li>coconut milk</li> <li>pan-fried halibut</li> <li>early autumn vegetables</li> <li>Thai spices </li> </ul> </li> <li>House Grilled Panini <ul class="menu_list"> <li>prosciutto</li> <li>provolone</li> <li>avocado</li> <li>sourdough roll</li> </ul> </li> <li>Southwest Slider <ul class="menu_list"> <li>whole chiles</li> <li>hamburger</li> <li>pepperjack cheese</li> <li>multigrain roll</li> </ul> </li> </ul> </div> </div></body>

index.html

Page 162: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

162 глава 4

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

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

отношению к родительским элементам списка блюд. Такую раз-

метку никак не назовешь предельно понятной или однозначной,

не правда ли?

Развлечения с магнитами. Решение

body

h4

li li li

ul class="menu_list"

lili li li li lili li li lili li

Каждое блюдо представляет

собой пункт списка…

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

…с перечнем ингредиентов

(ul.menu_list) в виде вло-

женного неупорядоченного

списка.

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

Меню использует неупорядоченный

список для хранения блюд.

ul class="menu_list"

ul class="menu_list"

ul class="menu_entrees"

div class="left_col"

div class="menu_wrapper"

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

Page 163: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 163

операции со структурой страниц в jQuery

Фрагмент реальной страницы HTML

<body> <div id="menu_wrapper"> <div class="left_col"> <h4>Dinner Entrees</h4> <ul class="menu_entrees"> <li>Thai-style Halibut <ul class="menu_list"> <li>coconut milk</li> <li>pan-fried halibut</li> <li>early autumn vegetables</li> <li>Thai spices </li> </ul> </li> <li>House Grilled Panini <ul class="menu_list"> <li>prosciutto</li> <li>provolone</li> <li>avocado</li> <li>sourdough roll</li> </ul> </li> <li>Southwest Slider <ul class="menu_list"> <li>whole chiles</li> <li>hamburger</li> <li>pepperjack cheese</li> <li>multigrain roll</li> </ul> </li> </ul> </div> </div></body>

index.html

Четкая структура веб-страницы (HTML) существенно упрощает написание кода jQuery. Однако элементы ингредиентов, которые нужно найти, не имеют пометок, которые бы упрощали программирование jQuery. Как же упростить выбор элементов?

Мозговой

штурм

Page 164: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

164 глава 4

классные ингредиенты

Íàçíà÷åíèå êëàññîâ ýëåìåíòàì

Как было показано во всех предыдущих главах, эффективность поиска элементов веб-страниц средствами jQuery можно повысить за счет правильного определения структуры HTML и CSS. Чтобы структура по-настоящему заработала, следует включить в таблицу стилей классы и иден-тификаторы и задать соответствующие классы и идентификаторы в атрибутах элементов HTML. Это упростит выбор элементов и сэкономит ваше время при программировании.

В jQuery роль селекторов не ограничивается управлением внешним видом и поведением стра-ницы. Селекторы также используются в jQuery для идентификации элементов страниц.

.meat

<li class="meat">turkey</li>

<li class="meat">chicken</li>

<li class="meat">eggs</li>

<li class="meat">lamb shoulder</li>

Можно написать отдельный се-лектор для каждого ингредиента, который нужно найти на странице...

…а можно сгруппиро-вать их в классе и на-писать один селектор для идентификации сразу всех элементов.

<li>turkey</li><li>chicken</li> <li>eggs</li> <li>lamb shoulder</li>

При задании атрибута class каждого элемен-та, входящего в список, этот элемент вклю-чается в класс meat («мясо»).

Что я делаю в категории

«мясо»?

Да ладно, это же не магазин... Просто нам нужно короткое, удоб-ное имя класса.

Page 165: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 165

операции со структурой страниц в jQuery

Найдите ингредиенты, которые должны заменяться вегетарианскими аналогами, и назначьте каждому из них соответствующий класс (fish, meat или hamburger). Если ингредиенту не ну-жен класс, оставьте строку пустой. Структура кода HTML соответствует внешнему виду меню на странице.

<li>Thai-style Halibut

<ul class="menu_list">

<li >coconut milk</li>

<li >pan-fried halibut</li>

<li >lemongrass broth</li>

<li >vegetables</li>

<li >Thai spices </li>

</ul>

</li>

<li>Braised Delight

<ul class="menu_list">

<li >lamb shoulder</li>

<li >cippolini onions</li>

<li >carrots</li>

<li >baby turnip</li>

<li >braising jus</li>

</ul>

</li>

<li>House Grilled Panini

<ul class="menu_list">

<li >prosciutto</li>

<li >provolone</li>

<li >avocado</li>

<li >cherry tomatoes</li>

<li >sourdough roll</li>

<li >shoestring fries </li>

</ul>

</li>

<li>House Slider

<ul class="menu_list">

<li >eggplant</li>

<li >zucchini</li>

<li >hamburger</li>

<li >balsamic vinegar</li>

<li >onion</li>

<li >carrots</li>

<li >multigrain roll</li>

<li >goat cheese</li>

</ul>

</li>

<li>Frittata

<ul class="menu_list">

<li >eggs</li>

<li >Asiago cheese</li>

<li >potatoes </li>

</ul>

</li>

<li>Coconut Soup

<ul class="menu_list">

<li >coconut milk</li>

<li >chicken</li>

<li >vegetable broth</li>

</ul>

</li>

<li>Soup Du Jour

<ul class="menu_list">

<li >grilled steak</li>

<li >mushrooms</li>

<li >vegetables</li>

<li >vegetable broth </li>

</ul>

</li>

<li>Hot and Sour Soup

<ul class="menu_list">

<li >roasted pork</li>

<li >carrots</li>

<li >Chinese mushrooms</li>

<li >chili</li>

<li >vegetable broth </li>

</ul>

</li>

<li>Avocado Rolls

<ul class="menu_list">

<li >avocado</li>

<li >whole chiles</li>

<li >sweet red peppers</li>

<li >ginger sauce</li>

</ul>

</li>

class="meat"

Упражнение

Page 166: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

166 глава 4

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

Найдите ингредиенты, которые должны заменяться вегетарианскими аналогами, и назначьте каждому из них соответствующий класс (fish, meat или hamburger). Если ингредиенту не ну-жен класс, оставьте строку пустой. Структура кода HTML соответствует внешнему виду меню на странице.

<li>Thai-style Halibut

<ul class="menu_list">

<li >coconut milk</li>

<li >pan-fried halibut</li>

<li >lemongrass broth</li>

<li >vegetables</li>

<li >Thai spices </li>

</ul>

</li>

<li>Braised Delight

<ul class="menu_list">

<li >lamb shoulder</li>

<li >cippolini onions</li>

<li >carrots</li>

<li >baby turnip</li>

<li >braising jus</li>

</ul>

</li>

<li>House Grilled Panini

<ul class="menu_list">

<li >prosciutto</li>

<li >provolone</li>

<li >avocado</li>

<li >cherry tomatoes</li>

<li >sourdough roll</li>

<li >shoestring fries </li>

</ul>

</li>

<li>House Slider

<ul class="menu_list">

<li >eggplant</li>

<li >zucchini</li>

<li >hamburger</li>

<li >balsamic vinegar</li>

<li >onion</li>

<li >carrots</li>

<li >multigrain roll</li>

<li >goat cheese</li>

</ul>

</li>

<li>Frittata

<ul class="menu_list">

<li >eggs</li>

<li >Asiago cheese</li>

<li >potatoes </li>

</ul>

</li>

<li>Coconut Soup

<ul class="menu_list">

<li >coconut milk</li>

<li >chicken</li>

<li >vegetable broth</li>

</ul>

</li>

<li>Soup Du Jour

<ul class="menu_list">

<li >grilled steak</li>

<li >mushrooms</li>

<li >vegetables</li>

<li >vegetable broth </li>

</ul>

</li>

<li>Hot and Sour Soup

<ul class="menu_list">

<li >roasted pork</li>

<li >carrots</li>

<li >Chinese mushrooms</li>

<li >chili</li>

<li >vegetable broth </li>

</ul>

</li>

<li>Avocado Rolls

<ul class="menu_list">

<li >avocado</li>

<li >whole chiles</li>

<li >sweet red peppers</li>

<li >ginger sauce</li>

</ul>

</li>

class=″meat"

class=″meat"class=″fish"

class=″meat"

class=″meat"

class=″hamburger"

class=″meat"

class=″meat"

Page 167: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 167

операции со структурой страниц в jQuery

Ñîçäàíèå êíîïîê

Предварительная подготовка в основном завершена — пора вернуться к салфетке с тре-бованиями шеф-повара. На следующем этапе вы должны создать две кнопки:

Измените разметку и сценарный код, чтобы создать две кнопки, описанные выше.

Присвойте кнопке перехода на вегетарианское меню идентификатор vegOn, а кноп-

ке восстановления меню — идентификатор restoreMe.

— Вторая кнопка должна восстанавливать меню в исходном состоянии.В д

— Кнопка «Go Vegetarian» автоматически заменяет непод-

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

<div class="topper">

<h2>Our Menu</h2>

<ul>

<li class="nav"> </li>

<li class="nav"> </li>

</ul>

</div>

$(document).ready(function() {

var v = false;

if (v == false){

v = true}

});//end button

if (v == true){

v = false;}

});//end button

});//end document ready

index.html

my_scripts.js

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

Page 168: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

168 глава 4

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

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

выше. Присвойте кнопке перехода на вегетарианское меню идентификатор

vegOn, а кнопке восстановления меню — идентификатор restoreMe.

<div class="topper">

<h2>Our Menu</h2>

<ul>

<li class="nav"> </li>

<li class="nav"> </li>

</ul>

</div>

$(document).ready(function() {

var v = f;

if (v == false){

v = true;}

});//end button

if (v == true){

v = false;}

});//end button

});//end document ready

index.html

my_scripts.js

<button id=″vegOn">Go Vegetarian</button>

<button id=″restoreMe">Restore Menu</button>

$("button#restoreMe").click(function(){

Создание элементов button с идентификаторами vegOn и restoreMe.

С кнопками связы-вается метод click.

В уточненный селектор входит как тип, так и идентификтор элемента.

$("button#vegOn").click(function(){

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

Page 169: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 169

операции со структурой страниц в jQuery

×òî äàëüøå?

Быстро справились! Две кнопки готовы. Вычеркнем их из списка требо-ваний и перейдем к тому, что должна делать кнопка «Go Vegetarian».

Сформулируйте (своими словами) описания трех операций, которые должна выполнять кнопка перехода на вегетарианское меню.

1.

2.

3.

Нам также понадобится вторая кнопка, восста-навливающая меню в исходном состоянии.

Нам д б в

Нам нужна кнопка вегетарианского меню, которая автома-

тически подставляет вегетарианские аналоги в веб-меню.

Замена осуществляется по следующим правилам:

— у рыбных блюд аналогов нет, они просто уда-

ляются из меню;

— гамбургеры заменяются гигантскими шам-

пиньонами;

— мясные ингредиенты (кроме гамбургеров)

и яйца заменяются тофу.

Упражнение

Page 170: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

170 глава 4

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

1.

2.

3.

Найти элементы li класса fish и удалить соответствующие блюда из меню.

Найти элементы li класса hamburger и заменить их гигантскими шампиньо-нами.

Найти элементы li класса meat и заменить их тофу.

Начнем с первого пункта: найти элементы li класса fish и удалить их из меню. В главе 2 мы находили элементы при помощи селекторов классов и удаляли их из DOM методом remove.

jQuery также поддерживает метод detach. Оба элемента — detach и remove — удаляют элементы из DOM. Чем отличаются эти два метода и какой из них следу-ет использовать в нашей ситуации?

Не огорчайтесь, если ваши ответы получились не-много другими. Навыки перевода требований в фор-мальные описания операций приходят с практикой.

div id="top"

div class="pic_box"

img id="thumbnail"

remove detach

$("img#thumbnail").remove(); $("img#thumbnail").detach();

div id="top"

div class="pic_box"

img id="thumbnail"

Метод remove удаляет элемент из DOM.

Метод detach извлекает выбранный элемент(-ы) из DOM, но продолжает хранить, чтобы позднее его можно было вернуть на место.

Нужно изба-виться от элементов

раз и навсегда?

Временно изыму элементы из DOM

и придержу их для вас.

Вашэлемент

Сформулируйте (своими словами) описания трех операций, которые должна выполнять кнопка перехода на вегетарианское меню.

Page 171: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 171

операции со структурой страниц в jQuery

Напишите справа селектор и вызов remove или detach, кото-

рый приведет к показанному результату.

li

ul class="menu_list"

ul class="menu_entrees"

li class="fish"

li li li

div id="top"

div class="pic_box"

Команда jQueryРезультат в DOM

div id="news_story"

p p img

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

Page 172: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

172 глава 4

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

Напишите справа селектор и вызов remove или detach,

который приведет к показанному результату.

li

ul class="menu_list"

ul class="menu_entrees"

li class="fish"

li li li

div id="top"

div class="pic_box"

Команда jQueryРезультат в DOM

div id="news_story"

p p img

$(″div#top").remove()

Когда для элемен-та выполняется метод remove или detach, все его до-черние элементы также исключа-ются из дерева.

$(″div p").detach()

$(″li.fish").detach()

Не забывайте,что отсоединя-

ются все эле-менты, соот-ветствующие

селектору.

Группировка эле-ментов по классу или идентифика-тору упрощает их выбор.

li

p, p

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

Page 173: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 173

операции со структурой страниц в jQuery

Включите строку из решения в функцию click кнопки vegOn из файла my_scripts.js. Откройте страницу в своем любимом браузере и убедитесь в том, что она работает правильно.

До выполнения $("li.fish").detach().

После выполнения $("li.fish").detach() ис-чезают все элементы с классом fish.

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

Как приказать DOM исключить из меню все блюдо?

Мы удалили эти элементы...

…а нужноудалить все блюдо.

Тест-драйв

Page 174: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

174 глава 4

обход дерева

В главе 1 вы узнали, что модель DOM имеет древовидную структуру. У дерева DOM есть корень, ветви и узлы. Интерпретатор JavaScript, встроенный в браузер, может обходить элементы дерева DOM (и выполнять операции с ними), причем jQuery особенно хорошо подходит для этой работы. Под «обходом дерева» понимаются перемещения вверх и вниз по дереву DOM.

Мы уже выполняли различные операции с DOM, начиная с главы 1. Примером таких операций служит только что рассмотренный метод detach (динамическое исключение элементов из DOM).

Но какие еще возможности открывает обход дерева? Чтобы понять, как работает обход, возьмем один раздел меню и представим его в виде дерева DOM.

Ïåðåìåùåíèå ïî äåðåâó DOM

li li li

ul class="menu_list"

lili class="fish"

li li li lili li li lili li

Надевайте альпинистское снаря-жение! Перемещаться по дереву DOM можно во всех направлениях: вверх и вниз, вправо и влево.

ul class="menu_list"

ul class="menu_list"

р

ul class="menu_entrees"

Чтобы подняться по дереву DOM, мы используем метод jQuery parent.

Чтобы спуститься по дереву DOM, мы используем метод jQuery children.

Для горизонтального перемещения по дереву DOM используются ме-тоды jQuery prev и next.

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

Лазаем по дереву DOM... Очень мило. Но как это мне поможет с удалением блюд

из меню?

Page 175: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 175

операции со структурой страниц в jQuery

Какой из этих методов поможет убрать из меню блюда, содержащие элементы класса fish?

Ìåòîäû îáõîäà äåðåâà DOM

Чтобы объяснить DOM, что мы хотим удалить блюда, в которые входят элемен-ты класса fish, необходимо идентифицировать эти элементы по связи между ними. Методы обхода дерева jQuery предоставляют такую возможность.

$(".fish"). parent()

$(".fish"). next()$(".fish"). prev()

Дочерние элемен-ты ul.menu_list.

Родитель li.fish

Выбираем все эле-менты класса fish.

Затем переходим к элемен-ту, который находится над этими элементами.

ul class="menu_list"

li class="fish"

$(".menu_list"). children()

Выбираем все элемен-ты класса menu_list.

Затем переходим к элементам, нахо-дящимся под этими элементами.

Выбираем все эле-менты класса fish.

Затем переходим к сле-дующему элементу с тем же родителем, находя-щимся слева.

Выбираем все эле-менты класса fish.

Затем переходим к следующе-му элементу с тем же роди-телем, находящимся справа.

li li

ul class="menu_list"

li li class="fish"

li li

ul class="menu_list"

li li class="fish"

Родитель li.fish

li li

ul class="menu_list"

li li class="fish"

Мозговой

штурм

Page 176: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

176 глава 4

долой слабые звенья!

Ñöåïëåííûå âûçîâû ìåòîäîâ

А если потребуется переместиться еще выше, ниже или глубже? Используйте сцепление методов — этот механизм по-вышает эффективность перемещения по страницам и вы-полнения операций с ними. Вот как он работает:

$(".fish").parent(). parent()

Родитель li.fish.

Чтобы подняться еще на один уровень наверх, включите еще один метод в цепочку.

Р д

ul class="menu_list"

li class="fish"

liРодитель родителя li.fish.

$(".menu_list").parent().next().remove()

Также цепочка может состоять

из разных методов.

li

li

ul class="menu_list"

ul class="menu_entrees"

Метод parent под-нимается к ро-дительскому элементу, содер-жащему выбранный элемент(-ы).

1

Метод next переме-щается к следующему элементу справа.

2

Метод remove удаля-ет элемент, к кото-рому мы перешли, из дерева DOM.

3

Первый метод parent в цепочке приводит сюда.

1

Второй метод parent в цепочке приводит сюда.

2

Page 177: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 177

операции со структурой страниц в jQuery

wЗагрузите страницу http://www.thinkjquery.com/chapter04/traversal/ и откройте кон-соль JavaScript в средствах разработчика вашего браузера. О средствах разработчика раз-ных браузеров рассказано в разделе «Примите к сведению» в начале книги. Выполните каждый из методов обхода со сцепленным методом detach, как показано ниже. Запиши-те, почему этот вызов поможет (или не поможет) в решении нашей задачи.Важно: Не забывайте обновлять страницу после выполнения каждой команды.

$(".menu_entrees").children().detach()

$(".fish").parent().parent().detach()

$(".fish").parent().detach()

$(".menu_list").children().detach()

Упражнение

Page 178: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

178 глава 4

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

Этот вызов отсоединяет элементы, дочерние по отношению к .menu_entrees. Он не подойдет для удаления блюд, содержащих рыбу, потому что он удаляет ВСЕ блюда в списке. Не то, что нам нужно...

Удаляются все блюда.

$(".menu_entrees"). children().detach()

$(".menu_list").children().detach()

Удаляются списки ингредиентов из всех блюд.

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

Загрузите страницу http://www.thinkjquery.com/chapter04/traversal/ и откройте кон-соль JavaScript в средствах разработчика вашего браузера. О средствах разработчика раз-ных браузеров рассказано в разделе «Примите к сведению» в начале книги. Выполните каждый из методов обхода со сцепленным методом detach, как показано ниже. Запиши-те, почему этот вызов поможет (или не поможет) в решении нашей задачи.Важно: Не забывайте обновлять страницу после выполнения каждой команды.

Page 179: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 179

операции со структурой страниц в jQuery

Этот вызов отсоединяет родительский элемент .fish. Он не подойдет для удаления блюд, содержащих рыбу, потому что он недостаточно высоко поднимается по дереву DOM. Вместо этого он удаляет эле-мент ul.menu_list (и все, что находится под ним).

Этот вызов отсоединяет родительский элемент .fish.Он делает именно то, что нам нужно.

$(".fish").parent().parent().detach()

$(".fish"). parent().detach()

Мы удалили список ингредиен-тов блюда, но не само блюдо.

То, что нужно - исчезли

только рыбные блюда.

Page 180: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

180 глава 4

куда девались элементы?

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

li li li

ul class="menu_list"

lili class="fish"

li li li li li li li li

ul class="menu_list"

ul class="menu_list"

ul class="menu_entrees"

li class="fish"

li class="fish"

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

Вызов $(".fish")parent().parent().detach() удаляет из DOM элементы трех блюд, содержащих ингредиенты класса fish.

Постойте-ка, разве мы не должны восстановить рыбные блюда в меню при

программировании второй кнопки?

Рыбные блюда должны вернуться в дерево DOM. Что для этого с ними нужно сделать?

Мозговой

штурм

Page 181: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 181

операции со структурой страниц в jQuery

Мы повидали уже немало конструкций jQuery и JavaScript. Какие из них нам

пригодятся для восстановления элементов класса .fish? Запишите для каж-

дой конструкции в столбце «Нужно ли использовать?» свой ответ «Да» или

«Нет» и объясните, почему вы выбрали (или не выбрали) эту конструкцию.

Один ответ мы уже записали, за вами еще три.

Нужно ли

использо-

вать?

Почему?

Завершитель Нет Завершитель — простой признак конца команды. Он не имеет отношения к восстановлению отсоединенных эле-ментов.

Переменная

Функция

Селектор

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

Page 182: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

182 глава 4

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

Нужно ли

использо-

вать

Почему?

Завершитель Нет Завершитель — простой признак конца команды. Он не имеет отношения к восстановлению отсоединенных эле-ментов.

Переменная Да Переменные используются для хранения информации. Если сохранить отсоединенные элементы в переменной, мы смо-жем их вернуть в дерево DOM, просто сославшись на пере-менную.

Функция Нет Функции выполняют операции с данными. Задача восста-новления отсоединенных элементов относится к хранению данных, а не к их обработке.

Селектор Нет Селектор выбирает элементы DOM. В нашем случае эле-менты уже выбраны, а нам нужен способ их сохранения.

В: А если я захочу избавиться от дан-ных, хранящихся в элементе, но чтобы сам элемент остался на месте?

О: Для удаления содержимого эле-мента можно воспользоваться методом empty. Например, для удаления всего текста из абзацев страницы достаточ-но выполнить следующую команду:$("p").empty();.

В: Можно ли обойти всех родителей элемента?

О: Да. Кроме метода parent, jQuery также поддерживает метод parents, об-ходящий всех родителей выбранного эле-мента. Позднее в этой главе будет приведен пример использования parents.

В: А если я хочу найти родительский элемент, ближайший к выбранному?

О: Воспользуйтесь методом closest. Как и метод parents, метод closest поднимается вверх по цепочке родителей, но останавливается при первом совпадении. Например, если вы хотите найти ближайший элемент ul над пунктом списка, используй-те команду: $("li").closest("ul").

В: Я уже знаю методы n e x t и previous, а если мне потребуется обойти все одноуровневые элементы дерева DOM?

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

В: Браузер Google Chrome содержит встроенную поддержку jQuery?

О: Нет. Мы можем выполнять код jQuery в средствах разработчика браузера Chrome только потому, что мы включили jQuery в страницу HTML. Если в открытой веб-странице не используется jQuery, вы не сможете выполнять команды jQuery в кон-соли JavaScript Chrome.

Возьми в руку карандаш Решение Мы повидали уже немало конструкций jQuery и JavaScript. Какие из них нам

пригодятся для восстановления элементов класса .fish? Запишите для каж-

дой конструкции в столбце «Нужно ли использовать?» свой ответ «Да» или

«Нет» и объясните, почему вы выбрали (или не выбрали) эту конструкцию.

Ниже приведен наш ответ.

частоЗадаваемые

вопросы

Page 183: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 183

операции со структурой страниц в jQuery

 ïåðåìåííûõ òàêæå ìîãóò õðàíèòüñÿ ýëåìåíòû

Переменные — штука весьма полезная; вот и сейчас они нам пригодятся. Вы уже встречались с переменными в первых трех главах, но тогда они использовались для хранения чисел и текстовых строк. А разве не удобно было бы хранить в перемен-ных еще и элементы DOM? Оказывается, такая возможность существует.

Браузер временно сохраняет полученные элементы в памяти. Если мы захотим воспользоваться ими позднее в своем коде, их нужно сохранить в переменной. Но как это сделать?

Интерпретатор JavaScript

DOM-версия страницы

$(".fish").parent().parent().detach();

ul class="menu_list"

lili class="fish"

li li li li li li li li

ul class="menu_list"

ul class="menu_list"

li class="fish"

lli class="fish"

li li li

Выполняется метод detach.1

Интерпретатор JavaScript при помо-щи библиотеки jQuery запрашивает у DOM нужные элементы.

2 DOM выбирает элементы и воз-вращает их интерпретатору.

3

Код jQuery

Засценой

Пожалуйста.

DOM, дай мне все эле-менты страницы с атрибутом

класса fish.

Page 184: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

184 глава 4

знак $

$f = $(".fish").parent().parent().detach();

Знак $ в начале имени переменной указывает, что здесь хранятся элементы, полученные от jQuery.

È ñíîâà çíàê $...

Сохранить элементы совсем не сложно. Создайте переменную (как для обычных чис-ловых и текстовых данных) и присвойте ей (при помощи знака =) результат команды, возвращающей элементы. Но разве не полезно было бы с первого взгляда видеть, что в переменной хранятся специальные данные — например элементы (вместо чисел и строк)? У программистов jQuery принято начинать имена переменных, предназначен-ных для хранения возвращаемых jQuery элементов, со знака $. Тогда любой програм-мист, который будет читать ваш код, сразу поймет, что в переменной хранятся данные, полученные от jQuery.

ul class="menu_list"

lili class="fish"

li li

li li li

li li li

ul class="menu_list"

ul class="menu_list"

li class="fish"

lli class="fish"

li

li

li

$f

Конечно, хранить много элементов в одной пере-менной неудобно.Поэтому в jQuery для хране-ния элементов используются массивы JavaScript. Давайте по-смотрим, что это такое.

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

ных элементов в одном контейнере? Разве это удобно?

Page 185: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 185

операции со структурой страниц в jQuery

Каждый раз, когда мы выбираем элементы DOM и сохраняем их в переменной, jQuery возвращает данные в виде массива. В сущности, массив — это перемен-ная с расширенными возможностями хранения данных.

Õðàíåíèå äàííûõ â ìàññèâàõ

В простой переменной хранится одно значение.

42Переменная

Хранимое значение

$a

Если весь массив на-

зывается $a, то для

обращения к отдель-

ной ячейке исполь-

зуется запись $a[n],

где n — номер ячейки

(нумерация начина-

ется с 0).

Массив

Имя пере-менной

$a[5]$a[4]$a[3]$a[2]$a[1]$a[0]

Массив представля-ет собой структу-ру данных, которая может содержать несколько переменных (как подставка содер-жит несколько про-бирок).

vВы можете сохранить и извлечь данные из любой ячейки. Например, для сохранения значения «15» в третьей ячейке используется следующая команда:

$a[2] = 15;

В массиве хранится много значений.

4 8 15 16 23 42

Третья ячейка имеет номер 2, потому что ну-мерация начинается с 0.

v

Для любознательных

Имена массивов необязательно начинать со зна-

ка доллара ($). Обозначение массивов jQuery зна-

ком $  — всего лишь распространенное правило,

принятое среди разработчиков jQuery.

Page 186: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

186 глава 4

так аккуратно!

Õðàíåíèå ýëåìåíòîâ â ìàññèâå

$f = $(".fish").parent().parent().detach();

ul class="menu_list"

lili class="fish"

li li

li

ul class="menu_list"

lili class="fish"

li li

li

ul class="menu_list"

lili class="fish"

li li

li

Когда мы выбираем и отсоединяем элементы li и присваиваем результат опера-ции переменной ($f), jQuery берет элементы, полученные от DOM, и аккуратно сохраняет их в массиве JavaScript. А когда позднее потребуется вернуть элементы обратно в массив, эта задача будет решаться намного проще.

Каждый отсоединенный эле-мент аккуратно помещается в одну из ячеек массива $f.

jQuery берет элементы,

полученные от DOM,

и аккуратно сохраняет

их в массиве.

$f

Элементы сохраняются вместе со всем содержимым. Все элементы можно легко вернуть обратно в страницу.$f[2]$f[1]$f[0]

Р А СС Л А Б Ь Т Е С Ь

Возможности массивов этим не ограничиваются.

Но сейчас не стоит отвлекаться от основной темы. Массивы на-много подробнее рассматрива-ются в главе 6.

Page 187: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 187

операции со структурой страниц в jQuery

1.

2.

3.

Включите приведенную на предыдущей странице строку кода, которая отсоеди-няет родителей элементов #fish, в функцию-обработчик click кнопки vegOn в файле my_scripts.js. Затем откройте страницу в своем любимом браузере и убе-дитесь в том, что все правильно работает.

Получилось! Давайте сверимся со списком.

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

То, чего мы хотели:

рыбные блюда исключены

из меню.

Мы уже умеем исключать элементы из DOM, но как динами-чески заменить содержимое DOM другим содержимым?

Найти элементы li класса fish и удалить соответствующие блюда из меню.Найти элементы li класса hamburger и заменить их гигантскими шампиньонами.Найти элементы li класса meat и заменить их тофу.

Тест-драйв

Мозговой

штурм

Page 188: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

188 глава 4

шило на мыло

...и ставлю на его место что-то

другое.

Èçìåíåíèå ýëåìåíòîâ ìåòîäîì replaceWith

Метод replaceWith позволяет заменить выбранные элементы новыми эле-ментами. Когда вам потребуется провести подобную замену в DOM, исполь-зуйте этот удобный метод jQuery. Допустим, вы хотите динамически заменить элемент заголовка 2-го уровня с текстом «Our Menu» заголовком 1-го уровня с текстом «My Menu». Вот как это делается методом replaceWith:

$("h2").replaceWith("<h1>My Menu</h1>");

Выбираем все элементы h2.

Заменяем выбранные элементы...

…содержимым, заключенным в скобки.

Интерпретатор JS находит эле-мент заголовка 2-го уровня…

1 …и заменяет его содержимым в круглых скобках. В модели DOM появляется новый элемент и новое содержимое.

2

h2

body

<h1>My Menu</h1>

body

h1

Я забираю выбранный эле-мент из DOM...

Page 189: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 189

операции со структурой страниц в jQuery

li class="hamburger"

ul class="menu_list"

Напишите код, который находит элементы li класса hamburger и заменяет их элемен-тами li класса portobello. Следующая схема поможет вам лучше представить суть задачи. Мы уже написали часть решения за вас; допишите остальное.

?Код, который вы напишете здесь…

li class="hamburger"

li class="portobello"

ul class="menu_list"

ul class="menu_list"

То, что за-меняется.

То, что долж-но остаться после замены.

×åì ïîìîæåò replaceWith?

Итак, мы должны найти элементы li класса hamburger и заменить их элементами li класса portobello. Но прежде чем браться за про-граммирование, стоит лишний раз подумать над задачей.

$( ).replaceWith( <em>Portobello Mushroom</em> );

Так должна вы-глядеть страница после замены.

...должен де-лать это.

Упражнение

Page 190: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

190 глава 4

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

Включите вызов replaceWith в функцию click кнопки vegOn в фай-ле my_scripts.js. Откройте страницу в своем любимом браузере и нажмите кнопку «Go Vegetarian». Убедитесь в том, что все работает правильно.

Гамбургеры заменены шампиньонами.

li class="hamburger"

ul class="menu_list"

Напишите код, который находит элементы li класса hamburger и заменяет их эле-ментами li класса portobello. Следующая схема поможет вам лучше понять суть задачи. Вот как выглядит наше решение:

?$( ).replaceWith( <em>Portobello Mushroom</em> );″.hamburger″ ″<li class=‘portobello’> </li>″

Выбираем все элементы класса hamburger.

Метод replaceWith динамически заменяет выбранное содер-

жимое элементом в круглых скобках. Главное — помнить,

что круглые скобки могут содержать код HTML.

Тест-драйв

Page 191: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 191

операции со структурой страниц в jQuery

Что там следующее в нашем списке?

Íå òîðîïèòåñü ñ replaceWith

Нужно найти элементы класса meat и заменить их элементами класса tofu.

li class="meat"

ul class="menu_list"

li class="tofu"

Вообще-то на этот раз replaceWith не подойдет.

Это же просто! Снова используем replaceWith,

верно?

Метод jQuery replaceWith — простой и мощ-ный инструмент. Но, к сожалению, для решения этой задачи он не подходит. Почему?

Мозговой

штурм

1.

2.

3.

Найти элементы li класса fish и удалить соответствующие блюда из меню.Найти элементы li класса hamburger и заменить их гигантскими шампиньонами.Найти элементы li класса meat и заменить их тофу.

Page 192: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

192 глава 4

неоднозначная замена

Êîãäà replaceWith íå ïîäõîäèò

Метод replaceWith хорошо подходит для вы-полнения замены типа «один к одному» — на-пример, замены класса hamburger классом portobello.

Замена «многие к одному»Çàìåíà «ìíîãèå ê îäíîìó»

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

Замена «один ко многим»Çàìåíà «îäèí êî ìíîãèì» Да, мы можем взять элемен-ты класса meat и заменить их все на tofu.

Но когда позднее потребуется выбрать тофу и восстановить старыми элемента-ми, возникает проблема. Модель DOM о них уже не помнит!

Тофу можно заменить одним типом мяс-ных ингредиентов, но это совсем не то, что нам нужно.

Таким образом, замену придется выпол-нять в два этапа.

Позднее DOM уже ничего не помнит о разных типах мясных ингреди-ентов.

Вставить элементы li класса tofu в DOM после элементов meat.

1

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

2

Замена «один к одному»

???? ??

Page 193: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 193

операции со структурой страниц в jQuery

Âñòàâêà HTML â DOM

Вставить элементы li класса tofu в DOM после элементов meat.

1

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

2

До настоящего момента мы занимались либо удалением, либо заменой элементов DOM. К счастью, создатели библиотеки jQuery также предоставили различные средства встав-ки в DOM. Мы рассмотрим два метода вставки: before и after.

Метод before вставляет содержимое перед выбранным элементом:

Метод after вставляет содержимое после выбранного элемента.

$(".meat").before("<li>Tofu</li>");

$(".meat").after("<li>Tofu</li>");

Напишите код jQuery, реализующий два этапа нашего решения.

ul class="menu_list"

lili class="meat"

li lili

ul class="menu_list"

li class="meat" li

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

Page 194: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

194 глава 4

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

Для кнопки переключения на вегетарианское меню выполнены все пункты списка.

Пора переходить к кнопке восстановления меню. Список задач для этой кнопки выглядит так:

найти шампиньоны в ингредиентах и заменить их гамбургерами;

найти тофу в ингредиентах и заменить его различными видами мясных ингредиентов (в правильном порядке).

вернуть рыбные блюда в меню (например, перед первым элементом меню в левом столбце);

Что же необходимо сделать для решения первой задачи?

С использованием before все понятно, но как задать первого потомка?

<li> Braised Delight</li>

ul class="menu_list"

ul class="menu_list"

ul class="menu_entrees"

div class= "left_col"

<li> Grilled Panini</li>

Нужно заново присо-единить рыбные блюда к этому элементу…

…перед первым потомком.

Вставить элементы li класса tofu в DOM после элементов meat.

1

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

2

Напишите код jQuery, реализующий два этапа нашего решения.

$(“.meat”).after(“<li class=‘tofu’><em>Tofu</em></li>”);

$m = $(“.meat”).detach();

1.

2.

3.

Найти элементы li класса fish и удалить соответствующие блюда из меню.

Найти элементы li класса hamburger и заменить их гигантскимишампиньонами.

Найти элементы li класса meat и заменить их тофу.

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

Page 195: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 195

операции со структурой страниц в jQuery

Ôèëüòðû (÷àñòü 1)

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

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

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

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

Давайте посмотрим, как работают фильтры, на примере одного эле-мента нашего меню:

$(".menu_list").children().last();$(".menu_list").children().first();

lili class="meat"

li li

li

ul class="menu_list"

li

$(".menu_list").children().eq(0);

lili class="meat"

li li

li

ul class="menu_list"

li

$(".menu_list").children().eq(1);

$(".menu_list").children().eq(2);

$(".menu_list").children().eq(3);

$(".menu_list").children().eq(4);

Метод first сокращает выбранное множество до первого элемента.

Метод last сокращает

выбранное множество

до последнего элемента.

Метод eq сокращает

выбранное множество

до элемента, индекс ко-

торого задан в круглых

скобках.

Вспомните, что jQuery воз-

вращает выбранные элемен-

ты в виде массива. Индекс,

передаваемый методу eq,

соответствует ячейке эле-

мента в массиве.

0

01

12

23

3

4

4

Page 196: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

196 глава 4

уточнение выбора

Теперь посмотрим, что собой представляют методы slice, filter и not.

filterslice notМетод slice оставляет в выбран-ном множестве только те эле-менты, индексы которых лежат в диапазоне, заданном в круглых скобках.

Метод filter оставляет в выбранном множестве толь-ко те элементы, которые соот-ветствуют селектору в круглых скобках.

Метод not исключает из вы-бранного множества все эле-менты, не соответствующие селек-тору в круглых скобках.

Метод slice сокращает выбран-ное множество до диапазона, границы которого передаются при вызове.

Метод filter сокращает выбран-

ное множество до подмножества,

определяемого селектором в кру-

глых скобках.

lili class="meat"

li li

ul class="menu_list"

li

01 2 3 4

$(".menu_list").children().slice(1,3);

$(".menu_list").parents().filter(".organic");

Метод not сокращает выбранное мно-жество до элементов, не соответству-ющих селектору в круглых скобках.

lili class="local"

li

ul class="menu_list organic"

li

$("ul.menu_list.organic").children().not(".local");

Какой из этих элементов поможет нам определить первого потомка меню?

Методы filter и not позволяют использовать селекторы для определения подмно-жеств выбранного множества. Селектор передается в аргументе при вызове метода.

li class="local"

ul class="organic"

Методы filter и not хорошо работа-

ют в сочетании с методами parents

и children.

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

В этом примере будет воз-

вращен только один эле-

мент — второй элемент li.

Ôèëüòðû (÷àñòü 2)

Page 197: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 197

операции со структурой страниц в jQuery

Стань DOMПредставьте себя на месте дерева DOM. Соедините команды jQuery

с элементом(-ами), которые будут выбраны при их выполнении.

Считайте, что страница не содержит других элементов. Ответ

для первой команды мы написали за вас.

body

h4

li

li lili li

ul class="menu_list"

ul class="menu_entrees"

div class="left_col"

div class="menu_wrapper"

li li

li lili lili lili li

ul class="menu_list"

ul class="menu_list"

$(".menu_list").parents().filter("div");

$("li").first();

$(".left_col").children().not("h4");

$(".menu_list li").eq(3); $(".menu_list").children().last();

$(".menu_list").parent().slice(1,3);

Напишите строку кода jQuery, которая вернет рыбные блюда в меню

(например, перед первым элементом, вложенным в menu_entrees).

.before($f);

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

Page 198: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

198 глава 4

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

Стань DOM. РешениеПредставьте себя на месте дерева DOM. Соедините команды jQuery

с элементом(-ами), которые будут выбраны при их выполнении.

Считайте, что страница не содержит других элементов. Ответ

для первой команды мы написали за вас.

li

li lili li

ul class="menu_list"

ul class="menu_entrees"

li li

li lili lili lili li

ul class="menu_list"

ul class="menu_list"

$(".menu_list").parents().filter("div");

$("li").first();

$(".menu_list li").eq(3); $(".menu_list").children().last();

Напишите строку кода jQuery, которая вернет рыбные блюда в меню

(например, перед первым элементом, вложенным в menu_entrees).

.before($f);

body

h4

div class="left_col"

div class="menu_wrapper"

$(".left_col").children().not("h4");

$(".menu_list").parent().slice(1,3);

$(".menu_entrees li").first()

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

Page 199: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 199

операции со структурой страниц в jQuery

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

Âåðíèòå ãàìáóðãåð íà ìåñòî

Помните это упражнение? Сейчас мы проделаем его в обратном порядке. Напишите код, который находит элементы li класса portobello и заменяет их элементами li класса hamburger. Следующая схема поможет вам лучше представить суть задачи. Мы уже на-писали часть решения за вас; допишите остальное.

Следующая задача кажется смутно знакомой, не правда ли? По сути, мы долж-ны проделать исходную замену в обратном порядке. Почему? Да потому что мы имеем дело с заменой «один к одному», а такие замены хороши своей логиче-ской простотой.

Хочу обратно...

Найти шампиньоны в ингредиентах и заменить их гамбургерами.

Найти тофу в ингредиентах и заменить его различными видами мясных ингредиентов (в правильном порядке).

Вернуть рыбные блюда в меню (например, перед первым элементом меню в левом столбце).

Замена «один к одному»

li class="portobello"

ul class="menu_list"

?Код, который вы напишете здесь…

…должен делать это.

$( ). replaceWith( Hamburger );

Упражнение

Page 200: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

200 глава 4

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

È ãäå æå ìÿñî?

Вспомните, что мы сделали с элементами li.meat? Давайте посмотрим:

Мы подошли к последнему пункту списка восстановления меню.

Затем мы отсоединили элементы li.meat, но сохранили их в $m.

$(".meat").after("<li class='tofu'><em>Tofu</em></li>");

$m = $(".meat").detach();

Элементы li.tofu были вставлены в DOM за элементами meat.

Так где взять эти элементы и как вернуть их на место?

Всего одна короткая строка с replaceWith — и гамбургеры вернулись на место! Отличная работа!

li class="portobello"

ul class="menu_list"

?$( ).replaceWith( Hamburger );

Выбираем все элемен-ты класса portobello. Метод replaceWith динамически заменяет выбранное содержимое элементом в круглых скобках.

".portobello" "<li class='hamburger'> </li>"

Найти шампиньоны в ингредиентах и заменить их гамбургерами.

Найти тофу в ингредиентах и заменить его различными видами мясных ингредиентов (в правильном порядке).

Вернуть рыбные блюда в меню (например, перед первым элементом меню в левом столбце).

Page 201: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 201

операции со структурой страниц в jQuery

Ìàññèâ îòñîåäèíåííûõ ýëåìåíòîâ

$m

Вспомните, что при хранении элементов jQuery мы начинаем имя перемен-ной со знака $, который показывает, что в переменной хранятся специальные данные. В нашем случае переменная содержит массив jQuery, в котором эле-менты $m хранятся следующим образом:

<li class="meat">

lamb shoulder</li>

<li class="meat">

proscuttio</li>

<li class="meat">

eggs</li>

<li class="meat">

chicken</li>

<li class="meat">

chicken</li>

<li class="meat">

chicken</li>

Каждый элемент li.meat…

…хранится в от-дельной ячейке…

…массива $m.

$m[2]$m[1]$m[0] $m[3] $m[4] $m[5]

Нужно вернуть на место каждый элемент li.meat, заменив им элемент li.tofu. Мы уже видели много методов, встав-ляющих элементы в DOM. Какой метод вы выбрали бы для этой задачи?

Мозговой

штурм

Page 202: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

202 глава 4

возвращение each

В главе 3 было показано, как использовать метод each для перебора элементов мас-сива. Сейчас мы снова воспользуемся этим методом для перебора всех элементов meat в массиве $m и их возвращения на исходные места. Но для этого необходимо поближе познакомиться с тем, как работает метод each.

$(".tofu").each(function(i){

$(this).after( );

});

Переменная i отсчитывает обработанные элементы (нумерация начинается с 0).

Метод each последова-тельно обрабатывает элементы массива, выпол-няя некоторую операцию с каждым элементом.

Для ссылки на теку-щий обрабатываемый элемент использу-ется запись $(this).

Здесь используется метод after,

но для обработки массива элемен-

тов можно использовать любой

метод jQuery.

Ìåòîä each è ïåðåáîð ìàññèâîâ

jQuery сохраняет результаты вы-бора в массиве.

Мы хотим вставить элемент meat после каждого элемента li.tofu.Что должно быть написано в скобках?

Метод each наглядно

демонстрирует мощь

сценариев jQuery: с его

помощью можно последо-

вательно обрабатывать

элементы массива.

$m

i = 0

Настоящая сила метода each проявляется при включении в него функции. Эта функция последовательно выполняет некоторую операцию с каждым перебираемым элементом.

Метод each напоминает

станок на конвейере.

Ключевым словом this обозначается элемент,

с которым работает функция.

Индекс отслеживает эле-

мент, с которым рабо-

тает функция.

Page 203: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 203

операции со структурой страниц в jQuery

Разложите магниты в правильном порядке, чтобы они образовали правиль-

ный код функции-обработчика кнопки restoreMenu. Несколько магнитов

уже находятся на своих местах.

$(".tofu").each( function(i){

.before($f);

$(".menu_entrees li").first()

});

$(".portobello").replaceWith(

$(".tofu").remove();

$m[i]);

$(this).after(

"<li class='hamburger'>Hamburger</li>");my_scripts.js

$("button#restoreMe").click(function(){

}

});

if (v == true){

v = false;

Развлечения с магнитами

Page 204: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

204 глава 4

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

Разложите магниты в правильном порядке, чтобы они образовали правиль-

ный код функции-обработчика кнопки restoreMenu. Несколько магнитов

уже находятся на своих местах.

my_scripts.js

$("button#restoreMe").click(function(){

$(".tofu").each( function(i){

.before($f);.b$(".menu_entrees li").first()

}

});

});

$(".portobello").replaceWith(

$(".tofu").remove();

$m[i]);

if (v == true){

v = false;

$$(this).after(

"<li class='hamburger'>Hamburger</li>");

Чтобы вернуть на место элементы

meat, мы указываем имя массива $m

и индекс, соответствующий элемен-

ту tofu, с которым в данный момент

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

Развлечения с магнитами. Решение

Page 205: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 205

операции со структурой страниц в jQuery

Âðîäå… âñå?

Мы выполнили все, что требовалось для кнопки восстановления меню. Давайте обновим файлы, и проект можно считать завершенным.

Да, вы абсолютно правы.

К счастью, веб-дизайнер уже включил класс veg_leaf в файл my_style.css. Вот как он выглядит:

Постойте, мы забылипро постскриптум...

.veg_leaf{

list-style-image:url('../images/leaf.png');

}

my_style.css

Напишите команду, которая назначает класс veg_leaf родителю ро-дителя элемента класса tofu.

Найти шампиньоны в ингредиентах и заменить их гамбургерами.

Найти тофу в ингредиентах и заменить его различными видами мясных ингредиентов (в правильном порядке).

Вернуть рыбные блюда в меню (например, перед первым элементом меню в левом столбце).

P.S. И еще хотелось бы, чтобы замененные

вегетарианские блюда в меню были помече-

ны — например зеленым листом.

Подсказка: в этом вам поможет addClass.

Упражнение

Page 206: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

206 глава 4

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

$(".tofu").parent().parent().addClass("veg_leaf");

В: С другими фильтрами все понятно, но от slice у меня до сих пор голова идет кругом. Можно объяснить подроб-нее?

О: Метод slice действительно непрост. Больше всего сложностей возникает с его параметрами: slice(start, end).

Первый параметр — start — является обязательным; без него slice работать не будет. Параметр start указывает, с какого индекса начинается выделяемый диапазон. Помните, что у первого элемента массива индекс равен 0. Параметр start также может принимать отрицательные значения. В этом случае slice отсчитывает значе-ния от конца, а не от начала массива.

В: А что делает параметр end метода slice?

О: Второй параметр метода slice — end — не является обязательным. Если он отсутствует, то slice начинает от позиции, заданной параметром start, и выбирает все элементы с индексами, большими start. Если забыть о том, что индексы элементов массива начинаются с 0, смысл параметра end может быть неочевидным.

В: Похоже, метод each способен на многое. А как each узнает, с каким эле-ментом он работает?

О: Настоящая сила each проявляется в сочетании с ключевым словом this. Ме-тод each автоматически отслеживает зна-чение индекса и «знает», с каким элементом он работает. Используйте each только при выборе нескольких элементов. Для об-ращения к текущему элементу используйте ключевое слово this, но заключите его в сокращенную форму jQuery: $(this).

В: Почему мы включаем «i» или «index» в каждую функцию each?

О: Индексная переменная, которой обыч-но присваивается имя «i» или «index», ис-пользуется функцией each для отслежива-ния элемента, с которым работает функция. При помощи этой переменной each опреде-ляет, когда перебор завершен, а обработку следует прекратить.

В: Как провести поиск элементов в мас-сиве jQuery?

О: Для поиска элементов в массиве jQuery используется метод find. Допустим, у нас

имеется массив элементов li в массиве jQuery: var $my_elements = $("li");Чтобы найти в этом массиве все якорные элементы, используйте следующую коман-ду: $my_elements.find("a"); В: Позволяет ли jQuery заключить эле-мент внутри другого элемента?

О: Да, позволяет. Допустим, изображение с дентификатором oreilly нужно за-ключить внутри якорного элемента. Это де-лается так:

$("img#oreilly").wrap("<a href='http://www.oreilly.com'></a>");

Пара перемещений по DOM, немного магии addClass — и дело сделано!

частоЗадаваемые

вопросы

Page 207: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 207

операции со структурой страниц в jQuery

Здорово! Наши клиенты в восторге от веб-меню, а самое замечательное, что

нам не приходится вести две разных версии меню. Вся информация на одной

странице!

С тех пор как мы в последний раз обновляли файлы, прошло уже нема-ло времени. Добавьте код кнопки восстановления меню, а также код до-бавления/удаления класса veg_leaf для блюд с вегетарианскими ана-логами. Также вы всегда можете загрузить файлы этой главы по адресу http://www.thinkjquery.com/chapter04/ и сравнить их со своим кодом.

Лист появился из-за добав-

ления класса veg_leaf.

Теперь у Александры будет

меньше хлопот с сопрово-

ждением сайта — и у нее

появится время для приго-

товления новых блюд.

Тест-драйв

Page 208: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

208 глава 4

ваш инструментарий jquery

Массивы

В массивах jQuery может хра-

ниться любая информация

(в том числе и элементы).

Как и в случае с переменными,

перед именем массива принято

ставить знак $, который пока-

зывает, что в массиве хранятся

специальные данные jQuery.

Âàø èíñòðóìåíòàðèé jQuery

Глава 4 осталась позади, а ваш творческий арсенал расширился: в нем появились средства обхода и выполнения операций с DOM, массивы и фильтры.

Обход DOM

Перемещение по дереву DOM

для выполнения различных опе-

раций.

Для перехода к нужной позиции

дерева используются отно-

шения между элементами и

различные методы (например,

parent и child).

Сцепленные вызовы методов

эффективны для быстрого

перемещения по дереву DOM.

Операции с DOM

Вы можете выполнять операции

добавления, замены и удален

ия

элементов из DOM:

detach

remove

replaceWith

before

after

ФильтрыФильтры предназначены для со-кращения множества выбранных элементов:first

equal

last

slice

filter

not

ГЛА

ВА 4

Page 209: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

jQuery эффекты и анимация5

Плавно и изящно

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

Взгляните, как я умею двигаться; я так грациозна.

Спорим, вы так не сможете!

Page 210: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

210 глава 5

только без flash

Фирма DoodleStuff поставляет детям принадлежности для рисования. Несколько лет назад фирма открыла популярный веб-сайт с интерактивными приложениями для де-тей. Популярность фирмы стала расти настолько быстро, что она не успевает справ-ляться с пожеланиями своих клиентов.

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

Детские проекты должны быть веселыми и простыми. Сможете создать приложе-ние для детей в возрасте от 6 до 10 лет? Не забудьте про визуальные эффекты и взаимодействие с пользователем.

Только, пожалуйста, без Flash!

Íîâûé çàêàç

Page 211: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 211

jquery эффекты и анимация

Ïðîåêò «Ñîáåðè ìîíñòðà»

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

У вас имеется подробное описание требований и необходимые графические файлы, но нет разметки HTML и кода CSS — с этого и следует начинать. Что для этого необходимо?

frame.pngширина: 545 пикселоввысота: 629 пикселов

Проект «Собери монстра»Развлекательное приложение «Собери монстра» адресовано детям конкретной возрастной группы. Оно позво-ляет «собрать» изображение монстра из 10 разных вариантов головы, глаз, носа и рта. Выбор частей монстра должен сопровождаться анимацией.

Модель изменения лица монстра

Графические файлы

Пользовательский интерфейс Анимация

После девяти щелчков каждая полоса должна «перематываться» к началу.

Модель анимации с молниями

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

headsstrip.png ширина: 3670 пикселов, высота: 172 пикселов

eyessstrip.png ширина: 3670 пикселов, высота: 79 пикселов

nosessstrip.png ширина: 3670 пикселов, высота: 86 пикселов

mouthsstrip.png ширина: 3670 пикселов, высота: 117 пикселов

lightning_01.jpg

lightning_02.jpg

lightning_03.jpg

Область головы

Область глаз

Область носа

Область рта

Рамка

Контейнерimg - lightning1

img - lightning2

img - lightning3

Щелкните, чтобы изменить голову монстра.

Щелкните, чтобы изменить глаза монстра.

Щелкните, чтобы изменить нос монстра

Щелкните, чтобы изменить рот монстра.

Page 212: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

212 глава 5

закладываем фундамент

Мы уже неоднократно говорили о том, как важно тщательно продумать структуру и стиль приложения до перехода к программированию. В данном случае это еще важнее — если не позаботиться о правиль-ном расположении всех визуальных элементов, с эффектами и анимацией очень скоро начнутся пробле-мы. Нет ничего противнее, чем глазеть в свой код jQuery и ломать голову над тем, почему же он не рабо-тает так, как нужно вам. Лучше заранее построить эскиз приложения и поразмыслить над тем, что будет происходить на экране.

Ìàêåò è ïîçèöèîíèðîâàíèå

Здесь должна быть область div с ши-риной 545 пикселов для рамки…

…и область div шириной 367 пикселов для изобра-жения лица монстра.

Ширина 367 пикселов

Какой атрибут CSS позволит нам это сделать?

Ширина каждой полосы 3670 пик-селов, но на экране отображаются только 367 пикселов.

div#frame

div#pic_box

div#head

div#eyes

div#nose

div#mouth

Высота 172 пиксела

Высота 79 пикселов

Высота 117 пикселов

Высота 86 пикселов

Полосы изображений размещаются в элемен-тах img, вложенных в область div соответ-ствующей части лица монстра. Например, тег img для headsstrip.jpg будет находиться внутри div#head.

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

Page 213: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 213

jquery эффекты и анимация

Запишите в пустых местах файлов HTML и CSS идентификатор CSS, свойство или зна-чение, обеспечивающее нужное размещение элементов приложения «Собери монстра». Если сомневаетесь, перечитайте две предыдущие страницы. Мы заполнили несколько пропусков за вас.

body><header id="top"><img src="images/Monster_Mashup.png" /><p>Make your own monster face by clicking on the picture.</p></header> <div id="frame"> <div id= > <div id= class="face"><img src="images/headsstrip.jpg"></div> <div id= class="face"><img src="images/eyesstrip.jpg"></div> <div id= class="face"><img src="images/nosesstrip.jpg"></div> <div id= class="face"><img src="images/mouthsstrip.jpg"></div> </div></div> <script type="text/javascript" src="scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript" src="scripts/my_scripts.js"></script></body>

#frame { position: left:100px; top:100px; width:545px; height:629px; background-image:url(images/frame.png); z-index: 2; overflow:}

#pic_box{ position: left:91px; top:84px;

height:460px; z-index: 1; overflow:}

.face{ position: left:0px; top:0px; z-index: 0;}

#head{

}

#eyes{

}

#nose{

}

#mouth{

}

index.html

my_style.css

relative;

"pic_box"

height:172px;

Упражнение

Page 214: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

214 глава 5

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

Запишите в пустых местах файлов HTML и CSS идентификатор CSS, свойство или значе-ние, обеспечивающее нужное размещение элементов приложения Monster Mashup. Если засомневаетесь, просмотрите еще раз две предыдущие страницы. Мы заполнили несколько пропусков за вас.

body><header id="top"><img src="images/Monster_Mashup.png" /><p>Make your own monster face by clicking on the picture.</p></header>

<div id="frame"> <div id= > <div id= class="face"><img src="images/headsstrip.jpg"></div> <div id= class="face"><img src="images/eyesstrip.jpg"></div> <div id= class="face"><img src="images/nosesstrip.jpg"></div> <div id= class="face"><img src="images/mouthsstrip.jpg"></div> </div></div> <script type="text/javascript" src="scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript" src="scripts/my_scripts.js"></script></body>

#frame { position: left:100px; top:100px; width:545px; height:629px; background-image:url(images/frame.png); z-index: 2; overflow:}

#pic_box{ position: left:91px; top:84px; height:460px; z-index: 1; overflow:}

.face{ position: left:0px; top:0px; z-index: 0;}

#head{

}

#eyes{

}

#nose{

}

#mouth{

}

index.html

my_style.css

relative;

"pic-box"

height:172px;

absolute;

hidden;

Присваивание overflow

значения hidden по-

зволяет скрыть часть

полосы изобра жения,

выходящую за границы

области pic_box.

relative;

height:79px;

height:86px;

height:117px;

hidden;

width:367px;

"head""eyes""nose""mouth"

При анимации позиции элемен-та используется абсолютное или относительное по-зиционирование.

Для этого также можно воспользо-ваться свойством CSS clip.

Page 215: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 215

jquery эффекты и анимация

index.html

my_style.css

Далее необходимо разобраться со структурными изменениями в файлах HTML и CSS. Включите приведенный ниже код в файлы index.html и my_style.css. Графи-ческие файлы можно загрузить по адресу www.thinkjquery.com/chapter05.

<div id="container"> <img class="lightning" id="lightning1" src="images/lightning-01.jpg" /> <img class="lightning" id="lightning2" src="images/lightning-02.jpg" /> <img class="lightning" id="lightning3" src="images/lightning-03.jpg" /> <div id="frame"> <div id="pic_box"> <div id="head" class="face"><img src="images/headsstrip.jpg"></div> <div id="eyes" class="face"><img src="images/eyesstrip.jpg"></div> <div id="nose" class="face"><img src="images/nosesstrip.jpg"></div> <div id="mouth" class="face"><img src="images/mouthsstrip.jpg"></div> </div> </div></div>

Åùå íåìíîãî ñòðóêòóðû è ñòèëÿ

#container{ position:absolute; left:0px; top:0px; z-index: 0;}

.lightning{ display:none; position:absolute; left:0px; top:0px; z-index: 0;}

body{

background-color:#000000;

}

p{

color:#33FF66;

font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;

font-size:12px;

}

#text_top {

position:relative;

z-index: 4;

}

Задание!

Чтобы использовать анимацию для элемен-та, следует задать его свойству position значение absolute, fixed или relative.

В исходном состоянии молнии должны быть невидимы.

Добавляем контейнер и вкладываем в него изображение с молниями.

Page 216: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

216 глава 5

для экспертов по щелчкам

Пользовательский интерфейс

После девяти щелчков каждая полоса должна «перематываться» к началу.

Область головы

Область глаз

Область носа

Область рта

Рамка

Контейнерimg - lightning1img - lightning2img - lightning3

Щелкните, чтобы изменить голову монстра.

Щелкните, чтобы изменить глаза монстра.

Щелкните, чтобы изменить нос монстра.

Щелкните, чтобы изменить рот монстра.

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

Ïðîðàáîòêà èíòåðôåéñà

Нужно проверять

каждый щелчок,

чтобы при дости-

жении конца полосы

«перемотать» ее

к началу.

Щелчок в каждой области прокру-чивает полосу изображений.

В: Что это за свойство CSS position? Почему оно необходимо для анимации и эффектов jQuery?

О: Свойство CSS position управляет тем, где и как браузерный движок размещает элементы. Многие эффекты jQuery реализу-ются с использованием свойства position. Если вы забыли, как работает это свойство, обращайтесь к превосходному объясне-нию в центре для разработчиков Mozilla:

http://developer.mozilla.org/en/CSS/position#Relative_positioning

В: Почему для анимации элементов свойству CSS position необходимо за-дать значение absolute, fixed или relative ?

О : Если оставить свойству CSS position значение по умолчанию (т. е. static), то для элемента будет невоз-можно задать позицию сторон (top, right, left и bottom). При использовании функции animate возможность измене-ния этих позиций необходима, а в режиме static это невозможно. Со значениями absolute, fixed и relative — такой проблемы нет.

В: Вы упомянули какой-то «браузер-ный движок». А это что такое?

О: Браузерный движок визуализации — один из важнейших компонентов браузера, который интерпретирует разметку HTML и код CSS и отображает результат в окне просмотра браузера. Google Chrome и Safari используют движок визуализации Webkit; Firefox использует Gecko, а Microsoft Internet Explorer — движок, который назы-вается Trident.

частоЗадаваемые

вопросы

Page 217: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 217

jquery эффекты и анимация

Расставьте магниты в правильном порядке, чтобы элемент div#head реагировал

на щелчки. Проследите за тем, чтобы переменные и условные конструкции сле-

довали в правильном порядке для обнаружения девятого щелчка.

$(document).ready(function(){

$("#head").click(function(){

if (headclix

});

});

var headclix

< 9){

headclix

else {

headclix

}

}

= 0;

+= 1;

= 0;

Развлечения с магнитами

Page 218: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

218 глава 5

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

Конечно, можно! Все элементы работают по той же схеме, что и элемент div#head (с небольшими изменениями вро-де имени переменной).

Расставьте магниты в правильном порядке, чтобы элемент div#head реагировал

на щелчки. Проследите за тем, чтобы переменные и условные конструкции следо-

вали в правильном порядке для обнаружения девятого щелчка.

$(document). ready(function(){

$("#head").click(function(){

if (headclix

});

});

var headclix = 0;

+= 1;

< 9){

headclix

В исходном состоянии пере-менная равна 0, потому что

щелчков еще не было.

else {

headclix = 0;

}

}

Условие ограничивает пользователя девятью щелчками.

Значение переменной headclix

увеличивается на 1.

Здесь будет размещаться код анимации.

Здесь будет размещаться код «перемотки» полосы изображений.

После девятого щелчка переменной headclix воз-вращается значение 0.

Если значение headclix больше либо равно 9, сделать следу-ющее:

Нельзя ли повторно использовать этот код для обработки

щелчков на других областях?

Развлечения с магнитами. Решение

Page 219: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 219

jquery эффекты и анимация

$(document).ready(function(){

$("#head").click(function(){ if (headclix < 9){ headclix += 1; } else{ headclix = 0; } });

});

my_scripts.js

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

нос и  рот). Вскоре мы дополним обработчики дополнительной функциональностью.

Проследите, чтобы переменные и условные конструкции следовали в правильном по-

рядке для обнаружения девятого щелчка.

Page 220: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

220 глава 5

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

$(document).ready(function(){

$("#head").click(function(){ if (headclix < 9){ headclix += 1; } else{ headclix = 0; } });

});

my_scripts.js

var headclix = 0, eyeclix=0, noseclix= 0, mouthclix = 0;

$("#eyes").click(function() { if (eyeclix < 9){ eyeclix += 1; } else{ eyeclix = 0; }});

$("#nose").click(function() { if (noseclix < 9){ noseclix += 1; } else{ noseclix = 0; }});

$("#mouth").click(function() { if (mouthclix < 9){ mouthclix += 1; } else{ mouthclix = 0; }});

Обратите внимание: все функции click очень похожи друг на друга с минимальными от-клонениями. Нельзя ли повторно использовать один фрагмент кода?

Терпение — этим мы займемся в главе 7.

Теперь каждая часть лица монстра реагиру-ет на щелчки, а после девяти щелчков поло-са «перематывается» в начало.

В одной строке можно

объявить и инициа-

лизировать несколько

переменных, разделяя

их запятыми.

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

нос и рот), а также расположили переменные и условные конструкции

в правильном порядке для обнаружения девятого щелчка.

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

Page 221: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 221

jquery эффекты и анимация

Пользовательский интерфейс

Модель анимации с молниями

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

Область головы

Область глаз

Область носа

Область рта

Рамка

Контейнерimg - lightning1img - lightning2img - lightning3

Щелкните, чтобы изменить голову монстра.

Щелкните, чтобы изменить глаза монстра.

Щелкните, чтобы изменить нос монстра.

Щелкните, чтобы изменить рот монстра.

Ýôôåêò ìîëíèè

Теперь займемся эффектом молнии. Прежде чем браться за реализацию эффекта, посмотрим, что об этом говорится в схеме приложения.

Изображения молнии вложены в контейнер div…

…молнии должны быстро проявляться и исчезать.

Возможно. Но нет ли чего-нибудь поинтереснее?В главе 1 мы воспользовались готовыми эффектами jQuery, а сейчас попробуем ра-зобраться поглубже.

Мы уже использовали эффекты изменения прозрачности в главе 1. Нельзя ли восполь-зоваться теми же средствами в приложении

«Собери монстра»?

Page 222: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

222 глава 5

махинации со свойствами

Êàê jQuery âûïîëíÿåò àíèìàöèþ ýëåìåíòîâ?

Во время загрузки файла CSS браузер задает визуальные свойства элементов стра-ницы. При использовании встроенных эффектов jQuery интерпретатор Java изме-няет эти свойства CSS, и изменения происходят динамически прямо у вас перед глазами. Но никакого волшебства в этом нет... Все дело в свойствах CSS. Давайте еще раз вернемся к тому, что вы уже видели.

Эффекты jQuery изменяют свойства CSS «на ходу»,

в результате чего страница изменяется прямо перед

глазами пользователя.

Интерпретатор JS изменя-ет свойство CSS display выбранного элемента так, что тот становится види-мым.

show

Интерпретатор JS задает свой-ству CSS display выбранного элемента значение none; эле-мент перестает отображаться на странице.

hide

Если элемент скрыт, то ин-терпретатор JS отображает его, и наоборот.

toggle

Ìåòîäû hide, show è toggle èçìåíÿþò ñâîéñòâî CSS display

Методы hide, show и toggle работают со свойством display. Но нам нужно, чтобы части лица не просто появ-лялись, а «скользили», а молнии проявлялись и исчезали. Как вы думаете, какие свойства CSS изменяются jQuery в эффектах скольжения и проявления/исчезновения?

Мозговой

штурм

Page 223: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 223

jquery эффекты и анимация

Ýôôåêòû èçìåíåíèÿ ïðîçðà÷íîñòè èçìåíÿþò ñâîéñòâî CSS opacity

В эффекте проявления fadeIn интерпретатор JavaScript изменяет свойство CSS opacity выбран-ного элемента от 0 до 100.

fadeIn

В эффекте исчезновения fadeOut интерпретатор JavaScript изменяет свойство CSS opacity выбран-ного элемента от 100 до 0, но сохраняет на страни-це место, занимаемое элементом.

fadeOut

fadeTo выполняет анима-цию выбранного элемента до заданного уровня про-зрачности (в процентах).

fadeTo

Для любознательных

Свойство CSS opacity по-разному работает в  раз-

ных браузерах. К счастью, jQuery берет на себя все

технические тонкости. Собственно, это единствен-

ное, что вам необходимо о них знать!

Page 224: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

224 глава 5

добавь чуть-чуть скольжения

Ýôôåêò ñêîëüæåíèÿ

Интерпретатор JavaScript приказывает DOM уменьшить свойство CSS height выбранного элемента до 0, а затем задать свойству display значение none. По сути, эле-мент скрывается посредством скольжения.

Интерпретатор JavaScript снова делает выбранный эле-мент(-ы) видимым, для чего его свойство height увели-чивается от 0 до высоты, заданной в стиле CSS.

Интерпретатор JavaScript проверяет, имеет изображе-ние полную или нулевую высоту, и переключает эффект скольжения в зависимости от результата. Если высота элемента равна 0, то интерпретатор JavaScript использу-ет скольжение вниз, а при полной высоте используется скольжение вверх.

slideUp

slideDown

slideToggle

Модель DOM страницы

Это что, волшебство

какое-то?

Эй, DOM, уменьши высоту выбранно-го элемента до 0, а потом измени свойство display.

Интерпретатор JavaScript

Page 225: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 225

jquery эффекты и анимация

Какие из готовых эффектов jQuery подойдут для приложения «Собери мон-

стра»? Для каждого вида эффектов напишите, можно ли использовать их в

нашем случае, и объясните, почему вы выбрали (или не выбрали) данный

эффект.

Эффект Можно ли ис-

пользовать?

Почему?

Скрытие/ото-

бражение

элемента

Скольжение

Изменение

прозрачности

В jQuery включены готовые эффекты только для вертикального скольже-ния элементов.В jQuery не существует методов slideRight или slideLeft (по крайней мере на момент написания книги). Не беспокойтесь, вскоре мы решим эту проблему…

В jQuery не существует

методов slideRight и slideLeft.

Выходит, элементы могут скользить только вверх-вниз? А если мне нужно, чтобы они скользили горизонтально?

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

Page 226: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

226 глава 5

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

Какие из готовых эффектов jQuery подойдут для приложения

«Собери монстра»?

Эффект Можно ли ис-

пользовать

Почему?

Отображение/

скрытиеНет Эти эффекты в нашем приложении бесполезны, нам не нуж-

но анимировать свойство display каких-либо элементов.Скольжение Нет Чуть ближе, и все же не то. Полоса изображений должна

скользить влево. Методы SlideUp и slideDown изменяют свойство height, а нам нужно свойство left.

Изменение

прозрачностиДа Эффекты изменения прозрачности позволяют выполнить

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

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

Êàê ðàáîòàþò ýôôåêòû èçìåíåíèÿ ïðîçðà÷íîñòè

$("#lightning1"). fadeIn("fast");

$("#lightning1").fadeIn(1000);

Идентификатор первого элемента img.

Параметр управляет скоро-стью завершения эффекта.

Используйте одно из строковых

значений: slow, normal или fast…

…или значение в миллисекундах. Например, если указать при вызове значение 1000, то анимация эффекта будет выполнена за одну секунду. 1 секунда = 1000 миллисекунд

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

Page 227: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 227

jquery эффекты и анимация

Напишите пару строк кода jQuery, которые выполняют следующие операции:

Элемент #lightning1 проявляется с продолжительностью в 1/4 секунды.1

Присоедините к первому вызову еще один, обеспечивающий исчезновение элемента #lightning1 за 1/4 секунды.

2

Êîìáèíèðîâàííûå ýôôåêòû

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

$("#lightning1"). fadeIn().fadeOut();

Методы соединя-ются друг с другом, словно звенья цепи.

Элемент переходит из скрытого

состояния в состояние видимости

с нулевой прозрачностью…

…а затем растворяется до полной прозрачности. Если не указать продол-

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

Упражнение

Page 228: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

228 глава 5

удар молнии

Çàäåðæêà ïðè èñïîëüçîâàíèè ýôôåêòîâ

function lightning_one(t){ $("#lightning1").fadeIn(250).fadeOut(250); setTimeout("lightning_one()",t);};

Эй, JavaScript, сделай мне новую функцию.

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

В этой строке используют-ся эффекты jQuery.

Метод setTimeout при-казывает интерпрета-тору выполнить функ-цию и сделать паузу перед ее повторным выполнением.

Оцените силу JS: вы сообщаете интер претатору, что функция долж-на вызывать себя снова и снова.

Продолжительность задерж-ки (тайм-аут) задается в миллисекундах (как и про-должительность эффекта, о которой мы говорили не-сколько страниц назад).

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

Параметр, определяющий задержку между ударами молнии (переменная с именем t). Мы используем его в коде функции.

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

Вспомните предыдущие главы: что мы использовали для повторяющихся операций? Правильно: функ-ции! Они появились в главе 3, когда мы создавали универсальную функцию click и генератор случайных чисел. В нашей ситуации можно использовать функции для выполнения эффекта, немного подождать и через некоторое время повторить вызов. Как же будет выглядеть функция для решения этой задачи?

Напишите пару строк кода jQuery, которые выполняют следующие операции:

Элемент #lightning1 проявляется с продолжительностью в 1/4 секунды.1

Присоедините к первому вызову еще один, обеспечивающий исчезновение элемента #lightning1 за 1/4 секунды.

2

$("#lightning1").fadeIn("250");

$("#lightning1").fadeIn("250").fadeOut("250");

Page 229: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 229

jquery эффекты и анимация

Расставьте магниты в правильном порядке. У вас должны получиться функции, повторяющие

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

function

setTimeout(

};

$("#lightning2")

lightning_two

.fadeIn(250)

"lightning_two()",

t);

(t){

.fadeOut(250);

function

setTimeout(

};

$("#lightning3")

lightning_three

.fadeIn(250)

"lightning_three()",

t);

(t){

.fadeOut(250);

Развлечения с магнитами

Page 230: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

230 глава 5

частоЗадаваемые

вопросы

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

Расставьте магниты в правильном порядке. У вас должны получиться функции, повторя-

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

function

setTimeout(

};

$("#lightning2")

lightning_two

.fadeIn(250)

"lightning_two()", t);

(t){

.fadeOut(250);

function

setTimeout(

};

$("#lightning3")

lightning_three

.fadeIn(250)

"lightning_three()", t);

(t){

.fadeOut(250);

В: Разве fadeIn().fadeOut() не то же самое, что toggle?

О: Отличный вопрос! Нет, не то же. toggle — одиночный метод, который просто переключает выбранный элемент из скрытого состояния в видимое и наоборот, в зависи-мости от его текущего состояния. Цепочка из fadeIn и fadeOut создает эффект, при котором выбранный элемент(ы) сначала проявляется, а после завершения эффекта становится невидимым.

В: Новый метод setTimeout? Отку-да он взялся? Из jQuery или из JavaScript?

О: setTimeout — метод JavaScript, ко-торый может использоваться для управле-ния некоторыми аспектами анимаций jQuery. Мы поближе познакомимся с setTimeout в следующих главах, особенно в главе 7.

Если вы захотите узнать о setTimeout, посетите Mozilla Developer’s Center: https://developer.mozilla.org/en/window.setTimeout. Дополнительную информа-цию можно найти в превосходной книге

Дэвида Фленагана «JavaScript. Подробное руководство».

В: Когда я использую эффект hide, элемент просто исчезает. Как замедлить его исчезновение?

О: Чтобы «замедлить» действие hide, show или toggle, передайте значение продолжительности в круглых скобках. Пример использования hide из главы 1: $("#picframe").hide(500);

Развлечения с магнитами. Решение

Page 231: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 231

jquery эффекты и анимация

$(document).ready(function(){ var headclix = 0, eyeclix = 0, noseclix = 0, mouthclix = 0; lightning_one(4000); lightning_two(5000); lightning_three(7000);

$("#head").click(function(){ if (headclix < 9){headclix+=1;} else{headclix = 0;} });

$("#eyes").click(function(){ if (eyeclix < 9){eyeclix+=1;} else{eyeclix = 0;} });

$("#nose").click(function(){ if (noseclix < 9){noseclix+=1;} else{noseclix = 0;} });

$("#mouth").click(function(){ if (mouthclix < 9){mouthclix+=1;} else{mouthclix = 0;} });

});//end doc.onready function

function lightning_one(t){ $("#container #lightning1").fadeIn(250).fadeOut(250); setTimeout("lightning_one()",t); }; function lightning_two(t){ $("#container #lightning2").fadeIn("fast").fadeOut("fast"); setTimeout("lightning_two()",t); }; function lightning_three(t){ $("#container #lightning3").fadeIn("fast").fadeOut("fast"); setTimeout("lightning_three()",t); };

my_scripts.js

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

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

Обновите файл сценариев приложения «Собери монстра» кодом из упражнения на предыдущей странице.

Âêëþ÷åíèå ôóíêöèé â ñöåíàðèéЗадание!

В этих строках вызывают-ся функции, выделенные жирным шрифтом в конце.

Определе-ния функций сверкания молний

Page 232: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

232 глава 5

тест-драйв

Проект «Собери монстра»Развлекательное приложение «Собери монстра» адресовано детям целевой возрастной группы. Оно позволяет «собрать» изображение из 10 вариантов головы, глаз, носа и рта. Переключение частей монстра должно сопро-вождаться анимацией.вождаться анимацией.

Модель изменения лица монстраАнимация

Модель анимации с молниями

Откройте страницу в своем любимом браузере и посмотрите, как работает эффект сверкания молний. Эффект проявле-

ния/исчезновения объединен с мето-дом setTimeout.

Итак, к настоящему моменту у вас работают функции click, а три молнии сверкают с разными интервалами. Давайте вернемся к схе-ме и посмотрим, что еще осталось сделать.

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

Пора создать пользовательский эффект, который будет сдви-гать полосы частей лица мон-стра влево.

Последняя нерешенная задача этого проекта

Молнии проявля-ются и исчезают с разными интер-валами, чтобы сверкание выгляде-ло реалистичнее.

Пора сдвигать изображения влево, а ни один из готовых эффектов

не подходит. Нельзя ли восполь-зоваться каким-нибудь другим

методом?

Тест-драйв

Page 233: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 233

jquery эффекты и анимация

Ñàìîäåëüíûå ýôôåêòû è animate

В jQuery нет методов slideRight и slideLeft, а на этой стадии проекта без них не обойтись. Означает ли это, что проект «Собери монстра» зашел в тупик?

Вовсе нет, в jQuery существует метод animate для построения ваших собственных эффектов. С его помощью можно создавать пользовательские анимации, которые по своим возможностям далеко превосходят готовые, стандартные эффекты. Метод animate позволяет изменять свой-ства CSS выбранных элеметов, с возможностью одновременной анимации нескольких свойств.

Давайте посмотрим, что можно сделать с помощью метода animate.

Ýôôåêòû äâèæåíèÿ

Анимация позиционных свойств CSS создает ил-люзию движения графиче-ского элемента по экрану.

Какое свойство CSS потребуется для анимации сдвига частей лица монстра влево при каждом щелчке?

Ýôôåêòû ìàñøòàáèðîâàíèÿ

Анимация свойств CSS height и width создает иллюзию увеличения или уменьшения элемента.

Мозговой

штурм

Page 234: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

234 глава 5

из области математики

×òî ìîæíî àíèìèðîâàòü?

Метод animate позволяет динамически изменять свойства шрифтов для создания текстовых эффектов. Также возможна одновременная анимация нескольких свойств CSS при одном вызове, что только до-бавляет интересных возможностей веб-приложениям.

При всей крутизне метода animate его возможности небезграничны. В его внутренней реализации ис-пользуются сложные математические вычисления (о которых вам, к счастью, беспокоиться не нужно), поэтому работать можно только со свойствами CSS, имеющими числовые значения. Знайте пределы воз-можностей, но не ограничивайте свое творческое воображение. Анимация обладает исключительной гибкостью, и с ней можно сделать много интересного.

Я уменьшаюсь, уменьшаюсь!Прощай, жестокий мир!

Я уменьшаюсь, уменьшаюсь!Прощай, жестокий мир!

Я уменьшаюсь, уменьшаюсь!Прощай, жестокий мир!

Я уменьшаюсь, уменьшаюсь!Прощай, жестокий мир!

Я уменьшаюсь, уменьшаюсь!Прощай, жестокий мир!

Òåêñòîâûå ýôôåêòû

Анимация шрифтовых свойств CSS способна создать иллюзию увеличения, уменьшения и полета текста.

Это всего лишь несколь-ко примеров. Для полного описания всех возможностей анимации нам понадобилось бы намного, намного больше места!

Метод animate работает только со свойствами CSS, имеющими числовые значения:

� borders, margin, padding

� element height, min-height и max-height

� element width, min-width и max-width

� font size

� bottom, left, right и top position

� background position

� letter spacing, word spacing

� text indent

� line height

Будьте осторожны!

Page 235: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 235

jquery эффекты и анимация

$("#my_div").animate({left:"100px"},500);

Выбираем элемент(-ы), к которому применяется анимация. Вызываем метод

animate.

Первый параметр animate определяет свойство CSS, к ко-торому применяется анимация.

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

В этом примере анимация применяется к свойству CSS left…

…для которого за-дается значение "100px".

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

$("#my_div").animate({ opacity: 0, width: "200", height: "800" }, 5000);

Но одна из самых замечательных особенностей animate — возможность одновременного измене-ния нескольких свойств выбранных элементов.

В этом примере одновре-менно изменяются свойства прозрачности и размеров элемента.

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

Параметры свойств CSS должны задаваться по стандарту DOM, а не по стандарту CSS.

Как вы думаете, что при этом происходит в браузере? Как метод animate изменяет страницу прямо на гла-зах у пользователя?

Будьте осторожны!

напряги мозги

Метод animate под увеличительным стеклом

Page 236: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

236 глава 5

в движении

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

То же самое происходит и на экране браузера, правда, без серии готовых изображений. Вместо этого интерпретатор JavaScript многократно вызывает функцию, изменяющую стилевое оформление эле-мента. Браузер воспроизводит (перерисовывает) изменения на экране. В процессе изменения стилевого оформления создается иллюзия движения или изменения внешнего вида элемента.

Ìåòîä animate èçìåíÿåò ñòèëåâîå îôîðìëåíèå

Интерпретатор JavaScript устанавливает таймер на время выполнения анимации.

1

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

2

Браузерный движок визуа-

лизации

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

4

Изменить свойство CSS left до 500px

за 400 миллисекунд.

Интерпретатор JavaScript

Интерпретатор многократно вызывает функцию, изменяю щую свойство CSS элемента (до завершения работы таймера). При каждом выполнении функции изменения воспроизводятся на экране.

3

Если параметр duration

при вызове animate не задан,

по умолчанию используется

значение 400 миллисекунд.

Браузер

Интерпретатор JavaScript

Думаю, это можно будет устроить через несколько миллисе-

кунд.

Я хочу запланиро-вать перерисовку

экрана.

Page 237: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 237

jquery эффекты и анимация

Анимация одновременного из-менения левого и правого полей всех абзацев.

Анимация изменения правой сто-роны #my_div до 0 за половину секунды.

Анимация межбуквенных интерва-лов всех абзацев с продолжитель-ностью по умолчанию (400 милли-секунд).

Анимация одновременного изме-нения внутренних полей и шири-ны #my_div.

Анимация изменения положения верхней стороны #my_div с про-должительностью slow.

Анимация изменения высоты всех изображений с продолжительно-стью fast.

Анимация изменения ширины #my_div, продолжающегося 1/4 секунды.

$("#my_div").animate({top: "150px"}, "slow")

$("p").animate({ marginLeft:"150px", marginRight:"150px"});

$("#my_div").animate({width: "30%"}, 250)

$("#my_div").animate({right: "0"}, 500)

$("p").animate({letterSpacing:"15px"});

$("#my_div").animate({ padding: "200px", width: "30%"}, "slow")

$("img").animate({height: "20px"}, "fast")

Соедините каждый фрагмент кода пользовательской анимации с его описанием.

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

Page 238: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

238 глава 5

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

Соедините каждый фрагмент кода пользовательской анимации с его описанием.

$("#my_div").animate({top: "150px"}, "slow")

$("p").animate({ marginLeft:"150px", marginRight:"150px"});

$("#my_div").animate({width: "30%"}, 250)

$("#my_div").animate({right: "0"}, 500)

$("p").animate({letterSpacing:"15px"});

$("#my_div").animate({ padding: "200px", width: "30%"}, "slow")

$("img").animate({height: "20px"}, "fast")

Анимация одновременного изме-нения левого и правого полей всех абзацев.

Анимация изменения правой сто-роны #my_div до 0 за половину секунды.

Анимация межбуквенных интерва-лов всех абзацев с продолжитель-ностью по умолчанию (400 милли-секунд).

Анимация одновременного изме-нения внутренних полей и шири-ны #my_div.

Анимация изменения положения верхней стороны #my_div с про-должительностью slow.

Анимация изменения высоты всех изображений с продолжительно-стью fast.

Анимация изменения ширины #my_div, продолжающегося 1/4 секунды.

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

Решение

Page 239: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 239

jquery эффекты и анимация

Òåêóùåå çíà÷åíèå ñâîéñòâà Çàäàííîå çíà÷åíèå ñâîéñòâà

Следует помнить, что метод animate изменяет текущее значение свойства CSS до значе-ния, заданного первым параметром. Чтобы пользовательская анимация была эффектив-ной, необходимо тщательно учесть, какое значение хранится в CSS в данный момент. В предыдущем примере значение left элемента #my_div изменялось до 100px. То, что при этом произойдет на экране, полностью зависит от текущего значения свойства left элемента #my_div.

#my_div{ left: 20px;}

$("#my_div").animate({left:"100px"});

#my_div

#my_div пере-мещается на 80 пикселов вправо.

Òåêóùåå çíà÷åíèå ñâîéñòâà Çàäàííîå çíà÷åíèå ñâîéñòâà

#my_div{ left: 200px;}

$("#my_div").animate({left:"100px"});

#my_div находится в началь-ной позиции 200px.

#my_div пере-мещается на 100 пикселов влево.

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

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

Îòêóäà è êóäà?

В анимации используется абсолютная позиция.

Прекрасно, но как это нам поможет с приложением «Собери монстра»?

Page 240: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

240 глава 5

относительно просто

Îòíîñèòåëüíàÿ àíèìàöèÿ = êàæäûé ðàç ïåðåìåñòèòü íà ñòîëüêî

При абсолютной анимации элемент перемещается в абсолютную позицию в визуальной си-стеме координат. При относительной анимации перемещение элемента задается относи-тельно последней позиции, в которую он переместился в процессе анимации.

Вспомните, что полосы изображений, которые должны отображаться, вложены в элемент div с идентификатором #pic_box. Свойству left элемента div#pic_box в текущем коде CSS задается значение 91px. Давайте подумаем, как должны двигаться полосы изображений для реализации эффекта горизонтального скольжения.

Àáñîëþòíûå è îòíîñèòåëüíûå ïåðåìåùåíèÿ ýëåìåíòîâ

367 пикселов367 пикселов 367 пикселовСначала отображается первый фрагмент головы (относительная пози-ция 0 пикселов).

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

Итак, метод animate должен смещать изображение на -367 пикселов при каж-дом вызове функции.

Вернемся к примеру абсолютного позиционирования на предыдущей странице:

$("#my_div").animate({ left:"100px"}); $("#head").animate({left:"???"});

Команда задает свойству left

элемента #my_div абсолютное

значение 100 пикселов.Но как приказать animate сме-

щать элемент на -367 пикселов

при каждом вызове?

Но как обозначить относительное перемещение элемента при вызове метода animate?

Page 241: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 241

jquery эффекты и анимация

$("#box").animate({left:"+=20"});

a = 20 a += 30

w Напишите пару строк кода jQuery, которые выполняют следующие операции:

В JavaScript существуют специальные операторы, которые сдвигают элемент(ы) на одинаковую величину при каждом вызове animate — операторы присваивания. Они обычно используются для присваивания, при котором новое значение переменной получается увеличением старого значе-ния на некоторую величину. Впрочем, звучит все это намного сложнее, чем на самом деле.

Êîìáèíèðîâàííûå îïåðàòîðû

Знак равенства — оператор

присваивания.

При объединении арифметических операторов со знаком = получается удобная сокращенная запись.

Оператор = присваивает переменной a значение 20.

Плюс в сочетании со знаком = является

сокращенной записью a = a + 30.

a -= 10Минус в сочетании со знаком = означает a = a – 10.

Элемент с идентификатором box смещается

на 20 пикселов при каждом вызове метода animate.

Комбинированные операторы помогают создавать относительную анимацию: новое значение вычисляется по формуле «текущее значение плюс или минус смещение в пикселах».

Вот что происходит с #box при каждом вызове метода animate:

Другие комбиниро-ванные операторы

присваивания:

� a *= 5 — это сокращенная запись операции a = a * 5.

� a /= 2 — это сокращенная запись операции a = a/2.

left = 20left = 0 left = 40

Изначально left равно 0.

Многократное изменение свойства left приводит к смещению элемента вправо в окне браузера.

Метод animate: left += 20.

Метод animate: left += 20.

Элемент #head перемещается на 367 пикселов влево при каждом вызове animate. Перемещение выполняется за 0,5 секунды.

1

Элемент #head перемещается обратно в исходную позицию (left:0px). Перемещение выполняется за 0,5 секунды.

2

Упражнение

Page 242: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

242 глава 5

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

В: Некоторые пользователи считают, что анимация мешает нормальному вос-приятию веб-страницы. Что делать, если я захочу разрешить пользователю от-ключать анимацию?

О: Справедливое замечание, некоторые пользователи считают, что анимация раз-дражает и усложняет работу с программой. Если вы хотите, чтобы пользователи могли отключить анимацию, свяжите функцию click кнопки (вы уже знаете, как это делается) со следующей строкой кода:

$.fx.off = true;Также для остановки анимации в jQuery может использоваться метод stop. Обе возможности описаны на сайте jQuery:

http://api.jquery.com/jQuery.fx.off/http://api.jquery.com/stop/

В: Вы пишете: «Параметры свойств CSS должны задаваться по стандарту DOM, а не по стандарту CSS». Что бы это значило?

О: Отличный вопрос! Метод animate получает параметры по стандарту DOM («синтаксис DOM»), а не по стандарту CSS.Различия лучше пояснить на конкретном примере. Чтобы задать толщину границы div в синтаксисе CSS, можно использовать следующую запись:

div { border-style:solid; border-width:5px; }

Предположим, что вы хотите анимировать изменение толщины границы. В jQuery для этого свойство задается в синтаксисе DOM:

$("div").animate({borderWidth:30},"slow");

Обратите внимание: в синтаксисе CSS имя свойства записывается в виде border-width, тогда как в синтаксисе DOM ис-пользуется запись borderWidth.

Различия между двумя вариантами записи более подробно рассматриваются в следу-ющей статье:

http://www.oxfordu.net/webdesign/dom/straight_text.html

В: А если я захочу анимировать из-менение цвета?

О: Для выполнения анимации цветовых переходов необходимо использовать би-блиотеку jQuery UI, которая поддерживает больше эффектов, чем jQuery. Мы будем рассматривать jQuery UI в главе 10, но без рассмотрения эффектов. Когда вы научи-тесь загружать и включать jQuery UI в ваше веб-приложение, с анимацией цветов осо-бых проблем уже не будет.

Напишите пару строк кода jQuery, которые выполняют следующие операции:

Элемент #head перемещается на 367 пикселов влево при каждом вызове animate. Перемещение выполняется за 0,5 секунды.

1

Элемент #head перемещается обратно в исходную позицию (left:0px). Перемещение выполняется за 0,5 секунды.

2

$("#head").animate({left:"-=367px"},500);

$("#head").animate({left:"0px"},500); Абсолютная анимация переводит голову монстра в исходное состояние, ими-тируя «перемотку».

частоЗадаваемые

вопросы

Page 243: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 243

jquery эффекты и анимация

Измените файл сценариев приложения «Собери монстра» — включите в него код, созданный нами в упражнении на предыдущей странице.

Âêëþ÷åíèå âûçîâîâ animate â ñöåíàðíûé êîä

$("#head").click(function(){ if (headclix < 9){ $(this).animate({left:"-=367px"},500); headclix+=1; } else{ $(this).animate({left:"0px"},500); headclix = 0; } }); $("#eyes").click(function(){ if (eyeclix < 9){ $(this).animate({left:"-=367px"},500); eyeclix+=1; } else{ $(this).animate({left:"0px"},500); eyeclix = 0; } }); $("#nose").click(function(){ if (noseclix < 9){ $(this).animate({left:"-=367px"},500); noseclix+=1; } else{ $(this).animate({left:"0px"},500); noseclix = 0; } }); $("#mouth").click(function(){ if (mouthclix < 9){ $(this).animate({left:"-=367px"},500); mouthclix+=1; } else{ $(this).animate({left:"0px"},500); mouthclix = 0; }

Задание!

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

my_scripts.js

Page 244: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

244 глава 5

тест-драйв

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

Мы реализовали пользова-тельский эффект горизон-тального скольжения.

Несколько щелчков мышью... и пользователь может создать собственное лицо монстра.

Тест-драйв

Page 245: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 245

jquery эффекты и анимация

Руководитель веб-проектов доволен результатами работы. Мы использовали гото-вые эффекты jQuery в сочетании с пользовательскими эффектами, созданными специально для конкретного приложения.

Ñìîòðè, ìàìà! Ðàáîòàåò áåç Flash!

Потрясающе! Пойду напугаю младшую

сестру монстром, кото-рого я сделала!

Целевой аудитории от 6 до 10 лет приложение понравилось. Все работает без Flash и дополнительных модулей браузера... jQuery нам безусловно при-

годится!

Вот здорово! Я создал столько монстров,

что сбился со счета!

Page 246: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

246 глава 5

ваш инструментарий jquery

Âàø èíñòðóìåíòàðèé jQuery

Глава 5 осталась позади, а ваш творческий инструмен-тарий расширился: добавились эффекты изменения прозрачности и скольжения, а также пользовательская анимация.

Эффекты изменения про-

зрачности

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

элементов:

fadeIn

fadeOut

fadeTo

Эффекты скольженияИзменение высоты элементов:slideUp

slideDownslideToggle

animate

Метод позволяет создавать пользовательские анима-

ции, когда готовых эффектов jQuery недостаточно.

Выполняет анимацию свойств CSS во времени.

Работает только со свойствами CSS, имеющими

числовые значения.

Перемещение элементов бывает абсолютным или

относительным.

Комбинированные операторы присваивания

(+=, -=) упрощают относительную анимацию.

ГЛА

ВА 5

Page 247: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

jQuery и JavaScript6

Люк jQuery, я твой отец!

Силы jQuery небезграничны. Хотя эта библиотека написана на JavaScript, к сожалению, она позволяет сделать не все, на что способен язык-родитель. В этой главе мы рассмотрим некоторые возможности JavaScript, необходимые для создания современных сайтов, и их применение в jQuery для создания пользовательских списков и объектов, а также средства перебора списков и объектов, которые существенно упростят вашу работу.

Сынок, есть некоторые вещи, с которыми ты один

просто не справишься...

Page 248: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

248 глава 6

jquery для картежников

От: Head First LoungeТема: Блэкджек на сайте

Привет!

Это твои знакомые из клуба «Head First». Надеемся, ты поможешь нам раз-

работать новое приложение для нашего сайта.

Нам бы ОЧЕНЬ хотелось иметь приложение для игры в блэкджек.

Справишься?

В идеале игрок щелкает на странице и получает две карты, с возможностью

потребовать сдачи дополнительных карт.

Правила нашего клуба, которые нам хотелось бы использовать:

1. Туз ВСЕГДА дает 11 очков (а не 1).

2. Если сумма очков игрока превышает 21 — перебор, игрок проиграл, игра

закончена.

3. Если сумма очков на руках игрока 21 — блэкджек, игра закончена.

4. Если сумма очков игрока не превышает 21, а на руках у него пять карт,

то игра закончена, а игрок побеждает.

Если ни одно из этих условий не выполнено, игрок может взять следующую

карту (или остановить сдачу).

Если оно из правил/условий выполнено, игра закончена.

Игрок должен иметь возможность сбросить текущую игру и начать заново.

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

Игра должна все делать сама.

Можешь сделать это для нас? Мы будем вечно благодарны!

-- КлубHead First

Ïðîãðàììèðóåì áëýêäæåê

Слухи о вашем мастерстве jQuery распространяются молниеносно. Смотрите, вам пришло сообщение из клуба «Head First», в котором вас просят помочь с разработкой очередного развлекательного приложения.

Page 249: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 249

jquery и javascript

Джим

Фрэнк

ДжоДжим: Парни, вы прочитали сообщение из клуба «Head First»?

Фрэнк: Да, они хотят разместить на своем сайте упрощенную ре-ализацию блэкджека. Мне кажется, это тривиально.

Джим: Элементарно? Но ведь это блэкджек! Нам понадобится колода карт, дилер, счетчик суммы очков... и так далее. И ты ду-маешь, что мы с этим справимся?

Джо: Просто не будет, но я думаю, что мы справимся. Как ты и сказал, кто-то должен сдавать карты. Мы напишем для этого функцию. Вероятно, в этой функции можно будет использовать наш старый генератор случайных чисел.

Джим: Кстати, да. А что с картами? Ведь их в колоде 52.

Фрэнк: Мы можем просто составить большой список и каждый раз выбирать случайную карту из списка.

Джим: Но как избежать повторного выбора одной карты?

Фрэнк: Пожалуй, я знаю, как это сделать...

Джим: Ого, впечатляет! А как насчет запоминания того, какие карты уже вышли? И подсчета очков?

Фрэнк: Ты меня подловил. Я пока не знаю, как это сделать.

Джо: Спокойно! В JavaScript и jQuery найдется немало полезных возможностей, которые нам помогут.

Джим: А зачем JavaScript? Мы можем использовать переменные или массивы jQuery для информации о картах. Я думал, нам не придется лезть в дебри JavaScript, раз уж мы используем jQuery…

Фрэнк: Переменные не решат проблем, в них в любой момент времени может храниться только конкретное значение: строка, текст или отдельный элемент страницы. А массивы jQuery по-зволяют хранить несколько значений, но это могут быть только элементы DOM, возвращаемые селектором.

Джо: Да, ты прав. Нам потребуется что-то более гибкое.

Фрэнк: Скажем, возможность определения наших собственных структур и типов переменных.

Джо: Снова в точку! А для создания структур нам понадобится JavaScript…

Page 250: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

250 глава 6

объективный взгляд

Îáúåêòû è õðàíåíèå äàííûõ

До настоящего момента мы использовали для хранения данных переменные и массивы. Переменные обеспечивают самый простой вариант хранения: одно значение связывается с одним именем. Хране-ние данных в массивах более эффективно: несколько значений связываются с одним именем.

Ïåðåìåííàÿ Ìàññèâ

Îáúåêò

Данные объекта хра-нятся в свойствах.

Имя свойствасвязывается… …со значением.Данные, описывающие

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

В переменной хранится одно значение. В массиве хранится несколько значений.

var a = 42; var v = [2, 3, 4]

leopardObject={ num_spots:"23", color:"brown"};

planeObject={ engines:"4", type:"passenger", propellor: "No"};

Объекты — еще более гибкая схема хранения данных. Они используются, когда для описания некото-рой сущности необходимо сохранить несколько переменных. Внутри объекта переменные называются свойствами. Объект может содержать функции, предназначенные для взаимодействия со свойствами объекта. Такая функция, созданная внутри объекта, называется методом.

Какими свойствами может обладать объект карты?

Объекты использу-

ются для хранения

нескольких значений,

описывающих некото-

рую сущность.

planeObject.engines;leopardObject.color;

Для обращения к свойствам объекта используется «точечная запись»:

Объект Его свойствоМозговой

штурм

Page 251: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 251

jquery и javascript

Ïîñòðîåíèå ñîáñòâåííûõ îáúåêòîâ

Объекты позволяют создавать ваши собственные переменные, которые работают именно так, как нуж-но вам. Вы можете создать объект, предназначенный для однократного использования, или же создать «шаблон» для построения объектов, который может использоваться снова и снова. О повторном ис-пользовании объектов мы поговорим чуть позже, а пока обсудим создание «одноразовых» объектов, а также рассмотрим некоторые термины и схемы, связанные с объектом.

Существует стандартный способ описания объектов с использованием диаграмм UML (Unified Modeling Language). UML — международный стандарт описания объектов в объектно-ориентирован-ном программировании.

Переменная, связанная с объектом, называется свойством объекта. Функция, связанная с объектом, на-зывается методом объекта. Объекты, рассчитанные на одноразовое использование, создаются ключе-вым словом var, как и все остальные переменные, встречавшиеся нам до настоящего момента.

Оказывается, практически все данные в jQuery и JavaScript —объекты.

Это относится к элементам, массивам, функциям, числам и дажестрокам, — все они имеют методы и свойства.

Имя объекта

Свойства объекта

Методы объекта

var myCountry = {

getCapital : function() {

alert(this.myCapital);

},

myName : 'USA',

myCapital : 'Washington DC'

},

Создаем объект с именем myCountry.

Создаем метод объ-екта с именем getCapital.

Создаем свойства объекта с име-нами myName и myCapital.

Задаем значения свойств.

Определение объекта всегда заключает-ся в фигурные скобки.

Эта функция выполняется при вызове метода.

UML-äèàãðàììà îáúåêòà

myCountry

myNamemyCapital

getCapital()

Эта структура покажет, как устроен ваш объект. Прежде чем браться за написание кода, полезно свериться с диаграммами UML.

А вот как этот объект определяется в программном коде:

Р А СС Л А Б Ь Т Е С Ь

Page 252: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

252 глава 6

объекты по шаблону

Ñîçäàíèå îáúåêòîâ äëÿ ïîâòîðíîãî èñïîëüçîâàíèÿ

У объектов есть одна интересная особенность: они могут иметь одинаковую структу-ру, но содержать разные значения свойств (или переменных). Как и в случае с функ-циями, рассчитанными на многократное использование (как мы делали в главе 3), можно создать «шаблон» (или конструктор) объекта, чтобы использовать его по-вторно. Конструктор объекта также может использоваться для создания экземпляров объекта.

Конструктор — всего лишь функция, поэтому для создания конструктора объекта следует использовать ключевое слово function вместо ключевого слова var. Далее ключевое слово new используется для создания нового экземпляра объекта.

function myPerson(a,b){

this.name = a;

this.age = b;

}

Имя объекта

Свойства объекта

Параметры/аргументы функции

Задаем значения свойств объекта.

Как вы думаете, где можно использовать такие объекты?

Хмм, словно план дома: один раз рисую, затем использую снова и снова. Это сэкономит

мне немало времени!

Объект в виде диаграммы UML

myPerson

nameage

Мозговой

штурм

Page 253: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 253

jquery и javascript

myCountry.getCapital();

alert(myCountry.myName);

Âçàèìîäåéñòâèå ñ îáúåêòàìè

После создания экземпляра объекта (независимо от того, создали ли его вы или кто-то другой) все операции с ним выполняются при помощи оператора «точка» (.). Чтобы вы лучше поняли, как работает этот механизм, давайте по-внимательнее присмотримся к только что определенным объектам myCountry и myPerson.

var actor1 = new myPerson('Jack', '42');

var actor2 = new myPerson('Mary', '33');

alert(actor1.name);

alert(actor2.age);

Значения, пере-данные в аргумен-тах функции new, задают значения свойств.

Обращение к свойству name экземпляра объекта myPerson с именем actor1

На странице выво-дится текст «Jack».

Обращение к свойству age property экземпляра объекта

myPerson с именем actor2 (в дан-

ном случае значение равно 33)

Создание новых экземпляров объ-екта myPerson с именами actor1 и actor2

Обращение к свойству myNameНа странице выво-дится текст «USA».

Вызов метода getCapitalНа странице будет выведен текст «Washington DC».

Новый экземпляр объекта создается командой «new ».

Да! Отличная мысль.Давайте подготовим страницу HTML и посмо-трим, как создать объект, представляющий карту.

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

в колоде?

Оператор «точка» ис-пользуется по схеме имя_объекта.имя_ме-тода() или имя_объекта.имя_свойства().

Page 254: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

254 глава 6

игра начинается

Ïîäãîòîâêà ñòðàíèöû

Ну что, скоро я буду сдавать

карты?

Задание!

Создайте файлы HMTL и CSS по приведенной ниже инфор-мации. Не забудьте создать файл my_scripts.js в папке scripts. На следующих страницах мы включим в него достаточно большой объем кода. Графику для всей главы можно загру-зить по адресу: http://thinkjquery.com/chapter06/images.zip.

<!DOCTYPE html>

<html>

<head>

<title>Head First Black Jack</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<div id="main">

<h1>Click to reveal your cards</h1>

<h3 id="hdrTotal"></h3><h3 id="hdrResult"></h3>

<div id="my_hand">

</div>

<div id="controls">

<div id="btnDeal">

<img src="images/deck_small.jpg">

</div>

</div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

</body>

</html>

index.html

>

#controls{

clear:both;

}

#my_hand{

clear:both;

border: 1px solid gray;

height: 250px;

width: 835px;

}

h3 {

display: inline;

padding-right: 40px;

}.current_hand{

float:left;

}

my_style.css

Page 255: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 255

jquery и javascript

Используя приведенную ниже UML-диаграмму объекта card, определите объект card с тремя параметрами name, suit и value. Значения параметров должны присваиваться соответствующим свойствам объекта. Этот конкретный объект пока не содержит ни одного метода. Часть кода мы уже написали за вас.

function card( ) {

}

Откройте страницу index.html в своем любимом бра-узере, ознакомьтесь с об-щей структурой страницы.

card

namesuitvalue

Тест-драйв

Упражнение

Page 256: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

256 глава 6

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

Ниже приведено определение объекта card. Включите его в файл my_scripts.js (раздел $(document).ready(function(){ });). Пока это весь код, который содержится в файле.

В: Чем «одноразовые» объекты отли-чаются от «многоразовых», пригодных для повторного использования?

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

В: Кажется, вы используете разные спо-собы задания свойств. Это так?

О: Да, так. Значения свойств могут за-даваться как с использованием оператора присваивания (=), так и с использованием

двоеточия (:), как мы сделали в примере. Оба способа являются действительными и взаимозаменяемыми.

В: Что еще мне нужно знать об объ-ектах?

О: Объекты JavaScript — достаточно сложная тема. Позднее в этой книге мы бу-дем использовать запись JSON ( JavaScript Object Notation). В этой записи обращение к свойствам производится несколько иным способом, который также может применять-ся к объектам JavaScript (так называемое «обращение по ключу»). Вместо записи:

object.my_propertyиспользуется запись:

object['my_property']

Результат остается неизменным — обра-щение к значению свойства

my_property.

В: Откуда появился стандарт UML?

О: Стандарт UML родился в середине 90-х, когда компании пытались разработать наглядный способ описания объектов. С тех пор UML прошел несколько циклов развития, а несколько конкурирующих частных фирм пытались утвердить свою версию в каче-стве общепринятого стандарта. К счастью, единый стандарт существует, и каждый разработчик со знанием UML сможет чи-тать и понимать диаграммы и информацию из других источников UML.

function card( name, suit, value ) {

this.name = name;

this.suit = suit;

this.value = value;

}

card

namesuitvalue

my_scripts.js

Ключевое слово function позволяет

многократно использовать определение.

Значения аргументов присваиваются свой-ствам объекта.

частоЗадаваемые

вопросы

Page 257: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 257

jquery и javascript

È ñíîâà ìàññèâû

Несколько элементов данных можно объединить в массив. Ячейки массива не-обязательно имеют отношение друг к другу, но такой способ хранения данных упрощает работу с ними. В главе 4 мы уже видели, как селектор jQuery возвраща-ет данные и сохраняет их в массиве. Сейчас мы воспользуемся JavaScript, чтобы работа с массивами стала еще эффективнее.

Ячейки массива могут содержать данные любого типа: строки, числа, объекты, даже элементы HTML! Существует несколько способов создания массивов:

И как упоминалось ранее, массивы тоже являются объектами, а значит, обладают методами и свойствами. Популярное свой-ство объекта length возвращает коли-чество ячеек в массиве. Для обращения к свойству length используется запись вида имя_массива.length.

var my_arr1 = new Array();

var my_arr2 = new Array('USA', 'China', 'Japan', 'Ireland');

var my_arr3 = ['USA', 'China', 'Japan', 'Ireland'];

Создание массива без ключевого слова new, но с заданием значений ячеек (перечисляемых в квадратных скобках [ ])

Создание массива ключевым словом new с заданием зна-чений ячеекСоздание пустого массива ключевым словом new

Не существует различий между способами созда-ния массивов.

На практике они выбира-ются впере мешку в зави-симости от назна че ния массива. Чтобы найти спи-

сок мето дов объекта массива, используйте в по-исковой системе строку «JavaScript array methods».

Это снова я! Мы уже встречались

в главе 4.

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

карты, верно?

Верно.Нам понадобится механизм хра-нения сданных карт и обращения к ним при сдаче. К счастью, мы уже знаем, как это делается…

Будьте осторожны!

Page 258: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

258 глава 6

ячейки и индексы

Îáðàùåíèå ê ÿ÷åéêàì ìàññèâà

В отличие от создания массивов, существует только один способ обращения к информации, хра-нящейся в ячейках. Индексирование массивов начинается с 0 — первой ячейке массива соответ-ствует порядковый номер (или индекс) 0. Мы уже использовали индексы в главе 3; если вы забыли, что это такое, вернитесь к ней и освежите память.

alert( my_arr2[0] ) ;

// В окне сообщения выводится строка USA

alert( my_arr3[2] );

// В окне сообщения выводится строка Japan

alert( my_arr1[1] );

// Ошибка, пустая ячейка

При обращении к ячейке массива по индексу кавычки не нужны.

При обращении к ячейкам массива всегда используются квадратные скобки [ ].

Имя массива, соз-данного на с. 257

При попытке обращения по несуществующему ин-дексу происходит ошибка.

Индекс ячейки определяет

ее позицию в массиве.Хорошо, у нас есть массив с запол-

ненными ячейками. И дальше нам так и придется работать с исходными

данными?

Конечно, нет!С ячейками легко выполняются операции добавления, изменения и удаления. Давайте посмотрим, как это делается.

Первой ячейке массива соот-ветствует индекс 0, второй — индекс 1 и т. д.

Page 259: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 259

jquery и javascript

Äîáàâëåíèå è îáíîâëåíèå ÿ÷ååê

В массив можно включить сколько угодно элементов. В приведенных ранее примерах в массивы my_arr2 и my_arr3 были изначально сохранены данные, а массив my_arr1 остался пустым. Однако в массиве можно добавлять новые и изменять существующие ячейки, причем эти операции также осуществляются по индексу. Рассмотрим несколько разных способов обновления массивов:

my_arr1[0] = "France";

alert( my_arr1[0] );

// Выводится строка France

my_arr1[1] = "Spain" ;

my_arr1[0] = "Italy" ;

alert( my_arr1[0] );

// Выводится строка Italy

my_arr3[2] = "Canada";

alert( my_arr3[2] );

// Выводится строка Canada

Задаем значение первой ячейки массива my_arr1.

Обновляем значение первой ячейки массива my_arr1.

Добавляем вторую ячейку в массив my_arr1.

Обновляем значение третьей ячейки массива my_arr3.

В файле my_scripts.js, после кода определения объекта card, создайте массив с именем deck, содержащий все 52 карты стандартной колоды.Вы можете использовать уже созданный объект card и многократно вы-зывать конструктор с нужными параметрами для создания каждой карты — от туза до короля с разными мастями (трефы, черви, бубны, пики) и ценно-стью (туз — 11 очков, двойка — 2 очка и т. д.).

Упражнение

Page 260: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

260 глава 6

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

Не забудьте, что список значений должен быть заключен в квадратные скобки.

Но в массиве так много карт! Похоже, для их

извлечения нам придется снова написать здоровенный блок кода. Тоже мне развлечение!

Файл my_scripts.js содержит массив deck c 52 картами стандартной колоды, а также определение объекта card. Для создания каждой карты используйте объект card и вызывайте конструктор с нужными параметрами.

Необязательно.

Конечно, к ячейкам можно обращаться по индексу, но мы также можем после-довательно пере-брать все ячейки при помощи конструк-ции, напоминающей each (см. главу 3), и нам не придется писать длинный код для каждой карты.

Пора познакомиться с циклами…

var deck = [

new card('Ace', 'Hearts',11),

new card('Two', 'Hearts',2),

new card('Three', 'Hearts',3),

new card('Four', 'Hearts',4),

new card('King', 'Hearts',10),

new card('Ace', 'Diamonds',11),

new card('Two', 'Diamonds',2),

new card('Three', 'Diamonds',3),

new card('Queen', 'Diamonds',10),

new card('King', 'Diamonds',10),

new card('Ace', 'Clubs',11),

new card('Two', 'Clubs',2),

new card('King', 'Clubs',10),

new card('Ace', 'Spades',11),

new card('Two', 'Spades',2),

new card('Three', 'Spades',3),

Не заббудьте чт

new card('Jack', 'Spades',10),

new card('Queen', 'Spades',10),

new card('King', 'Spades',10)

];

my_scripts.js

При создании каждого объекта card передаются три параметра.Задаем имя массива.

Page 261: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 261

jquery и javascript

Ïîâòîðåíèå îïåðàöèé

В нашем приложении придется часто сдавать и возвращать карты в массив. К счастью, в JavaScript как раз для подобных ситуаций существуют циклы. Самое интересное, что вы ими уже пользовались: в гла-ве 3 метод jQuery each использовался для перебора элементов на основании селектора jQuery. На этот раз у нас больше свободы выбора, так как в JavaScript существует несколько разновидностей циклов, которые имеют слегка различающийся синтаксис и предназначены для разных целей.

Да, мне нравится повторять одно и то же

много раз!

Циклы for выполняют фрагмент кода

заранее определенное количество раз.

Циклы do...while выполняют фрагмент

кода и повторяют его, пока не будет

выполнено некоторое условие.

ИнициализацияВыполняется один раз в начале цикла.

1

Проверка условияПринятие решения об остановке цикла или выполнении сле-дующей итерации (обычно в зависимости от значения пере-менной).

2

Тело циклаОсновной код, повторяемый при каждом выполнении цикла.

3

ОбновлениеОбновление переменных, используемых при проверке условия.

4

Цикл for:

1 2 3 4 2 3 4... ... ... ... ... ... ...

Цикл do...while:

1 3 4 2 3 4 2... ... ... ... ... ... ...

Одно выпол-нение цикла

Другое выполне-ние цикла

Одно выпол-нение цикла

Другое выполне-ние цикла

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

Цикл do...while выполняет код минимум один раз, а потом продолжает выполнять его до тех пор, пока не будет выполнено некоторое условие (ска-жем, логическая переменная сменит состояние или счетчик в коде достигнет заданного значения). Цикл do...while выполняется один и более раз.

Все циклы независимо от их типа состоят из четырех частей.

Page 262: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

262 глава 6

подробнее о циклах

Öèêëû for

for( var i=0 ; i < my_arr2.length ; i++ ){

alert( my_arr2[i] );

}

.length — общий метод всех массивов, возвращает количество заполненных ячеек в цикле.

Переменная цикла увеличивается с каж-дым выполнением.

Обращение к ячейке массива с использованием переменной, определен-ной в цикле

Часть в круглых скобках ( ) определяет, как долго будет выполняться цикл.Начинается

с ключевого слова for.

В цикле объ-является переменная, которая будет использовать-ся в качестве индекса для обращения к ячейкам массива. Эта переменная используется только внутри цикла.

Тело цикла всегда заключается в фигурные скобки.

Тело цикла завер-шается фигурной скобкой.

var i=0;

do{

alert(my_arr2[i]);

i++;

}while (i<=5);

1 2

3

4

1

3

4

2

Тело цикла заключается в фигурные скобки.

Переменная цикла увели-чивается при каждом его выполнении.

Цикл начинается с ключе-вого слова do.

Цикл завершается ключе-вым словом while.

Öèêëû do...while

Цикл for:

1 2 3 4 2 3 4... ... ... ... ... ... ...

Одно выполне-ние цикла

Другое выполнение цикла

Цикл do...while:

1 3 4 2 3 4 2... ... ... ... ... ... ...

Одно выполне-ние цикла

Другое выполне-ние цикла

В цикле объявляется перемен-ная, которая будет использо-ваться в качестве индекса для обращения к ячейкам массива. Не забывайте, что эта пере-

менная может использоваться только внутри цикла.

Циклы под увеличительным стеклом

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

Page 263: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 263

jquery и javascript

ДжимФрэнкДжо

Фрэнк: У нас есть массив объектов card, но нам ведь нужно из-влечь случайную карту при сдаче, верно?

Джо: Да, и к счастью, мы уже написали функцию getRandom в гла-ве 3. Она будет возвращать случайное число каждый раз, когда по-требуется извлечь карту из массива.

Джим: И что мы будем делать с этой картой?

Фрэнк: Информацию о ней нужно сохранить. Мы должны просум-мировать очки и определить, дошел игрок до 21 очка или нет.

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

Джим: Карты будут сохраняться в переменных?

Фрэнк: Лучше воспользоваться массивом...

Джо: Точно! Причем хранить сами карты необязательно; доста-точно хранить их индексы. По ним можно будет проверить, содер-жится ли карта в массиве использованных карт used_cards.

Джим: И как мы узнаем, содержится ли значение в массиве?

Фрэнк: При помощи вспомогательного метода jQuery с именем inArray.

Джо: Звучит разумно. Но мне кажется, что для этого нам стоит воспользоваться несколькими функциями. Нам понадобится слу-чайное число от 0 до 51; потом нужно проверить, не было ли оно использовано ранее. Если карта уже использована, повторяем по-пытку, а если нет — извлекаем из колоды соответствующую карту и сохраняем ее индекс. Также необходимо вывести изображение карты для игрока.

Джим: И как мы выведем изображение карты?

Фрэнк: Вообще-то изображения у нас уже есть, они упорядочены по мастям и типам, мы воспользуемся этими атрибутами объекта card для отображения графики на странице.

Джо: Точно. Мы создадим элемент DOM и присоединим его к эле-менту div my_hand, уже находящемуся на странице.

Фрэнк: Наши усилия по созданию объекта card уже окупаются… За дело!

Циклы позволят нам быстро переме-щаться по массиву карт. Этак мы быстро управимся с заданием... Что там дальше?

Page 264: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

264 глава 6

игра в прятки с переменными

А если мы захотим узнать, в какой

ячейке массива haystack хранится

это значение?

Ïîèñê èãîëêè â ñòîãå ñåíà

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

var index = $.inArray( value, array );

Создаем переменную для хранения возвращаемого значения функции.

Сокращенная запись jQuery

Вызов вспомогательного метода inArray

Искомое значение Массив, в котором

ищется значение

Где именно в нашем приложении следует проверять, использовалось ли ранее полученное значение?

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

Вспомогательный метод, который пригодится в нашей конкретной ситуации, называется inArray. Он возвращает позицию (индекс) ячейки, в которой был найден искомый элемент, если он был найден, конечно. Если найти значение в массиве не удалось, метод возвращает –1. Как и другие вспомогательные методы, inArray не требует передачи селектора, он вызывается прямо для функции jQuery или ее сокращения.

var haystack = new Array('hay', 'mouse', 'needle', 'pitchfork')

Создание массива со всякой всячиной

var needle_index = $.inArray( 'needle', haystack );

Искомое значение

Массив, в котором ищется значение

Мозговой

штурм

Page 265: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 265

jquery и javascript

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

должны содержаться определения двух функций (deal и hit), а также слушателя события click для

элемента с идентификатором btnDeal и определение нового массива used_cards, в котором хра-

нится информация о сданных ранее картах.

дальше � 265

var used_cards = new ___________();

function ___________{

for(var i=0;i<2;i++){

hit();

}

}

function getRandom(num){

var my_num = Math.floor(___________________*num);

return my_num;

}

function __________{

var good_card = false;

do{

var index = ________________(52);

if( !$.inArray(index, ______________ ) > -1 ){

good_card = true;

var c = deck[ index ];

_____________[used_cards.length] = index;

hand.cards[hand.cards.length] = c;

var $d = $("<div>");

$d.addClass("current_hand")

.appendTo(_____________);

$("<img>").appendTo($d)

.attr( _______ , 'images/cards/' + c.suit + '/' + c.name + '.jpg' )

.fadeOut('slow')

.fadeIn('slow');

}

}__________(!good_card);

good_card = false;

}

$("#btnDeal").click( _____________(){

deal();

$(this).toggle();

});my_scripts.js

deal()

hit()

getRandom

used_cards

Array

used_cards

"#my_hand"

'src'

while

function

Math.random()

Развлечения с магнитами

Page 266: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

266 глава 6

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

Ниже приведен завершенный код функций deal и hit, а также код слушателя события click для

элемента с идентификатором btnDeal и определение массива used_cards, в котором хранится

информация об уже сданных картах.

var used_cards = new ___________();

function ___________{

for(var i=0;i<2;i++){

hit();

}

}

function getRandom(num){

var my_num = Math.floor(___________________*num);

return my_num;

}

function __________{

var good_card = false;

do{

var index = ________________(52);

if( !$.inArray(index, ______________ ) > -1 ){

good_card = true;

var c = deck[ index ];

_____________[used_cards.length] = index;

hand.cards[hand.cards.length] = c;

var $d = $("<div>");

$d.addClass("current_hand")

.appendTo(_____________);

$("<img>").appendTo($d)

.attr( _______ , 'images/cards/' + c.suit + '/' + c.name + '.jpg' )

.fadeOut('slow')

.fadeIn('slow');

}

}__________(!good_card);

good_card = false;

}

$("#btnDeal").click( _____________(){

deal();

$(this).toggle();

});

my_scripts.js

cards = new

___________

ar i=0;i<2;

deal()

__________

ood card =

hit()

__

y(index,

_ getRandom __(52);

______________ )__

__om _

used_cards

_____________Array

var c = deck[ i

_____________[u__

hand.cards[hand

used_cards

current_hand

_____________)__

ppendTo($d)

"#my_hand"

($ )

_______ ,__

t('slow')

($ )

'src'

}

__________(__

ood card =

while

_______ __________function

____________________Math.random()

Создаем массив для хранения использованных карт.

Используем цикл for для двукратного вызова функции hit.Снова функция getRandom!

Управляющая переменная цикла do…while

Проверяем, была ли использована только что отобранная карта, при помощи функции inArray.

Если карта уже использо-

вана, повторяем попытку.

Строим путь к изо-бражению из свойств объекта card.

Включаем индекс карты в массив used_cards.

Получаем карту из массива deck.

Функция deal вызывается в обработчике click.

Заставляем карту «миг-нуть» на экране.

Развлечения с магнитами. Решение

Page 267: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 267

jquery и javascript

Включите код из упражнения с магнитами в файл my_scripts.js (после определения массива deck), откройте страницу в браузере. Щелкните на изображении колоды, чтобы получить карты.

Как вы думаете, что следует использовать для хранения всей этой информации?

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

Я пока сдаю только две карты. А значит, я почти всегда выигрываю! Но пусть игра будет честной. Сможе-те ли вы организовать сдачу допол-

нительных карт?

Тест-драйв

Мозговой

штурм

Page 268: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

268 глава 6

полуфабрикаты HTML и CSS

Вы уже стали настоящим профессионалом по стилю и структуре страниц, так что мы просто приводим обновленный код файлов index.html и my_style.css для сравнения. После включения нового кода HTML и CSS на странице появляются новые элементы, вско-ре мы свяжем их с программным кодом.

<!DOCTYPE html>

<html>

<head>

<title>Head First Black Jack</title>

<link href="styles/my_style.css" rel="stylesheet">

</head>

<body>

<div id="main">

<h1>Click to reveal your cards</h1>

<h3 id="hdrTotal"></h3>

<h3 id="hdrResult"></h3>

<div id="my_hand">

</div>

<div id="controls">

<div id="btnDeal">

<img src="images/deck_small.jpg">

</div>

<div id="btnHit">

<img src="images/deck_small.jpg">

</div>

<div id="btnStick">

<img src="images/stick_small.jpg">

</div>

</div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

</body>

</html>

index.html

>

#controls{

clear:both;

}

.current_hand{

float:left;

}

#my_hand{

clear:both;

border: 1px solid gray;

height: 250px;

width: 835px;

}

#btnHit, #btnStick, #btnRestart{

display:none;

float:left;

}

h3 {

display: inline;

padding-right: 40px;

}

my_style.css

Добавляем но-

вые элементы

для сдачи карт

и отказа.

Добавляем код CSS для новых элементов.

Готово к употреблению

Page 269: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 269

jquery и javascript

Используя приведенную ниже диаграмму UML, создайте «одноразовый» объект с именем hand. Свойство cards должно содержать новый пустой массив. Свойству current_total при-сваивается значение 0. Метод sumCardTotal должен перебирать все карты в свойстве cards, суммировать их значения и задавать полученную сумму как значение свойства current_total. Далее свойство current_total используется для задания значения элемента с идентифика-тором hdrTotal. Мы уже написали небольшую часть кода объекта за вас.

var hand = {

cards : new Array(),

current_total : 0,

sumCardTotal: function(){

}

};

В: Существуют ли другие типы циклов, о которых мне следует знать?

О: Да, существуют. Цикл while очень по-хож на do…while, но условие в нем про-веряется в начале. Также существует цикл for…in, который перебирает свойства объекта и последовательно возвращает их значения.

В: Итак, я запустил цикл на выполне-ние. Могу ли я прервать его в середине?

О: Да, при помощи очень простой коман ды: break. При выполнении этой команды в любой точке цикла его выполнение преры-вается, а управление передается команде, следующей за циклом.

В: А что такое appendTo? Раньше мы видели только append. Эти методы чем-то различаются?

О: При использовании append селектор, вызывающий метод, является контейнером, в который вставляется содержимое. С другой стороны, при использовании appendTo со-держимое задается до метода (либо в виде се-лекторного выражения, либо в виде разметки HTML, созданной «на месте») и вставляется в заданный контейнер.

hand

cardscurrent_total

sumCardTotal()

частоЗадаваемые

вопросы

Упражнение

Page 270: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

270 глава 6

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

var hand = {

cards : new Array(),

current_total : 0,

sumCardTotal: function(){

}

};

this.current_total = 0;

for(var i=0;i<this.cards.length;i++){

var c = this.cards[i];

this.current_total += c.value;

}$("#hdrTotal").html("Total: " + this.current_total );

Итак, теперь у нас имеется объект hand со свойством card (массив), и функция, которая перебирает массив card, получает ценность текущей карты и обновляет сумму очков.

Нет, это определенно нежелательно. По правилам, описанным в со-общении из клуба «Head First», победитель определяется по не-скольким различным критери-ям. Давайте еще раз вспомним эти критерии.

Если сумма очков игрока превыша-ет 21, то происходит перебор. Игрок проиграл, игра закончена.

1

Если сумма очков игрока равна точ-но 21, то игрок набрал блэкджек, игра закончена.

2

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

3

Если ни одно из этих условий не вы-полнено, игрок может потребовать сдачи следующей карты (или остано-вить сдачу).

4

Создаем новый массив для свойства card.

Задаем свойству current_

total значение 0.

Выводим сумму на экран в элементе hdrTotal.

Перебираем ячейки массива card.

Получаем текущую

карту из массива.

Прибавляем очки к current_total.

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

разве не так?

hand

cardscurrent_total

sumCardTotal()

Page 271: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 271

jquery и javascript

Ïîðà ïðèíèìàòü ðåøåíèå... ñíîâà!

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

if( myBool == true ){

// Здесь что-то делаем!

}else{

// Иначе делаем что-то другое!

}

Проверяемое условие

Оператор проверки

равенства

Начало условной команды if

Переменная JavaScriptКод, который должен выпол-няться, если условие истинно.

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

if( myNumber < 10 ){

// Здесь что-то делаем!

}else if( myNumber > 20 ){

// Иначе делаем что-то другое!

}else{

// Наконец, делаем что-то третье!

}

Проверяемое условие

Другое проверяемое условие

Где в нашем коде вы бы использовали конструкцию if / else if / else?

Мозговой

штурм

Page 272: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

272 глава 6

то или это... или что-то еще!

Îïåðàòîðû ñðàâíåíèÿ è ëîãè÷åñêèå îïåðàòîðû

Условные конструкции (такие как if/else или do…while) должны принимать правильное решение на основании проверяемого условия. Для этого в них используются специальные операторы сравнения и логические операторы. В JavaScript существуют семь разных операторов сравнения и три логических оператора, а также оператор сокращенной записи конструкции if/else, называемый тернарным оператором. Некоторые из этих операторов уже встреча-лись нам ранее, а ниже приведен полный список.

Ðàâåíñòâî

a == b

Íåðàâåíñòâî

a != b

Ìåíüøå

a < b

Áîëüøå

a > b

Îòðèöàíèå

!a

Ìåíüøå ëèáî ðàâíî

a <= bÁîëüøå ëèáî ðàâíî

a >= b

Îïåðàòîðû ñðàâíåíèÿ

Ëîãè÷åñêèå îïåðàòîðû

Òî÷íîå ðàâåíñòâî

a === b

Èëè

a || b

È

a && b

Истина, если значение a равно b

Истина, если значение

a не равно b

Истина, если зна-чение a меньше b

Истина, если a меньше ИЛИ равно bИстина, если зна-чение a больше b

Истина, если a больше ИЛИ равно b

Истина, если значение a равно b и оба значения имеют одинаковый тип

Истина, если значение aложно илине существует (для элементов DOM)

Истина, если истинно хотя бы одно из двух значений a и b

Истина, если зна-чения a и b истинны одновременно

Page 273: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 273

jquery и javascript

Измените объект hand так, чтобы он проверял значение свойства current_total

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

исходное сообщение). Ниже приведен существующий объект, а также основа кода,

который вам необходимо написать.

var hand = {

cards : new Array(),

current_total : 0,

sumCardTotal: function(){

this.current_total = 0;

for(var i=0;i<this.cards.length;i++){

var c = this.cards[i];

this.current_total += c.value;

}

$("#hdrTotal").html("Total: " + this.current_total );

if(this. > 21){

$("#btnStick").trigger("click");

$("#hdrResult").html("BUST!");

} (this.current_total ){

$("#btnStick").trigger("click");

$("#hdrResult").html("BlackJack!");

}else if( .current_total 21 this.cards.length == 5){

$("#btnStick").trigger("click");

$("#hdrResult").html("5 card trick!");

}

// Продолжаем игру! :)

}

}

};

my_scripts.js

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

Page 274: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

274 глава 6

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

В метод sumCardTotal включена логика проверки очков сдан-

ных карт. Даже в этом простом приложении количество условных

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

var hand = {

cards : new Array(),

current_total : 0,

sumCardTotal: function(){

this.current_total = 0;

for(var i=0;i<this.cards.length;i++){

var c = this.cards[i];

this.current_total += c.value;

}

$("#hdrTotal").html("Total: " + this.current_total );

if(this.current_total > 21){ $("#btnStick").trigger("click");

$("#hdrResult").html("BUST!");

}else if(this.current_total == 21){

$("#btnStick").trigger("click");

$("#hdrResult").html("BlackJack!");

}else if(this.current_total <= 21 && this.cards.length == 5){ $("#btnStick").trigger("click");

$("#hdrResult").html("BlackJack - 5 card trick!");

}else{ // Продолжаем игру! :)

}

}

};

Проверяем условие:

значение current_total

больше 21.

Проверяем условие: равно ли свойство current_total 21

Проверяем условие: свойство current_total меньше либо равно 21 и игрок уже получил 5 карт.

В противном случае не делаем ничего!

my_scripts.js

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

Page 275: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 275

jquery и javascript

Но мы пока не можем вызвать новые функции, потому что они

существуют сами по себе, верно?

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

Расставьте магниты так, чтобы у вас получилась функция, добавляющая несколько слушателей со-

бытий в приложение. Слушатели должны подключаться к элементам с идентификаторами btnHit

и btnStick. Кнопка btnHit должна сдавать очередную карту, а кнопка btnStick — останавливать

игру. Также после сдачи каждой карты должен вызываться метод sumCardTotal. Мы также включили

завершающий фрагмент функции hit, в который тоже необходимо внести изменения.

}while(!_______________);

good_card = false;

hand.___________________();

}

$("#btnDeal").click( _____________(){

deal();

$(this).toggle();

$("#btnHit")._____________();

$("#btnStick").toggle();

});

$("______________").click( function(){

hit();

});

$("#btnStick").click( function(){

$("#hdrResult").html(______________);

});

toggle

function

sumCardTotal

#btnHit

'Stick!'

good_card

my_scripts.js

Развлечения с магнитами

Page 276: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

276 глава 6

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

}while(!_______________);

good_card = false;

hand.___________________();

}

$("#btnDeal").click( _____________(){

deal();

$(this).toggle();

$("#btnHit")._____________();

$("#btnStick").toggle();

});

$("______________").click( function(){

hit();

});

$("#btnStick").click( function(){

$("#hdrResult").html(______________);

});

my_scripts.js

В: Существуют ли другие способы сравнения значений в JavaScript?

О: Существуют, впрочем, это не столько способ сравнения значений как таковой, а скорее способ принятия решений в зави-симости от значений переменных. Мы имеем в виду конструкцию switch, которая может проверять много разных условий. Если вам приходится писать длинные серии команд if / else if / else, их часто удается заменить конструкцией switch.

В: Вы упоминали о сокращенной форме команды if/else. Как она выглядит?

О: При использовании так называемого тернарного оператора усло-вие отделяется от выполняемого действия вопросительным знаком:

a > b ? код_true : код_false

Следующий код добавляет слушателей событий к кнопкам, а также вызывает

метод sumCardTotal после каждой сдачи карты.

();

_____________

.toggle();

toggle

___ __(_____ __function

ard = false;

____________ __________sumCardTotal

_____________

hit();#btnHit

____________)'Stick!'

_______________)

d = false;d = false;

good_cardЦикл выполняется,

пока не найдена подходящая карта.

В конце hit вычисляется сумма очков текущей руки.

Кнопка сдачи двух исходных карт скрывается, две другие кнопки отображаются.

Задаем выводимое

сообщение.

Сдаем две исходные карты.

Запросить одну карту.

Развлечения с магнитами. Решение

частоЗадаваемые

вопросы

Page 277: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 277

jquery и javascript

Включите весь новый код в файл my_scripts.js после функции hit (не забудьте обновить завершающий фрагмент самой функции hit). Откройте страницу в своем любимом браузере.

Джим Фрэнк Джо

Фрэнк: Не торопись. Нам еще нужно реализовать возмож-ность сброса, чтобы после окончания партии игрок мог на-чать игру заново без перезагрузки страницы.

Джо: Также необходимо проследить за тем, чтобы игроки не получали карты из предыдущих раздач. Из массивов нужно все удалить.

Джим: Но как мы это сделаем? Мы динамически добавляли элементы HTML, включали в массивы новые значения. И те-перь это все нужно стереть?

Фрэнк: Да. Способы решения этих задач слегка различаются, но нам действительно придется все стереть.

Джо: Кажется, я знаю! В jQuery для очистки содержимого элементов используется метод empty. Для очистки массивов существует несколько решений, но не все они одинаково рабо-тают во всех браузерах. Какой же способ лучше подойдет нам?

Ну что, готово?

Тест-драйв

Page 278: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

278 глава 6

с чистого листа

Ñòèðàíèå èíôîðìàöèè â jQuery

Помните, как в главе 2 мы использовали метод jQuery remove для безвозвратного удаления конкретного элемен-та и всех его потомков из DOM? Такое решение отлично работает, если вы хотите удалить родительский элемент. Но если основной элемент должен остаться на своем ме-сте, а вы хотите только стереть его содержимое, лучше воспользоваться методом jQuery empty. Этот метод, как и remove, требует указания селектора, но элемент, для кото-рого он был вызван, остается на своем месте.

body

div id="main"

div id="my_hand"

div class=

"current_hand"div class=

"current_hand"

$("#my_hand").empty();

Текущая структура страницы

Часто мы используем jQuery для того, чтобы нам не прихо-дилось писать несколько строк кода JavaScript. К счастью, некоторые операции выполняются в JavaScript так же про-сто, как в jQuery; это как раз один из таких случаев. Син-таксис слегка отличается, но конечный результат остается неизменным, а вам не приходится отслеживать свою теку-щую позицию в DOM. Для очистки массива в JavaScript до-статочно сделать свойство length равным 0:

À â JavaScript åùå ïðîùå

used_cards.length = 0;

Проще простого, верно?

Итак, нам осталось выбрать то, что нужно стереть?

Да, но порядок стирания информации тоже важен.

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

Элементы, которые мы хотим удалить

Page 279: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 279

jquery и javascript

Включите в файл index.html новый элемент div (по аналогии с другими управляющими

элементами div), присвойте ему идентификатор btnRestart. Разместите в нем элемент

изображения с источником restart_small.jpg из папки images.

Также включите в файл my_scripts.js слушателя события click для элемента btnRestart.,

который очищает элемент my_hand, массив used_cards и массив cards в объекте hand.

Кроме того, он должен отображать новый элемент div с идентификатором result и свой

элемент div, стирать разметку HTML элементов hdrResult, а в завершение отображать

элемент btnDeal и инициировать для него событие click.

<div id="btnStick">

<img src="images/stick_small.jpg">

</div>

<div id=" "><img src="" id="imgResult">

</div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

index.html

$("#hdrResult").html('Stick!');

});

$("#btnRestart").click( function(){

.toggle();

$(this).

$("#my_hand").

$("#hdrResult").html('');

used_cards. = 0;

.length = 0;

hand. = 0;

$("#btnDeal").toggle()

. ('click');

});

my_scripts.js

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

Page 280: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

280 глава 6

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

Итак, у нас есть кнопка сброса, которая возвращает все элемен-

ты в  исходное состояние. Теперь немного волшебства JavaScript

со  свойством length, и дело сделано!

<div id="btnStick">

<img src="images/stick_small.jpg">

</div>

<div id="btnRestart"> <img src="images/restart_small.jpg"> </div> <div id="result"><img src="" id="imgResult"></div> </div>

</div>

<script src="scripts/jquery-1.6.2.min.js"></script>

index.html

$("#hdrResult").html('Stick!');

$("result").toggle();

});

$("#btnRestart").click( function(){

$("#result").toggle(); $(this).toggle(); $("#my_hand").empty(); $("#hdrResult").html('');

used_cards.length = 0; hand.cards.length = 0; hand.current_total = 0;

$("#btnDeal").toggle()

.trigger('click');});

my_scripts.js

Кнопка сброса начи-нает игру заново.

Результат делается более наглядным.

Все элементы

возвращаются

в исходноесостояние.

Имитируем щелчок на элементе btnDeal.

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

Page 281: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 281

jquery и javascript

Добавьте событие click для элемента btnRestart в файл my_scripts.js. Также не забудьте включить дополнительную разметку HTML в файл index.html.

Как здорово! Почти то, что я хотела... Только одна мелочь: нельзя ли сделать отображение результата более эффектным и интересным? Извини, что надоедаю со своими просьбами.

Тест-драйв

Page 282: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

282 глава 6

все любят победителей

if(this.current_total> 21){

$("#btnStick").trigger("click");

$("#imgResult").attr('src','images/x2.png');

$("#hdrResult").html("BUST!")

.attr('class', 'lose');

}else if(this.current_total == 21){

$("#btnStick").trigger("click");

$("#imgResult").attr('src','images/check.png');

$("#hdrResult").html("BlackJack!")

.attr('class', 'win');

}else if(this.current_total <= 21 && this.cards.length == 5){

$("#btnStick").trigger("click");

$("#imgResult").attr('src','images/check.png');

$("#hdrResult").html("BlackJack - 5 card trick!")

.attr('class', 'win');

}else{}

$("#hdrTotal").html("Total: " + this.current_total );

}

};

function end(){

$("#btnHit").toggle();

$("#btnStick").toggle();

$("#btnRestart").toggle();

}

$("#btnStick").click( function(){

$("#hdrResult").html('Stick!')

.attr('class', 'win');

$("#result").toggle();

end();

});

×òîáû áûëî êðàñèâåå

Задание!

Включите в файл my_scripts.js новую функцию end, которая вызывается кнопкой btnStick, а также внесите изменения в логике sumCardTotal. Обновленную версию файла my_style.css можно загрузить по адресу:http://thinkjquery.com/chapter06/end/styles/my_style.css.

Назначаем атри-

буту src элемента

imgResult изображение

в зависимости от

результата игры.

Переключаем состояние

всех элементов управле-

ния для завершения игры.

Вызываем функцию end для завершения игры (после отказа от сдачи карты). my_scripts.js

Задаем класс заго-ловка в зависимости от результата игры.

Page 283: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 283

jquery и javascript

Обновите код метода sumCardTotal объекта hand в файле my_scripts.js. Также не забудьте загрузить новую версию файла my_style.css и установить ее на место старой.

Потрясающе! Великолепно! Теперь посетители клуба «Head

First» смогут провести время за игрой в блэкджек!

Тест-драйв

Page 284: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

284 глава 6

ваш инструментарий jquery и javascript

Âàø èíñòðóìåíòàðèé jQuery è JavaScript

Глава 6 осталась позади. В ней ваш творческий инструментарий расширился: в нем появились объекты JavaScript, массивы и циклы.

Объекты JavaScript

Автономное создание и исполь-

зование конструкторов.

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

конструктора

Массивы

Создание массивов

Сохранение значений в ячейках

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

Обновление содержимого массива

Циклы

Цикл for

Цикл do...while

Логические операторы

Операторы сравнения

jQuery.empty

$.inArray — вспомогательный метод

.attr

.trigger

ГЛА

ВА 6

Page 285: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Хочу функцию «СделатьУборку»...

Пользовательские функции для пользовательских эффектов7

Что будем делать?

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

Page 286: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

286 глава 7

ой-ой...

Веб-приложение «Собери монстра» из главы 5 пользовалось большим успехом у детей и родите-лей. Но похоже, где-то допущена ошибка, из-за которой с эффектом молний возникают проблемы. Джилл из DoodleStuff сообщает о проблемах, а заодно просит доработать приложение.

Мы обнаружили, что когда поль-зователь открывает в браузере новую вкладку,

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

что-то не так!

Íàäâèãàåòñÿ áóðÿ

Попробуйте воспроизвести проблему. Что произошло с молниями? Почему после перехода на другую вкладку исчезли паузы между разрядами?

Когда посетитель запускает при-ложение «Собери монстра»…

…а потом открывает новую вкладку, остается на ней на несколько минут…

…а потом возвращается на вкладку приложения «Собери монстра», молнии непре-рывно сверкают, словно эффекты не поспевают друг за другом.

Джилл, директор

по контролю ка-

чества

Мозговой

штурм

Page 287: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 287

пользовательские функции

Ìû ñîçäàëè ìîíñòðà... ôóíêöèþ-ìîíñòðà

Функция сверкания молнии, написанная нами в главе 5, таит скрытый подвох. Она про-должает работать непрерывно, даже если пользователь ушел со страницы. А когда пользо-ватель возвращается на вкладку, таймер пытается наверстать упущенное время и быстро перерисовывает молнию на экране. Похоже, таймер работает не так, как мы хотели. Что же произошло?

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

function lightning_one(t){ $("#lightning1").fadeIn(250).fadeOut(250); setTimeout("lightning_one()",t);};

Метод setTimeout приказывает

интерпретатору JS выполнить

функцию, а затем повторить ее

выполнение с некоторой задержкой.

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

Задержка в миллисекундах

Функция, которая бесконечно и бесконтрольно запускает сама себя? Слишком сложно и небезо-пасно! Как вернуть происходящее

под контроль?

Здесь мы указываем ин-терпретатору JS, что функция должна вызывать сама себя снова и снова.

С функциями, вызывающими сами себя, нужно быть очень осторожным.

Бесконечные циклы могут поглощать ресурсы системы, а это вызовет сбой в браузере посетителя.

Будьте осторожны!

Page 288: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

288 глава 7

один объект правит всеми

Óïðàâëåíèå âðåìåííûìè ýôôåêòàìè

К счастью, анимацией сверкания молний можно управлять при помощи объекта JavaScript’s window. Объект window создается каждый раз, когда посетитель открывает в браузере новое окно; на базе этого объекта реализованы многие полезные функции jQuery и JavaScript. В мире JavaScript объект window является глобальным. Иначе говоря, он находится на верхнем уровне иерархии JavaScript.

Допустим, вы открыли в браузере три вкладки. Браузер создает для каждой вкладки от-дельный объект window. Это такой же объект, как и те, с которыми мы работали в гла-ве 6; он тоже обладает свойствами, обработчиками событий и методами. И эти объекты чрезвычайно удобны: при помощи обработчиков событий onblur и onfocus объекта window можно узнать, какие операции выполняются пользователем на уровне браузера.

Интерпретатор JavaScript использует объект window для представления окна, от-крытого в браузере.

Каждый раз, когда поль-зователь открывает новую вкладку, страницу или фрейм, создается новый объект window.

Браузер Объект window

Браузер

Объект window Объект window Объект window

Объект window также поддерживает методы работы с таймером, которые мы можем исполь-зовать в пользовательских функциях. У объекта window много методов, но нас сейчас интере-суют только эти методы, необходимые для ис-правления ошибки с молниями.

Когда вы щелкае-те на этом окне, браузер передает ему «фокус» (со-бытие onFocus).

Теперь фокус принадлежит этому окну.Если щелкнуть на другом окне, то ис-ходное окно теряет «фокус» (событие onBlur).

Не путайте обработ-чики событий onblur и onfocus объекта JavaScript window с методами jQuery blur и focus.

Методы jQuery blur и focus связываются с полями форм HTML и другими элементами, но не с объектом window.

Будьте осторожны!

Page 289: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 289

пользовательские функции

Соедините каждое свойство, обработчик события или метод окна window с его описанием.

Свойство объекта window для чтения или задания имени окна.

Свойство объекта window, ссыла-ющееся на основное содержимое загруженного документа.

Обнаруживает, когда окно полу-чает щелчок, нажатия клавиш или другой ввод.

Обнаруживает, когда окно теряет фокус.

Метод объекта window, исполь-зуемый для отмены задержки перед вызовом.

Метод объекта window, задаю-щий задержку между повторяю-щимися выполнениями функции или другой команды.

Метод объекта window, задаю-щий задержку перед выполнени-ем функции или другой команды.

window.name

window.onfocus

window.setTimeout()

window.setInterval()

window.clearTimeout()

window.clearInterval()

window.onblur

window.history

window.document

Свойство объекта window для обращения к URL-адресам, кото-рые ранее загружались в окне.

Метод объекта window, отменя-ющий задержку между повторны-ми вызовами.

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

Page 290: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

290 глава 7

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

window. name

window. onfocus

window. setTimeout()

window. setInterval()

window.clearTimeout()

window. clearInterval()

window. onblur

window. history

window. document

Обработчики событий onfocus и onblur объекта window обнаруживают полу-чение/потерю фокуса окном, но как что-то сделать в ответ на эти события?

Свойство объекта window для чтения или задания имени окна.

Свойство объекта window, ссыла-ющееся на основное содержимое загруженного документа.

Обнаруживает, когда окно полу-чает щелчок, нажатия клавиш или другой ввод.

Обнаруживает, когда окно теряет фокус.

Метод объекта window, исполь-зуемый для отмены задержки перед вызовом.

Метод объекта window, задаю-щий задержку между повторяю-щимися выполнениями функции или другой команды.

Метод объекта window, задаю-щий задержку перед выполнени-ем функции или другой команды.

Свойство объекта window для обращения к URL-адресам, кото-рые ранее загружались в окне.

Метод объекта window, отменя-ющий задержку между повторны-ми вызовами.

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

Мозговой

штурм

Решение

Page 291: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 291

пользовательские функции

Îáðàáîòêà ñîáûòèé áðàóçåðà â onblur è onfocus

Итак, мы знаем, что в window.onfocus можно определить, когда окно получает фокус (то есть посетитель активизирует страницу или передает окну ввод с кла-виатуры или мыши), а в window.onblur можно обработать потерю фокуса актив-ным окном. Но что нужно сделать для обработки этих событий? Методам onfocus и onblur следует присвоить ссылку на функцию.

window.onblur = blurResponse;

function blurResponse(){

}

Оператор присваивания

Опре-деление функции

window.onfocus = focusResponse;

function focusResponse(){

}

Ссылкана функцию

Оператор присваивания

Опре-деление функции

То, что должно происходитьв ответ на собы-тие браузера.

Давайте опробуем обработчики событий onfocus и onblur объекта window в деле. Найдите в файлах главы 7 папку с именем window_tester. Загрузите файл window_tester.html из этой папки в своем любимом браузере. Откройте вторую вкладку и поэкспериментируйте с переключением между двумя вкладками.

Перед нами наглядный пример того, какую пользу приносит написание пользова-тельских функций. Имеется объект window, содержащий гору информации о том, что пользователь делает в браузере; вы пишете пользовательскую функцию, которая работает с данными, полученными от объекта. Получается, что при обработке собы-тия можно делать абсолютно все, что угодно, главное написать для этого подходящую пользовательскую функцию...

Ссылкана функцию

Тест-драйв

Page 292: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

292 глава 7

тест-драйв

Загрузите файл window_tester.html, откройте вторую вкладку и попро-буйте переключаться между окнами, попеременно щелкая на них.

Открываем файл window_tester.html в одном окне.

Открываем вторую вкладку.

При переключениях

между окнами сцена-

рий сообщает о по-

лучении и потере

фокуса.

При помощи информации, полученной от объекта window, можно остановить молнии, когда посетитель покидает окно приложения «Собери монстра», и продолжить отображение эффекта после его возвращения.

Тест-драйв

Page 293: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 293

пользовательские функции

Сложите из магнитов определения функций для обработчиков onblur и onfocus. Первая

функция останавливает сверкание молнии, когда браузер теряет фокус (она называется

stopLightning). Другая функция снова запускает эффект при получении фокуса браузером

(ей присваивается имя goLightning). Код функций пока писать не нужно, просто разложите

магниты с комментариями (начинающимися с //) внутри каждой функции.

window.onfocus

=

=

stopLightning;

//Код остановки молний

//Код запуска молний

goLightning;

function

};

stopLightning(){

function

};

goLightning window.onblur

(){

Развлечения с магнитами

Page 294: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

294 глава 7

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

Ниже приведены объявления функций для обоих обработчиков событий объекта window.

window.onfocus

=

=

stopLightning;

//код остановки молний

//Код запуска молний

goLightning;

function

};

stopLightning (){

function

};

goLightning

window.onblur

(){

Но пока в этих функциях нет ничего, кроме комментариев. Функции должны что-то делать! Может, просто скопиро-

вать сюда код старых функций?

Верно. Функции ничего не делают... пока. Не торопитесь копировать старый код. Эффект свер-кания молнии удобнее реализовать с использовани-ем методов работы с таймером объекта window.

Наши функции при-

сваиваются собы-

тиям window.onblur

и window.onfocus.

При вызове этой функции молнии оста-навливаются.

А при вызове этой функции они начинают сверкать снова.

Развлечения с магнитами. Решение

Page 295: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 295

пользовательские функции

Ìåòîäû ðàáîòû ñ òàéìåðîì îïðåäåëÿþò âðåìÿ âûïîëíåíèÿ ôóíêöèé

И в JavaScript, и в jQuery имеются методы для выполнения функций по таймеру. У объекта JavaScript window есть четыре метода для работы с таймером: setTimeout, clearTimeout, setInterval и clearInterval. jQuery поддерживает метод delay. Давайте поближе позна-комимся с этими методами и их возможностями.

Какой из этих методов подойдет для исправления функции goLightning?

Напишите для каждого метода, пригодится ли он в нашей ситуации, и объясни-

те, почему вы его выбрали (или не выбрали).

Метод Будем исполь-

зовать?

Почему?

setTimeout

setInterval

delay

setTimeout(myFunction, 4000); slideDown().delay(5000).slideUp();setInterval(repeatMe, 1000);

Функция, вы-зываемая по истечении тайм-аута

Задержка таймера (в миллисе-кундах)

Интервал между вызо-вами функ-ции (в мил-лисекундах)

Функция, вызываемая после исте-чения каж-дого интер-вала

Выполнение таких цепо-чек в jQuery называется «очередью эффектов».

В данном при-мере метод delay вставляет 5-се-кундную задержку между эффектами slideUp и slideDown..

setTimeout setInterval delay

Ìåòîäû JavaScript Ìåòîä delay jQuery

Я определяю вре-мя, через которое

должна выпол-няться функция.

Я приказываю функции выпол-

няться снова через заданный промежу-

ток времени.

Я добавляю паузу между эффекта-ми, объединен-ными в цепочку.

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

Page 296: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

296 глава 7

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

Итак, setInterval лучше всего подой-дет для функции goLightning, но функция

stopLightning должна остановить таймер. Как бы это сделать? Может методом

clearInterval?

Хороший вопрос! Метод clearInterval останавливает вызов функции по таймеру, запущенный методом setInterval. При вызове clearInterval необходимо передать параметр. Вот как это делается:

myInterval = setInterval(repeatMe, 1000);

clearInterval(myInterval);

Метод Будем исполь-

зовать

Почему?

setTimeout Нет Метод setTimeout предназначен для создания задержки перед однократным выполнением функции.

setInterval Да Метод setInterval предназначен для многократного вы-полнения функции с заданными интервалами. Именно это нам и нужно в эффекте с молниями.

delay Нет Метод delay хорошо подходит для создания серий эф-фектов, но у него нет средств планирования отло-женного запуска.

Какой из этих методов подойдет для исправления функции

goLightning? Вот наши ответы.

Присваивается переменной, идентифицирующей

метод setInterval.

Переменная пере-дается в параметре clearInterval.

Метод clearInterval останавливает таймер setInterval и прекращаетпериодическое выполнение.

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

Page 297: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 297

пользовательские функции

Обнаруживает, когда текущее окно получает фокус, и вызывает метод goLightning.

Обнаруживает, когда текущее окно теряет фокус, и вызывает функцию stopLightning.

Выполняет функцию lightning_one каждые 4 секунды, с присваива-нием результата переменной int1.

Останавливает таймер и прекраща-ет повторение для int1.

Создает пятисекундную паузу между эффектами fadeIn и fadeOut.

Устанавливает задержку 4 секунды перед вызовом функции wakeUp.

window.clearInterval(int1);

$("#container #lightning1").fadeIn(250).delay(5000).fadeOut(250).;

int1 = setInterval( function() { lightning_one(); }, 4000 );

window.onblur = stopLightning;

Соедините каждый вызов метода с его описанием.

window.onfocus = goLightning;

setTimeout(wakeUp(),4000);

В: Метод setTimeout во всех браузерах работает одинаково?

О: Нет. Mozilla Firefox и Google Chrome работают так, как было описано выше («складывая» вызовы функций). Internet Explorer 9 продолжает вызывать функцию так, как предполагалось в главе 5. Это показывает, что проблемы с межбраузерной совместимостью возникают не только у веб-дизайнеров.

В: Можно ли использовать функции setInterval и setTimeout для чего-то другого, кроме объекта window?

О: К сожалению, нельзя. Это конкретные методы объ-екта window, и вызываться они могут только по ссылке на объект window. Однако возможен вызов методов без префикса «window»; браузер определит, что вызов нужно связать с текущим объектом window. Впрочем, префикс все же рекомендуется указывать.

частоЗадаваемые

вопросы

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

Page 298: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

298 глава 7

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

window.clearInterval(int1);

$("#container #lightning1").fadeIn(250).delay(5000).fadeOut(250).;

int1 = setInterval( function() { lightning_one(); }, 4000 );

window.onblur = stopLightning;

Соедините каждый вызов метода с его описанием.

window.onfocus = goLightning;

setTimeout(wakeUp(),4000);

Ïèøåì ôóíêöèè stopLightning è goLightning

Теперь вы больше знаете о таймере, давайте посмотрим, как использовать эти методы в нашем коде.

Функция stopLightning вызывается

при потере фокуса браузером.

Функция goLightning вызывается при получении фокуса браузером.

Сброс таймеров для трех интер-валов. Нам понадобятся три вызова clearInterval. Знаете, почему?

Установка трех таймеров для трех интервалов. Да, здесь нам понадо-бятся три вызова setInterval.

Молнии запускаются при загрузке страницы.goLightning();

window. onblur = stopLightning;

window. onfocus = goLightning;

function stopLightning (){

//Код остановки молний

};

function goLightning (){

//Код запуска молний

};

Обнаруживает, когда текущее окно получает фокус, и вызывает метод goLightning.

Обнаруживает, когда текущее окно теряет фокус, и вызывает функцию stopLightning.

Выполняет функцию lightning_one каждые 4 секунды, с присваива-нием результата переменной int1.

Останавливает таймер и прекраща-ет повторение для int1.

Создает пятисекундную паузу между эффектами fadeIn и fadeOut.

Устанавливает задержку 4 секунды перед вызовом функции wakeUp.

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

Решение

Page 299: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 299

пользовательские функции

Пора исправить недостатки приложения «Собери монстра». Заполните пропуски име-нами переменной, функции или метода. Если вы сомневаетесь, снова просмотрите код на двух предыдущих страницах. Мы заполнили некоторые пропуски за вас.

goLightning(); window.onblur = stopLightning; window.onfocus = goLightning; var int1, int2, int3 ; function goLightning(){ = ( function() { }, 4000 );

= ( function() { }, 5000 ); = ( function() { }, 7000 ); } function stopLightning() { window. ( ); window. ( ); window. ( ); } function { $("#container #lightning1").fadeIn(250).fadeOut(250); };

function { $("#container #lightning2").fadeIn(250).fadeOut(250); }; function { $("#container #lightning3").fadeIn(250).fadeOut(250); };

int1

int1

lightning_three();

lightning_one()

my_scripts.js

Упражнение

Page 300: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

300 глава 7

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

goLightning(); window.onblur = stopLightning; window.onfocus = goLightning; var int1, int2, int3 ; function goLightning(){ = ( function() { }, 4000 );

= ( function() { }, 5000 ); = ( function() { }, 7000 ); } function stopLightning() { window. ( ); window. ( ); window. ( ); } function { $("#container #lightning1").fadeIn(250).fadeOut(250); };

function { $("#container #lightning2").fadeIn(250).fadeOut(250); }; function { $("#container #lightning3").fadeIn(250).fadeOut(250); };

int1

int1

lightning_three();

lightning_one()

my_scripts.js

У нас появились две пользовательские функции, реагирующие на события onfocus и onblur объекта window (в них используются функции, написанные нами в главе 5).

clearIntervalclearInterval int2clearInterval int3

setInterval

setIntervalint2

setIntervalint3

lightning_one();

lightning_two();

lightning_two()

lightning_three()

Сброс таймеров для трех интервалов

Устанавливаем три разных таймера с тремя интервалами.

Определения трех функций.

Здесь вызывается функция lightning_one.

Затем вызываем

функцию lightning_two.

И последней вызывается

функция lightning_three.

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

Page 301: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 301

пользовательские функции

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

Вносить все изменения и исправления в код, написанный для главы 5, было бы слиш-ком сложно; проще начать заново, с пустого файла сценария. Найдите в архиве кода, загруженного для книги, папку главы 7. В ней находится вложенная папка begin, которая имеет следующую структуру:

index.html

jquery-1.6.2.min.js

images scripts

my_scripts.js

styles

begin

Включите код с предыдущей страницы…

…в блок $(document).ready своего файла сценария.

$(document).ready(function(){

});//end doc.onready function

Откройте приложе-ние «Собери монстра» в окне браузера.

Откройте новую вкладку, оставайтесь на ней пару минут.

Затем вернитесь на исходную вкладку с приложением «Собери монстра». При возвра-щении первый эффект молнии должен запу-ститься только через четыре секунды.

Задание!

Тест-драйв

Page 302: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

302 глава 7

приводим в порядок функции

var headclix = 0, eyeclix = 0, noseclix = 0, mouthclix = 0;

$("#head").click(function(){ if (headclix < 9){ $("#head").animate({left:"-=367px"},500); headclix+=1; } else{ $("#head").animate({left:"0px'},500); headclix = 0; } }); $("#eyes").click(function(){ if (eyeclix < 9){ $("#eyes").animate({left:"-=367px"},500); eyeclix+=1; } else{ $("#eyes").animate({left:"0px"},500); eyeclix = 0; } }); $("#nose").click(function(){ if (noseclix < 9){ $("#nose").animate({left:"-=367px"},500); noseclix+=1; } else{ $("#nose").animate({left:"0px"},500); noseclix = 0; } });//end click $("#mouth").click(function(){ if (mouthclix < 9){ $("#mouth").animate({left:"-=367px"},500); mouthclix+=1; } else{ $("#mouth").animate({left:"0px"},500); mouthclix = 0; } });//end click

my_scripts.js

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

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

написанных в главе 5?

Нельзя линаписать одну функцию, которую можно будет использовать в каждом из этих случаев?

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

Page 303: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 303

пользовательские функции

var clix = __________; // head,eyes,nose,mouth

$("#head").click( function(){

_______________ });//end click function $("#eyes").click( function(){

_______________ } );//end click function $("#nose").click( function(){

_______________ });//end click function $("#mouth").click( function(){

_______________ });//end click function function moveMe(________){ if (__________ < 9){ $(obj).animate({left:"-=367px"},500); clix[i] = clix[i]+1; }else{ clix[i] = 0; $(______).animate({left:"0px"},500); } }

[0,0,0,0]

moveMe(2, this);

moveMe(3, this);

moveMe(1, this);

moveMe(0, this);

clix[i]

i, obj

obj

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

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

из подвижных частей изображения. В первом параметре moveMe передается индекс массива clix,

а во втором — ссылка на часть изображения, на которой был сделан щелчок.

my_scripts.js

Развлечения с магнитами

Page 304: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

304 глава 7

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

var clix = __________; // head,eyes,nose,mouth

$("#head").click( function(){

_______________ });//end click function $("#eyes").click( function(){

_______________ } );//end click function $("#nose").click( function(){

_______________ });//end click function $("#mouth").click( function(){

_______________ });//end click function function moveMe(________){ if (__________ < 9){ $(obj).animate({left:"-=367px"},500); clix[i] = clix[i]+1; }else{ clix[i] = 0; $(______).animate({left:"0px"},500); } }

my_scripts.js

__________;[0,0,0,0]

_______________/end click function

moveMe(2, this);

_______________/end click function

moveMe(3, this);

_______________//end click function

moveMe(1, this);

_______________/end click function

moveMe(0, this);

__________$(obj).anclix[i]

________)i, obj

ix[i]______)obj

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

Одна функция создает меньше проблем с сопровождением кода, в ней проще нахо-

дить и исправлять ошибки.

Универсальная функция moveMe снижает риск ошибок программи-рования и сокращает количество функций, которые вам придется сопровождать.

Дублирующаяся логика теперь сосредоточена в одном месте. Если в про-грамме обнару-жится ошибка, исправить ее будет проще и быстрее, чем в нескольких дубликатах.

Функция moveMe получает ссылку на ячейку массива clix. Эта инфор-мация может использоваться для отслеживания количества щелчков на каждом элементе.

Функции moveMe также переда-ется ссылка на текущий объект для выполнения анимации.

Преобразование набора пе-ременных в массив делает код более компактным.

Развлечения с магнитами. Решение

Page 305: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 305

пользовательские функции

Внешне страница приложе-ния нисколько не изменилась, но мы-то знаем, что код стал более эффективным, содержит меньше дубликатов и создает меньше проблем с сопровождением.

Включите код из упражнения с магнитами на предыдущей странице в файл my_scripts.js. Сохраните файл, откройте страницу index.html в бра-узере и убедитесь в том, что новая версия функции правильно обраба-тывает щелчки на разных частях лица монстра.

Тест-драйв

Page 306: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

306 глава 7

молния ударяет дважды

Íîâàÿ ïðîñüáà

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

встроить ее в приложение?.. А еще ино-гда хочется сбросить текущее изображе-

ние и начать все заново...

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

Мне нравятся мои мон-стры... Но интересно по-смотреть, какие монстры получатся у компьютера.

Page 307: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 307

пользовательские функции

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

Но на этот раз потребует-ся число от 1 до 10 (потому что каждая полоса состоит из 10 фрагментов).

Каждая часть лица монстра оказы-вается в случайной позиции, умножен-ной на ширину каждого фрагмента. Для случайного числа 7 целевая пози-ция равна 7 * 367, то есть 2569.

Текущая позиция вычисляется как количе-

ство щелчков, умноженное на расстояние

между частями лица на полосе (367 пик-

селов). В нашем примере текущая позиция

равна 2 * 367, то есть 734.

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

Ñëó÷àéíûå ìîíñòðû

Получение случайного числа.1 Для каждой части лица выбирается случайная позиция.

2

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

var my_num = Math.floor((Math.random()*5) + 5);

Так мы получали случайные числа в главах 2 и 3.

Хм, вас послушаешь, вроде бы все просто... Но что мы будем делать

с определением текущей позиции? Как узнать, какая часть лица отображает-ся на полосе, особенно если ее кто-то

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

Page 308: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

308 глава 7

чем больше знаешь...

...è ôóíêöèÿ getRandom óæå ãîòîâà

function getRandom(num){

var my_random_num = Math.floor(Math.random()*num);

return my_random_num;

}

var current_position = clix[index] ;

Мы уже создавали функции для получения случайных чисел в главах 2, 3 и 6. Сейчас мы сможем использовать готовую функцию с минимальными изменениями.

К счастью, нам не потребуются ни новые переменные, ни новые функции. Текущая позиция опреде-ляется значением в соответствующей ячейке массива clix, в которой хранится информация, сколько раз пользователь щелкнул на каждой части лица монстра. Нам понадобится одна строка кода:

Функция getRandom получает в аргументе число…

Умножая Math.random на число, переданное в ар-гументе, мы генерируем случайное число в интер-вале от 0 до num.

…генерирует и возвраща-ет целое число. В данном случае генерируется число от 0 до 10.

num = 10;getRandom(num);

return my_random_num;

var my_random_num = Math.floor(Math.random()*num);

Ìû óæå çíàåì òåêóùóþ ïîçèöèþ...

Вызов дает значение целевой позиции (т. е. случай-ный фрагмент лица), к которой мы хотим перейти.

Переменной теку-щей позиции при-сваивается значение clix[index].

Функции, специализирующиеся на решении одной

задачи, иногда называют вспомогательными.

Передаем значение функции

Присваиваем значение переменной и передаем ее функции:1

Выполняем основную операцию функции:2

Возвращаем результат:3

Page 309: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 309

пользовательские функции

var w = 367; // Ширина одного фрагмента

var m = 10; // Количество фрагментов

$("#btnRandom").click( randomize );

$("#btnReset").click( );

function getRandom(num){

var my_random_num = Math.floor(Math.random()*num);

return my_random_num;

}

function randomize(){

$(".face").each(function(index){

var target_position = getRandom(m);

var current_position = clix[index] ;

clix[index] = target_position;

var move_to = target_position * w;

$(this).animate({left:"-="+move_to+"px"},500);

});

};

<header id="top">

<img src="images/Monster_Mashup.png" />

<button id="btnRandom">Randomize</button>

<button id="btnReset">Reset</button>

<p>Make your own monster face by clicking on the picture.</p>

</header>

Включите код, выделенный жирным шрифтом, в файлы index.html и my_scripts.js. В нем определяется функция, генерирующая слу-чайное изображение монстра, а также выводятся сообщения с информацией о целевой позиции (выбранной на основании слу-чайного числа) и текущей позиции (определяемой количеством щелчков, сделанных посетителем).

Переменной target_position присваивается результат вызова getRandom.

Обновляем clix[index], чтобы пользователь мог продолжать щелкать на частях лица мон-стра.

Переменной move_to при-сваивается случайная позиция, умноженная на ширину одного фрагмен-та на полосе.Выполняем пользователь-

ский код анимации пере-мещения полосы влево.

Определение случайной позиции для каждой ча-сти лица

index.html

my_scripts.js

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

Готово к употреблению

Page 310: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

310 глава 7

тест-драйв

Включите код с предыдущей страницы в ваши файлы, откройте стра-ницу index.html в своем любимом браузере для тестирования функции randomize. Щелкните на кнопке Randomize 10–20 раз, чтобы тщательно протестировать новую функцию.

Ãåíåðàòîð ìîíñòðîâ ðàáîòàåò...

...íî òîëüêî íà íåñêîëüêèõ ïåðâûõ ùåë÷êàõ

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

Конечно, зубы — главное,что есть у монстра, но остаться

без лица как-то не хочется!

Но через несколько щелчков начинаются какие-то проблемы.

Тест-драйв

Page 311: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 311

пользовательские функции

Повторные вызовы animate продолжают

смещать полосу изображений влево и вскоре

выводят ее за пределы видимости. Изобра-

жение, что называется, «уходит за край».

Части лица пропадают? Такого мы не про-граммировали. Они должны были попадать в случайную позицию! Может, мы оказались

слишком далеко?

Вы правы. У наших функций имеются непредвиденные побочные эффекты. Но скорее всего, эти функции делают в точности то, что мы написа-ли в своем коде. Давайте посмотрим, что мы могли упустить.

$(this).animate({left:-="+move_to+"px"},500);

Если пользователь продолжает щелкать на кнопке Randomize, полоса уйдет налево так дале-ко, что изображения перестанут отображаться на экране.

Помогите!Мы хотим обратно

в рамку!

Как вы думаете, что нужно сделать, чтобы поло-са изображений не уходила за край, а оставалась на случайных фрагментах монстра?

напряги мозги

Page 312: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

312 глава 7

откуда и куда?

Ïåðåìåùåíèå îòíîñèòåëüíî òåêóùåé ïîçèöèè

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

Ñèòóàöèÿ 1: target_position > current_position

Функция getRandom вернула значение 5. Таким образом, переменной target_position присваивается значение 5, то есть она больше перемен-ной current_position. Мы должны написать логику для обработки этой ситуации.

Ñèòóàöèÿ 2: target_position < current_position

Далее пользователь щелкает на кнопке Randomize, которая генерирует случайное число в интервале от 0 до 9. Рассмотрим две принципиально возможные ситуации.

Пользователь находится на этом изображении. Текущая

позиция 2, потому что посетитель щелкнул дважды.

Функция getRandom вернула значение 1. Переменная target_position равна 1, то есть она меньше переменной current_position. Как вы думаете, какую логику следует применить в этом случае (по образцу условной логики из ситуации 1)?

target_position = 1 current_position = 2

Если переменная target_position меньше current_position, нужно

вычесть target_position из current_position и сместить полосу

изображений вправо вызовом animate({left:"+=".

target_position = 5Вычитая current_position из target_position, полу-чаем 3. Нужно переме-ститься на три позиции влево.

На сколько позиций нуж-но сместить полосу?

Вычитая target_position из current_position, по-лучаем 1. Необходимо сместиться на одну позицию вправо.

current_position = 2

Если переменная target_position variable больше current_position,

нужно вычесть current_position из target_position и сместить

полосу изображений влево вызовом animate({left:"-=".

0 1 3 5 7 94 6 822

0 1 3 5 7 94 6 822

0 1 3 5 7 94 6 822

Page 313: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 313

пользовательские функции

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

Каждый фрагмент может использоваться только один раз; некоторые фраг-

менты могут остаться неиспользованными. Ваша задача  — исправить

ошибку в функции, чтобы части лица монстра не оставались пустыми.

Внимание: каждый

фрагмент может

быть использован

не более одного

раза!

var w = 367;var m = 10;

function getRandom(num){ var my_random_num = Math.floor(Math.random()*num); return my_random_num;}function randomize(){ $(".face"). { var target_position = getRandom(m); var current_position = clix[index] ; clix[index] = target_position;

if( ) { var move_to = ( ) * w; $(this).animate( ); }else if( ){ var move_to = ( ) * w; $(this).animate( ); }else{ // Позиция не изменилась - ничего не делать. } });};

each(function(index)

target_position > current_position

target_position - current_position target_position + current_position

target_position == current_positiontarget_position < current_positioncurrent_position - target_position

{left:"+="+move_to+"px"},500

{left:"="+move_to+"px"},500

{left:"-="+move_to+"px"},500

Page 314: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

314 глава 7

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

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

Каждый фрагмент может использоваться только один раз; некоторые фраг-

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

в функции, чтобы части лица монстра не оставались пустыми.

var w = 367;var m = 10;

function getRandom(num){ var my_random_num = Math.floor(Math.random()*num); return my_random_num;}function randomize(){

$(".face"). {

var target_position = getRandom(m);

var current_position = clix[index] ;

clix[index] = target_position;

if( ) {

var move_to = ( ) * w;

$(this).animate( );

}else if( ){

var move_to = ( ) * w;

$(this).animate( );

}else{

// Позиция не изменилась - ничего не делать.

}

});

};

each(function(index)

target_position > current_position

target_position < current_position

target_position - current_position

current_position - target_position{left:"+="+move_to+"px"},500

{left:"-="+move_to+"px"},500

target_position + current_position

target_position == current_position

{left:"="+move_to+"px"},500

Выполнить следующий код для каждого элемента класса face.

…вычесть target_position из current_position.

Эти фрагмен-ты оказались лишними.

...вычесть target_position из current_position.

Полоса изображений перемещается вправо. Для этого используется вызов animate({left:"+="...

Если переменная target_position больше current_position…

Полоса изображений перемеща-ется влево. Для этого исполь-зуется вызов animate({left:"-=".

Если переменная target_position меньше current_position...

Page 315: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 315

пользовательские функции

Совершенно верно.

Помните кнопку Reset в файле index.html несколько страниц назад? Осталось связать ее с пользовательской функцией сброса.

Разложите магниты по местам так, чтобы у вас получился код кнопки и пользо-

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

.animate({left:"0px"},500);({left:"0px"} 500);

.each(function(index){});

$(".face") $(this)

clix[index] = 0;

}

function reset(){

$("#btnReset").click( reset );

Функция генерирования случайных монстров работает отлично. Пора пере-ходить к функции сброса изображения

в исходное состояние?

Развлечения с магнитами

Page 316: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

316 глава 7

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

Вуаля! Всего несколько строк — кнопка сброса работает,

и монстра можно собирать заново.

.animate({left:"0px"},500);

.each(function(index){

});

$(".face")

Связываем пользова-тельскую функцию сброса с кнопкой.

Обнуляем массив clix.

$(this)

clix[index] = 0;

}

Определяем пользователь-скую функцию сброса.

Каждая полоса возвращается к началу, для чего ее свойству CSS left присваивается абсолютная по-зиция 0px.

Используем each, чтобы функция сбрасывала теку-щую позицию каж-дой части до 0.

function reset(){

$("#btnReset").click( reset );

В: Объект window существует во всех браузерах?

О: Да, все современные браузеры под-держивают объект window, с которым вы можете работать. Каждый объект window (по одному на каждую вкладку браузера) также имеет отдельный объект document, в который загружается веб-страница.

В: Почему перемещения выполняются относительно текущей позиции? Почему я не могу перейти туда, куда указывает случайное число?

О: Такое решение будет работать, но вам придется возвращать изображение в на-чальную позицию, а потом перемещать его в позицию, определяемую генератором случайных чисел. Это удваивает объем кода, который вам придется написать, и за-медляет работу приложения.

В: Как работает функция reset?

О: Функция reset просто перебирает все элементы с классом face и присваивает их свойству CSS left значение 0. Затем она обнуляет все ячейки массива clix, как на момент загрузки страницы.

Развлечения с магнитами. Решение

частоЗадаваемые

вопросы

Page 317: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 317

пользовательские функции

Ниже приведен весь код, написанный на предыдущих страни-цах. Если вы еще не сделали этого ранее, добавьте код, выде-ленный жирным шрифтом, в файл my_scripts.js и приготовьтесь к тестированию всех новых возможностей приложения.

Задание!

var w = 367; // Ширина одного фрагмента

var m = 10; // Количество фрагментов

$("#btnRandom").click( randomize );

$("#btnReset").click( reset );

function getRandom(num){

var my_random_num = Math.floor(Math.random()*num);

return my_random_num;

}

function randomize(){

$(".face").each(function(index){

var target_position = getRandom(m);

var current_position = clix[index] ;

clix[index] = target_position;

if( target_position > current_position ) {

var move_to = (target_position - current_position) * w;

$(this).animate({left:"-="+move_to+"px"},500);

}else if( target_position < current_position ){

var move_to = (current_position - target_position) * w;

$(this).animate({left:"+="+move_to+"px"},500);

}else{

// Позиция не изменилась - ничего не делать.

}

});

}

function reset(){

$(".face").each(function(index){

clix[index] = 0;

$(this).animate({left:"0px"},500);

});

} my_scripts.js

Page 318: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

318 глава 7

хорошая работа!

Введите код с предыдущей страницы, откройте файл index.html в своем любимом брау-зере для тестирования функций randomize и reset. Щелкните на кнопке Randomize 10–20 раз, чтобы тщательно протестировать новую функцию. Время от времени щел-кайте на кнопке Reset, она тоже должна работать так, как задумано.

Âñå ðàáîòàåò!

Части лица монстра те-перь перемещаются влево-вправо, отчего приложение смотрится еще лучше.

А кнопка Resetвозвращает всев исходное состояние.

Тест-драйв

Page 319: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 319

пользовательские функции

«Ñîáåðè ìîíñòðà-2» — íàñòîÿùèé õèò!

Смотри, а у меня получилась Акуло-

Волко-Мумия!

Я только что собрала Свино-Ведьмо-Оборотня... Он будет главным героем повести, которую я сей-

час пишу.

Благодаря вашей работе приложение «Собери монстра» пользуется огромной популярностью!

Вы справились с проблемами и реализовали новые функции за рекордное время! Я уговорила

босса выплатить вам премиальные.

Page 320: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

320 глава 7

ваш инструментарий jquery

Âàø èíñòðóìåíòàðèé jQuery

Глава 7 осталась позади. Ваш творческий инструмен-тарий расширился: появился объект window, функции работы с таймером и пользовательские функции.

Объект window

Объект верхнего уровня в иерархии

JavaScript.

Обладает свойствами, обработчи-

ками событий и методами, которые

позволяют обнаруживать события

браузера и реагировать на них.

Событие onFocus сообщает об акти-

визации окна браузера.

Событие onBlur сообщает о потере

фокуса окном.

Функции работы с таймером

Методы объекта window.

setTimeout обеспечивает вызов функ-

ции с заданной задержкой.

setInterval многократно выполняет

функцию с заданными промежутками.

clearInterval отменяет запланирован-

ные периодические вызовы функции.

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

Старайтесь по возможности объединять и оптимизировать ваши функции, чтобы уменьшить объем программного кода. Чем компактнее код, тем проще его со-провождать и отлаживать.

ГЛА

ВА 7

Page 321: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

jQuery и Ajax8

Пожалуйста, передайте данные

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

Щепотку Ajax, каплю jQuery и семь

чашек сливок. Дорогая, ты уверена, что правильно

записала рецепт?

Page 322: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

322 глава 8

данные в реальном времени!

От: Отдел маркетинга MegaCorps

Тема: 42-й Ежегодный марафон Интернетвиля — страница результатов

Привет группе веб-разработчиков,

Наша фирма публикует веб-страницу с результатами марафона на кубок Интернет виля. Но наша

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

Пользователи желают моментального обновления информации, как в Twitter и Facebook, и хотят сразу

видеть результаты.Предлагаем вам работу за хорошее вознаграждение. А если сможете обновить нашу страницу

результатов марафона к следующей неделе, можете рассчитывать на места в VIP-ложе в финале.

(Мы упоминали, что в этом году соревнования проходят на Мауи?)

Вот что нам нужно:

1) должна существовать возможность вывода результатов соревнований для мужчин, для женщин

или для всех участников сразу;

2) информация на странице должна обновляться по мере того, как участники пересекают финишную

прямую;

3) обновление результатов должно происходить без перезагрузки страницы;

4) на странице должно быть указано время последнего обновления и частота обновлений.

Пользователи имеют право запускать и останавливать обновления по своему усмотрению.

Внешне страница изменится не сильно, поэтому работу можно начать с прошлогодней версии.

Гонка для нас очень важна, и мы с нетерпением ждем, что у вас получится!

--Диона Хаузни, руководитель отдела маркетинга Фирма MegaCorp Ежегодные

соревнования

В этом году марафон проходит на Мауи,

заказывайте билеты заблаговременно!

ЕЕ

с рсор

Áåãîì ê ñîâðåìåííûì òåõíîëîãèÿì

Похоже, наша

группа уже

представляет

себя на Гавайях...

Но сначала нуж-

но выполнить

работу!

Чуваки, Мауи! Вот здорово,мы попадем на VIP-вечеринку!

Page 323: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 323

jquery и ajax

Эти вкладки соз-даются модулем расширения (по-дождите немного, все объясним)...

Результат вызова функции getTime.

После заверше-ния марафона информация жестко кодиру-ется в странице.

Íàñòðîéêà ìîäóëÿ ðàñøèðåíèÿ

Модули расширения совершенствуют функциональ-ность базовой библиотеки jQuery или упрощают выполнение некоторых операций. В приведенном примере модуль idTabs в сочетании с CSS преобра-зует элемент ul во вкладки, активизируемые щелч-ками, и сообщает ссылкам a в элементах li, какие элементы div должны отображаться. Этот модуль расширения предоставляет очень удобную навига-ционную структуру для страниц, обеспечивая визу-альное разделение разных видов информации при использовании общей области вывода.

Ïðîøëîãîäíÿÿ ñòðàíèöà

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

Пока не обра-щайте внима-ния на модули расширения.

Они предоставляют дополнительную функциональность для стандартной биб-лиотеки jQuery. Мы остановимся на этой теме в главе 10, а пока просто посмотрим, что может сделать этот модуль для уско-рения работы над проектом…

Р А СС Л А Б Ь Т Е С Ь

Page 324: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

324 глава 8

готовый код

Прежде чем двигаться дальше, мы также просмотрим прошло-годние файлы. Код и разметка находятся в файле last_year.zip (вместе с другими файлами этой главы, которые можно загру-зить по адресу http://thinkjquery.com/chapter08 ). Ниже приведены фрагменты трех основных файлов, которые нам понадобятся: my_style.css, index.html и my_scripts.js.

#main ul a:hover {

color:#FFF;

background:#111;

}

#main ul a.selected {

margin-bottom:0;

color:#000;

background:snow;

border-bottom:1px solid snow;

cursor:default;

}

#main div {

padding:10px 10px 8px 10px;

*padding-top:3px;

*margin-top:-15px;

clear:left;

background:snow;

height: 300px ;

}

#main div a { color:#000; font-weight:bold;

}

body{

background-color: #000;

color: white;

}

/* Стиль вкладок */

#main {

color:#111;

width:500px;

margin:8px auto;

}

#main > li, #main > ul > li

{ list-style:none; float:left; }

#main ul a {

display:block;

padding:6px 10px;

text-decoration:none!important;

margin:1px 1px 1px 0;

color:#FFF;

background:#444;

}

my_style.css

Комментарий CSS

Весь дальнейший код CSS предна-значен для создания вкладок.

Готово к употреблению

Page 325: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 325

jquery и ajax

<div id="main">

<ul class="idTabs">

<li><a href="#about">About the Race</a></li>

<li><a href="#finishers">All Finishers</a></li>

</ul>

<div id="about">

<h4>About the race</h4>This race Bit to Byte Campaign!

</div>

<div id="finishers">

<h4>All Finishers</h4>

<ul id="finishers_all">

<li>Name: Bob Hope. Time: 25:30</li>

<li>Name: John Smith. Time: 25:31</li>

<li>Name: Jane Smith. Time: 25:44</li>

...

</ul>

</div>

...

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

<script src="scripts/jquery.idTabs.min.js"></script>

$(document).ready(function(){

getTime();

function getTime(){

var a_p = "";

var d = new Date();

var curr_hour = d.getHours();

(curr_hour < 12) ? a_p = "AM" : a_p = "PM";

(curr_hour == 0) ? curr_hour = 12 : curr_hour = curr_hour;

(curr_hour > 12) ? curr_hour = curr_hour - 12 : curr_hour = curr_hour;

var curr_min = d.getMinutes().toString();

var curr_sec = d.getSeconds().toString();

if (curr_min.length == 1) { curr_min = "0" + curr_min; }

if (curr_sec.length == 1) { curr_sec = "0' + curr_sec; }

$('#updatedTime').html(curr_hour + ":" + curr_min + ":" + curr_sec + " " + a_p );

}

});

my_scripts.js

Новый экземпляр объекта JavaScript Date

Методы объекта Date

Тернарный оператор JavaScript (подробности чуть позже)

index.html

Часть информации о прошло-

годних участниках закодирована

в странице. Тем, кто занимался

обновлением, не позавидуешь...

Как обычно, включаем файлы JavaScript. Этот же механизм используется для подключения модулей расширения.

Создание ссылок, которые будут преобразованы во вкладки модулем расширения.

Элементы div для хранения содержимого вкладок

Вызов пользовательской функции getTime

Page 326: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

326 глава 8

долой жесткое кодирование результатов

Äàåøü äèíàìèêó!

Заказчик хочет, чтобы страница обновлялась практически в реальном времени, так что от жесткого кодирования результатов в файле HTML придется отказаться. А код JavaScript прежде использовался только для обновления времени на странице! А нам представи-лась идеальная возможность поднять свои навыки jQuery на следующий уровень. jQuery, JavaScript, немного Ajax и XML... И веб-приложения следующего поколения начинают вы-глядеть как динамические (в отличие от статических) настольные приложения, оперативно реагирующие на происходящие события.

Ajax (сокращение от Asynchronous JavaScript and XML, т. е. «Асинхронный JavaScript и XML») — механизм передачи структурированных данных между веб-сервером и браузе-ром, без участия посетителя сайта. При использовании Ajax ваши страницы и приложе-ния запрашивают у веб-сервера только то, что им действительно необходимо — только те части страницы, которые должны измениться, и веб-сервер предоставляет им только эти данные. Это приводит к сокращению трафика, более компактным обновлениям и ускоре-нию перерисовки.

А самое лучшее, что страницы AJax строятся на базе стандартных интернет-технологий, которые вы уже встречали в этой книге или уже знали прежде:

HTML

CSS

JavaScript

The DOM

При использовании Ajax ваши веб-страницы

запрашивают у сервера необходимую инфор-

мацию в тот момент (и там), когда это нужно.

Для использования Ajax необходимо поближе познакомиться с весьма популярным форматом данных XML и с методом jQuery для обработки Ajax-запросов ajax.

Page 327: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 327

jquery и ajax

Ñòðàíèöà, óæå

çàãðóæåííàÿ â áðàóçåðå

Ñåðâ

åðÑòðàíèöà, óæå

çàãðóæåííàÿ â

áðàóçåðå

Ñåðâ

åð

ÑÒÀÐÛÅ è ÍÎÂÛÅ âåá-òåõíîëîãèè

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

Çíàêîìüòåñü: Ajax

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

Код JavaScript Çàïðîñ Ajax,ïåðåäàííûé ñåðâåðó

1

Код jQuery или JavaScript обра-щается к серверу с запросом Ajax.

Код JavaScriptÎòâåò, ïîëó÷åííûé

îò ñåðâåðà

2

Îáíîâëåíèå ÷àñòè

ñòðàíèöû

Код jQuery или JavaScript получает результат, раз-бирает его и обновляет только часть страницы.

Page 328: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

328 глава 8

главное — данные

Ñòðóêòóðà Ajax

Как упоминалось ранее, Ajax — механизм передачи структурированных данных между веб-сервером и браузером без участия посетителя сайта. Но в действительности Ajax — не монолит, а комбинация нескольких разных технологий для построения впечатля-ющих, интерактивных веб-приложений. JavaScript позволяет взаимодействовать со структурой DOM страницы. Асинхронность означает, что передача данных может осу-ществляться в фоновом режиме, без нарушения работы страницы или участия пользо-вателя, взаимодействующего со страницей. А буква «X» в названии относится исключи-тельно к формату данных.

×òî òàêîå Ajax?

Да, можно использовать HTML. Но в области пере-дачи информации XML об-ладает рядом уникальных преимуществ перед своим родственником HTML. Да-вайте разберемся, что это за преимущества.

Но почему нельзя ис-пользовать HTML? Зачем

нужен еще один язык разметки?

XML

XML (eXtensible Markup Language) — спецификация хранения информации, а также описания структуры этой ин-формации. И хотя XML является языком разметки (как и HTML), он не имеет соб-ственных тегов. XML позволяет автору разметки создать любые теги, которые ему потребуются.

Àñèíõðîííûé

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

JavaScript

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

A J A X

Page 329: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 329

jquery и ajax

<?xml version="1.0" encoding="utf-8"?>

<books>

<book>

<title>The Hitchhikers Guide to the Galaxy</title>

<author>Douglas Adams</author>

<year>1980</year>

</book>

<book>

<title>The Color of Magic</title>

<author>Terry Pratchett</author>

<year>1983</year>

</book>

<book>

<title>Mort</title>

<author>Terry Pratchett</author>

<year>1987</year>

</book>

<book>

<title>And Another thing...</title>

<author>Eoin Colfer</author>

<year>2009</year>

</book>

</books>

Ôàêòîð «X»

XML — сокращение от слов « eXtensible Markup Language» (т. е. «расширяемый язык разметки»). Это широко распространенный, стандартизированный способ представления данных и текста в форма-те, который может обрабатываться без существенного вмешательства человека. Информация, от-форматированная в XML, может передаваться между разными платформами, приложениями и даже разными языками (как языками программирования, так и естественными). Она также может исполь-зоваться в широком спектре средств разработчика и служебных программ. Данные в формате XML легко создаются и редактируются; все, что для этого необходимо — это простой текстовый редактор и объявление XML в начале файла. А остальное зависит только от вас!

XML íè÷åãî íå ÄÅËÀÅÒ!

Это может прозвучать немного странно, но XML сам по себе практически ничего не делает. Задача XML — структурирование и хранение информации для передачи. По сути, XML является метаязыком для описания языков разметки. Иначе говоря, XML предоставляет механизм описания тегов и струк-турных отношений между ними. Важно понимать, что XML не заменяет HTML, а лишь дополняет его. Во многих веб-приложениях XML используется для форматирования данных для передачи, тог-да как HTML используется для форматирования и отображения данных. Посмотрим, как выглядит файл XML с информацией о книгах.

XML используется для фор-

матирования данных с целью

передачи, тогда как HTML

используется для форматиро-

вания и отображения данных.

Объявление XML должно присутствовать в каж-дом документе. В нем определяется версия XML, используемая в документе.

Другие теги используются для хранения данных.

Закрытие корневого узла (или тега)

Потомки корневого узла (открывающие и закрывающие теги).В данном случае опи-сываются книги.

Корневой узел (или тег)

books.xml

Page 330: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

330 глава 8

не бывает глупых вопросов

В: Главное достоинство XML —- воз-можность создания своих тегов?

О: Точно! Очень удобно определять эле-менты и структуры, соответствующие по-требностям вашей задачи. Что еще лучше, формат XML стандартизирован, поэтому очень многие люди умеют работать с ним.

В: А не проще ли определить собствен-ный формат данных?

О: На первый взгляд кажется, что проще, но закрытые форматы данных (которые вы создаете для себя) создают проблемы. Если их не документировать, пользовате-ли забудут, как они работают. А если что-нибудь изменится, вам придется проследить за обновлением всего: клиента, сервера, базы данных, документации… Это весьма хлопотно.

В: И что, XML действительно так широ-ко используется?

О: Благодаря гибкости при создании лю-бых необходимых структур данных, язык XML стал основой многих языков разметки в Web. Сейчас существует более 150 разных типов языков, основанных на XML: RSS (RDF Site Summary или Real Simple Syndication)

для создания каналов новостей или аудио/видеоматериалов; KML (Keyhole Markup Language) для географической информации, используемой в Google Earth; OOXML (Office Open XML) для файлов текстовых процессо-ров, предложенный Microsoft; SVG (Scalable Vector Graphics) для описаний двумерных векторных изображений; SOAP (Simple Object Access Protocol) для определений методов обмена информацией с веб-службами... Ко-личество применений XML огромно!

В: Ладно, я понимаю, почему XML стоит использовать, но разве он не превра-щается в «закрытый формат данных», когда мы начинаем объявлять имена элементов?

О: Нет, не превращается. Именно в этом и заключается изящество XML: он гибок. Сервер и клиент должны работать с оди-наковыми именами элементов, но это со-ответствие часто может быть согласовано на стадии выполнения.

В: А разве не все веб-страницы асин-хронны? Скажем, браузер загружает графику, когда я уже просматриваю страницу...

О: Браузеры асинхронны, а стандартные веб-страницы — нет. Когда веб-странице требуется информация от программы на

стороне сервера, обработка приостанав-ливается, пока сервер не ответит... если только страница не выдаст асинхронный запрос. А для решения этой задачи как раз и предназначается Ajax.

В: Как определить, когда стоит использо-вать Ajax и асинхронные запросы?

О: Руководствуйтесь простым правилом: если вы хотите, чтобы какие-то действия выполнялись, когда пользователь продол-жает работать, вам нужен асинхронный запрос. Но если для продолжения работы пользователю необходима информация или ответ от вашего приложения, пускай подождет. В таких ситуациях используют синхронные запросы.

В: Разве для взаимодействия с XML не нужно использовать XHTML?

О: XHTML — это и есть XML. Язык XHTML не так близок к HTML, как счита-ется. У XHTML более жесткие требования к парсингу кода, он происходит из того же семейства, что и XML. Но это не означает, что он может взаимодействовать с XML лучше, чем HTML. В разметке, приведенной в книге, используется HTML5, который будет включать в себя XHTML5 после публикации спецификаций.

Уговорили, я уже хочу использовать Ajax. Но ведь начинать нужно с про-работки структуры, верно? Так было

всегда... Вы правы.

Давайте разберемся со струк-турой, чтобы мы могли пе-рейти к включению поддерж-ки Ajax в наши страницы…

частоЗадаваемые

вопросы

Page 331: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 331

jquery и ajax

Сложите из магнитов код создания двух новых вкладок, на которых отображается инфор-

мация о результатах участников: мужчин (идентификатор male) и женщин (идентификатор

female). Вкладку About можно убрать, но вкладка All Finishers должна остаться. В каждом

разделе создайте пустой элемент ul для информации об участниках. Также удалите все

существующее содержимое из элемента ul finishers_all.

<body>

<header>

<h2>________________________</h2>

</header>

<div id="main">

<ul class="idTabs">

<li><a href="_____________">Male Finishers</a></li>

<li><a href="#female">____________________</a></li>

<li><a href="#all">All Finishers</a></li>

</ul>

<div id="male">

<h4>Male Finishers</h4>

<ul id="______________________"></ul>

</div>

<div __________________________>

<h4>Female Finishers</h4>

<ul id="finishers_f"></ul>

</div>

<div _________________________>

<h4>All Finishers</h4>

<ul id=______________________></ul>

</div>

</div>

<footer>

<h4>Congratulations to all our finishers!</h4>

<br>Last Updated: <div id=______________________></div>

</footer>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src=______________________________></script>

<script src="scripts/jquery.idTabs.min.js"></script>

</body>

index.html

2011 Race Finishers!

Female Finishers

finishers_m

id="all"

"finishers_all"

"updatedTime"

id="female"

#male

"scripts/my_scripts.js"

Развлечения с магнитами

Page 332: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

332 глава 8

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

<body>

<header>

<h2>________________________</h2>

</header>

<div id="main">

<ul class="idTabs">

<li><a href="_________">Male Finishers</a></li>

<li><a href="#female">____________________</a></li>

<li><a href="#all">All Finishers</a></li>

</ul>

<div id="male">

<h4>Male Finishers</h4>

<ul id="_______________"></ul>

</div>

<div _______________>

<h4>Female Finishers</h4>

<ul id="finishers_f"></ul>

</div>

<div ____________>

<h4>All Finishers</h4>

<ul id=___________________></ul>

</div>

</div>

<footer>

<h4>Congratulations to all our finishers!</h4>

<br>Last Updated: <div id=________________></div>

</footer>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src=__________________________></script>

<script src="scripts/jquery.idTabs.min.js"></script>

</body>

index.html

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

>

>________________________</

r>

2011 Race Finishers!

____________________</

Finishers</a></li>

____________________Female Finishers

_______________">finishers_m

____________>

h4>All Finishe

id="all"

___________________><"finishers_all"

our finishers!</h

________________><"updatedTime"

v>

_______________>

<h4>Female Finishe

id="female"

s >

"_________"

"#female">

#male

Наш список победителей

Включение модуля рас-ширения jQuery необхо-димо для соз-дания вкладок.

p jq y j

__________________________><

"scripts/jquery.idTabs.min.j

"scripts/my_scripts.js"

Развлечения с магнитами. Решение

Page 333: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 333

jquery и ajax

Хорошая работа!

Страница постепенно принимает нуж-ный вид. Теперь давайте посмотрим, как получить данные с сервера, чтобы заполнить каждую вкладку актуальной информацией.

Включите в файл index.html код, созданный нами в упражнении с магнитами, и откройте страницу в своем любимом браузере.

Отлично, с этим моду-лем расширения работа идет как по маслу! Я уже слышу

шум прибоя...

Тест-драйв

Page 334: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

334 глава 8

метод GET

А пока включите в файл my_scripts.js следующий код (только строки, выделенные жирным шрифтом).

$(document).ready(function(){

$.ajax({

url: "finishers.xml",

cache: false,

dataType: "xml",

success: function(xml){

}

});

getTime();

function getTime(){

var a_p = "";

var d = new Date();

my_scripts.js

$.ajax({

url: "my_page.html"

success: function(data){

}

});

Сокращение jQueryМетод jQuery ajax

URL-адрес данных, запрашиваемых через Ajax

Эта функция выполняется в том случае, если метод ajax был выполнен успешно. Вскоре мы напишем код этой функции.

Данные, возвраща-емые в результате вызова ajax

Полный список всех параметров метода приведен на сайте до-кументации jQuery по адресу http://api.jquery.com/jQuery.ajax/. Также в jQuery существуют вспомогательные методы для рабо-ты с вызовами Ajax. Вскоре мы вернемся к ним, честное слово.

Загружаем файл finishers.xml средствами Ajax.

Параметр обеспечивает ло-кальное кэширование резуль-татов, снижающее количе-ство обращений к серверу.

Тип данных, которые мы рассчитываем получить от сервера.

Ïîëó÷åíèå äàííûõ ìåòîäîì ajax

Нужны данные? jQuery и Ajax их вам с удовольствием предоставят. Метод jQuery ajax возвращает объект (еще не забыли главу 6?) с данными о конкретной опера-ции, которую вы пытаетесь выполнить. Метод ajax может получать много раз-ных параметров; в частности, с его помощью можно отправить данные серверу (POST) или же запросить их с сервера (GET).

Page 335: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 335

jquery и ajax

Включите в файл my_scripts.js код с предыдущей страницы. Затем загрузите файл с дан-ными XML для этой главы по адресу http://thinkjquery.com/chapter08/step2/finishers.xml и сохраните его в одном каталоге с файлом index.html. Когда это будет сделано, откройте файл index.html в браузере и перейдите на вкладку «Network» (в средствах разработчика в Google Chrome) или на вкладку «Net» (в Firebug для Firefox). Ваш файл XML должен быть здесь вместе с остальными файлами страницы.

Все верно. Теперь, мы знаем, что файл XML загружается, нужно выбрать нужный текст и отобразить его на экране. Нам следует перебрать данные всех участников марафона, чтобы вклю-чить их в нужный список на странице. И действительно, вызовы ajax полезно включить в функции, чтобы их было удобно вызывать в случае надобности.

Вызовы ajax подчиняются политике единого домена!

Политика единого домена — концепция безопасности для JavaScript и других сценарных языков на стороне клиента. Она позволяет сценариям, выполняемым на странице, обращаться к ресурсам (таким как свойства и методы элементов) на том же сервере. Обращения к элементам страниц других серверов блокируются. Проверка не распространяется на директи-вы JavaScript include, но наш файл XML ей подвержен. Это означает, что он должен находиться на одном сервере с загружающей его страницей.

Какая мне польза от XML в сред-ствах разработчика? Как увидеть

данные на экране там, где они мне нужны? И разве не нужно включить

в функцию вызов вида $.ajax?

Тест-драйв

Будьте осторожны!

Page 336: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

336 глава 8

методы find и each

Ðàçáîð äàííûõ XML

Мы должны как-то извлечь данные каждого участника из файла XML и отобразить их на экране. К счастью, в jQuery имеется метод find, который ищет элементы по заданному критерию. Метод find перебирает потомков элементов в структу-рированном, иерархическом наборе данных (таком как дерево DOM или доку-мент XML) и строит новый массив с подходящими элементами. Методы find и children похожи (метод children рассматривался в главе 4, когда мы строили вегетарианское меню), однако children переходит только на один уровень вниз по дереву DOM, а нам, возможно, потребуется спуститься глубже.

Сочетание методов find и each позво-

ляет найти группу элементов по неко-

торому условию и в цикле обработать

каждый найденный элемент.

Как вы думаете, с какими компонентами доку-мента XML необходимо взаимодействовать для отображения результатов участников на экране?

$("li").find("ul").css('background-color', 'blue');

Здесь может быть любой селектор.

Здесь может быть любой другой метод jQuery: события, операции с текстом, опера-ции со стилями и т. д.

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

li lili

lili

lilili li

li li

ul

ul

ul

ul

$("li").find("ul")

Команда находит все элементы ul,

содержащиеся в элементах li, и за-

дает синий цвет фона.

lili

ul

li

Мозговой

штурм

Page 337: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 337

jquery и ajax

Расставьте магниты так, чтобы у вас получилась функция getXMLRacers, которая вызывает

метод ajax и загружает файл finishers.xml. После успешной загрузки функция стирает все те-

кущее содержимое списков, после чего находит всех участников в файде XML, определяет пол

каждого участника, присоединяет его к соответствующему списку и в любом случае включает

участника в список finishers_all. Затем вызов функции getTime обновляет текущее время

на странице.

function _____________

$.ajax({

url: _________________,

cache: false,

dataType: "xml",

_________ function(xml){

$(_______________).empty();

$('#finishers_f')__________;

$('#finishers_all').empty();

$(xml).find________________(function() {

var info = '<li>Name: ' + $(this).find________________ + ' ' + $(this).find("lname").text() + '. Time: ' + ____________________.text() + '</li>';

if( $(this).find("gender").text() == "m" ){

$('#finishers_m').append_______

}else if ( $(this).find("gender").text() == "f" ){

__________________.append(info);

}else{ }

__________________.append(info);

});

___________

}

});

}

"finishers.xml"

success:

getXMLRacers(){

.empty()

getTime();

(info)

("runner").each

("fname").text()

$('#finishers_f')

$('#finishers_all')

'#finishers_m'

$(this).find("time")

my_scripts.js

Развлечения с магнитами

Page 338: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

338 глава 8

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

Используя find и each, мы перебираем файл finishers.xml, проверяем пол каждого участника,

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

В этом примере строка, начинающаяся с «var info = ...», оказалась слишком длинной, поэтому мы разбили ее надвое. Вам в своем коде делать это необязательно.

function _____________

$.ajax({

url: _________________,

cache: false,

dataType: "xml",

_________ function(xml){

$(_______________).empty();

$('#finishers_f')__________;

$('#finishers_all').empty();

$(xml).find________________(function() {

var info = '<li>Name: ' + $(this).find________________ + ' ' + $(this).find("lname").text() + '. Time: ' + ____________________.text() + '</li>';

if( $(this).find("gender").text() == "m" ){

$('#finishers_m').append_______

}else if ( $(this).find("gender").text() == "f" ){

__________________.append(info);

}else{ }

__________________.append(info);

});

___________

}

});

}

({

_________________,

e: false,

"finishers.xml"

yp

_________ f

$(

________success:

_____________

jax({

getXMLRacers(){

)__________;

l').empty();

__________.empty()

___________

}

getTime();

d_______

ender") te

(info)

_

d________________(f

= '<li>Name: ' +

("runner").each

d________________ +text() + '<

________________("fname").text()

( $( )

__________________

else{ }

$('#finishers_f')

__________________.a$('#finishers_all')

(

_______________)

'#fi i h f')

__

_

)

'#finishers_m'

+ $(this).find______________

") text() == "m" ){

+ d________.t

( fname_$(this).find("time")

my_scripts.js

Очистка всех элемен-

тов ul для заполнения

обновленными данными

Перебор всех элементов runner в файле XML

Проверка пола каждого участника для включения в со-ответствующий список

Кроме того, все

участники включаются

в список finishers_all.Вызов функции getTime для включения в страницу обновленного времени по-следнего вызова функции getXMLRacers

Развлечения с магнитами. Решение

Page 339: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 339

jquery и ajax

Включите в файл my_scripts.js функцию getXMLRacers. Также замените вызов функ-ции getTime (в секции document.ready) вызовом функции getXMLRacers. Функция getTime теперь вызывается в нашей новой функции. Проследите за тем, чтобы код вы-полнялся через веб-сервер. Так что URL-адрес, например, должен начинаться с префик-са http://, а не file://. Также убедитесь в том, что файл XML находится на одном сервере с файлом HTML; в противном случае у вас возникнут проблемы с нарушением политики единого домена.

Да, должна.

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

Потрясающе, у меня есть функция, которую можно вызвать для получения данных XML. Разве она не должна вы-

зываться многократно, чтобы обновлять страницу автоматически?

Тест-драйв

Page 340: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

340 глава 8

всему свое время

Ïëàíèðîâàíèå ñîáûòèé

Как было показано в предыдущей главе, JavaScript и jQuery поддерживают методы для вызова функ-ций с течением времени. У объекта JavaScript window есть четыре метода для работы с таймером: setTimeout, clearTimeout, setInterval и clearInterval. jQuery поддерживает метод delay, но этот метод предназначен для создания эффектов и не поддерживает возможности планирования или повторения действий. Значит, этот метод в нашем случае бесполезен...

Не торопитесь! Это далеко не очевидно. Метод setInterval обычно используется для плани-рования периодических событий на странице, а при зависимости от внешних ресурсов (таких как наш файл данных) он может создать проблемы.

С setInterval следующий вызов произойдет даже, если вызываемая функция еще не завершила работу.

Если вы ожидаете информации с другого сервера или реак-ции пользователя, setInterval может повторно вызвать функцию до получения результатов первого вызова. Порядок возвращения результатов необязательно соответствует порядку вызова функций.

setTimeout(myFunction, 4000); slideDown().delay(5000).slideUp();setInterval(repeatMe, 1000);

setTimeout setInterval delay

Ìåòîäû JavaScript Ìåòîä delay jQuery

Я определяю вре-мя, по истечении которого должна

выполняться функ-ция.

Я приказываю функции выпол-няться через за-

данный промежуток времени.

Я добавляю пау-зу между эффек-тами, объединен-ными в цепочку.

А разве нет? Нужно использовать setInterval, как и в прошлый раз.

Правильно?

Функция, вы-зываемая по истечении тайм-аута

Задержка таймера (в милли-секундах)

Интервал между вызо-вами (в мил-лисекундах)

Функция, вы-зываемая после исте-чения каждого интервала

Выполнение таких цепо-чек в jQuery называется «очередью эффектов».

В данном при-мере метод delay вставляет 5-се-кундную задержку между эффектами slideUp и slideDown.

Будьте осторожны!

Page 341: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 341

jquery и ajax

Ñàìîàêòèâèçèðóåìûå ôóíêöèè

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

Создайте функцию с именем startAJAXcalls, которая вызывается при загрузке страницы

и которая вызывает функцию getXMLRacers каждые 10 секунд. Определите в начале сценарно-

го файла (в секции $(document).ready) переменную с именем FREQ, которой присваивается

периодичность повторных вызовов getXMLRacers в миллисекундах. Используйте setTimeout

для вызова функции startAJAXcalls с целью ее самоактивизации после завершения

getXMLRacers. Также включите в код вызов функции startAJAXcalls для запуска таймера.

$(document).ready(function(){

function startAJAXcalls(){

}

getXMLRacers();

function getXMLRacers(){

$.ajax({

url: "finishers.xml",

cache: false,

my_scripts.js

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

Page 342: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

342 глава 8

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

Функция startAJAXcalls вызывает setTimeout для вызова

getXMLRacers, чтобы получить данные XML и вызвать саму себя. Такой

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

сле завершения предыдущего вызова. Мы предотвращаем накопление

запросов к серверу при низкой пропускной способности сети или если

ответ от сервера не успел вернуться до момента следующего запланиро-

ванного вызова.

В: Во всех книгах об Ajax говорится, что я должен исполь-зовать объект XMLHttpRequest. Это так?

О: Да, но не в jQuery. Веб-программисту не нужно работать с этим объектом напрямую. jQuery делает это за вас при использовании метода ajax. Кроме того, поскольку вызовы Ajax зависят от брау-зера, jQuery вычисляет оптимальный способ выполнения запросов Ajax для каждого посетителя сайта.

В: А что произойдет, если сервер вернет ошибку или не от-ветит? Приложение так и будет ждать?

О: Нет, бесконечное ожидание вам не грозит. Продолжительность тайм-аута задается в одном из параметров вызова ajax. Кроме того, по аналогии с параметром success, позволяющим выполнить функ-цию при успешном завершении, также существуют другие параметры для обработки событий error, complete и т. д.

$(document).ready(function(){

function startAJAXcalls(){

}

getXMLRacers();

function getXMLRacers(){

$.ajax({

url: "finishers.xml",

cache: false,

my_scripts.js

var FREQ = 10000;

setTimeout( function() {getXMLRacers();startAJAXcalls();

},FREQ

);

Функция getXMLRacers мно-гократно вызыва-ется из setTimeout.

Функция будет по-вторно выполнена через 10 секунд.

Значение пере-менной FREQ передается в параметре.

Вызов функции

getXMLRacers обе-

спечивает наличие

данных при загрузке

страницы.

Переменной FREQ присваивается значение 10000 (параметр функ-ции setTimeout задается в милли-секундах).

Так как мы ожи-даем завершения последнего вызова нашей функции, ис-пользуется функ-ция setTimeout.

Запуск только

что созданной функции на-чинает цикл периодических вызовов.

startAJAXcalls();

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

частоЗадаваемые

вопросы

Page 343: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 343

jquery и ajax

Обновите файл my_scripts.js только что написанным кодом. Не забудьте включить вы-зов новой функции сразу же после вызова функции getXMLRacers в конце сценария.Откройте страницу в браузере, воспользуйтесь средством «Network» Google Chrome или «Net» в Firebug для Firefox и убедитесь в том, что файл загружается каждые 10 секунд. По-сле проверки измените файл XML в своем любимом текстовом редакторе (используйте приведенные ниже данные) и убедитесь в том, что данные нового участника появились на странице... (Не забудьте сохранить файл XML после обновления!)

<runner>

<fname>Justin</fname>

<lname>Jones</lname>

<gender>m</gender>

<time>29:14</time>

</runner>

Включите данные это-го участника в файл XML, сохраните его. Убедитесь в том, что данные будут автоматиче-ски загружены на страницу.

Ого, все лучше и лучше! Но нет ли более простого

способа вывода обновленного времени на странице?

Тест-драйв

Page 344: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

344 глава 8

кто не хочет большего?

Ñåðâåð íàì ïîìîæåò

Как вы уже видели, HTML хорошо подходит для отображения информации на странице, а XML — для форматирования передаваемых данных. А если вы хотите, чтобы страница что-то делала, например определяла текущее время или читала информацию из базы дан-ных? Конечно, можно выйти из положения при помощи jQuery и JavaScript, но почему бы не воспользоваться технологией, предназначенной специально для таких задач?

Стоп! Если вы не выполнили ин-струкции из Приложения II по уста-новке PHP и MySQL, то следующая страница работать не будет. Для нее необходима рабочая поддержка PHP.

Сделайте это, прежде чем читать дальше.

Ñåðâåðíûå ÿçûêè ïðèõîäÿò íà ïîìîùü!

Существует много разных серверных языков (например, JSP, ASP и Cold Fusion), но наше внимание будет сосредоточено на одном из них: PHP.

PHP (сокращение от PHP: Hypertext Processor; да, вот такое рекурсивное сокращение — не спрашивайте нас, почему!) — бесплатный серверный язык сценариев общего назначения, используемый для построения динамических веб-страниц. Файлы, содержащие код PHP, выполняются на сервере; сгенерированный код HTML передается браузеру для отображе-ния. Технология PHP более подробно описана в следующей главе, а пока давайте посмо-трим, как она поможет нам с реализацией «обновляемого времени».

PHP используется

для динамического

генерирования раз-

метки HTML, кото-

рая затем отобража-

ется в браузере.

.php

.php

.php

PHP

Ñåðâ

åð

Áðàóçåð

Page 345: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 345

jquery и ajax

Êîòîðûé ÷àñ?

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

date (string $format [, int $timestamp = time() ]);

За полным списком параметров функции date обращайтесь по адресу http://php.net/manual/en/function.date.php.

<?php

date_default_timezone_set('America/Los_Angeles');

echo date("F j, Y, g:i:s a");

?>

Создайте новый файл в той же папке, в которой находится файл index.html, присвойте ему имя time.php. Включите в файл time.php следующий фрагмент:

time.php

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

вает в страницу за-

данную информацию.

Вызов функции date с этими параметрами возвращает дату в том же формате, что и функция JavaScript.

Открывающий тег PHP сообщает серверу, что далее следует код PHP.

Закрывающий тег PHP

В квадратных скобках [ и ] указаны необязательные параметры.Вызываем функцию PHP date.

Параметр с описанием формата,

в котором должна возвращаться

дата. Представляет собой строку.Команды в PHP завер-шаются знаком «;».

PHP тоже использу-ет знак $, но только для переменных.

Задание!

Компоненты формата даты: F — полное название месяца j — день без начальных нулей Y — год из 4 цифр g — часы в 12-часовом формате i — минуты с начальными нулями s — секунды с начальными нулями a — am или pm в нижнем регистре

Page 346: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

346 глава 8

тест-драйв

Сохраните файл time.php, откройте его в браузере и убедитесь в правильности форма-та даты. Код PHP должен выполняться через веб-сервер, поэтому URL-адрес должен начинаться с префикса http://, а не file://. Также убедитесь в том, что URL-адрес ука-зывает на сервер, на котором вы занимаетесь разработкой кода.

Да, отправляться на Гавайи еще рано. Еще нужно кое-что сделать.

Вывести на странице информацию о том, когда произошло последнее обновление.

1

Вывести частоту обновлений.2

Предоставить пользователям возможность прекращать и снова запускать обновление на их усмотрение.

3

Небольшой фрагмент кода PHP — и время отображается на экране. Гораздо проще, чем при использовании JavaScript!

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

Мне уже не терпится обзавестись брон-зовым загаром. С PHP задача обновления

времени решается проще простого, но ведь у нас остались и другие требования?

Тест-драйв

Page 347: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 347

jquery и ajax

<footer>

<h4>Congratulations to all our finishers!</h4>

<br><br>

Last Updated: <div id="updatedTime"></div>

</footer>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

index.html

function

"Page refreshes every " + FREQ/1000 + " second(s).");

}

.

.

.

.

function

$( ).load( );

}

Добавьте тег <span> с идентификатором freq в нижний блок страницы index.html. Он ну-

жен для вывода результата новой функции showFrequency, сообщающей частоту обнов-

ления страницы. Также создайте другую функцию с именем getTimeAjax, которая загру-

жает файл time.php с использованием метода load — вспомогательного метода jQuery

для работы с Ajax. Этот метод получает в параметре URL-адрес и автоматически выводит

результат в области div с идентификатором updatedTime. Наконец, замените вызов

функции getTime в getXMLRacers вызовом новой функции getTimeAjax.

my_scripts.js

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

Page 348: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

348 глава 8

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

Итак, мы добавили тег <span> с идентификатором freq в нижний блок страницы

index.html; в нем будет отображаться частота обновления страницы. Также была соз-

дана новая функция getTimeAjax, которая загружает файл time.php с использова-

нием вспомогательного метода Ajax load, а потом записывает результат в область

updatedTime. Функция getXMLRacers также была изменена, теперь вместо функции

JavaScript getTime в ней используется функция getTimeAjax.

<footer>

<h4>Congratulations to all our finishers!</h4>

<br><br>

Last Updated: <div id="updatedTime"></div>

</footer>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/my_scripts.js"></script>

index.html

function

"Page refreshes every " + FREQ/1000 + " second(s).");

}

.

.

.

.

function

$( ).load( );

}

my_scripts.js

<span id="freq"></span>

showFrequency(){$("#freq").html(

getTimeAjax(){'#updatedTime' "time.php"

Добавляем элемент для вы-вода частоты обновлений.

Создаем две новые функции: для вывода частоты и для получения времени с сервера средствами Ajax.

Загружаем файл

time.php сред-

ствами Ajax.Результат выводится на

экран в элементе updatedTime.

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

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

Page 349: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 349

jquery и ajax

Это не так просто.

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

Но как остановить работу функции, которая вызывает

сама себя?

Вывести на странице информацию о том, когда произошло последнее обновление.

1

Вывести частоту обновлений.2

Предоставить пользователям возможность прекращать и снова запускать обновление на их усмотрение.

3

Какие конструкции из рассмотрен-ных нами ранее проверяли выпол-нение условий?

Включите только что написанный код в файл my_scripts.js. Также не забудьте включить но-вый элемент span в файл index.html и заменить вызов функции getTime на getTimeAjax.

Тест-драйв

Мозговой

штурм

Page 350: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

350 глава 8

очередная условная проверка

Îòêëþ÷åíèå ïëàíèðîâàíèÿ ñîáûòèé íà ñòðàíèöå

В главах 5 и 7 мы создали функцию, которая использовала setTimeout для постоянного вызова функций, создававших эффект молнии. Это привело к неожиданным последствиям — при потере фокуса страни-цей и последующем возвращении визуальные эффекты начинали гро-моздиться друг на друга.

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

Нужно найти другое решение. Может, что-нибудь из того, что мы уже видели? Мы не можем использовать события браузера window.onblur и window.onfocus — не заставлять же пользователя поки-дать страницу для обновления. Но уже в нескольких главах нам встре-чались примеры выполнения кода в условных конструкциях; давайте воспользуемся этой возможностью и на этот раз.

Как вы думаете, какую условную конструкцию сле-дует применить в данной ситуации? (Подсказка: мы уже использовали ее для проверки пола участников в файле XML.)

Еще монстры нужны??

В: А что еще, кроме XML, можно загру-жать в странице средствами Ajax?

О: При использовании jQuery на странице можно загружать много разных видов ин-формации. Как вы уже видели, метод load позволяет загрузить результаты файла PHP прямо в элемент HTML. Также возможна загрузка других файлов HTML, файлов JavaScript, простого текста и объектов JSON (JavaScript Object Notation). Объекты JSON рассматриваются в следующей главе.

В: Какие еще вспомогательные методы для работы с Ajax существуют в jQuery?

О: В jQuery существует пять вспомога-тельных методов для работы с Ajax: get, getJSON, getScript, post и load. Первые четыре вызываются через объект jQuery, но метод load может вызываться для любого элемента, который использует-ся в качестве приемника для возвращаемых данных.

В: Когда следует использовать метод load, а когда ajax?

О: Метод load предназначен для за-грузки конкретного блока данных в кон-кретное место, как в нашей функции getTimeAjax. Метод ajax намного сложнее, он имеет больше параметров и находит более широкое применение. Он мо-жет использоваться для загрузки другой информации, а также для передачи данных на сервер для обработки. Эти возможности будут представлены в следующей главе.

Мозговой

штурм

частоЗадаваемые

вопросы

Page 351: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 351

jquery и ajax

Создайте глобальную переменную repeat со значением по умолчанию true. Создайте функ-

цию, которая изменяет переменную repeat по щелчку новой кнопки с идентификатором

btnStop. Запишите в элемент span с идентификатором freq код HTML для вывода сообщения

«Updates paused». Создайте кнопку btnStart, которая присваивает глобальной переменной

repeat значение true и вызывает функции startAJAXcalls и setTimeout, когда пере-

менная repeat принимает значение true. Разместите новые кнопки в нижнем блоке страницы.

$(document).ready(function(){

var FREQ = 10000;

function startAJAXcalls(){

setTimeout( function() {

getXMLRacers();

startAJAXcalls();

},

FREQ

);.. $("#btnStop").click(function(){

$("#freq").html( );

});

function(){

startAJAXcalls();

});

<footer>

<h4>Congratulations to all our finishers!</h4>

<br>

<span id="freq"></span> <br><br> index.html

my_scripts.js

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

Page 352: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

352 глава 8

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

Когда все сделано, в приложении появляется переменная repeat. От ее со-

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

XML с обновленной информацией. Значение переменной меняется кнопка-

ми btnStop и btnStart, находящимися в нижнем блоке стра ницы. Эти

кнопки задают текст элемента span с идентификатором freq, чтобы при

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

$(document).ready(function(){

var FREQ = 10000;

function startAJAXcalls(){

setTimeout( function() {

getXMLRacers();

startAJAXcalls();

},

FREQ

);.. $("#btnStop").click(function(){

$("#freq").html( );

});

function(){

startAJAXcalls();

});

<footer>

<h4>Congratulations to all our finishers!</h4>

<br>

<span id="freq"></span> <br><br> index.html

my_scripts.js

var repeat = true;

repeat = false;"Updates paused."

$("#btnStart").click(repeat = true;

showFrequency();

)

if(repeat) {

<button id="btnStop">Stop Page Updates</button><button id="btnStart">Start Page Updates</button>

По умолчанию пере-

менная равна true,

поэтому при загрузке

страницы обновление

включено.

Проверяем переменную repeat.

При щелчке на кнопке btnStop переменной присваивается значе-ние false.

Кнопка btnStart возвраща-

ет переменной значение true.

Также необходимо вызвать

функцию startAJAXcalls для

того, чтобы файл снова за-

гружался.Новые кнопки раз-мещаются в нижнем блоке страницы.

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

Page 353: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 353

jquery и ajax

Включите новый код в файлы my_scripts.js и index.html. Загрузите страницу в своем любимом браузере и убедитесь в том, что она по-прежнему работает. Проверьте, что новые кнопки действительно останавливают выдачу запросов Ajax (воспользуйтесь вкладкой «Network» в Google Chrome или вкладкой «Net» в Firebug для Firefox).

Это будет ЛУЧШИЙ выезд нашей группы!

Работает!

Итак, теперь наша страница обнов-ляется в реальном времени (через обновление файла XML), а пользо-ватели имеют возможность запу-скать и останавливать обновление по своему усмотрению.

Тест-драйв

Page 354: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

354 глава 8

ваш инструментарий jquery/ajax

Ajax

Комбинация технологий, позволяю-

щая обновить часть веб-страницы

без повторной загрузки всей стра-

ницы.

Использует обращения к служебно-

му серверу, который обрабатыва-

ет данные до того, как вернуть их

приложению.

В jQuery функциональность Ajax

реализуется методом ajax.

Вспомогательные методы

ajax()

В jQuery существует пять вспо-

могательных методов, упрощаю-

щих вызов ajax. Все они по умол-

чанию получают разные наборы

параметров, но в конечном итоге

вызывают метод ajax:

$.get

$.getJSON

$.getScript

$.post

$.load

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

Часто используется для хранения информации или для форматирова-ния данных с целью передачи.Используется во многих распро-страненных веб-технологиях: RSS, SOAP/веб-службы, SVG и др.

Âàø èíñòðóìåíòàðèé jQuery/Ajax

Глава 8 осталась позади. Ваш творческий инструментарий расширился: в нем появи-лись навыки работы с PHP, XML и Ajax.

PHPСерверный язык сценариев; позволя-

ет обработать содержимое веб-

страницы на сервере до того, как

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

зеру.

ГЛА

ВА 8

Page 355: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Данные JSON9

Клиент встречается с сервером

Возможность чтения данных из файлов XML безусловно полезна, но иногда этого оказывается недостаточно. Другой, более эффектив-ный формат передачи данных JSON (JavaScript Object Notation) упрощает получение данных со стороны сервера. Кроме того, данные JSON проще генерируются и читаются, чем данные XML. При помощи jQuery, PHP и SQL можно создать базу данных для хранения информации, которая позднее чи-тается с использованием JSON и отображается на экране средствами jQuery. Вот она, истинная мощь веб-приложений!

Цветы? Надеюсь, потом будут и данные. Но это может

стать началом прекрасной дружбы.

Page 356: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

356 глава 9

надо было проверить...

От: Отдел маркетинга MegaCorpТема: Re: страница результатов 42-го ежегодного марафона

Привет веб-программистам!

Нам очень понравились изменения, внесенные вами на сайте.

Однако мы столкнулись с проблемой: в нашем офисе никто не знает XML! И мы не понимаем,

как включить данные новых участников в файл для сайта.

Мы пытались, но при малейшей неточности на сайте начинает твориться что-то странное...

Участники не отображаются; поля исчезают со страницы, хотя они и присутствуют в файле

XML. Все это очень странно.

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

полей и нажать кнопку. Вы сможете это сделать?

И так, чтобы возможные ошибки не нарушали нормальной работы сайта...

Знаю, что до вылета на Гавайи осталось всего три дня, но нам хотелось бы, чтобы сайт зара-

ботал до нашего отъезда. Как вы думаете, мы успеем?

--Диона Хаузни Руководитель отдела маркетинга Фирма MegaCorp

Ежегодные соревнования

Отсчет пошел:осталось 3 дня!

ЕЕ

с рсор

 îòäåëå ìàðêåòèíãà MegaCorp íèêòî íå çíàåò XML

Page 357: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 357

данные json

Îøèáêè â XML

Если файл XML содержит некорректные данные, то чтение и разбор XML перестают работать. Такие ошибки возникают из-за проблем с тегами (если вы забыли закрыть тег или использова-ли неправильный регистр символа в имени тега). Данные тоже могут создать проблемы, если они не были должным образом закодированы для использования в XML.

Куда исчезли все участники?

При открытии файла XML в браузере выводится информа-

ция об обнаруженных ошибках.

Неправильный регистр символов в теге <runner>

Непра-вильный откры-вающий

тег

Снова непра-вильный регистр в теге <runner>Похоже, XML не подойдет. Как орга ни зовать ввод информации об участниках в отделе маркетинга?

Мозговой

штурм

Page 358: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

358 глава 9

формы приходят на помощь

Ââîä äàííûõ íà âåá-ñòðàíèöå

Скорее всего, вы уже подумали об использовании формы HTML. На форме можно ввести любые данные и передать их серверу для обработки, а используемые на них разнообразные элементы позво-ляют вводить самые разные виды данных. Формы будут более подробно описаны в главе 10, а пока мы воспользуемся всего двумя простейшими элементами форм: текстовым полем и раскрывающим-ся списком. Возможно, вы уже профессионально разбираетесь в формах, и все же давайте в общих чертах посмотрим, с чем мы имеем дело.

Наверное, проще всего создать новую вкладку с формой для

ввода данных?

<input type="text" name="txtEmail" />

<select name="truthiness">

<option value="1">True</option>

<option value="0">False</option>

</select>

Тег <input> со-

общает фор-ме, что этот

элемент будет

поставлять информацию.

Атрибут type указывает браузеру, как следует ото-бражать этот элемент.

Имя элемента передается серверу для обработки.

Закрывающий тег элемента

Тег < select> сооб-

щает браузеру,

что нужно вы-

вести раскрыва-

ющийся список.

Элемент option опреде-

ляет пункт раскрываю-

щегося списка.Значение value выбранного пункта списка отправляется серверу.

Да, такое решение будет работать и легко реали-зуется, так как мы уже умеем добавлять новые вкладки.

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

Page 359: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 359

данные json

<ul class="idTabs">

<li><a href="#male">Male Finishers</a></li>

<li><a href="#female">Female Finishers</a></li>

<li><a href="#all">All Finishers</a></li>

<li><a href="#new">Add New Finisher</a></li>

</ul>

<div id="male">

<h4>Male Finishers</h4><ul id="finishers_m"></ul>

</div>

<div id="female">

<h4>Female Finishers</h4><ul id="finishers_f"></ul>

</div>

<div id="all">

<h4>All Finishers</h4> <ul id="finishers_all"></ul>

</div>

<div id="new">

<h4>Add New Finisher</h4>

<form id="addRunner" name="addRunner" action="service.php" method="POST">

First Name: <input type="text" name="txtFirstName" id="txtFirstName" /> <br>

Last Name: <input type="text" name="txtLastName" id="txtLastName" /> <br>

Gender: <select id="ddlGender" name="ddlGender">

<option value="">--Please Select--</option>

<option value="f">Female</option>

<option value="m">Male</option>

</select><br>

Finish Time:

<input type="text" name="txtMinutes" id="txtMinutes" size="10" maxlength="2" />(Minutes)

<input type="text" name="txtSeconds" id="txtSeconds" size="10" maxlength="2" />(Seconds)

<br><br>

<button type="submit" name="btnSave" id="btnSave">Add Runner</button>

<input type="hidden" name="action" value="addRunner" id="action">

</form>

</div>

Включите в файл index.html новую вкладку для вво-да информации об участниках на форме. Также внесите изменения в файл my_style.css, чтобы уве-личить ширину элемента с идентификатором main.

Добавляем новую форму HTML для сбора данных и их передачи серверу.

Скрытое поле HTML. Вскоре мы расскажем о том, как используется это поле.

Добавляем новую вкладку.

Атрибут action сообщает форме, куда следует передать данные для обработки. Атрибут

method определя-ет способ передачи данных сер-веру.

#main {

background:#181818;

color:#111;

padding:15px 20px;

width:600px;

border:1px solid #222;

margin:8px auto;

}

index.html

my_style.css

Готово к употреблению

Page 360: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

360 глава 9

тест-драйв

Новая форма Новая форма HTML в браузереHTML в браузере

Откройте файл index.html в браузере. Перейдите на вкладку Add New Finisher, присмотритесь к новой форме и полям, добавленным на страницу.

Итак, теперь у нас есть форма для ввода данных. Как, по вашему мнению, следует организовать хра-нение и выборку данных?

Тест-драйв

Мозговой

штурм

Page 361: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 361

данные json

<form id="my_form" method="get" action="x.php">

<input type="text" name="a" value="1" />

<input type="text" name="b" value="2" />

</form>

<form id="my_form" method="post" action="x.php">

<input type="text" name="a" value="1" />

<input type="hidden" name="c" value="3" />

</form>

<?php

echo $_GET["a"] ; // Writes out "1"

echo $_GET["b"] ; // Writes out "2"

?>

<?php

echo $_POST["a"] ; // Writes out "1"

echo $_POST["c"] ; // Writes out "3"

?>

×òî äåëàòü ñ äàííûìè

Теперь необходимо отправить серверу данные, введенные на форме, и как-то их сохранить. Для сохра-нения информации в базе данных мы воспользуемся другим языком, PHP. Не волнуйтесь, скоро мы по-говорим о PHP и базах данных, а пока сосредоточимся на том, как передать данные от формы серверу.

Существуют два способа отправки данных серверу с использованием HTTP: GET и POST (они также называются «методами»). Главное различие между GET и POST — конкретный механизм передачи дан-ных. GET присоединяет имена полей формы и их значения в конец URL-адреса в формате пар «ключ/значение». PHP читает эту информацию из ассоциативного массива $_GET[], который передается сер-веру при отправке данных формы. Передаваемые данные следуют после знака ? в URL-адресе.

Метод POST тоже передает данные в ассоциативном массиве, но они кодируются другим способом, и эти данные не видны конечному пользователю в URL-адресе. В ассоциативном массиве $_POST[] хранится вся информация из элементов формы. Таким образом, как и массив $_GET[], он состоит из пар «ключ/значение» элементов формы.

Метод HTTP GET Метод HTTP POST

Отправка данных серверу. Отправка данных серверу.

x.php?a=1&b=2 x.php

Да, форма может отправить информацию...

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

В этой главе мы будем использовать метод POST.

Но если форма отправляет информацию сама, для чего

jQuery и все остальное?

Page 362: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

362 глава 9

серьезная сериализация

Ôîðìàòèðîâàíèå äàííûõ ïåðåä îòïðàâêîé

Прежде чем отправлять информацию серверу (средствами Ajax), необходимо сначала подготовить ее — преобразовать в формат, который может передаваться вызовами Ajax и который будет поня-тен серверу. Для этого данные сериализуются в один объект, чтобы вызов Ajax мог передать их как единое целое. В jQuery существуют два вспомогательных метода сериализации данных: serialize и serializeArray. Первый объединяет весь ввод на форме в одну строку пар «ключ/значение», разделенных амперсандами (&). Второй создает ассоциативный массив пар «ключ/значение»; массив также является одним объектом, но он намного лучше структурирован, чем результат serialize. Мы рассмотрим обе возможности, но при работе с данными марафона будет использо-ваться метод serializeArray.

$("#my_form").serialize(); $("#my_form:input").serializeArray();

Селектор иден-

тификатора формы

Метод serialize Вызов методаserializeArray

Селектор идентификатора формы, за которым следу-ет фильтр элемента HTML input. Селектор должен най-ти только элементы HTML с типом «input».

serialize serializeArray

<form id="my_form">

<input type="text" name="a" value="1" />

<input type="text" name="b" value="2" />

<input type="hidden" name="c" value="3" />

</form>

<form id="my_form">

<input type="text" name="a" value="1" />

<input type="hidden" name="c" value="3" />

</form>

a=1&b=2&c=3

[

{

name: "a",

value: "1"

},

{

name: "c",

value: "3"

}

]

Результат Результат

Page 363: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 363

данные json

$('_______________').click(function() {

var data = $("#addRunner :input").___________________();

$.post($("#addRunner").attr('action'), __________ , _______________(json){

if (json.status == "fail") {

alert(json._____________);

}

if (json.status == ______________) {

alert(json.message);

clearInputs();

}

}, "json");

});

function ___________________{

$("#addRunner :input").each(function(){

$(this).val('');

});

}

$("#addRunner").______________(function(){

return false;

});

Îòïðàâêà äàííûõ ñåðâåðó

jQuery предоставляет вспомогательный метод post, предназначенный для отправки данных серверу. Метод post получает несколько параметров (в числе которых URL-адрес, по которому отправляется информация), передаваемую информацию и функцию-обработчик, которая выполняется после за-вершения отправки POST.

Создайте слушателя события click для #btnSave, который получает данные формы и сериализует их.

Информация отправляется серверу методом jQuery post. URL-адрес для отправки берется из атрибута

action формы. Создайте функцию clearInputs , стирающую все данные из полей формы, если отправ-

ка была успешной. Необходимо отменить отправку данных формы по умолчанию (возвращая false),

для чего следует использовать слушателя . submit формы с идентификатором addRunner.

$.post(url_to_send, data, function(json){

});URL-адрес, на который отправля-ются данные

Вспомога-

тельный

метод jQuery Передаваемые дан-ные (уже прошед-шие сериализацию)

Данные возвращаются в объекте с именем json. Не обращайте на него внимания, мы займемся им позднее в этой главе.

Выполня-ется эта функция обратного вызова.

my_scripts.js

serializeArray

#btnSave

"success"

clearInputs()

submit

function

data

message

Развлечения с магнитами

Page 364: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

364 глава 9

Тест-драйв

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

Создайте слушателя события click для #btnSave, который получает данные формы и сериализует их.

Информация отправляется серверу методом jQuery post. URL-адрес для отправки берется из атрибута

action формы. Создайте функцию clearInputs , стирающую все данные из полей формы, если отправ-

ка была успешной. Необходимо отменить отправку данных формы по умолчанию (возвращая false), для

чего следует использовать слушателя . submit формы с идентификатором addRunner.

После внесения последних изменений внешний вид страницы не изменится. Тем не менее включи-те в файл my_scripts.js созданный код. Откройте страницу index.html в браузере, перейдите на вкладку «Network» (Chrome) или «Net» (Firebug); при каждом нажатии кнопки btnSubmit должна происходить отправка POST файлу service.php. Метод POST указывается в разделе Request Method вкладки Headers. Здесь же приводятся данные формы (Form Data). Осталось только найти место для их сохранения…

$('___________').click(function() {

var data = $("#addRunner :input").________________();

$.post($("#addRunner").attr('action'), ________ , ___________(json){

if (json.status == "fail") {

alert(json.___________);

}

if (json.status == ___________) {

alert(json.message);

clearInputs();

}

}, "json");

});

function _______________{

$("#addRunner :input").each(function(){

$(this).val('');

});

}

$("#addRunner").___________(function(){

return false;

});

________________()

n')

________________serializeArray

___________'

var data = $

#btnSave

___________)

age);

"success"

_______________{

dRunner :input").

clearInputs()

___________(submit

___________(jfunction________ ,data

___________)message

my_scripts.js

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

Готовим данные всех полей формы к отправ-ке на сервер.

Проверка значения, возвращенного сервером (и заданного в коде PHP), позволяет узнать, успешно ли прошла отправка POST.

Используем фильтр элементов HTML для перебора всех полей input формы и стирания их содержимого.

Отменяем отправку данных формой по умолчанию, чтобы выполнить ее кодом jQuery в событии click кнопки.

Развлечения с магнитами. Решение

Page 365: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 365

данные json

В MySQL данные

хранятся в табли-

цах базы данных.

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

Сама база данных часто

хранится в файлах на

жестком диске, но это

необязательно.

Сервер баз данных MySQL может обслу-живать несколько баз данных.

В базе данных мо-жет быть несколь-ко таблиц.

Веб-сервер

Сервер баз данных

Серверный компьютер

Клиентский браузер

База данных MySQL

Сервер баз данных выполняет с базой данных операции чтения и записи.

Веб-сервер обрабатыва-ет запросы веб-страниц, выполняет сценарии PHP и возвращает данные в формате HTML. Данные

Веб-сервер

Сервер баз данных

SQL — язык струк-турированных за-просов (Structured Query Language).

Õðàíåíèå èíôîðìàöèè â áàçå äàííûõ MySQL

Реляционные системы управления базами данных (РСУБД) представляют собой высокоуровневые приложения, предназначенные для хранения и ор-ганизации информации об отношениях между различными видами данных.

Существует великое множество разнообразных РСУБД (также часто назы-ваемых серверами баз данных) разного назначения и размера (и разной стоимости). Для наших целей будет использоваться бесплатный сервер баз данных MySQL. Для взаимодействия с сервером баз данных используется язык, понятный сер-веру, — в нашем случае это язык SQL. Сервер баз данных обычно работает в сочетании с веб-сервером (иногда на одном компьютере) над чтением и за-писью данных, а также выдачей готовых веб-страниц.

SQL — язык запросов,

используемый для взаи-

модействия с базой дан-

ных MySQL.

<? php

>?

Page 366: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

366 глава 9

запускаем базу данных

create database hfjq_race_info;

CREATE USER 'runner_db_user'@'localhost' IDENTIFIED BY 'runner_db_password';

GRANT SELECT,INSERT,UPDATE,DELETE ON hfjq_race_info.* TO 'runner_db_user'@'localhost';

use hfjq_race_info;

CREATE TABLE runners(

runner_id INT not null AUTO_INCREMENT,

first_name VARCHAR(100) not null,

last_name VARCHAR(100) not null,

gender VARCHAR(1) not null,

finish_time VARCHAR(10),

PRIMARY KEY (runner_id)

);

Ñîçäàíèå áàçû äàííûõ äëÿ èíôîðìàöèè îá ó÷àñòíèêàõ

Стоп! А вы уже установили и настроили MySQL и PHP? Прежде чем продолжать,

обязательно выполните инструкции по установке и настройке PHP и MySQL

из приложения II.Хорошо, проезжайте.

Теперь вы сможете выпол-нить задания этой главы.

Мы уже написали код создания базы данных, та-блиц и пользователей за вас. Запустите MySQL Workbench, откройте новое подключение и вы-полните следующий код SQL:

Создаем базу данных с именем hfjq_race_info.

Создаем пользователя runner_db_user, задаем ему пароль и разреша-ем этому пользователю получать, добавлять, обновлять и удалять данные из базы.

Указываем сценарию, что следующий фраг-мент относится к на-шей новой базе данных.

Создаем таблицу runners, в которой хранится вся необходимая информа-ция об участниках марафона.

Готово к употреблению

Page 367: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 367

данные json

И где же данные?

Сейчас мы ими займемся.

Только что выполненный нами код SQL только создает базу данных, создает пользователя, предоставляет новому пользователю доступ к базе данных и создает таблицу для хранения информации. Теперь давайте посмотрим, как сохранить в таблице данные.

Запустите MySQL Workbench и откройте подключение к серверу. Вставьте код SQL на па-нель Query и щелкните на значке с молнией, чтобы его выполнить. На панели Output в нижней части окна должны появиться сообщения об успешном выполнении операций.

Тест-драйв

Page 368: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

368 глава 9

это здесь, а это вставляем сюда…

Ñòðîåíèå êîìàíäû insert

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

Включение данных в таблицы осуществляется командой insert.

insert into [table_name] ( column_name1, column_name2, column_name3)

values ('value1', 'value2', 'value3' );

Список данных, сохраняемых в таблице (должен соответство-

вать списку столбцов). Элементы

списка разделяются запятыми.

Ключевое слово «values» сообщает команде, что список столбцов завершен, а далее следуют соб-ственно данные.

Ключевые сло-ва «insert into» определяют операцию.

Указывает, в какую таблицу заносятся данные.

Разделенный запятыми список столбцов, в кото-рых сохраняются данные

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

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

Порядок следования имен столбцов и значений важен!

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

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

Значения

Данные вставля-ются в таблицу.

Таблица базы данных

В таблицу добавляется новая запись (строка).

Реляционная база данных

Будьте осторожны!

Page 369: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 369

данные json

insert into runners (first_name, last_name, gender, finish_time)

values ('John','Smith','m','25:31') ;

Напишите команды SQL insert для вставки данных, уже хранящихся в файле XML. Каждая команда должна вставлять одну запись в созданную нами таблицу. Первую команду мы написали за вас.

Упражнение

Page 370: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

370 глава 9

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

insert into runners (first_name, last_name, gender, finish_time)

values ('John','Smith','m','25:31') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Jacob','Walker','m','25:54') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Mary','Brown','f','26:01') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Jenny','Pierce','f','26:04') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Frank','Jones','m','26:08') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Bob','Hope','m','26:38') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Jane','Smith','f','28:04') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Ryan','Rice','m','28:24') ;

insert into runners (first_name, last_name, gender, finish_time) values ('Justin','Jones','m','29:14') ;

Весь код SQL, необходимый для вставки информации об участниках в таблицы базы данных, написан. Запустите MySQL Workbench и выполните код.

Пора использовать новый язык: PHP.

Не беспокойтесь! Мы ограничимся толь-ко тем, что необходимо для взаимодей-ствия на стороне сервера (включая обще-ние с сервером баз данных).

Хорошо, информация об участниках сохранена в базе данных. Как теперь

извлечь ее для веб-приложения?

Page 371: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 371

данные json

<? php

>?

Èñïîëüçîâàíèå PHP äëÿ ðàáîòû ñ äàííûìè

PHP — язык программирования, и для его использования необхо-дима соответствующая среда: веб-сервер с поддержкой PHP. Сце-нарии PHP и веб-страницы, использующие сценарии, должны размещаться на веб-сервере (вместо простого запуска сценария из локальной файловой системы).

Браузеры ничего не знают о PHP, а следовательно, не могут выполнять сценарии PHP.

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

Сценарии PHP должны

выполняться на веб-сервере,

иначе они работать не будут.

В отличие от страниц HTML,

которые можно открыть в

браузере локально, сценарии PHP

всегда должны «открываться»

по URL-адресу из веб-сервера.

Как быстро определить, была ли веб-страница предоставлена веб-сервером? URL-адреса таких стра-ниц начинаются с префикса «http:». Веб-страницы, открываемые как локальные файлы, всегда начинаются с префикса «file:».

Для браузера этот сценарий PHP представляет собой бес-смысленный набор символов.

Веб-сервер «понимает» код PHP и выполняетсценарий!

Если у вас имеется локаль-но установленный веб-сервер с поддержкой PHP, вы сможете протестиро-вать сценарии PHP прямо на локальном компьютере.

<? php

>?

PHP и MySQL?Я думала, мы здесь изучаем jQuery! Что происходит?

Будет и jQuery, не беспокойтесь.

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

Page 372: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

372 глава 9

отправка post

Îáðàáîòêà äàííûõ POST íà ñåðâåðå

Мы уже рассмотрели специальный объект $_POST, создаваемый для передачи информации веб-серверу от формы в браузере. Он представляет собой ассоциативный массив со всей отправлен-ной информацией, при этом в качестве ключа используется имя (а не идентификатор!) элемента HTML, а содержимое элемента HTML сохраняется как значение ассоциативного массива. Код PHP на сервере читает объект $_POST и определяет, какая информация была отправлена серверу.

Информация извлекается из массива по ключу, с которым она была отправлена (имя элемента HTML). Так значения становятся доступными в сценарии PHP.

echo $_POST["txtFirstName"];

Значение выводится

на экран.

Имя массива, автоматически соз-даваемого для данных, отправляе-мых файлу PHP методом POST.

Имя элемента HTML, в котором вводились данные на форме.

Ну что еще? Я хочу на пляж!!!

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

Page 373: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 373

данные json

<?php

mysql_connect('127.0.0.1', 'runner_db_user', 'runner_db_password')

OR die( 'Could not connect to database.');

mysql_select_db('hfjq_race_info');

echo "Connected!";

?>

Ïîäêëþ÷åíèå ê áàçå äàííûõ èç êîäà PHP

Помните, как ближе к концу процесса установки PHP мы выбирали библиотеку?

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

Имя сервера, на котором находится база данных MySQL

Пользователь MySQL, с права-ми которого вы подключаетесь к базе данных

Пароль MySQL для пользователя

mysql_connect — функция библиотеки PHP, включенной в ходе установки PHP.

mysql_select_db сообщает PHP, с какой базой данных мы будем работать.

Если подключение к базе данных прошло успешно, сообщение выводится на экран, а если нет, выполнение сценария не до-стигнет этой точки.

Закрывающий тег PHP

Команда die выводит сообщение и заверша-ет сценарий PHP.

Откройте теги PHP.

service.php

Page 374: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

374 глава 9

тест-драйв

Вы правы.

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

Пока что не очень впечатляет. Ну да, мы подключились... но я по-прежнему не вижу данных!

Откройте свой любимый текстовый редактор и добавьте код с предыдущей страницы. Сохраните файл под именем service.php в одном каталоге с файлом index.html этой главы. Откройте файл service.php в браузере и просмотрите результаты запроса к базе данных.

Не забудьте, что код PHP должен выполняться через веб-сервер, поэтому ваш URL-адрес должен начинаться с префикса http://, а не file://.

Тест-драйв

В: MySQL Workbench — единственный способ управления базой данных MySQL?

О: Нет! Существуют другие способы и другие инструменты. PHPMyAdmin — стандартный инструмент на базе веб-технологий для управ-ления базами данных MySQL. Также базой данных можно управлять из окна терминала, вводя данные в командной строке.

В: Какие еще существуют библиотеки PHP?

О: Существует много разных библиотек PHP для разных целей: SSL, работы с электронной почтой (SMTP или IMAP), сжатия данных, про-верки подлинности, подключения к другим базам данных и т. д. Чтобы получить полный список, введите в своей любимой поисковой системе «библиотеки PHP».

частоЗадаваемые

вопросы

Page 375: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 375

данные json

×òåíèå èç áàçû äàííûõ

Для чтения информации из базы данных используется команда select. Данные возвращаются в виде итогового набора ( resultset) — со-вокупности всех данных, запрашиваемых в запросе select. Команда select также позволяет объединить информацию из нескольких таблиц; таким образом, итоговый набор может содержать данные из двух и более таблиц.

Создайте команду select для получения данных, необходимых для отображения списка

участников на сайте. Из таблицы runners нужно прочитать столбцы first_name, last_name, gender и finish_time. Отсортируйте данные по столбцу finish_time, от низких

значений к высоким. Если понадобится, имена столбцов можно уточнить на с. 366, где мы

создавали таблицу.

select column_name1, column_name2 from table_name order by column_name1 asc

Ключевое слово « order by», за которым следуют име-на одного или нескольких столбцов, обеспечивает сортировку возвращаемых данных в указанном порядке.

Ключевое слово «from» сообщает команде, что список столбцов завер-шен, а за ним следует информация о том, откуда следует взять данные.

Ключевое слово «select» определяет выполняе-мую операцию.

Разделенный запяты-ми список столбцов, из которых извлека-ются данные

Указываем, из какой таблицы извлека-ются данные.

Ключевое слово «asc» в секции «order by» указывает, как сле-дует упорядочить результаты (asc — по возрастанию, desc — по убыванию).

Команда SQL select читает столбцы данных

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

щает данные в виде итогового набора.

Более подробная инфор-мация о PHP, SQL, базах данных и таблицах при-ведена в книге «Head First PHP & MySQL».

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

Page 376: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

376 глава 9

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

Вы только что создали собственную команду SQL для чтения

информации об участниках из базы данных.

SELECT first_name, last_name, gender, finish_time FROM runners order by finish_time ASC

Список столбцов, из кото-рых читаются данные

Выполните команду select в MySQL Workbench. Убедитесь в том, что все данные возвращаются в итоговом наборе.

Потрясающе! Я вижу данные в Workbench... но

ведь они нужны нам на веб-странице?

Да, это верно.

Давайте посмотрим, как вы-вести на странице информа-цию, прочитанную из базы данных.

Способ упоря-дочения данных

Таблица, из которой читаются данные

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

Тест-драйв

Page 377: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 377

данные json

Äîñòóï ê äàííûì â êîäå PHP

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

Сложите из магнитов код PHP, в котором определяется функция db_connection для

подключения к базе данных. Создайте переменную $query и присвойте ей текст напи-

санной ранее команды select для выборки информации всех участников из базы дан-

ных. Создайте переменную $result, которой присваивается результат вызова функции

db_connection с передачей переменной $query в параметре. Наконец, переберите в

цикле while все строки итогового набора (данные которого хранятся в ассоциативном

массиве) и выведите их на экран.

<?php

$query = "SELECT first_name, last_name, gender, finish_time _____ runners order by ______________ASC ";

$result = ___________________($query);

while ($row = mysql_fetch_array(____________, MYSQL_ASSOC)) {

print_r(_______);

}

_______________db_connection(__________) {

mysql_connect('127.0.0.1', 'runner_db_user', 'runner_db_password')

OR _____ ('Could not connect to database.');

_____________________('hfjq_race_info');

return mysql_query($query);

}

?>

service.php

function

$query

$result finish_time

db_connection

$row

die

FROM

mysql_select_db

Развлечения с магнитами

Page 378: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

378 глава 9

частоЗадаваемые

вопросы

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

В: Команда select возвращает всю информацию из таблицы? Я могу огра-ничить состав возвращаемых столбцов, а как насчет строк?

О: Да, строки можно ограничить при по-мощи секции where. Мы поговорим об этом в главе 11, а сейчас достаточно сказать, что в секции where передается условие-фильтр, и команда select возвращает строки, ко-торые удовлетворяют указанному условию.

В: Команда может читать данные только из одной таблицы?

О: В запросе можно объединить сколько угодно таблиц, обычно для этого исполь-зуется общий идентификатор или условие where. Объединение большого количества таблиц существенно замедляет запросы к базе данных, поэтому будьте осторожны при использовании этой возможности. Чтобы получить дополнительную информацию по этой теме, почитайте главу 8 книги «Изучаем PHP & MySQL» или главу 2 «Изучаем SQL».

В: Почему база данных находится по адресу 127.0.0.1? Я вижу свой сайт на «localhost». Откуда такие различия?

О: Хороший вопрос. Ответ: различий нет. Адрес 127.0.0.1 и имя «localhost» обознача-ют одно и то же — компьютер/сервер, на ко-тором вы работаете в настоящий момент.

Перед вами небольшой фрагмент кода PHP, который читает информацию из базы дан-

ных, перебирает содержимое полученного массива и выводит его на веб-странице.

<?php

$query = "SELECT first_name, last_name, gender, finish_time _____ runners order by _______________ASC ";

$result = _________________($query);

while ($row = mysql_fetch_array(__________, MYSQL_ASSOC)) {

print_r(_______);

}

___________db_connection(__________) {

mysql_connect('127.0.0.1', 'runner_db_user', 'runner_db_password')

OR _____ ('Could not connect to database.');

_________________('hfjq_race_info');

return mysql_query($query);

}

?> service.php

___________db

mysql_conn

function __________)

1', 'runner

$query

__________,$result

y = "SELECT first________________AS

lt = _

SELECT fi_______________finish_time

_____($______________ e

db_connection

y q

_______);$row

nect

(

_conn

_

die

_____ ruFROM

_____

_________________('

_____

________

_____

mysql_select_db

Развлечения с магнитами. Решение

Page 379: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 379

данные json

Безусловно!

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

Включите в файл service.php только что написанный код. Откройте страницу в браузере, чтобы увидеть результаты запроса к базе данных. Не забывайте, что код PHP должен вы-полняться через веб-сервер, поэтому URL-адрес должен иметь префикс http://, а не file://.

Результат: все данные успешно выве-дены на экран.

Да, это наши данные, но они какие-то сложные и запутанные. Нельзя

ли их немного «причесать»?

Тест-драйв

Page 380: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

380 глава 9

простой способ

{

books:{

book:[

{

title:'The Color of Magic',

author:'Terry Pratchett',

year:1983

},

{

title:'Mort',

author:'Terry Pratchett',

year:1987

},

{

title:'And Another thing...',

author:'Eoin Colfer',

year:2009

}

]

}

}

<?xml version="1.0" encoding="utf-8"?>

<books>

<book>

<title>The Color of Magic</title>

<author>Terry Pratchett</author>

<year>1983</year>

</book>

<book>

<title>Mort</title>

<author>Terry Pratchett</author>

<year>1987</year>

</book>

<book>

<title>And Another thing...</title>

<author>Eoin Colfer</author>

<year>2009</year>

</book>

</books>

Íà ïîìîùü ïðèõîäèò JSON!

JSON (сокращение от JavaScript Object Notation) — облегченный формат передачи данных. Обычный человек сможет читать и писать в этом формате. Он легко разбирается и генерируется компьютером. Поэтому JSON идеально подходит для структурирования и передачи данных. JSON основан на подмно-жестве стандарта JavaScript и нейтрален к языку — может использоваться практически с любым языком программирования. Формат JSON превосходит XML по эффективности передачи данных; фактически он рассматривает пары «имя/значение» как ассоциативные массивы. Значения могут быть строками, числами, массивами, объектами, логическими значениями («истина/ложь») или null.

XML vs. JSON

Пары «имя/значение», разделенные двоето-чием

Строковые значе-ния заключаются в кавычки.

Для чисел кавычки не нужны.

Объекты за-ключаются в фигурные скобки { }.

Объекты разделяются запятыми.

Массив с данными

Корневой элемент

Для обращения к информации в объектах JSON используется та же запись, как при обращении к дру-гим объектам — точечный синтаксис (.). Массивы в объектах JSON не отличаются от обычных массивов JavaScript и обладают теми же свойствами (например, length). В приведенном объекте JSON, чтобы узнать количество полученных книг нужно использовать конструкцию books.book.length. Объекты JSON имеют разную структуру, для обращения к объекту массива столько точек может и не понадобиться.

Свойства разделяются запятыми.

Многократные вхождения тегов увеличивают объем передаваемых данных.

Элементы не связаны между

собой, если не считать кор-

невого элемента. Поэтому

нам приходилось искать их

методом find().

Page 381: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 381

данные json

Если эта запись выглядит знакомо — это потому, что она почти не отличается от метода post, использованного нами ранее для получения данных от фор-мы. Этот простой метод представляет собой сокращенную запись для вызова метода ajax, в которой несколько параметров уже заданы заранее. В полной записи этот вызов выглядел бы так:

Да, можно.

Нам снова повезло: создатели PHP уже позаботились об этом. Продол-жим изучение базовых возможно-стей PHP, а затем посмотрим, как объединить их с другими функци-ями PHP для получения данных в формате JSON.

jQuery + JSON = ïîòðÿñàþùå

Формат JSON очень широко распространен и прост в использовании, поэтому создатели jQuery предусмотрели специальное сокращение для работы с данными JSON: метод getJSON.

$. getJSON(url_to_load, function(json) {

});URL-адрес, с которого загружаются данные

Сокраще-ние jQuery

Вызов метода getJSON

Данные возвращаются в объекте с именем json (подробности чуть позже).

Выполняемая функция обратного вызова

Но наши данные не хранятся в формате JSON — это простой

набор массивов. Можно ли преоб-разовать эти массивы в JSON?

$.ajax({

url: url_to_load,

dataType: 'json',

data: json,

success: function(json){

};

});

Page 382: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

382 глава 9

нарушать не советуем

Íåñêîëüêî ïðàâèë PHP...

По правде говоря, никто не любит правила программирования. Но у PHP есть еще не-сколько особенностей (большей частью из области синтаксиса), которые необходимо знать для подготовки данных к использованию в jQuery. К счастью, многие из этих кон-цепций уже встречались нам в контексте JavaScript, так что изучение будет настолько бы-стрым и безболезненным, насколько это возможно…

Îñíîâíûå ïðàâèëà PHP

1. Весь код PHP должен быть заключен в теги<?php и ?> .

2. PHP может чередоваться с HTML, при этом код PHP заключается в теги <?php и ?>.

3. Все строки кода PHP должны заканчиваться точкой с за-пятой (;).

Ïðàâèëà äëÿ ïåðåìåííûõ

1. Имена всех переменных должны начинаться со знака доллара ($).

2. За $ следует как минимум одна буква или знак подчеркивания, далее идет произвольная ком би нация букв, цифр и подчеркиваний.

3. Дефисы ( - ), пробелы ( ) и любые специаль-ные символы (кроме $ и _) в именах пере-менных запрещены.

Ïðàâèëà äëÿ öèêëîâ

1. В PHP поддерживаются циклы for, while и do...while — с таким же синтаксисом, как в JavaScript.

2. В PHP также существует дополнительная раз-новидность циклов — так называемый цикл foreach, который последовательно переби-рает элементы массива до обнаружения кон-ца массива, после чего автоматически оста-навливается.

<div><span> Hello

<?php

echo "Bob"; ?>

</span></div>

<?php

for ($i = 1; $i <= 10; $i++) {

echo $i;

}

while ($j <= 10) {

echo $j++;

}

$a = array(1, 2, 3, 17);foreach ($a as $v) {

echo "Current value: $v.\n";

}

?>

<?php

$u = "USA"; // OK

$home_country = "Ireland"; // OK

$another-var = "Canada"; // Causes an error

?>

Page 383: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 383

данные json

Ïðàâèëà PHP (åùå íåìíîãî)...

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

Ïðàâèëà äëÿ ìàññèâîâ

1. Новые массивы создаются ключевым словом array (как и в JavaScript).

2. Обращения к ячейкам массивов выполняются по индексу ячейки, который указывается в ква-дратных скобках [ ] (как и в JavaScript). Индек-сы начинаются с нуля, как и в JavaScript.

3. Массивы могут быть ассоциативными, обра-щение к ячейкам осуществляется по ключу, а не по индексу. Содержимое таких массивов пред-ставляет собой пары «ключ/значение».

4. Чтобы сохранить в ассоциативном массиве но-вую пару «ключ/значение», используйте опе-ратор =>.

Ïðàâèëà óñëîâíûõ êîíñòðóêöèé

1. Команда if имеет такой же синтаксис, как в JavaScript (это относится и к условию else, и к else if).

2. Операторы сравнения работают так же, как в JavaScript.

3. Логические операторы тоже не отличаются от JavaScript, с одним дополнением: вместо операторов могут использоваться их эквива-ленты and, or и not.

Ïðàâèëà âûâîäà íà ýêðàí

1. Для вывода на экран используются ключевые слова echo и print.

2. Содержимое массива выводится командой print_r.

<?php

$my_arr2 = array('USA', 'China', 'Ireland');

echo $my_arr2[2]; // Выводит "Ireland"

$arr = array("foo" => "bar", 12 => true);

echo $arr["foo"]; // Выводит "bar"

echo $arr[12]; // Выводит true

?>

<?php

if ($x > $y){

echo "x is greater than y";

}

elseif ($x == $y) {

echo "x is equal to y";

}

else {

echo "x is smaller than y";

}

?>

<?php

echo "Bob"; print_r($my_arr2);?>

Page 384: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

384 глава 9

всего один массив

Ôîðìàòèðîâàíèå âûâîäà ñðåäñòâàìè PHP

Хорошо, мы разобрались с основами, теперь посмотрим, что PHP может сделать для нас! Функция json_encode в PHP преобразует ассоциативный массив в строку значений, закодированную в формате JSON.

echo json_encode(array_name);

$my_array = array();

array_push($my_array, array('my_key' => 'my_val'));

Вызов этой функции PHP кодирует массив в форма-те JSON.

Создаем новый,пустой массив.

Здесь передается любая информация, добавля-емая в массив. В дан-ном случае в массив $my_array включается другой ассоциативный массив.

Вызываем функцию array_push с параме-трами.

Пара «имя/значе-ние», включаемая в этот массив

Значение записы-вается в источник вызова (браузер, вызов ajax и т. д.).

Кодируемый массив

Но прежде чем данные можно будет закодировать, они должны оказаться в одном ассоциативном массиве. Мы уже видели метод для перебора итогового набора и вы-вода всех входящих в него ассоциативных массивов. Но сейчас нам нужно взять все эти массивы и объединить их в один массив. При помощи функции PHP array_push мы можем добавлять новые элементы в конец массива.

Функция json_encode стала доступна только в PHP версии 5.2. Если вы

используете более раннюю версию PHP, либо обновите ее, либо введите

строку «json_encode PHP альтернативы» в своей любимой поисковой си-

стеме и найдите описание этой функции от создателей PHP. После этого вы

сможете написать собственную реализацию функции, чтобы пользоваться

всеми ее замечательными возможностями.

Для любознательных

Приемный массив передается в первом параметре.

Page 385: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 385

данные json

В: Кто придумал JSON? Создатели jQuery?

О: Нет. Дуглас Крокфорд, специалист по JavaScript из Yahoo!, изобрел JSON как то, что он назвал «обезжиренной альтернативой XML». Он приводит обоснования этой характеристики в статье: http://www.json.org/fatfree.html.

В: Разве JSON это не JavaScript?

О: И да, и нет. JSON базируется на подмножестве JavaScript, ECMA 262 Third Edition, но может использоваться в разных языках для передачи данных. Список языков, поддерживающих JSON, приведен по сайте http://www.json.org/.

В: Выходит, JavaScript и PHP имеют похожий синтаксис. По-чему же я не могу просто использовать JavaScript?

О: Как мы уже упоминали, PHP является серверным языком сценариев и может взаимодействовать с веб-сервером и базами данных от вашего имени. Код выполняется на сервере и генерирует разметку HTML, которая затем передается клиенту. JavaScript, напротив, работает только в вашем браузере, а все его взаимо-действия осуществляются на стороне клиента.

В: Понятно. Еще раз, что такое PHP?

О: PHP (рекурсивное сокращение от «PHP: Hypertext Preprocessor») — популярный, распространяемый с открытым ко-дом язык сценариев общего назначения, который особенно хорошо подходит для веб-программирования и может встраиваться в HTML.

В: Откуда взялся PHP?

О: Язык PHP появился в 1994 году. Он был создан Расмусом Лердорфом и предназначался для отображения его резюме в Интернете. В июне 1995 года был опубликован исходный код, что позволило другим разработчикам заняться обновлением и исправлением ошибок. Проект ждало большое будущее: сейчас он используется на более чем 20 миллионах сайтов по всему миру.

Вы узнали много нового о PHP, MySQL и JSON. Сейчас мы возьмемся за

большое упражнение, которое поможет сложить все фрагменты вое-

дино, так что отдохните и выпейте чашку кофе, прогуляйтесь, сделайте

что-нибудь такое, чтобы ваш мозг отдохнул и был готов к тому, что его

ожидает. А когда все будет сделано, переверните страницу, и... вперед!

Р А СС Л А Б Ь Т Е С Ь

частоЗадаваемые

вопросы

Page 386: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

386 глава 9

длинное упражнение

Включите в файл my_scripts.js новую функцию getDBRacers, которая обращается

с вызовом к файлу service.php. Вызов должен возвращать объект JSON, а затем отобра-

жать сообщение с количеством возвращенных участников. Также измените таймер

startAJAXCalls, чтобы вместо функции getXMLRunners вызывалась эта новая

функция. Наконец, измените файл service.php, чтобы он возвращал данные участников,

прочитанные из базы данных и закодированные в формате JSON.

function startAJAXcalls(){

if(repeat){

setTimeout( function() {

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

startAJAXcalls();

},

FREQ

);

}

}

function getDBRacers(){

$.getJSON(.......... function(.....) {

.....(json.runners........);

});

getTimeAjax();

}

my_scripts.js

Длинные упражнения

Page 387: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 387

данные json

<?php

$query = "SELECT first_name, last_name, gender, finish_time FROM runners order by finish_time ASC ";

$result = ..................($query);

$runners = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

.............($runners, array('fname' => $row['first_name'], 'lname' => $row['last_name'], 'gender' => $row['gender'], 'time' => $row['finish_time']));

}

echo ............(array("runners" => ............));

exit;

function db_connection($query) {

mysql_connect('127.0.0.1', 'runner_db_user', 'runner_db_password')

OR die(fail('Could not connect to database.'));

mysql_select_db..................

return mysql_query($query);

}

function fail($message) {

die(json_encode(array('status' => 'fail', 'message' => $message)));

}

function success($message) {

die(json_encode(array('status' => 'success', 'message' => $message)));

}

?>

service.php

Page 388: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

388 глава 9

решение длинного упражнения

В файле my_scripts.js появилась новая функция getDBRacers, которая обраща-

ется с  вызовом к файлу service.php. Старая функция getXMLRunners стала лиш-

ней, ее можно удалить. Новая функция получает данные JSON, возвращенные

файлом service.php, и выводит количество полученных участников. Функция

startAJAXCalls также изменилась; теперь в ней вызывается новая функция.

Обновленный файл service.php возвращает участников, прочитанных из базы дан-

ных, закодированных в формат JSON и упорядоченных по возрастанию значений

finish_time.

function startAJAXcalls(){

if(repeat){

setTimeout( function() {

getDBRacers(); startAJAXcalls();

},

FREQ

);

}

}

function getDBRacers(){

$.getJSON("service.php", function(json) { alert(json.runners.length); });

getTimeAjax();

}

my_scripts.js

Планирование вызова новой функции

Метод jQuery getJSONобращаетсяс вызовом к файлу service.php.

Объект json содер-жит массив с именем runners, полученным при вызове метода json_encode в PHP.

Как и другие массивы, этот также имеет свойство length.

Данные, получен-ные в результате вызова getJSON

Решение длинных упражнений

Page 389: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 389

данные json

<?php

$query = "SELECT first_name, last_name, gender, finish_time FROM runners order by finish_time ASC ";

$result = db_connection($query);

$runners = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

array_push.($runners, array('fname' => $row['first_name'], 'lname' => $row['last_name'], 'gender' => $row['gender'], 'time' => $row['finish_time']));

}

echo json_encode(array("runners" => $runners)); exit;

function db_connection($query) {

mysql_connect('127.0.0.1', 'runner_db_user', 'runner_db_password')

OR die(fail('Could not connect to database.'));

mysql_select_db ('hfjq_race_info');.

return mysql_query($query);

}

function fail($message) {

die(json_encode(array('status' => 'fail', 'message' => $message)));

}

function success($message) {

die(json_encode(array('status' => 'success', 'message' => $message)));

}

?>

service.php

Запрос к базе данных для получения информации об участниках

Создаем новый массив для хранения полученных данных.

Перебираем итоговый набор, получаем ассо-циативные массивы.

Полученные данные поме-щаются в ассоциативный

массив.

Ассоциативный массив ко-дируется в JSON и записы-вается в источник вызова.

Функция для взаи-модействия с базой данных

Итоговый набор возвра-

щается стороне, вы-звавшей эту функцию.Функции обработки ошибки или успеш-ного завершения в наших сценариях

Page 390: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

390 глава 9

тест-драйв

Включите новый код в файлы service.php и my_scripts.js, откройте файл index.html в браузере. Откройте вкладку «Network» в средствах разработчика; убедитесь в том, что информация JSON загружается успешно.

Хорошо. И теперь для выво-да информации мы исполь-

зуем find и each, как при работе с XML?

Не совсем.

Мы знаем, что данные хранятся в формате JSON, потому что они были созданы в на-шем коде PHP. Пора (наконец-то) плотно заняться объектом JSON, о котором мы так много говорили, и вывести из него получен-ные данные.

Функция вы-дает количе-ство записей, возвращенных в объекте JSON.

В разделе «Network» средств разработ-чика информация JSON выводится на соответствующей вкладке.

Тест-драйв

Page 391: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 391

данные json

function getDBRacers(){

$.getJSON( , function(json) {

if (json.runners. > 0) {

$('#finishers_m').empty();

$('#finishers_f').empty();

$('#finishers_all').empty();

$. (json.runners,function() {

var info = '<li>Name: ' + this['fname'] + ' ' + this['lname'] + '. Time: ' + this[ ] + '</li>';

if(this['gender'] == 'm'){

$(' ').append( info );

}else if(this['gender'] == 'f'){

$('#finishers_f').append( );

}else{}

$(' ').append( info );

});

}

});

getTimeAjax();

}

Ðàáîòà ñ äàííûìè â îáúåêòå JSON

Функция PHP json_encode преобразует ассоциативный массив в строку значений, закоди-рованную в формате JSON. Далее с этими данными можно работать в коде JavaScript как с ассоциативными массивами; таким образом, мы можем перебрать их и обработать так же, как мы обрабатываем данные в других массивах.

При работе с XML нам приходилось перебирать данные для поиска следующего участника. Таким образом, после обнаружения участника нам приходилось проводить повторный поиск для проверки пола. Помните объект JSON, который возвращается функцией json_encode? Мы можем напрямую обращаться к свойствам этого объекта при помощи точечного синтак-сиса (.). Массив runners содержится в этом объекте в виде свойства. А получив доступ к мас-сиву, мы можем по ключу ассоциативного массива определить пол участника, что намного эффективнее повторного поиска.

Измените функцию getDBRunners так, чтобы она получала объект JSON от файла service.php.

Выбирайте список, в который нужно занести участника, используя условную конструкцию.

Будьте внимательны! Проверьте, содержит ли объект JSON данные хотя бы одного участника.

my_scripts.js

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

Page 392: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

392 глава 9

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

Используя условную конструкцию и информацию, полученную в  объекте

JSON, можно определить, в какой список следует включить участника. Как и

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

Для перебора всех элементов массива, возвращенного в объекте JSON, можно

воспользоваться методом each. Этот метод несколько отличается от метода

(селектор).each тем, что он позволяет перебирать содержимое массивов,

не относящихся к jQuery, таких как наш массив runners.

function getDBRacers(){

$.getJSON("service.php", function(json) {

if (json.runners.length> 0) { $('#finishers_m').empty();

$('#finishers_f').empty();

$('#finishers_all').empty();

$.each(json.runners,function() { var info = '<li>Name: ' + this['fname'] + ' ' + this['lname'] + '. Time: ' + this[‘time’] + '</li>'; if(this['gender'] == 'm'){

$('#finishers_m').append( info );

}else if(this['gender'] == 'f'){

$('#finishers_f').append(info); }else{}

$('finishers_all').append( info ); });

}

});

getTimeAjax();

}

my_scripts.js

Получаем информацию от файла service.php.

Проверяем, имеются ли данные в массиве runners.

Очищаем все списки.

Проверяем свойство

gender текущего

объекта (m или f).

Включаем участника в список all_runners.

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

Для любознательных

Page 393: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 393

данные json

Измените функцию getDBRacers в файле my_scripts.js. Откройте файл index.html и убедитесь в том, что данные участников успешно загружаются из базы данных MySQL с использованием Ajax, JSON и PHP.

Информация об участ-никах, про-читанная из базы данных

Очень хорошо, мы можем получать данные, но ведь на самом деле нужно,

чтобы этот способ работал с созданной нами формой. Верно?

Очень верное замечание.

А когда это будет сделано — добро пожаловать на Гавайи! Но сначала нужно убедиться в том, что вводимые дан-ные не причинят вреда нашему приложению.

Тест-драйв

Page 394: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

394 глава 9

данные должны быть чистыми

Èñïîëüçîâàíèå îäíîãî ôàéëà PHP äëÿ ðàçíûõ öåëåé

Мы рассмотрели два способа отправки данных серверу для обработки файлом PHP: POST и GET. При помощи условной конструкции можно определить, какой метод использовался при вызове файла PHP, и выполнить соответствующие действия. Помните скрытое поле, которое мы добавили на форму несколько страниц назад?

Ïðîâåðêà è ÷èñòêà äàííûõ â PHP

В последнее время развелось слишком много спам-ботов и хакеров, пытающихся взять под контроль ваши данные для неблаговидных целей. Никогда не доверяйте данным, введенным на веб-формах! Всегда выполняйте проверку и чистку информации, передаваемой серверу, перед вставкой в базу дан-ных. Эти операции гарантируют, что тип данных соответствует типу конкретного поля (проверка), а полученные данные не содержат информации, опасной для вашего сервера или базы данных (чист-ка). Подобные меры помогают защититься от внедрения SQL, межсайтовых сценарных атак и многих других неприятностей, о которых можно узнать в Интернете. Мы воспользуемся методами PHP, кото-рые предотвратят возможные проблемы и гарантируют, что используемые данные будут корректны.

<?php

htmlspecialchars($_POST["a"]) ; // Замена символов безопасными комбинациями

empty($_POST["b"]) ; // Метод "empty" проверяет пустые значения

preg_match('',$var); //"Регулярное выражение". $var проверяется на соответствие шаблону.

?>

Преобразует некоторые специальные символы

HTML в формат, безопасный для баз данных

Функция проверки по регулярному выражению.

Шаблоны регулярных выражений могут быть

предельно точными, что позволяет жестко

контролировать вводимые данные.

Выявление пу-стых строк

Существует много других функций, используемых для чистки данных: htmlentities, trim, stripslashes, mysql_real_escape_string и многие другие. За более подробной информацией обращайтесь к главе 6 книги «Изучаем PHP & MySQL».

<input type="hidden" name="action" value="addRunner" id="action">

Если это значение присутствует, значит выполняется отправка данных формы методом POST. В этом случае нужно выполнить функции проверки и чистки данных и убедиться, что получены все необходимые данные. Если обновить функцию getJSON для чтения участников из базы данных с параметром из URL-адреса (для объекта $_GET PHP), можно отделить и выполнить только этот фрагмент кода в файле PHP. Значит, нам придется сопровождать только один файл PHP.

$.getJSON("service.php?action=getRunners", function(json) {

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

Все прибирают на своих столах и едут в аэропорт! Мы теперь знаем, как

доделать форму, верно?

Page 395: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 395

данные json

Внесите в файл service.php изменения. Файл будет обрабатывать оба вида запросов, GET и POST. Включите в него функции db_connection, success и fail, которые мы создали ранее.

<?php

if ($_POST['action'] == 'addRunner') {

$fname = htmlspecialchars($_POST['txtFirstName']);

$lname = htmlspecialchars($_POST['txtLastName']);

$gender = htmlspecialchars($_POST['ddlGender']);

$minutes = htmlspecialchars($_POST['txtMinutes']);

$seconds = htmlspecialchars($_POST['txtSeconds']);

if(preg_match('/[^\w\s]/i', $fname) || preg_match('/[^\w\s]/i', $lname)) {

fail('Invalid name provided.');

}

if( empty($fname) || empty($lname) ) {

fail('Please enter a first and last name.');

}

if( empty($gender) ) {

fail('Please select a gender.');

}

$time = $minutes.":".$seconds;

$query = "INSERT INTO runners SET first_name='$fname', last_name='$lname', gender='$gender', finish_time='$time'";

$result = db_connection($query);

if ($result) {

$msg = "Runner: ".$fname." ".$lname." added successfully" ;

success($msg);

} else { fail('Insert failed.');} exit;

}elseif($_GET['action'] == 'getRunners'){

$query = "SELECT first_name, last_name, gender, finish_time FROM runners order by finish_time ASC ';

$result = db_connection($query);

$runners = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

array_push($runners, array('fname' => $row['first_name'], 'lname' => $row['last_name'], 'gender' => $row['gender'], 'time' => $row['finish_time']));

}

echo json_encode(array("runners" => $runners));

exit;

}

service.php

Проверяем, было ли отправлено

на сервер значение addRunner

(из скрытого поля).

Чистка данных в массиве $_POST

Проверка данных подтверж-

дает, что поля формы были

заполнены.

Если проверка не прошла, вызывается функция fail.

Приказываем базе данных

вставить новую запись… …и проверить, успешно была выполнена опе-рация или нет.

Проверяем, было ли отправлено в строке URL-адреса значение getRunners.

Получаем и воз-вращаем данные участников.

Готово к употреблению

Page 396: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

396 глава 9

Тест-драйв

гавайи ждут...

function getDBRacers(){

$.getJSON("service.php?action=getRunners", function(json) {

if (json.runners.length > 0) {

$('#finishers_m').empty();

.

.

}

});

getTimeAjax();

}

Потрясающе! Садимся на самолет,

а остальное добьем уже на пляже...

Задание!

Обновите вызов getJSON, чтобы в нем передавался параметр URL-адреса action со значением getRunners. По этому параметру файл service.php узнает, что он должен вернуть данные участников.

Обновите файлы service.php и my_scripts.js, откройте файл index.html в браузере. Убедитесь в том, что данные участников были загружены успешно. Вы также можете ввести данные новых участников в форме на новой вкладке.

my_scripts.js

Page 397: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 397

данные json

Âàø èíñòðóìåíòàðèé jQuery/Ajax/PHP/MySQL

Глава 9 осталась позади. Вы освоили азы работы с PHP, MySQL и JSON, а также расширили свои познания в Ajax.

MySQLПозволяет

хранить информацию

в базах данных и таблицах, с вы

-

полнением операций чтения и за-

писи информации на языке SQL.

SQLЯзык запросов для

взаимодействия

с приложениями баз данных (таки-

ми как MySQL).

PHPСерверный язык сценариев для обработки содержимого веб-страницы до ее передачи клиент-скому браузеру.Сценарий PHPТекстовый файл с кодом PHP

для выполнения операций на веб-сервере.

с пр

ми как MySQL).

JSONФункция getJSON используется для

получения от сервера данных, за-

кодированных в формате JSON.

Для отправки данных формой ис-

пользуется метод POST. Перед

отправкой данные необходимо

отформатировать функцией

serializeArray.

<?php ?>Теги, в которые должен быть заключен весь код PHP в ваших сценариях PHP.echoКоманда PHP для отправки выходных данных в окно браузера. Синтаксис:echo ‘Hello World’;World ;

$_POSTСпециальная переменная для хра-нения данных формы. json_encode

Команда преобразует массив в данные, закодированные в фор-мате JSON (необходимо по прави-лам jQuery).

ГЛА

ВА 9

Page 398: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 399: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

jQuery UI10

Переработка форм

Пользователи и их данные — жизнь и смерть веб-приложений. Ввод данных пользователем — серьезная задача, которая может отнять много времени у веб-разработчика. Вы уже видели, как jQuery упрощает построение веб-приложений, использующих Ajax, PHP и MySQL. Теперь давайте посмотрим, как jQuery упрощает построение пользовательского интерфейса форм для ввода данных пользователем. Заодно вы узнаете много полезного о jQuery UI — официальной библиотеке пользовательского интерфейса для jQuery.

Мне нравится твоя форма. Может,

зайдем ко мне, побол-таем об интерфейсах?

Ух... Надеюсь, моя форма пройдет

проверку.

Page 400: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

400 глава 10

кто видел снежного человека?

Доктор Паттерсби и доктор Гимли стремятся собрать как можно больше информации о встречах с крип-тидами по всему миру. Их сайт cryptozoologists.org пользуется уважением как у профессиональных крип-тозоологов, так и у любителей. У них есть для вас особо важное поручение: обновление устаревшей формы для ввода информации о встречах с криптидами.

Криптиды — существа, неизвест-ные науке или не признаваемые

научным сообществом. Сбор данных о встречах с ними играет важней-шую роль в наших исследованиях.

Знаменитые криптиды — снежный человек, чупакабра и лохнесское чудовище. Нам

нужна более совершенная форма для ввода информации о том, где люди видели этих

существ.

Cryptozoologists.org íóæäàåòñÿ â ïåðåðàáîòêå

Немедленно уберите репортеров!

Доктор Гимли

Доктор Паттерсби

??

??Криптозоологи хотят избавиться от своей старой, неудобной формы HTML.

400 гглава 10

Сообщение о наблюдении криптида

Пожалуйста, введите подробное описание своей встречи с крип-

тидом под своими контактными данными.

Заполните форму и щелкните на кнопке "Enter"

для отправки данных.

Дата наблюдения:

Где вы видели существо:

Тип существа:

Описание существа:

ReptileMammal

Bird

Внешний вид и поведение

формы не внушает эн-

тузиазма. Она сделана на

уровне конца 1990-х годов.

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

Page 401: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 401

jquery ui

Íîâàÿ ôîðìà HTML

Сообщение о наблюдении криптидов

ИНФОРМАЦИЯ О ВСТРЕЧЕ С КРИПТИДОМ

Дата наблюдения:

Тип: Дистанция (в футах): Вес:Рост:Окрас кожи/меха:

Данные о месте встречи

Широта:Долгота:

Дополнительная информация:

Месяц

В действующей форме используется

текстовое поле, что повышает риск

некорректного ввода. Мы хотим,

чтобы пользователь выбирал дату

в календаре, чтобы информация была

по возможности точной.

Нам хочется,

чтобы пользо-

ватели вводили

значения, двигая

ползунок. Пользо-

вателям удобно,

а мы получаем

точную инфор-

мацию.

Можно ли улучшить внешний вид

кнопки? «Угловатость» выглядит

несовременно.

Как насчет системы сме-шения цветов?

RGB

В существующей форме данные вводятсяпри помощи кнопок-переключателей;можно ли использовать что-нибудьпосимпатичнее?

Млекопитающее

Enter

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

Криптозоологи поставили перед нами непростую задачу. Фактически они хотят построить такой же пользовательский интерфейс, как в настольном приложении. Как вы думаете, jQuery поможет ее решить?

Мозговой

штурм

Page 402: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

402 глава 10

разговор в офисе

ДжимФрэнк Джо

Фрэнк: Я видел. Сейчас они используют форму HTML, но воз-можностей HTML и CSS недостаточно для новой формы, ко-торую они от нас требуют.

Джим: И не говори. Когда-нибудь пытались применять к эле-ментам форм стили CSS? Визит к стоматологу и то приятнее.

Фрэнк: Да уж, а насчет jQuery... Я пока не видел в jQuery ни-чего, что помогло бы нам строить такие компоненты интер-фейса.

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

Фрэнк: Вероятно, для их реализации нам придется использо-вать комбинацию JavaScript, jQuery и CSS.

Джим: Сколько логики придется написать... Только для вре-менного окна календаря потребуется множество строк кода и сложные стили CSS.

Джо: Хм... Для таких задач должен существовать какой-нибудь модуль расширения jQuery.

Джим: Точно, модули расширения! Мы уже использовали та-кой модуль пару глав назад для создания вкладок на странице результатов гонки. Значит, вкладки — это еще не все?

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

Джим: Так может, какой-нибудь разработчик или группа раз-работчиков уже занимались этой задачей?

Фрэнк: Это существенно упростило бы нам жизнь.

Джо: Давайте пороемся на jQuery.com и посмотрим, что нам удастся найти.

Парни, вы уже видели эскиз формы для криптозоологов?

Page 403: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 403

jquery ui

А как было бы замечательно, если бы существовала библиотека модулей расширения jQuery для пользовательского интерфейса...

Но это, конечно, всего лишь мечты…

Page 404: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

404 глава 10

знакомство с jquery ui

jQuery UI ýêîíîìèò âðåìÿ è ñèëû

К счастью для всех разработчиков, в jQuery имеется официальная библиотека модулей расширения пользовательского интерфейса для подобных проектов. Эта библиотека называется jQuery UI, и в нее входят три основных типа модулей расширения базовой функциональности jQuery: эффекты, взаимо-действия и виджеты.

ÂèäæåòûÂçàèìîäåéñòâèÿÝôôåêòû

jQuery UI дополняет jQuery многими новыми эффекта-ми. Заставьте свои элемен-ты прыгать, взрываться, пульсировать или трястись! В jQuery UI также включены функции плавности — слож-ные математические опера-ции, которые делают ани-мацию более реалистичной.

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

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

Опробуйте некоторые эффекты, взаимодействия и виджеты jQuery UI. Посетите следующие URL-адреса и выполните инструкции.

URL Инструкции

http://jqueryui.com/demos/animate/#default Щелкните на кнопке Toggle Effect.

http://jqueryui.com/demos/effect/default.html Выберите эффект из раскрывающегося списка, щелкните на

кнопке Run Effect.

http://jqueryui.com/demos/

draggable/#default

Нажмите кнопку мыши в прямоугольнике с надписью «Drag

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

в выделенной области экрана.

http://jqueryui.com/demos/accordion/#default Щелкая в разных секциях, проследите за тем, как они разво-

рачиваются и сворачиваются.

http://jqueryui.com/demos/dialog/#animated Щелкните на кнопке Open Dialog, чтобы открыть пользова-

тельское диалоговое окно jQuery UI. Намного лучше обыч-

ного, скучного окна сообщения JavаScript, не правда ли?

Механизм модулей расширения jQuery позво-

ляет веб-разработчикам расширять базовую

функциональность библиотеки jQuery.

В работе с пользова-тельским интерфейсом в этой главе наше вни-мание будет уделяться виджетам.

Тест-драйв

Page 405: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 405

jquery ui

Взаимодействие: у элемента появляют-ся маркеры перетаскивания, при помо-щи которых пользователь изменяет его размеры.

Виджет: отображение текущего состоя-ния (в процентах) некоторого процесса.

Взаимодействие: элемент DOM стано-вится приемником для перетаскивае-мых элементов.

Эффект: элемент увеличивается в раз-мерах и рассеивается, словно облачко дыма.

Взаимодействие: изменение порядка элементов посредством перетаскива-ния.

Виджет: создание набора сворачива-емых областей для организации веб-содержимого.

Виджет: вывод списка возможных зна-чений при заполнении поля пользова-телем.

Puff

Explode

Sor table

Progressbar

Droppable

Autocomplete

Blind

Accordion

Resizable Эффект: элемент распадается на части, которые разлетаются в разных направ-лениях.

Эффект: элемент скользит вверх или вниз, словно жалюзи.

Соедините каждый модуль расширения jQuery UI с описанием типа и дей-ствия. Подсказка: если у вас возникнут сомнения, поэкспериментируйте с демонстрационным сайтом Test Drive (см. предыдущую страницу).

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

Page 406: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

406 глава 10

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

Соедините каждый модуль расширения jQuery UI с описанием типа и действия.

Puff

Explode

Sor table

Progressbar

Droppable

Autocomplete

Blind

Accordion

Resizable

Взаимодействие: у элемента появляются маркеры перетаскивания, при помощи которых пользователь изменяет его раз-меры.

Виджет: отображение текущего состоя-ния (в процентах) некоторого процесса.

Взаимодействие: элемент DOM стано-вится приемником для перетаскиваемых элементов.

Эффект: элемент увеличивается в раз-мерах и рассеивается, словно облачко дыма.

Взаимодействие: изменение порядка эле-ментов посредством перетаскивания.

Виджет: создание набора сворачива-емых областей для организации веб-содержимого.

Виджет: вывод списка возможных значе-ний при заполнении поля пользователем.

Эффект: элемент распадается на части, которые разлетаются в разных направ-лениях.

Эффект: элемент скользит вверх или вниз, словно жалюзи.

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

Решение

Page 407: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 407

jquery ui

http://jqueryui.com/download

Задание!

Откройте в браузере страницу загрузки jQuery UI.1

Выберите загружаемые компоненты.2

Выберите тему для загрузки.3

Нам потребуются толь-ко базовые компоненты и виджеты; установите показанные флажки.

Одно из главных достоинств jQuery UI — темы оформления. Группа разработчиков jQuery UI включила весь код CSS для создания интерфейса профессионального уровня. Вы даже можете создать собственную тему оформления при помощи приложения jQuery UI «theme roller». Галерею всех тем jQuery UI можно просмотреть по URL-адресу http://jqueryui.com/themeroller/#themeGallery

Выберите тему Sunny.

Нажмите кнопку Download.4

Итак, я загрузил библио теку jQuery UI! Как

теперь начать с ней работать?

Распакуйте архив и включите библиотеку в папку проекта.На следующей странице описана структура jQuery UI.

Прежде чем сделать что-либо с jQuery UI, необходимо настроить нужные ком-поненты, выбрать тему и загрузить ее копию. Выполните следующие действия:

Page 408: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

408 глава 10

структура jquery ui

Ñîäåðæèìîå ïàêåòà jQuery UI

Ñïèñîê çàäà÷ ïðîåêòà

1. Создать календарь для выбора даты наблюдения.2. Создать более привлекательные кнопки-переключатели для выбора типа

существа.3. Создать ползунки для ввода расстояния, веса и роста существа, широты

и долготы места наблюдения.4. Создать компонент для выбора цвета существа.5. Создать более симпатичную кнопку отправки данных.

После загрузки и распаковки jQuery вы увидите, что пакет имеет следующую структуру:

index.htmldevelopment-bundle

jquery-ui-1.8.16.custom

jquery-1.6.2.min.js

jquery-ui-1.8.16.custom.css

jquery-ui-1.8.16.custom.min.js

images

Выбранная вами тема находится в папке css.

Чтобы виджеты jQuery UI выглядели нормально, в секции head формы sightings.html должна присутствовать ссылка на этот файл.

На момент напи-сания книги послед-няя версия jQuery UI имела номер 1.8.16.

В форму sightings.html необходимо включить секцию script со ссылкой на этот файл.

Разработчики UI позаботились о том, чтобы у вас была копия библио-теки jQuery.

Мы включили папку jQuery UI в архив кода, загруженный вами в начале книги. Вы найдете ее в папке end внутри папки ch10.

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

css

sunny

js

Page 409: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 409

jquery ui

Ïîñòðîåíèå êàëåíäàðÿ

<input type="text" name="sighting_date">

Возьмите обычное поле HTML input.3

Создайте тег <script> со ссылкой на jQuery UI.2

Включите в тег <input> атрибут id со значением "datepicker".4

Откройте файл в своем любимом браузере и щелкните на поле input.6

Создайте файл JavaScript и включите следующий фрагмент между фигурными скобками $(document).ready(function(){}.

5

<input type="text" name="sighting_date" id="datepicker">

<link type="text/css" href="jquery-ui-1.8.16.custom/css/sunny/jquery-ui-1.8.16.custom.css" rel="stylesheet" />

<script src="jquery-ui-1.8.16.custom/js/jquery-ui-1.8.16.custom.min.js"></script>

$('#datepicker').datepicker();

Создайте ссылку на CSS-файл jQuery UI:1

Вот и все! Вы

только что до-

бавили на форму

интерактивный

виджет.

Вы не поверите, как легко включаются виджеты jQuery UI в форму HTML. Начнем с календаря:

Page 410: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

410 глава 10

работаем эффективнее, а не больше

Здорово, все происходит само собой, а мне достаточно написать немного кода HTML и jQuery. Но я вынуждена использовать конкрет-ный вариант оформления и функций календаря?

А если я захочу что-нибудь другое?

Интер-претатор

JavaScript

Модель DOM- страницы

$("#datepicker").datepicker();

Как и любой другой код jQuery, написанный вами, datepicker использует селектор и метод.

1

Интерпретатор JavaScript запрашивает у DOM элемент с идентификатором datepicker.

2DOM получает выбранный элемент, выполняет для него элемент datepicker и возвращает интерпретатору.

3

Код jQuery

Засценой

Пожалуйста.

Дай мне элемент стра-ницы с идентификатором

datepicker.

Не беспокойтесь, у вас есть выбор.

Давайте посмотрим, что можно сделать.

Основные события происходят здесь, в методе datepicker.

Метод datepicker приказывает интерпретатору JS построить календарь «на ходу», вместе со всем кодом HTML, CSS и встроенной интерактивностью.

4

Виджет, так не-ожиданно появляю-щийся на странице, представляет со-бой таблицу, вло-женную в несколько областей div.

Íåçàìåòíîå âìåøàòåëüñòâî jQuery UI

На первый взгляд происходящее кажется каким-то волшебством, но в действительности jQuery UI представляет собой хорошо спроектированный и написанный блок кода, который не придется писать вам. Давайте разберемся в том, как он работает.

Page 411: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 411

jquery ui

$("#datepicker").datepicker({ stepMonths: 3});

$("#datepicker").datepicker({ changeMonth: true});

Èçìåíåíèå ïàðàìåòðîâ âèäæåòà

Кнопка для перехода к следующему месяцу. При каждом щелчке гене-рируется новая таблица для соответствующего месяца.

Кнопка для пере-

хода к предыду-

щему месяцу

Текущая дата выделяется другим цветом.

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

Íàñòðîéêà âèäæåòà datepicker

w

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

Виджет datepicker со-держит множество настраиваемых па-раметров. Параметр stepMonths определяет расстояние перехода в месяцах.

Так как библиотека jQuery UI построена на базе jQuery, вам не придется писать большой объем кода, чтобы приспособить виджет datepicker к вашим потребностям. На момент на-писания книги виджет datepicker поддерживал 46 разных настраиваемых параметров.

Если задать параметру

changeMonth значение true,

то пользователь сможет

выбрать месяц в раскрываю-

щемся списке.

Напишите фрагмент кода, который позволит пользователю виджета datepicker выбрать и год, и месяц в раскрывающемся списке. Подсказка: если вы задае-те значения нескольких параметров, разделите их запятыми.

Упражнение

Page 412: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

412 глава 10

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

Напишите фрагмент кода, который позволит пользователю виджета datepicker вы-брать и год, и месяц в раскрывающемся списке. Подсказка: если вы задаете значения нескольких параметров, разделите их запятыми.

$(‘#datepicker’).datepicker({ changeMonth: true, changeYear: true});

Найдите файл sightings_begin.html в папке begin внутри папки ch10. Сохраните его под именем sightings_end.html в папке end главы 10. Включите код, выделенный ниже жирным шрифтом, в файлы sightings_end.html и my_scripts.js.

<head> <title>Submit Your Cryptid Sighting</title> <link rel="stylesheet" type="text/css" href="style/form.css" /> <link type="text/css" href="jquery-ui-1.8.16.custom/css/sunny/jquery-ui-1.8.16.custom.css" rel="stylesheet" /></head>

<h3>Date of Sighting:</h3> <input type="text" name="sighting_date" id="datepicker" />

В начале файла sightings_end.html

$(document).ready(function(){

$('#datepicker').datepicker({ changeMonth: true, changeYear: true});

});//end doc ready

my_scripts.js

<script src="scripts/jquery-1.6.2.min.js"></script> <script src="scripts/my_scripts.js"></script> <script src="jquery-ui-1.8.16.custom/js/jquery-ui-1.8.16.custom.min.js"></script> </body></html> Ближе к концу файла

sightings_end.htmlВключаем библиотеку jQuery UI,

чтобы пользоваться ее классными

возможностями пользовательского

интерфейса.

Чтобы виджеты выглядели так, как положено, необхо-димо подключить CSS-файл jQuery UI.

Код datepicker

sightings_end.html

Готово к употреблению

Page 413: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 413

jquery ui

1. Создать календарь для выбора даты наблюдения.

2. Создать более привлекательные кнопки-переключатели для выбора типа существа.

3. Создать ползунки для ввода расстояния, веса и роста существа, широты и долготы места наблюдения.

4. Создать компонент для выбора цвета существа.

5. Создать более симпатичную кнопку отправки данных.

Введите код с предыдущей страницы, откройте файл sightings_end.html в своем люби-мом браузере и протестируйте виджет. Пощелкайте на кнопках «вперед» и «назад», откройте списки месяца и года и убедитесь в том, что все работает нормально.

Êàëåíäàðü ðàáîòàåò!

Виджет datepicker работает именно так, как требуется.

Опции changeMonth Опции changeMonth и changeYear тоже и changeYear тоже работают.работают.

Âû÷åðêèâàåì...

Пункт 1 выполнен, переходим к пункту 2.

Тест-драйв

Page 414: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

414 глава 10

кнопка, на которой хочется щелкнуть

Ñòèëüíûå êíîïêè

$( "#radio" ).buttonset();

<div id="radio">

<input type="radio" id="radio1" name="radio" />

<label for="radio1">Choice 1</label>

<input type="radio" id="radio2" name="radio" />

<label for="radio2">Choice 2</label>

<input type="radio" id="radio3" name="radio" />

<label for="radio3">Choice 3</label>

</div>

Размещаем кнопки-пере-ключатели внутри кон-тейнерного элемента.

Ãðóïïèðîâêà âèäæåòîâ button

Метод buttonset автоматически

группирует кнопки и вызывает метод

button для каждого элемента.

Метод button преобразует классическую кнопку-переклю-чатель HTML в эффектную, более интерактивную кнопку.

<input type="radio" id="radio1" name="radio" />

<label for="radio1">Choice 1</label>

Виджет button при помощи стилевого оформления придает элементу label вид кнопки.

Этот элемент будет обнов-лен при щелчке пользователя.

$( "#radio1" ).button();

В коде jQuery выбираем контейнерный элемент.

Для построения групп кнопок в jQuery UI существует ме-тод buttonset, который преобразует отдельные элементы в группу по ссылке на контейнерный элемент группы.

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

Код HTML одной кнопки-переключателя

И соответствующая команда jQuery

Что значит «более привлекательные» применительно к кнопкам? В основном это вопрос стиля: если кнопка будет хорошо смотреться, пользователю захочется щелкнуть на ней. В библиотеку jQuery UI входит чрезвычайно полезный виджет button. Его метод button помогает создавать более привлекательные элементы форм — кнопки отправки данных, переключатели и флажки.

Page 415: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 415

jquery ui

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

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

Развлечения с магнитами

my_scripts.js

<input type="radio" id="radio1" name="creature_type" />

<div id="type_select">

sightings_end.html

$( "#type_select" ).buttonset();

<label for="radio1">Chupacabras</label>

</div><input type="radio" id="radio2" name="creature_type" />

<label for="radio2">Jersey Devil</label>

<input type="radio" id="radio3" name="creature_type" />

<label for="radio3">Loch Ness Monster</label>

<i t

<input type="radio" id="radio4" name="creature_type" />

<label for="radio4">Sasquatch</label>

Page 416: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

416 глава 10

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

Мы создали набор кнопок-переключателей, соответствующих

общей теме формы.

Развлечения с магнитами. Решение

$( "#type_select" ).buttonset();

my_scripts.js

<input type="radio" id="radio1" name="creature_type" />

<label for="radio1">Chupacabras</label>

</div>

<div id="type_select">

sightings_end.html

<input type="radio" id="radio2" name="creature_type" />

<label for="radio2">Jersey Devil</label>

<input type="radio" id="radio3" name="creature_type" />

<label for="radio3">Loch Ness Monster</label>

<input type="radio" id="radio4" name="creature_type" />

<label for="radio4">Sasquatch</label>

В папке code мы доба-вили остальные кнопки (Yeti и Other). Здесь они не приведены из-за нехватки места.

Page 417: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 417

jquery ui

Берем обычные кнопки-переключатели HTML…

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

Включите приведенные строки кода в файлы sightings_end.html и my_scripts.js. Затем от-кройте страницу в любимом браузере и убедитесь в том, что она работает правильно.

1. Создать календарь для выбора даты наблюдения.

2. Создать более привлекательные кнопки-переключатели для выбора типа существа.

3. Создать ползунки для ввода расстояния, веса и роста существа, широты и долготы места наблюдения.

4. Создать компонент для выбора цвета существа.

5. Создать более симпатичную кнопку отправки данных.

Как видите, ничего сложного. Что там следующее в списке?

Тест-драйв

Page 418: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

418 глава 10

ограничение вводимых данных

Îãðàíè÷åíèå ââîäà ÷èñëîâûõ äàííûõ

Расширения jQuery UI позволяют использовать для ввода данных ползунки, которыми пользователь управляет при помощи мыши или клавиатуры. Эти элементы также помогают контролировать диа-пазон вводимых чисел. Как вы уже видели, при наличии библиотеки jQuery UI построить виджет для работы с календарем проще простого. С ползунком (виджет slider) дело обстоит ничуть не сложнее.

$("#slide_me"). slider();<div id="slide_me"></div>

$( "#slide_me" ).slider({

value:0,

min: 0,

max: 100,

step: 5,

orientation: 'vertical'

});

Пользователь перемещает ползунок

при помощи указателя мыши или кла-

виш управления курсором.

Ползунки также поддерживают многочисленные возможности настройки. Предпо-ложим, пользователь должен ввести набор чисел. Наименьшее допустимое значение равно 0, а наибольшее 100. Кроме того, пользователи должны вводить числа с прира-щением 5. Соответствующие значения параметров виджета slider выглядят так:

При перемещении рукоятки по шкале

изменяется текущее значение элемента.

Параметр value задает начальное значение пол-зунка.

Параметр min задает наимень-шее значение, которое может быть введено пользователем.

Параметр max задает наибольшее значение, которое может быть введено пользователем.Параметр step задает величину приращения.

Параметр orientation определяет ориентацию виджета (горизонталь-ная или вертикальная).

Создание ползунка в файле HTML

Сопутствующий код jQuery

Page 419: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 419

jquery ui

<input type="text" id="my_value" readonly="readonly"/>

<div id="slide_me"></div>

$( "#slide_me" ).slider({

slide: function( event, ui ) {

$( "#my_value" ).val( ui.value);

}

});

$( "#my_value" ).val( $( "#slide_me" ).slider( "value" ));

Нужно связать ползунок с одним из обработчиков событий вид-жета slider.Мы уже видели, как задаются параметры виджета, но не рассматривали другую, полезную возможность jQuery UI. Многие компоненты jQuery поддерживают об-работчики событий, ползунок не является исключением. На момент написания книги виджет slider из библиотеки jQuery UI поддерживал пять обработчиков со-бытий: create, start, slide, change и stop. Чтобы связать ползунок с полем ввода формы, воспользуемся обработчиком события slide.

У виджета slider есть немало по-лезных параметров, но как перене-

сти значение, введенное ползунком, в поле ввода формы?

Ñöåíàðíûé êîä jQuery äëÿ âèäæåòà slider

Ðàçìåòêà HTML äëÿ âèäæåòà slider

Это обработчик события slide. Событие slide инициируется при перемеще-нии ползунка.

Событие slide свя-зывается с функ-цией обратного вызова. При выпол-нении эта функция задает значение поля ввода мето-дом jQuery val.

Когда пользователь двигает ползунок, вызывается функ-ция, а элемент input обнов-ляется текущим значением ползунка.

The input "my_value"

The slider "slide_me"

Чтобы запретить пользователю

вводить числа, используйте значение

«readonly».

Page 420: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

420 глава 10

длинное упражнение

Заполните пропуски в коде полей input. Криптозоологи оставили замечания по поводу настройки ползунков.

Расстояние от существа (в футах):

Начальное значение = 0.

Минимальное расстояние = 0.

Максимальное расстояние = 500.

Приращение = 10 футов.

my_scripts.js

$( "#slide_dist" ).slider({

slide: function( event, ui ) {

$( "#distance" )

}

});

<h3>Distance from Creature (in ft.):</h3>

<input type="text" id=" " class="just_display" name="creature_distance" readonly="readonly"/>

<div id=" "></div>

</div>

</div>

sightings_end.html

Длинные упражнения

Page 421: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 421

jquery ui

Вес существа (в фунтах):

Начальное значение = 0.

Минимальный вес = 0.

Максимальный вес = 5000.

Приращение = 5 фунтов.

my_scripts.js my_scripts.js

$( " " ).slider({

slide: function( event, ui ) {

$( " " ).val( ui.value);

}

});

$( "#slide_weight" ).slider({

$( "#weight" ).val( ui.value);

}

});

sightings_end.html

<h3>Creature Weight (in lbs.):</h3>

<input type="text" id="weight" class="just_display" name="creature_weight" readonly="readonly"/>

<div id=" "></div>

<h3>Creature Height (in ft.):</h3>

<input type="text" id="height" class="just_display" name="creature_height" readonly="readonly"/>

<div id="slide_height"></div>

Рост существа (в футах):

Начальное значение = 0.

Минимальное значение = 0.

Максимальное значение= 20.

Приращение = 1 фут.

Page 422: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

422 глава 10

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

Заполните пропуски в коде полей input. Криптозоологи оставили свои замечания по поводу настройки ползунков.

Расстояние от существа (в футах):

Начальное значение = 0.

Минимальное расстояние = 0.

Максимальное расстояние = 500.

Приращение = 10 футов.

my_scripts.js

$( "#slide_dist" ).slider({

slide: function( event, ui ) {

$( "#distance" )

}

});

<h3>Distance from Creature (in ft.):</h3>

<input type="text" id=" " class="just_display" name="creature_distance" readonly="readonly"/>

<div id=" "></div>

</div>

</div>

sightings_end.html

value:0,

step: 10,

.val( ui.value);

max:500,min:0,

distance

slide_dist

Решение длинных упражнений

Page 423: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 423

jquery ui

Вес существа (в фунтах):

Начальное значение = 0.

Минимальный вес = 0.

Максимальный вес = 5000.

Приращение = 5 фунтов.

my_scripts.js my_scripts.js

$( " " ).slider({

slide: function( event, ui ) {

$( " " ).val( ui.value);

}

});

$( "#slide_weight" ).slider({

$( "#weight" ).val( ui.value);

}

});

sightings_end.html

<h3>Creature Weight (in lbs.):</h3>

<input type="text" id="weight" class="just_display" name="creature_weight" readonly="readonly"/>

<div id=" "></div>

<h3>Creature Height (in ft.):</h3>

<input type="text" id="height" class="just_display" name="creature_height" readonly="readonly"/>

<div id="slide_height"></div>

Рост существа (в футах):

Начальное значение = 0.

Минимальное значение = 0.

Максимальное значение= 20.

Приращение = 1 фут.

slide_weight

#slide_heightvalue:0,min:0,

value:0,

step: 1,max:20,

min:0,

slide: function( event, ui ) {#height

step: 10,max:5000,

Page 424: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

424 глава 10

тест-драйв

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

Теперь пользовате-ли могут вводить данные, перемещая рукоятки ползун-ков, а криптозоо-логи могут лучше контролировать вводимые данные.

Осталось построить еще два числовых ползунка: для ввода широты и долготы... И мы сможем вычеркнуть еще один пункт в списке задач!

Тест-драйв

Page 425: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 425

jquery ui

Но широта и долгота могут прини-мать отрицательные и дробные значения (например, 0.00001). Работает ли виджет

slider с такими числами?

Заполните пропуски в коде jQuery, чтобы создать на форме ползунки для ввода ши-

роты и долготы. Ползунок широты должен работать в диапазоне от –90 до 90 с  при-

ращением 0.00001. Ползунок долготы должен работать в диапазоне от –180 до  180

с приращением 0.00001.

value:0, slide: function( event, ui ) { $( " " ).val( ui.value); } });

value:0, slide: function( event, ui ) { $( " " ).val( ui.value); } });

my_scripts.js

Создатели jQuery UI подумали и об этом.Виджет slider может работать как с отрицательными, так и с дробными числами. Отрицательные числа могут указываться в качестве текущего, максимального и минимального значения. Попробуйте и посмотрите, как это выглядит в действии.

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

Page 426: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

426 глава 10

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

Заполните пропуски в коде jQuery, чтобы создать на форме ползунки для ввода широты и дол-

готы. Ползунок широты должен работать в диапазоне от –90 до 90 с приращением 0,00001.

Ползунок долготы должен работать в диапазоне от –180 до 180 с приращением 0,00001.

value:0, slide: function( event, ui ) { $( " " ).val( ui.value); } });

value:0, slide: function( event, ui ) { $( " " ).val( ui.value); } });

my_scripts.js

$( "#slide_lat" ).slider({

min: -90,max: 90,step: 0.00001,

latitude

longitude

step: 0.00001,

min: -180,max: 180,

$( "#slide_long" ).slider({

Что дальше? Нужно создать интерфейс для ввода цвета существа. Компонент определения цвета будет состоять из ползунков, соответствующих трем цветовым составляющим (красная, зеленая и синяя).

К настоящему моменту мы вычеркнули уже несколько пунктов списка задач.

1. Создать календарь для выбора даты наблюдения.

2. Создать более привлекательные кнопки-переключатели для выбора типа существа.

3. Создать ползунки для ввода расстояния, веса и роста существа, широты и долготы места наблюдения.

4. Создать компонент для выбора цвета существа.

5. Создать более симпатичную кнопку отправки данных.

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

Page 427: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 427

jquery ui

Ñîçäàíèå öâåòà ïî òðåì ñîñòàâëÿþùèì

Ïîëçóíêè äîëæíû ðàáîòàòü ïî òîìó æå ïðèíöèïó

Значения интенсивности красного, зеленого и синего лежат в диапазоне от 0 до 255. Когда все три интенсивности находятся на минимуме (то есть равны 0), получается черный цвет. При максимальных значениях цветовых составляющих (все три состав-ляющие равны 255) получается белый цвет.

Когда красная, зеленая и синяя со-ставляющие равны 0, получается черный цвет.

Когда красная составляющая равна 255 (а зеленая и синяя равны 0), получается красный цвет.

Когда зеленая составляющая рав-на 255 (а красная и синяя равны 0), получается зеленый цвет.

Когда синяя составляющая равна 255 (а красная и зеленая равны 0), получается синий цвет.

Итак, мы должны построить три ползунка для трех цветовых составляющих: красной, зеленой и синей. Затем текущие значения всех ползунков объединяются в один цвет. Давайте посмот-рим, что должен делать каждый из трех виджетов slider.

Когда красная, зеленая и синяя составляющие равны 255, полу-чается белый цвет.

Цвет элемента div#swatch определяется комбинацией значений трех ползунков.

Образец цвета должен изменять-

ся каждый раз, когда пользователь

перемещает один из ползунков.

Значения ползунков лежат в диапазоне 0–255.

Полям input присваиваются иден-тификаторы CSS red_val, green_val и blue_val.Цвет

#red

#green

#blue

#swatch

RGB

RG

B

RGB

RGB

RGB

RGB

Page 428: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

428 глава 10

готовый код

//color slider styles #slide_dist, #slide_weight, #slide_height {

margin-bottom:14px;

}

#swatch { width: 75px; height: 75px; background-image: none; } #red .ui-slider-range { background: #ef2929; } #red .ui-slider-handle { border-color: #ef2929; }

#green .ui-slider-range { background: #8ae234; } #green .ui-slider-handle { border-color: #8ae234; }

#blue .ui-slider-range { background: #729fcf; } #blue .ui-slider-handle { border-color: #729fcf; }

<h3>Color of Creature (use the color sliders to enter):</h3>

Color (in hexadecimal):<input type="text" class="just_display" name="creature_color" id="color_val" readonly="readonly"/><br /><br /> <div id="swatch" class="ui-widget-content ui-corner-all"></div>

Red:<input type="text" class="just_display" name="creature_color" id="red_val" readonly="readonly"/> <div id="red"></div>

Green:<input type="text" class="just_display" name="creature_color" id="green_val" readonly="readonly"/> <div id="green"></div>

Blue:<input type="text" class="just_display" name="creature_color" id="blue_val" readonly="readonly"/> <div id="blue"></div>

Включите код, выделенный жирным шрифтом, в файлы sightings_end.html и form.css, чтобы подготовить их к по-строению компонента выбора цвета.

form.css

sightings_end.html

Эти стили ис-пользуют цвет ползунка в его оформлении.

Этот идентификатор стиля CSS определя-ет образец, в котором будет отображаться текущий цвет при перемещении ползунка.

Область div для красного ползунка

Область div для зеленого ползунка

Область div для синего ползунка

Область div для образца цвета

Поле input, которое будет содержать шестнадцате-ричное значение цвета

Готово к употреблению

Page 429: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 429

jquery ui

$( "#red, #green, #blue" ).slider({

orientation: "horizontal",

range: "min",

max: 255,

value: 127,

slide: refreshSwatch,

change: refreshSwatch

});

Диапазон: пользователь может указывать только максимум.

В: А что это за код CSS, прилагаемый к jQuery UI?

О: Одно из преимуществ jQuery UI в том, что разработчики уже написали много слож-ного кода CSS и вам не придется этим за-ниматься. Дополнительная информация об этом коде содержится в файле пакета jQuery UI jquery-ui-1.8.16.custom/css/sunny/jquery-ui-1.8.16.custom.css. За более под-робными описаниями классов CSS обра-щайтесь к документации jQuery UI по адресуhttp://jqueryui.com/docs/Theming/API.

В: Вы сказали, что мы можем создать собственную тему для jQuery UI. Как это сделать?

О: Используйте приложение Theme Roller для jQuery UI. Сначала откройте страницу приложения в браузере: http://jqueryui.com/themeroller/

Щелкните на вкладке Roll your own. Здесь определяются такие параметры конфигура-ции, как шрифты, состояния нажатия кнопок, тени и т. д. Задайте нужные изменения, и лементы пользовательского интерфейса изменяется в соответствии с заданными значениями.Когда тема будет настроена так, как вам нужно, щелкните на кнопке Download Theme. Открывается страница Build Your Download, на которой создается пользовательский пакет jQuery UI. Если вы захотите сохранить свою тему на будущее, просто создайте закладку для страницы Build Your Download.

В: Не пойму, что это за виджеты взаи-модействий. Для чего они нужны?

О: Взаимодействия используются для реализации интерактивных функций, свой-ственных настольным приложениям.Виджеты Draggable обеспечивают возмож-ность перетаскивания элементов.

Виджет Droppable может использоваться в качестве приемника для перетаскиваемых элементов.Виджет Resizable включает возможность масштабирования элемента. Размеры эле-мента изменяются перетаскиванием угла, правой или нижней стороны. Виджеты Selectable обеспечивают поддерж-ку выделения элементов. Посетитель сайта может захватить эти элементы мышью, как при выделении группы файлов на рабочем столе. Виджеты Sortable могут переставляться пользователем в интерактивном режиме.

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

частоЗадаваемые

вопросы

Следующий фрагмент сценарного кода задает конфигурацию цветовых ползунков

(красного, зеленого и синего). Прочитайте каждую строку и подумайте, что она

может делать, на основании того, что вы уже знаете о jQuery и jQuery UI. Запиши-

те справа свои описания. Если вы не уверены, запишите хотя бы предположения.

Мы заполнили одну строку за вас.

Page 430: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

430 глава 10

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

Ôóíêöèÿ refreshSwatch

Чтобы завершить построение цветового компонента, необходимо создать функцию JavaScript для обновления образца цвета. Ниже приведена заготовка функции, а также некоторые ключевые вопросы, над которыми следует подумать до написания кода.

Следующий фрагмент сценарного кода задает конфигурацию цветовых

ползунков (красного, зеленого и синего). Прочитайте каждую строку

и подумайте, что она может делать, используя ваши знания о jQuery и

jQuery UI. Запишите справа свои описания. Если вы сомневаетесь, запи-

шите ваши предположения. Ниже приведены наши ответы.

function refreshSwatch() {

var red = ??? var green = ??? var blue = ??? var my_rgb = ??? $( "#swatch" ).???; $( "#red_val" ).val(red );

$( "#blue_val" ).val( blue);

$( "#green_val" ).val( green);

$( "#color_val" ).val(my_rgb);

}

Как перенести текущие значения ползунков в эти переменные?

В этой переменной следует объединить значения RGB для задания цвета образца.

Какой метод jQuery позволит нам задать цвет образца?

Ничего сложного. Достаточ-но просто воспользоваться методом jQuery val, чтобы в полях input отображалось значение ползунков в процессе изменения. Пользователь будет видеть, какое значение уста-новлено на ползунке.

$( "#red, #green, #blue" ).slider({

orientation: "horizontal",

range: "min",

max: 255,

value: 127,

slide: refreshSwatch,

change: refreshSwatch

});

Диапазон: пользователь может указывать только максимум..

Преобразует области div в виджеты slider.Выбирает горизонтальную ориентацию ползунка.

Маркер ползунка устанавливается в середине.

При перемещении ползунка вызывается функция refreshSwatch.Эта функция вызывается при изменении любого значения.

Максимальное значение 255 (ограничения цветовой модели).

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

Page 431: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 431

jquery ui

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

С получением значений от ползунков все понятно, но как

создать образец цвета? Разве не нужно написать код преобразования шест-надцатеричных веб-цветов?

А ведь и верно! Можно написать функцию преобразования десятичных значений в шестнадцатеричные, а можно просто ис-пользовать десятичные значения.Вспомните, что свойство CSS background-color позволяет задавать цвета в следующем виде:

background-color:rgb(255,0,255)

R G B

w Заполните пропуски в коде функции refreshSwatch.

function refreshSwatch() {

var red =

var green =

var blue =

var my_rgb =

$( "#swatch" ). ;

$( "#red_val" ).val(red );

$( "#blue_val" ).val( blue);

$( "#green_val" ).val( green);

$( "#color_val" ).val(my_rgb);

}

Упражнение

Page 432: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

432 глава 10

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

function refreshSwatch() {

var red =

var green =

var blue =

var my_rgb =

$( "#swatch" ). ;

$( "#red_val" ).val(red );

$( "#blue_val" ).val( blue);

$( "#green_val" ).val( green);

$( "#color_val" ).val(my_rgb);

}

Заполните пропуски в коде функции refreshSwatch.

Включите в файл my_scripts.js код ползунков и функ-ции refreshSwatch. Также добавьте фрагмент, при-веденный ниже. Он инициирует выполнение функции refreshSwatch при загрузке веб-страницы, чтобы стра-ница загружалась с образцом цвета вместо пустого поля.

$( "#red" ).slider( "value", 127 );

$( "#green" ).slider( "value", 127 );

$( "#blue" ).slider( "value", 127 );

$( "#red" ).slider( "value" );

$( "#blue" ).slider( "value" );

$( "#green" ).slider( "value" );

"rgb(" + red + "," + green + "," + blue + ")";

Объединяя значения RGB в этой переменной…

…мы задаем в CSS образца комбинацию значений трех цветов.

$( "#swatch" ).css( "background-color", my_rgb );

Готово к употреблению

Page 433: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 433

jquery ui

Откройте файл sightings_end.html в любимом браузере. Проверьте, как работают пол-зунки, с использованием мыши и клавиатуры (клавиши со стрелками влево и вправо должны изменять состояние ползунка на одно приращение).

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

Цветовые ползунки — классная штука! Наши исследования пойдут

намного быстрее.

Тест-драйв

Page 434: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

434 глава 10

последняя кнопка

È ïîñëåäíåå...

В: Мы использовали запись RGB для свойства background-color постро-енных нами цветовых ползунков. А если мы захотим создать ползунок, использу-ющий стандартные шестнадцатеричные обозначения цветов?

О: Мы постарались создать самый эле-гантный и простой код цветового ползун-ка. Но если вам нужен ползунок с вводом данных в шестнадцатеричном формате, считайте, что вам повезло. Вы можете ис-пользовать пример кода, размещенный на сайте jQuery UI. Откройте в браузере сле-дующий URL-адрес:

http://jqueryui.com/demos/slider/#colorpicker

Найдите и откройте ссылку View Source. Выделите и скопируйте код HTML, CSS и jQuery в текстовом поле, сохраните его в но-вом документе. Не забудьте включить этот документ в соответствующие файлы CSS и jQuery своего пакета jQuery. Вот и все, у вас появился компонент выбора цвета, исполь-зующий шестнадцатеричные коды цветов.

В: Мне нужно поле формы, которое предлагает возможные условия поиска в процессе ввода. В jQuery UI есть что-нибудь подобное?

О: Да! Одним из новшеств jQuery UI на момент написания книги (август 2011 года) стал виджет Autocomplete, который пред-лагает варианты во время ввода данных в поле формы.

Откуда берутся эти варианты? Вы пере-даете их в массиве JavaScript, через URL-адрес или при помощи функции обратного вызова, которая получает данные с сервера при помощи методов Ajax, описанных в гла-вах 8 и 9. За дополнительной информацией об этом виджете обращайтесь на страницу демонстрационного приложения jQuery UI:

http://jqueryui.com/demos/autocomplete/

В: jQuery UI поддерживает проверку данных форм?

О: Нет. К сожалению, jQuery UI не под-держивает проверку форм, но в jQuery есть модуль расширения, который хорошо справ-ляется с этой задачей. Модуль расширения можно найти по адресу:

http://bassistance.de/jquery-plugins/jquery-plugin-validation/

За дополнительной информацией обра-щайтесь к приложению I, в котором этот модуль расширения рассматривается более подробно.

В нашем списке задач остался последний пункт.

1. Создать календарь для выбора даты наблюдения.

2. Создать более привлекательные кнопки-переключатели для выбора типа существа.

3. Создать ползунки для ввода расстояния, веса и роста существа, широты и долготы места наблюдения.

4. Создать компонент для выбора цвета существа.

5. Создать более симпатичную кнопку отправки данных.

частоЗадаваемые

вопросы

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

Page 435: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 435

jquery ui

w

Постойте! Да, мы использова-ли кнопки из главы 1, но ведь кнопка jQuery UI и элемент

HTML — не одно и то же!

Напишите одну строку кода, которую следует добавить в файл my_scripts.js для преоб-разования «классической» кнопки в кнопку jQuery UI, соответствующей теме оформления.

Верное замечание.Мы использовали метод jQuery click и метод jQuery UI button, но не занимались выбором элементов форм, например кнопок от-правки данных. Ниже приведена краткая справка по выбору таких элементов.

� $(":input") = Выбор всех элементов input

� $(":text") = Выбор всех элементов типа text

� $(":radio") = Выбор всех элементов типа radio

� $(":checkbox") = Выбор всех элементов типа checkbox

� $(":submit") = Выбор всех элементов типа submit

� $(":reset") = Выбор всех элементов типа reset

� $(":checked") = Выбор всех полей input в состоянии checked

� $(":selected") = Выбор всех полей input в состоянии selected

� $(":enabled") = Выбор всех незаблокированных полей input

� $(":disabled") = Выбор всех заблокированных полей input

� $(":password") = Выбор всех полей input, предназначенных для ввода пароля

Упражнение

ÊËÞ×ÅÂÛÅ ÌÎÌÅÍÒÛ

Page 436: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

436 глава 10

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

$( "button:submit" ).button(); ;

Не забудьте включить эту строку в файл my_scripts.js и протестировать ее, открыв файл sightings_end.html в своем любимом браузере.

Мы очень довольны вашей работой, так что непременно обратимся к вам за помощью

в следующей главе.

Тоже мне, удружили!Теперь не будет

ни минуты покоя!

Page 437: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 437

jquery ui

Форма отлично смотрится, но на данный момент она не отправляет никакие данные. Впрочем, вы уже узнали все необходимое в главе 9. Пора подумать, как сделать стильную форму полностью функциональной. Папка end в архиве кода этой главы содержит все файлы, необходимые для работы: sightings.html, service.php и sightings.sql. Конечно, вам придется проделать часть работы по на-стройке самостоятельно, но ведь в этом и заключается задача веб-разработчика, не так ли? Мы включили методы Ajax и JSON, описанные в главе 9, чтобы построенная вами форма могла отправлять данные.

Всю необходимую подготовку вы должны провести самостоятельно (т. е. запустить сценарий sightings.sql или же создать базу данных с полями из сценария самостоятельно и включить ме-тоды Ajax и JSON в файл my_scripts.js). Также до перехода к главе 11 в базе данных необходимо создать несколько записей. Если вам понадобится освежить в памяти информацию о MySQL, PHP и AJAX, обращайтесь к главам 8 и 9.

Дополнительный материал

У этого упражнения нет решения. Если у вас возникнут проблемы, вы всегда можете зайти на форум книги по адресу www.headfirstlabs.com и пообщаться с авторами или другими читателями.

Упражнение

Page 438: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

438 глава 10

ваш инструментарий jquery

jQuery UI

Официальная библиотека

jQuery с тремя основными

типами расширений для базо-

вой функциональности jQuery:

эффекты, взаимодействия

и виджеты.

Âàø èíñòðóìåíòàðèé jQuery

Глава 10 осталась позади. Ваш творческий потенциал дополнился навыками использования jQuery UI.

Виджет

Компонент, расширяющий функ-

циональность веб-приложения.

Экономит время при програм-

мировании, упрощает создание

удобных, практичных элементов

пользовательского интерфейса.

Виджет button

Предоставляет метод button

для создания более привлекатель-

ных элементов форм — кнопок

отправки данных, переключате-

лей и флажков.

Виджет datepicker

Метод datepicker приказывает

интерпретатору JS построить

календарь «на ходу»

— вместе

со всем кодом HTML, CSS и встро-

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

Поддерживает большое количе-

ство настраиваемых параметров.

ПолзункиЭлементы пользовательского интерфейса, которыми можно управлять как мышью, так и клавиатурой; ограничивают набор

вводимых данных.Поддерживают пять обработ-чиков событий, которые могут использоваться для связывания ползунка с полем input формы:

create, start, slide, change и stop.

ГЛА

ВА 10

Page 439: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Интересно, что мне подарят в этом году? Надеюсь, новый API...

jQuery и API11

Объекты, сплошные объекты

Даже самый талантливый разработчик не сможет сделать всю работу в одиночку... Мы уже видели, как включать расширения jQuery (такие как jQuery UI или вкладки) для повышения уровня функциональности приложения. Чтобы поднять наше приложение на следующий уровень — ис-пользовать Интернет и информацию из крупных информационных систем типа Google, Twitter или Yahoo! — понадобится... нечто большее. Эти компании предоставляют вам программные интерфейсы (API, Application Programming Interface). В этой главе мы рассмотрим основы работы с API, а также исполь-зуем очень распространенный сервис Google Maps API.

Page 440: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

440 глава 11

снова с криптидами

Ãäå âèäåëè ñíåæíîãî ÷åëîâåêà?

Доктор Паттерсби и доктор Гимли хотят добавить на свой сайт новые классные возможности. Как думаете, вы справитесь с этой задачей?

От: Доктор Гимли [[email protected]]

Тема: Обновления на сайте

Привет,Спасибо вам за то, что помогли сделать наш сайт более удобным и упростили

сбор данных о наблюдениях. Трафик заметно вырос, и мы едва справляемся

с обработкой всех собранных данных.

У нас есть несколько пожеланий для того, чтобы сделать информацию более

доступной для широких масс. Многие люди интересуются данными наблюдений,

и мы бы хотели предоставить им возможность собранных данных.

Вот что нам нужно:

1) нужно предоставить пользователю возможность просмотреть данные отдельного

наблюдения и всю информацию, связанную с ним. Наряду с информацией

о существе нам хотелось бы видеть информацию на карте Google;

2) выбирая маркер на карте Google, пользователь получает дополнительную

информацию о наблюдении;

3) нам хотелось бы, чтобы при выборе типа существа из списка отображалась

информация обо всех существах, связанных с выбранным типом в нашей

базе данных. При этом информация обо всех существах должна отображаться

на карте Google, чтобы мы могли найти места частых наблюдений для более

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

реагировали на щелчки для получения дополнительной информации (как

и пункты списка существ)?

Надеюсь, мы хотим не слишком многого, ведь вся информация уже хранится в базе

данных?Ждем ответа!

--Доктор Гимли и доктор Паттерсби cryptozoologists.org

Page 441: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 441

jquery и api

Джо: Ты говоришь о карте Google, которую нам предсто-ит создать?

Фрэнк: Ага. Тривиально, в общем.

Джим: Тривиально? Они хотят полноценную карту Google!

Фрэнк: Угу.

Джим: С несколькими маркерами на карте — по одному для каждого криптида. И эти маркеры должны реагиро-вать на щелчки выводом дополнительной информации.

Фрэнк: Да! И я, кажется, знаю, как это делать.

Джим: А еще щелчки в списке должны взаимодейство-вать с маркерами — на карте должны появляться времен-ные окна с дополнительной информацией.

Фрэнк: Это уже сложнее... Я пока не знаю, как это сде-лать.

Джо: Беспокоиться не о чем. Разработчики Google Maps уже предоставили API, с которым мы все сделаем.

Джим: Чего предоставили?

Фрэнк: API... Программный интерфейс, короче. Так, компании типа Google, Netflix и Yahoo! дают нам возмож-ность использовать свой сервис на наших сайтах.

Джим: Это хорошо, конечно, но есть ли в нем временные окна и все остальное, что нужно выводить на карте?

Джо: Должно быть. Наверное, нам стоит поближе позна-комиться с интерфейсом Google Maps API и понять, как он работает.

Не вижу препятствий. Собственно, они хотят не так уж много.

Джим ФрэнкДжо

Page 442: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

442 глава 11

изучаем API

Google Maps API

Использование любого API на вашем сайте начинается с поиска докумен-тации и примеров кода в Интернете. Мы загрузили этот пример по адресу http://code.google.com/apis/maps.

var map;

function initialize() { var myLatlng = new google.maps.LatLng(40.720721,-74.005966); var myOptions = { zoom: 13, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP

}

map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); google.maps.event.addListener(map, 'zoom_changed', function() {

setTimeout(moveToNewYork, 3000);

}); var marker = new google.maps.Marker({

position: myLatlng, map: map, title:"Hello World!"

});

google.maps.event.addListener(marker, 'click', function() {

map.setZoom(8);

});

} function moveToNewYork() {

var NewYork = new google.maps.LatLng(45.526585, -122.642612); map.setCenter(NewYork);

}Так, некоторые переменные и функции выглядят знакомо,

а все остальное?

Это код Google.Но все не так страшно, как может показаться. Давайте разберемся, что же происходит в этом коде.

Page 443: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 443

jquery и api

 API èñïîëüçóþòñÿ îáúåêòû

var map;

var myLatlng = new google.maps.LatLng(40.720721,-74.005966);

var myOptions = {

zoom: 13,

center: myLatlng,

mapTypeId: google.maps.MapTypeId.ROADMAP

}

map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

google.maps.event.addListener(map, 'zoom_changed', function() {

setTimeout(moveToNewYork, 3000);

});

Объявляем переменные. Переменной присваивается новый объект Google LatLng.

Передаем широту и долготу в парамет-рах объекта.

Размещаем карту в элементе map_canvas.

Создаем массив для хранения параметров карты.

Перемен-ной map присва-ивается новый объект Google Maps.

Добавляем слушателя события к карте Google.

var marker = new google.maps.Marker({

position: myLatlng,

map: map,

title:"Hello World!"

});

function moveToNewYork() {

var NewYork = new google.maps.LatLng(45.526585, -122.642612);

map.setCenter(NewYork);

}

Объявляем переменную для объекта Marker.

Передаем нуж-ные значения в параметрах.

Объект LatLng, объявленный ранее.

Объект Map, объявленный ранее.

Объявляем функцию для вызова кода Google.

Выбираем централь-ную точку карты.

Создаем другой объект LatLng.

В главе 6 мы создавали объекты JavaScript. Используя свойства и методы этих объектов, мы орга-низуем хранение и обработку информации так, как считаем нужным. Многие компании — Google, Netflix, Microsoft и Yahoo! — тоже создают объекты для работы со своими данными через API. Если вы успели забыть, что такое объекты и как они работают, вернитесь к главе 6 и перечитайте ее.

Page 444: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

444 глава 11

почему именно объекты?

Потому что это ускоряет работу.Из главы 6 вы знаете, что информацию удобно хранить в объектах. Объекты ис-пользуются для хранения переменных, относящихся к одной сущности. Фактически API — это набор конструкторов объектов, которые позволяют создавать собствен-ные экземпляры объектов, определенных другими разработчиками. Если есть эк-земпляр объекта, вы можете использовать все его свойства и методы в коде!

Внедрить в приложение поддержку географических карт достаточно сложно; имен-но поэтому Google использует объекты в своем API. Это позволяет разработчикам создавать объекты с множеством разных методов и свойств, необходимых для по-строения карты.

Объект карты содержит свойства zoom, center и mapTypeId, а также много других свойств, в предыдущем примере не использовавшихся. Объект карты также поддер-живает многочисленные методы, например setCenter.

<!DOCTYPE html>

<html>

<head>

<title>View Cryptid Sightings</title>

<link type="text/css" href="style/form.css" rel="stylesheet"/>

<link type="text/css" href="jquery-ui-1.8.16.custom/css/sunny/jquery-ui-1.8.16.custom.css" />

</head>

<body>

< div class="ui-widget-header ui-corner-top form_pad">

<h2>View Cryptid Sightings</h2>

</div>

<div class="ui-widget-content form_pad">

<div id="map_canvas"></div>

</div>

<script src="http://maps.google.com/maps/api/js?sensor=false"></script>

<script src="scripts/jquery-1.6.2.min.js"></script>

<script src="scripts/maps.js"></script>

</body>

</html>

Задание!

Включаем Google Maps API.

Включаем библиотеку jQuery.

Включаем файл maps.js.

Создаем область для размещения карты.

display_one.html

Создайте страницу display_one.html и сохра-ните ее в папке проекта этой главы.

Значит, в APIs все делается при помощи объектов? И почему мы должны исполь-

зовать объекты, созданные кем-то другим?

Page 445: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 445

jquery и api

Âêëþ÷åíèå êàðò Google â ñòðàíèöó

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

Расставьте магниты так, чтобы у вас получился код функции initialize. Эта функция долж-

на создавать новый экземпляр объекта Google Maps map с использованием параметров,

определенных в коде. Объект map размещается в элементе map_canvas страницы. Также

включите в существующий файл form.css определения стилей контейнера карты.

Область div с идентификатором map_canvas.

Код Google Maps API, добавленный с включением фрагмента <script type="text/javascript"

src="http://maps.google.com/maps/api/js?sensor=false"></script>.

Чтобы создать карту Google на странице, необходимо создать файл maps.js и включить в него функцию с вызовом кода API.

$(document).ready. ____________{

var _____________

function ______________{

var latlng = new google.maps.LatLng. ____________________;

var mapOpts = {

_____________: 13,

center: latlng,

mapTypeId: google.maps.MapTypeId._____________

};

map = ___________google.maps.Map(document.getElementById(_____________), mapOpts);

}

initialize();

});

#map_canvas {

_____________ :left;

height: 450px;

width: ____________

}

form.css

maps.js(45.519098,-122.672138) initialize()

"map_canvas" (function()

zoom

new

HYBRID

map; float

450px;

Развлечения с магнитами

Page 446: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

446 глава 11

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

Расставьте магниты так, чтобы получился код функции initialize. Эта функция должна

создавать новый экземпляр объекта Google Maps map с параметрами, определенными в

коде. Объект map размещается в элементе map_canvas страницы. Также включите в суще-

ствующий файл form.css определения стилей контейнера карты.

В: А что это за объект LatLng и свойство mapOpts?

О: За дополнительной информацией об объ-ектах, методах и прочих аспектах API обращай-тесь по адресу http://code.google.com/apis/maps/documentation/javascript/reference.html. На сайте имеются примеры кода и более подробная ин-формация о разных объектах и методах, которые понадобятся вам при программировании.

В: Google Maps — это единственный способ создания карт?

О: Конечно, нет! Однако это самый популяр-ный способ, поэтому мы здесь им и воспользова-лись. Другие компании (такие как Yahoo!, Microsoft, MapQuest и OpenLayers) тоже предлагают свои картографические API.

$(document).ready. ____________{

var _______

function ______________{

var latlng = new google.maps.LatLng. --- ____________________;

var mapOpts = {

______: 13,

center: latlng,

mapTypeId: google.maps.MapTypeId._________

};

map = ______google.maps.Map(document.getElementById(______________), mapOpts);

}

initialize();

});

#map_canvas {

_______ :left;

height: 450px;

width: ________

}

form.css

maps.js

--- ____________________;(45.519098,-122.672138)

______________{

latlng = new goog

______________initialize()

______________),"map_canvas"

. ____________{(function()

______:

center:

zoom

______gonew

_________HYBRID

r _____

nction

___

ini

map;

_______

height: float

p ;

________450px;

Развлечения с магнитами. Решение

частоЗадаваемые

вопросы

Page 447: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 447

jquery и api

Включите в файл maps.js функцию initialize, собранную из магнитов. Также убедитесь в том, что файл maps.js включен в display_one.html. Затем откройте файл display_one.html в браузере. Весь код должен выполняться через веб-сервер, поэтому URL-адрес должен начинаться с префикса http://, а не file://.

Отлично, разместить карту на страни-це было несложно... Но на ней нет никаких

данных криптидов. Их нужно загрузить из базы данных, верно?

Точно.В главе 9 вы научились читать информацию из базы данных MySQL с использованием кода jQuery, Ajax, JSON, PHP и MySQL. Хотя список задействованных технологий получается довольно длинным, в результате мы получаем именно то, что нужно. Давай-те посмотрим, как использовать эти технологии на этот раз.

Тест-драйв

Page 448: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

448 глава 11

старые знакомые

×òåíèå äàííûõ JSON ñðåäñòâàìè SQL è PHP

В главе 9 было показано, как команда SQL select извлекает нужную информацию из базы данных, чтобы файл PHP мог преобразовать ее в формат JSON и вернуть странице с использованием Ajax.

Вы также научились использовать Ajax для получения от файла PHP информации, закодированной в формате JSON. С возвращением данных JSON страницей PHP все было просто — функция json_encode получала массив и возвращала данные JSON, с которыми можно было работать средствами jQuery.

SELECT COLUMN_NAME1, COLUMN_NAME2 FROM TABLE_NAME order by COLUMN_NAME1 ASC

$my_array = array();

array_push($my_array, array('my_key' => 'my_val'));

echo json_encode($my_array);

Весь код PHP и SQL для этой главы мы написали за вас. Скопируйте базу данных MySQL из главы 10 и двигайтесь дальше! Остальной код SQL и PHP находится в архиве кода главы; выполните его на своем сервере. Весь код PHP и SQL, объединенный в один файл, можно за-грузить по адресу http://thinkjquery.com/chapter11/end/service.zip.

Сама база данных часто

хранится в файлах на

жестком диске, но это

необязательно.

Веб-сервер

Сервер баз данных

Серверный компьютер

Клиентский браузер

База данных MySQL

Веб-сервер обрабатыва-ет запросы веб-страниц, выполняет сценарии PHP и возвращает данные в формате HTML.

Данные

<? php

>?

JSON

Page 449: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 449

jquery и api

function getAllSightings(){

$.getJSON("service.php?action=getAllSightings",___________________ {

if (______________length > 0) {

$("#sight_list")___________________;

___________________(json.sightings,function() {

var info = 'Date: ' + this['date'] + ', Type: ' + this['type'];

var $li = $("<li />");

___________________

$li.addClass(___________________);

$li.attr('id', this['id']) ;

$li.appendTo(___________________);

});

}

});

}

#sight_nav{

float:left;

}

ul#sight_list{

width:150px;

padding:0px;

margin:0px;

}

li.sightings {

padding:4px;

background:#7B7382;

border:1px #000 solid;

color:#fff;

___________________

}

___________________

background:#eee;

color:#000;

}

form.css

maps.js

Расставьте магниты в коде файлов display_one.html, forms.css и maps.js так, чтобы обеспечить

загрузку данных в формате JSON и их отображение на экране. Добавьте элементы div и ul

для хранения данных, немного кода CSS для стилевого оформления списка, а также функ-

цию получения данных (через JSON) для включения криптидов в список.

list-style:none;

li.sightings:hover {

"map_canvas"

"sight_list"function(json)

json.sightings.

.empty()

$.each

$li.html(info);

"sightings"

"#sight_list"

<div class="ui-widget-content form_pad">

<div id= ___________________></div>

<div id="sight_nav">

<ul id= ___________________>

</ul>

</div>

</div>

display_one.html

Развлечения с магнитами: jQuery, HTML и CSS

Page 450: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

450 глава 11

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

<div class="ui-widget-content form_pad">

<div id= _______________></div>

<div id="sight_nav">

<ul id=_________________>

</ul>

</div>

</div>

display_one.html

function getAllSightings(){

$.getJSON("service.php?action= getAllSightings",_________________{

if (_____________ .length > 0) {

$("#sight_list") ________;

_______(json.sightings,function() {

var info = 'Date: ' + this['date'] + ', Type: ' + this['type'];

var $li = $("<li />");

______________

$li.addClass(____________);

$li.attr('id', this['id']) ;

$li.appendTo(_____________);

});

}

});

}

#sight_nav{

float:left;

}

ul#sight_list{

width:150px;

padding:0px;

margin:0px;

}

li.sightings {

padding:4px;

background:#7B7382;

border:1px #000 solid;

color:#fff;

________________

}

__________________

background:#eee;

color:#000;

}

form.css

maps.js

Расставьте магниты в файлах display_one.html, forms.css и maps.js так, чтобы загружать дан-

ные в формате JSON и отображать их на экране. Добавьте элементы div и ul для хранения

данных, немного кода CSS для стилевого оформления списка, а также функцию получения

данных (через JSON) для включения криптидов в список.

________________list-style:none;

__________________

background:#eee;

li.sightings:hover {

g

= _______________><

="sight nav">

"map_canvas"

g t_ a

=_________________>

ight nav >

"sight_list"

_________________{function(json)

(_____________ .le

("#sight list")

_____________ ljson.sightings. g

) ________;

ghtings,fun

) .empty()

_______(j

var in$.each

$li.addClass($li.html(info);

____________)

this['id'])

;"sightings"

(_____________);"#sight_list"

Развлечения с магнитами: jQuery, HTML и CSS. Решение

Page 451: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 451

jquery и api

Включите в файл maps.js только что созданную функцию getAllSightings. Вклю-чите ее вызов в конец функции initialize. Откройте файл display_one.html в бра-узере. Предполагается, что в главе 10 вы уже включили информацию о нескольких существах в базу данных; если вы еще этого не сделали, обязательно сделайте сейчас. Помните, что весь код должен выполняться через веб-сервер; соответственно URL-адрес должен начинаться с префикса http://, а не file://.

Все это хорошо, конечно... Только на карте по-прежнему

ничего не отображается.

Точно. Нужно нанести данные криптидов на карту. В интерфейса Google Maps для этой цели существует очень простой метод. Давайте посмотрим, как он работает.

Тест-драйв

Page 452: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

452 глава 11

маркеры на карте

Òî÷êè íà êàðòå — ìàðêåðû

Естественно, Google поддерживает возможность нанесения точек на карту, только они называются не точками, а маркерами (marker). Маркеры представляют собой объекты (как и все остальное в Google Maps API); они также обладают методами и свойствами, через которые с ними выполняются необходи-мые операции.

var myLatLng = new google.maps.LatLng(45.519098,-122.672138);

var my_marker = new google.maps.Marker({

position: myLatlng,

map: map,

title:"Hi! I’m a marker. Seen me around before?"

});

Здесь мы задаем позицию маркера,

карту, на которой он размеща-

ется, и название маркера.

Передаем аргументы для задания

свойств объекта my_marker.

Определенный ранее объект LatLng передается в параметре.

Определяем объект с именем my_marker

как экземпляр объекта маркера Google.

Готовый объект кар-ты. Вы уже видели, как он работает.

Вызываем конструктор объекта Google Marker.

Определяем новый объект LatLng из Google Maps API.

Передаем фактические значения широты и дол-готы в параметрах.

Привет! Я маркер. Раз познако-миться. Мы ведь уже встречались

на картах Google, не так ли?

Page 453: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 453

jquery и api

function getAllSightings(){

$.getJSON("service.php?action=getAllSightings", function(json) {

if (json.sightings.length > 0) {

$("#sight_list").empty();

$.each(json.sightings,function() {

var info = 'Date: ' + this['date'] + ', Type: ' + this['type'];

var $li = $("<li />");

$li.html(info);

$li.addClass("sightings");

$li.attr('id', this['id']) ;

$li.click(function(){

______________________ this['id'] );

});

$li.appendTo("#sight_list");

});

}

});

}

function getSingleSighting(______________________){

$.getJSON("service.php?action=getSingleSighting&id="+id, function(json) {

if (json.sightings.length > 0) {

__________________________________

var loc = new google.maps.LatLng(this['lat'], this['long']);

var my_marker = new google.maps______________________({

______________________loc,

map: map,

title:this['type']

});

_________________setCenter(loc, 20);

});

}

});

} maps.js

Возьми в руку карандашВключите в функцию getAllSightings добавление слушателя события click к элементу списка

до того, как он будет включен в список. Событие click должно вызывать getSingleSighting

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

загрузит информацию о наблюдении и добавит его на карту в виде маркера.

Page 454: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

454 глава 11

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

После включения всего кода элементы списка реагируют на щелчки,

они загружают данные о криптиде, на котором щелкнул пользова-

тель, и размещают их на карте.

function getAllSightings(){

$.getJSON("service.php?action=getAllSightings", function(json) {

if (json.sightings.length > 0) {

$("#sight_list").empty();

$.each(json.sightings,function() {

var info = 'Date: ' + this['date'] + ', Type: ' + this['type'];

var $li = $("<li />");

$li.html(info);

$li.addClass("sightings");

$li.attr('id', this['id']) ;

$li.click(function(){

this['id'] );

});

$li.appendTo("#sight_list");

});

}

});

}

function getSingleSighting( ){

$.getJSON("service.php?action=getSingleSighting&id="+id, function(json) {

if (json.sightings.length > 0) {

var loc = new google.maps.LatLng(this['lat'], this['long']);

var my_marker = new google.maps ({

loc,

map: map,

title:this['type']

});

setCenter(loc, 20);

});

}

});

} maps.js

getSingleSighting(

id

$..each(json..sightings,function() {

..Markerposition:

map.

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

Page 455: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 455

jquery и api

Включите в файл maps.js только что созданные функции getAllSightings и getSingleSighting. Откройте файл display_one.html в браузере (как и прежде, с использованием префикса http://).

Ого! Да, это впечатляет. А как насчет нашей второй просьбы? Помните, об одно-

временном отображении данных нескольких наблюдений?

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

ддальше � 455

р р

3) Нам хотелось бы, чтобы при выборе типа существа из списка отображалась

информация обо всех существах, связанных с выбранным типом в нашей базе

данных. При этом информация о существах должна отображаться на карте

Google, чтобы найти места частых наблюдений для внимательного изучения.

Можно ли сделать так, чтобы все эти точки тоже реагировали на щелчки для

получения дополнительной информации (как и пункты списка существ)?

Тест-драйв

Page 456: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

456 глава 11

готовый код раскрывающегося списка существ

Создайте новую страницу с именем display_type.html и сохраните ее в одном каталоге с другими файлами HTML этого проекта. Новый файл будет отображать список доступных типов существ. Все суще-ства выбранного типа отображаются на карте. По структуре и сти-лю новая страница почти не отличается от старой, если не считать добавления элемента select с идентификатором ddlTypes.

Ñïèñîê çàäà÷ äëÿ îòîáðàæåíèÿ íåñêîëüêèõ ñóùåñòâ

Вот что нужно сделать для реализации последнего требования.

1. Создать раскрывающий список типов существ (информация из базы данных).

2. При изменении состояния списка получить соответствующий список существ.

3. Вывести информацию обо всех существах из базы данных, в списке и на карте.

4. И список, и маркеры на карте должны реагировать на щелчки, чтобы на карте отображалась дополнительная информация.

<!DOCTYPE html> <html> <head> <title>View Cryptid Sightings</title> <link type="text/css" href="style/form.css" rel="stylesheet" /> <link type="text/css" href="jquery-ui-1.8.16.custom/css/sunny/jquery-ui-1.8.16.custom.css"/> </head> <body> <div class="ui-widget-header ui-corner-top form_pad"> <h2>View Cryptid Sightings</h2> </div> <div class="ui-widget-content form_pad"> <div id="map_canvas"></div> <div id="sight_nav"> <select id="ddlTypes"> <option value="">-- Please Select --</option> </select> <ul id="sight_list"></ul> </div> </div> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script src="scripts/jquery-1.6.2.min.js"></script> <script src="scripts/maps.js"></script> </body></html>

display_type.html

Добавляем раскрывающийся список,

заполняемый типами существ.

Включаем Google Maps API.

Включаем библиотеку jQuery.Включаем файл maps.js.

Готово к употреблению

Page 457: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 457

jquery и api

Расставьте магниты так, чтобы заполнить пропуски в функции getAllTypes, которая вызывает файл

service.php (включенный в архив кода этой главы) для получения списка разных типов существ

в базе данных. Полученные типы включаются в раскрывающийся список с идентификатором

ddlTypes. Для раскрывающегося списка определяется слушатель события change, который вы-

водит выбранное значение. Поскольку файл maps.js используется для двух файлов HTML, в функ-

цию initialize включается проверка существования раскрывающегося списка. Если список

существует, то вызывается функция getAllTypes, а если нет — функция getAllSightings.

function initialize(){

.

.

map = new google.maps.Map(document.getElementById(________________), mapOpts);

if ( $('#ddlTypes').length ) {

___________________

}else{

___________________

}

}

function getAllTypes(){

$.getJSON("service.php?action=getSightingsTypes", function(json_types) {

if (___________________creature_types.length > 0) {

$.each(json_types.creature_types,___________________

var info = this['type'];

var $li = ___________________

$li.html(info);

$li___________________("#ddlTypes");

});

}

});

}

___________________change(function() {

if($(this).val() != ""){

alert( $(this).val() );

}

});

maps.js

$("<option />");

function() {

getAllTypes();

json_types.

getAllSightings();

"map_canvas"

$('#ddlTypes').

.appendTo

Развлечения с магнитами

Page 458: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

458 глава 11

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

function initialize(){

.

.

map = new google.maps.Map(document.getElementById(_____________), mapOpts);

if ( $('#ddlTypes').length ) {

______________

}else{

_________________

}

}

function getAllTypes(){

$.getJSON("service.php?action=getSightingsTypes", function(json_types) {

if (___________ creature_types.length > 0) {

$.each(json_types.creature_types,_____________

var info = this['type'];

var $li = ________________

$li.html(info);

$li_________ ("#ddlTypes");

});

}

});

}

_______________ change(function() {

if($(this).val() != ""){

alert( $(this).val() );

}

});

maps.js

Проверка существования элемента по свойству length.

Добавляем слушателя для события change рас-крывающегося списка.

Присоединяем новый пункт к раскрывающемуся списку.

Задаем текст пункта раскрыва-ющегося списка.

Получение типов из базы данных с использованием JSON и PHP.

Значение выбранного пункта списка.

Теперь в нашем приложении имеется раскрывающийся список, связанный с картой Google,

и функция получения информации (в формате JSON) о типах существ, а приложение выводит

сообщение о выбранном типе существа.

yp

________________

info);

$("<option />");

) {

,_____________function() {

______________

else{

getAllTypes();

(___________ cr

.each(json typ

json_types.

_________________getAllSightings();

_____________),"map_canvas"

_______________ ch

if($(this).val(

р$('#ddlTypes').

i.html(i

i_________ ("

info);

.appendTo

Развлечения с магнитами. Решение

Page 459: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 459

jquery и api

Включите в файл maps.js функцию getAllTypes и слушателя события change раскры-вающегося списка. Также внесите необходимые изменения в функцию initialize. Наконец, откройте файл display_type.html (снова с использованием префикса http://).

1. Создать раскрывающийся список типов существ (информация читается из базы данных).

2. При изменении состояния раскрывающегося списка получить из базы список существ выбран-ного типа.

3. Вывести информацию обо всех существах, полученную из базы данных, в списке и на карте.

4. И список, и маркеры на карте должны реагировать на щелчки, чтобы на карте отобража-лась дополнительная информация.

Работа идет полным ходом, карта готова в кратчайшие сроки! Пора вычеркнуть пару требований из списка.

Тест-драйв

Page 460: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

460 глава 11

не так быстро

Эй, не так быстро! Когда я выбираю один из пунктов раскрывающегося списка, никакие

существа не отображаются. Я вижу только окно сообщения! По-моему, второй пункт

еще не готов.

var markersArray = [];

var bounds = new google.maps________________;

function getSightingsByType(type){

$.getJSON("service.php?action=getSightingsByType&type="+type, function(json) {

if (_________sightings.length > 0) {

$('#sight_list').empty();

$.each(json.sightings,function() {

var loc = new google.maps______________(this['lat'], this['long']);

var opts = {

map: map,

position:________________

};

А ведь и верно!

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

И тогда этот элемент списка может будет вычеркнуть. Но раз уж мы занялись этой задачей, заодно выполним тре-тий пункт из списка задач. Закатайте рукава, нам придется изрядно повозиться, чтобы собрать все воедино.

Длинные упражнения Заполните пропуски в коде функции getSightingsByType. Этой функции

передается один параметр: тип существа, по которому просматривается информа-ция. Функция получает данные в формате JSON, перебирает возвращенных существ (если они есть) и добавляет на карту маркеры. Создайте еще две глобальные переменные: массив с именем markerArray, и новый объект Google Maps LatLngBounds с именем bounds, и функцию, которая удаляет предыдущие маркеры перед добавлением новых, когда выбор в списке меняется.

Page 461: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 461

jquery и api

var marker = new google.maps________________(opts);

markersArray.push(________________);

var $li = $("<li />");

$li.html('Date: ' + this['date'] + ', Type: ' + this['type']);

$li________________("sightings");

$li.appendTo("#sight_list");

bounds.extend(loc);

});

map.fitBounds(bounds);

}

});

}

$('#ddlTypes').change(function() {

if($(this).val() != ""){

clearOverlays();

________________( $(this).val() );

}

});

function ________________ {

if (markersArray) {

for (i in markersArray) {

markersArray[i].setMap(null);

}

markersArray.length = 0;

bounds = null;

bounds = new________________LatLngBounds();

}

}

maps.js

Page 462: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

462 глава 11

решение длинного упражнения

После добавления двух новых глобальных переменных и вызовов функций Google Maps приложение добавляет и удаляет маркеры на карте при изменении выбора в списке. Маркеры, добавленные на карту, включаются в массив markerArray и использу-ются для расширения границ карты bounds. Таким образом, карта масштабируется по точкам при помощи функции fitBounds. Функция getSightingsByType, теперь вызываемая при любом изменении выбора в раскрывающемся списке, добавляет маркеры на карту и включает существо в список на странице.

var markersArray = [];

var bounds = new google.maps ;

function getSightingsByType(type){

$.getJSON("service.php?action=getSightingsByType&type="+type, function(json) {

if ( sightings.length > 0) {

$('#sight_list').empty();

$.each(json.sightings,function() {

var loc = new google.maps (this['lat'], this['long']);

var opts = {

map: map,

position:

};

var marker = new google.maps (opts);

markersArray.push( );

var $li = $("<li />");

$li.html('Date: ' + this['date'] + ', Type: ' + this['type']);

$li ("sightings");

$li.appendTo("#sight_list");

bounds.extend(loc);

});

map.fitBounds(bounds);

}

});

}

..LatLngBounds()(

..addClass

marker

loc

..LatLng

json.

Новый объект LatLngBounds.

Получаем данные в формате JSON.

Создаем новый объект Marker

для каждой точки на карте.

Включаем теку-щие координаты в объект bounds.

Выбираем масштаб по границам объекта bounds, чтобы на карте были видны все точки наблюдений.

..Marker

Решение длинных упражнений

Page 463: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 463

jquery и api

Мы включили функцию clearOverlays, которая удаляет ра-

нее добавленные маркеры перед добавлением новых. На картах

Google все дополнительные элементы, размещаемые на базовой

карте, называются слоями (overlays); это могут быть объекты типа

Marker, Line, Polyline, Polygon и других типов.

$('#ddlTypes').change(function() {

if($(this).val() != ""){

clearOverlays();

( $(this).val() );

}

});

function {

if (markersArray) {

for (i in markersArray) {

markersArray[i].setMap(null);

}

markersArray.length = 0;

bounds = null;

bounds = new LatLngBounds();

}

}

maps.js

..google..maps.

clearOverlays()

Перед добавлением мар-керов удаляем с карты все старые маркеры.

Значение раскрывающегося списка передается в параметре функции.

Удаляем объект Marker с карты.

Также сбрасываем переменную bounds.

getSightingsByType

Для любознательных

Page 464: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

464 глава 11

тест-драйв

Включите только что созданный код в файл maps.js. Откройте файл display_type.html в браузере и выберите один из типов существ в списке.

Осталось совсем немного… Всего один пункт!

1. Создать раскрывающийся список типов существ (информация читается из базы данных).

2. При изменении состояния раскрывающегося списка получить из базы список существ выбран-ного типа.

3. Вывести информацию обо всех существах, полученную из базы данных, в списке и на карте.

4. И список, и маркеры на карте должны реагировать на щелчки, чтобы на карте отобража-лась дополнительная информация.

Тест-драйв

Page 465: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 465

jquery и api

В: Значит, я могу бесплатно использо-вать Maps API на своем сайте?

О: Да! Google бесплатно предоставляет API всем (для использования в личных или коммерческих целях), при условии выполне-ния пользовательского соглашения.

В: Но я не знаю, выполняю я эти усло-вия или нет. Где можно ознакомиться с пользовательским соглашением?

О: Полный текст пользовательско-го соглашения находится по адресу http://www.google.com/apis/maps/terms.

В: Google Maps API работает с картами всего мира?

О: Осталось совсем немного стран, на которые сервис Google Maps не распро-страняется. Список можно найти на сайте Google Maps API list.

В: Могу ли я пользоваться этими кар-тами на мобильных устройствах?

О: Да, можете. На момент издания кни-ги вышла 3 версия Google Maps API. Она разрабатывалась с учетом мобильных устройств, для браузеров с поддержкой JavaScript.

В: Но я бы хотел написать специаль-ное приложение. Google Maps API мне подойдет?

О: Если вы пишете на платформе Android или iPhone — подойдет. Google предостав-ляет для этих платформ библиотеки, кото-рые следует включить в приложение. На других мобильных платформах вам при-дется использовать API так же, как на сайте.

В: Полная версия Google Maps позво-ляет находить маршруты. Способен ли на это данный API?

О: Нет, это невозможно. Компания Google разработала другой API — Google Directions API, который позволяет искать маршруты.

В: А как насчет поиска мест на карте по адресу?

О: На профессиональном жаргоне это называется геокодированием. У Google для этого есть специальный Geocoding API. Все упоминавшиеся интерфейсы входят в семейство Google Maps API. К счастью, все данные от Google поставляются в формате JSON, с которым вы уже умеете работать.

В: Какие еще API входят в семейство Google Maps API?

О: Directions API и Geocoding API отно-сятся к подразделу, называемому Maps API Web Service. Также в этот подраздел входят интерфейсы Distance API, Elevation API и Places API.

В: А есть и другие?

О: Да. Есть Static Maps API для браузе-ров, не имеющих полноценной поддерж-ки JavaScript; Maps API для Flash; и даже Earth API, который позволяет загрузить на страницу приложение Google Earth для про-смотра трехмерного изображения земного шара, проведения виртуальных экскурсий и рисования фигур. Впрочем, для его ис-пользования необходимо установить модуль расширения Google Earth.

В: Существуют ли API для других язы-ков, кроме JavaScript?

О: Да! Доступно бесчисленное множество разных APIs, одни бесплатны, другие требу-ют приобретения лицензии. Если вы ищете некую функциональность, которую вам не хочется писать самостоятельно, вполне возможно, что для нее уже существует го-товый API.

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

Мозговой

штурм

частоЗадаваемые

вопросы

Page 466: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

466 глава 11

и снова щелчки

var contentString = "This is an InfoWindow";

var my_infowindow = new google.maps.InfoWindow({

content: contentString

});

google.maps.event.addListener(my_marker, 'click', function() {

my_infowindow.open(map,my_marker);

});

Создаем экземпляр объекта Google Maps InfoWindow.

Определяем переменную с содержимым, которое нужно отобразить.

Приказываем карте прослу-шивать событие click для нашего объекта маркера.

Этот код выполняется

при щелчке на маркере

(на карте появляется

временное окно).

Задаем значение свойства content объекта InfoWindow.

Ïðîñëóøèâàíèå ñîáûòèé êàðòû

Мы уже почти подошли к концу. Вы уже видели разнообразные события, которые jQuery и JavaScript предоставляют для создания интересных интерактивных веб-приложений. Так как Google Maps API состоит из кода JavaScript (хотя и очень хорошо написанного и эффективного), он может использовать способность браузера прослушивать события и действовать соответствующим образом.

И по тем же причинам, по которым в jQuery были добавлены собственные функции создания слушате-лей, разработчики Google Maps предоставили возможность добавления слушателей событий через API. Не все браузеры одинаково работают со слушателями событий, и такой подход гарантирует, что API сможет управлять тем, как слушатели добавляются к странице. Ниже показано, как добавить слушателя события click для создания временного окна Google Maps InfoWindow.

В Google Maps API почти со всеми типами объектов (Map,

Marker, Line, InfoWindow, TrafficOverlay, Polygon и  другие)

связываются события. И хотя события разных объектов часто

имеют одинаковые имена, они могут получать разные пара-

метры! Обязательно просмотрите документацию по объекту,

который вы намереваетесь использовать.

Для любознательных

Page 467: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 467

jquery и api

var info_window = new google.maps________________({content: ''});

function________________(type){

$.getJSON("________________ action=getSightingsByType&type="+type, function(json) {

if (json.sightings.length > 0) {

$('#sight_list').empty();

$.each(json.sightings,function() {

var info = 'Distance: ' + this[_________] + '<br>' + ' Height: ' + this['height'];

info += ', Weight: ' + this['weight'] + ', Color: ' + this['color'] + '<br>';

info += 'Latitude: ' + this['lat'] + ', Longitude: ' + this[_________];

var loc = new _____________________(this['lat'], this['long']);

var opts = {

map: map,

position:_____________

};

var marker = new google.maps _____________(opts);

markersArray.push(marker);

google.maps.event_____________(marker, 'click', function() {

info_window.content = info;

info_window.open(map, marker);

});

var $li = $("<li />");

$li.html('Date: ' + this['date'] + ', Type: ' + this['type']);

$li.addClass("sightings");

$li_________(function(){

info_window.content = info;

info_window.open(map, _________);

});

$li.appendTo("#sight_list");

_________ extend(loc);

});

map _____________ (bounds);

}

});

} maps.js

Возьми в руку карандашЗаполните пропуски в коде функции getSightingsByType, добавляющей функциональ-

ность обработки щелчков к маркерам на карте и к пунктам списка. Создайте глобальную пере-

менную info_window, которая представляет собой новый экземпляр объекта Google Maps

InfoWindow; по умолчанию объект инициализируется пустой строкой.

Page 468: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

468 глава 11

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

Обновленная функция getSightingsByType отображает данные в фор-

мате списка и на карте, а также заставляет маркеры карты и пункта списка

реагировать на щелчки.

var info_window = new google.maps ({content: ''});

function (type){

$.getJSON(" action=getSightingsByType&type="+type, function(json) {

if (json.sightings.length > 0) {

$('#sight_list').empty();

$.each(json.sightings,function() {

var info = 'Distance: ' + this[ ] + '<br>' + ' Height: ' + this['height'];

info += ', Weight: ' + this['weight'] + ', Color: ' + this['color'] + '<br>';

info += 'Latitude: ' + this['lat'] + ', Longitude: ' + this[ ];

var loc = new (this['lat'], this['long']);

var opts = {

map: map,

position:

};

var marker = new google.maps (opts);

markersArray.push(marker);

google.maps.event (marker, 'click', function() {

info_window.content = info;

info_window.open(map, marker);

});

var $li = $("<li />");

$li.html('Date: ' + this['date'] + ', Type: ' + this['type']);

$li.addClass("sightings");

$li (function(){

info_window.content = info;

info_window.open(map, );

});

$li.appendTo("#sight_list");

extend(loc);

});

map (bounds);

}

});

} maps.js

..fitBounds .

bounds.

marker

..click

..addListener

..Marker

loc

google.maps.LatLng"long''

‘distance'

service..php?

..InfoWindowgetSightingsByType

Добавляем слушателя события click к объекту Marker на карте.

Добавляем слушателя события к списку, чтобы на карте открывалось окно InfoWindow.

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

Page 469: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 469

jquery и api

Включите в файл maps.js новый код, созданный нами на предыдущей странице. Затем откройте файл display_type.html в браузере и выберите существо в списке. Щелкните на маркерах списка, чтобы просмотреть дополнительную информацию о существе.

1. Создать раскрывающийся список типов существ (информация читается из базы данных).

2. При изменении состояния раскрывающегося списка получить из базы список существ выбран-ного типа.

3. Вывести информацию обо всех существах, полученную из базы данных, в списке и на карте.

4. И список, и маркеры на карте должны реагировать на щелчки, чтобы на карте отобража-лась дополнительная информация.

Тест-драйв

Page 470: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

470 глава 11

вы — звезда jquery

Ïîëó÷èëîñü!!!

Всего на нескольких страницах вам удалось создать полностью работоспособный сайт, использующий код на нескольких языках (PHP, SQL, JavaScript и jQuery), а так-же работающий с Google Maps API средствами Ajax и JSON для отображения доволь-но сложных данных. Не так уж мало!

Меня когда-нибудь оставят в покое?

Сайт выглядит роскошно. Именно то, что мы хотели!

Спасибо!

Page 471: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 471

jquery и api

Âàø èíñòðóìåíòàðèé jQuery API

Глава 11 осталась позади, а вы научились использовать jQuery с разными API (а также JavaScript, PHP, MySQL, Ajax, JSON и не только!).

API Прикладные программные интерфейсы —

код, предоставляемый другими людьми

(или компаниями) для работы с их дан-

ными, объектами и различными видами

сервиса.

API предоставляют конструкторы, при

помощи которых вы создаете свои экзем-

пляры их объектов. Создавая экземпляр,

вы получаете возможность использования

всех методов и свойств, связанных с эти-

ми объектами, в своем коде.

ГЛА

ВА 10

Page 472: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

472 глава 11

надеемся еще увидеться

Ïàðà ñëîâ íà ïðîùàíèå…

Жаль, что нам пора расставаться, но теперь вы знаете все необходимое для построения собственных сайтов, использующих jQuery, и вам пора заняться делом. Нам было приятно представить вам мир jQuery. Черкните нам пару строк или расскажите о своих классных разработках Feel на сайте Head First Labs:http://headfirstlabs.com.

Ðàäû áûëè âñòðåòèòüñÿ ñ âàìè â ñòðàíå jQuery!

Page 473: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Хочешь еще чем-нибудь поделиться со мной?

Приложение I. Остатки

Десять важных вещей(которые мы не рассмотрели)

Даже после всего сказанного многое осталось «за кадром». Существует масса других полезных возможностей jQuery и JavaScript, которые нам не удалось вместить в книгу. Было бы неправильно даже не упомянуть о них. Мы хотим, чтобы вы были готовы к любому аспекту jQuery, с которым вы можете столкнуться во время самостоятельных исследований.

Page 474: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

474 приложение I

все без исключения

1. Âñå, ÷òî åñòü â áèáëèîòåêå jQuery

Вероятно, вы уже поняли, что библиотека jQuery огромна. Мы постарались представить основной материал, который может понадобиться новичку. Теперь вы знаете все необходи-мое и можете продолжить самостоятельное изучение библиотеки.

.add()

.addClass()

.after()jQuery.ajax().ajaxComplete().ajaxError()jQuery.ajaxPrefilter().ajaxSend()jQuery.ajaxSetup().ajaxStart().ajaxStop().ajaxSuccess().andSelf().animate().append().appendTo().attr().before().bind().blur()jQuery.browser.change().children().clearQueue().click().clone().closest()jQuery.contains().contents().context.css()jQuery.cssHooks.data()jQuery.data().dblclick()deferred.always()deferred.done()

deferred.fail()deferred.isRejected()deferred.isResolved()deferred.pipe()deferred.promise()deferred.reject()deferred.rejectWith()deferred.resolve()deferred.resolveWith()deferred.then().delay().delegate().dequeue()jQuery.dequeue().detach().die()jQuery.each().each().empty().end().eq().error()jQuery.errorevent.currentTargetevent.dataevent.isDefaultPrevented()event.isImmediatePropagationStopped()event.isPropagationStopped()event.namespaceevent.pageXevent.pageYevent.preventDefault()event.relatedTargetevent.resultevent.stopImmediatePropagation()event.stopPropagation()

event.targetevent.timeStampevent.typeevent.whichjQuery.extend().fadeIn().fadeOut().fadeTo().fadeToggle().filter().find().first().focus().focusin().focusout()jQuery.fx.intervaljQuery.fx.offjQuery.get().get()jQuery.getJSON()jQuery.getScript()jQuery.globalEval()jQuery.grep().has().hasClass()jQuery.hasData().height().hide()jQuery.holdReady().hover().html()jQuery.inArray().index().innerHeight().innerWidth().insertAfter().insertBefore()

Ìåòîäû jQuery

Page 475: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 475

остатки

1. Âñå, ÷òî åñòü â áèáëèîòåêå jQuery (ïðîäîëæåíèå)

.is()jQuery.isArray()jQuery.isEmptyObject()jQuery.isFunction()jQuery.isPlainObject()jQuery.isWindow()jQuery.isXMLDoc()jQuery().jquery.keydown().keypress().keyup().last().length.live().load().load()jQuery.makeArray().map()jQuery.map()jQuery.merge().mousedown().mouseenter().mouseleave().mousemove().mouseout().mouseover().mouseup().next().nextAll().nextUntil()jQuery.noConflict()jQuery.noop().not()jQuery.now().offset().offsetParent().one().outerHeight().outerWidth()

jQuery.param().parent().parents().parentsUntil()jQuery.parseJSONjQuery.parseXML().position()jQuery.post().prepend().prependTo().prev().prevAll().prevUntil().promise().prop()jQuery.proxy().pushStack().queue()jQuery.queue().ready().remove().removeAttr().removeClass().removeData()jQuery.removeData().removeProp().replaceAll().replaceWith().resize().scroll().scrollLeft().scrollTop().select().serialize().serializeArray().show().siblings().size().slice().slideDown()

.slideToggle()

.slideUp()

.stop()jQuery.sub().submit()jQuery.support.text().toArray().toggle().toggle().toggleClass().trigger().triggerHandler()jQuery.trim()jQuery.type().unbind().undelegate()jQuery.unique().unload().unwrap().val()jQuery.when().width().wrap().wrapAll().wrapInner()

Ìåòîäû jQuery (ïðîäîëæåíèå)

Page 476: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

476 приложение I

все без исключения (продолжение)

1. Âñå, ÷òî åñòü â áèáëèîòåêå jQuery

Селектор "Все" ("*")Селектор "Атрибут содержит префикс" [name|="value"]Селектор "Атрибут содержит" [name*="value"]Селектор "Атрибут содержит слово" [name~="value"]Селектор "Атрибут завершается" [name$="value"]Селектор "Атрибут равен" [name="value"]Селектор "Атрибут не равен" [name!="value"]Селектор "Атрибут начинается" [name^="value"]:animated:button:checkbox:checkedСелектор дочерних элементов ("parent > child")Селектор классов (".class"):contains()Селектор потомков ("ancestor descendant"):disabledСелектор элементов ("element"):empty:enabled:eq():even:file:first-child:first:focus:gt()

Селектор "Имеет атрибут" [name]:has():header:hiddenСелектор идентификаторов ("#id"):image:input:last-child:last:lt()Селектор множественных атрибутов [name="value"][name2="value2"]Множественный селектор ("selector1, selector2, selectorN")Селектор "Следующий смежный" ("prev + next")Селектор следующих одноуровневых элементов ("prev ~ siblings"):not():nth-child():odd:only-child:parent:password:radio:reset:selected:submit:text:visible Selector

Ñåëåêòîðû jQuery

Page 477: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 477

остатки

2. jQuery CDN

CDN (Content Distribution Networks, «сети доставки контента») — большие сети серверов, предназначенные для хранения и распространения информации (данных, программ-ных продуктов, кода API, мультимедийных файлов и видеороликов и т. д.), обеспечи-вающие доступность информации в Интернете. Каждый узловой сервер содержит копию предоставляемых данных. Рациональное размещение узлов в Сети позволяет ускорить доступ к информации для многих пользователей. Примеры традиционных CDN — Windows Azure и Amazon CloudFront.

Многие крупные фирмы предоставляют копии jQuery в общедоступных сетях CDN. Ниже приводятся ссылки на копии jQuery, которыми вы можете пользоваться.

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

http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js

http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js

http://code.jquery.com/jquery-1.6.2.min.js (компактная версия)

Google Ajax API CDN

Microsoft CDN

jQuery CDN (через Media Temple)

http://code.jquery.com/jquery-1.6.2.js (исходная версия)

Page 478: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

478 приложение I

метод noConflict

3. Ïðîñòðàíñòâî èìåí jQuery: ìåòîä noConflict

Многие библиотеки JavaScript используют символ $ в качестве имени функции или пере-менной, как это делает jQuery. В случае jQuery $ представляет собой синоним для имени jQuery, поэтому вся функциональность работает и без использования $. Если вам понадо-бится включить другую библиотеку JavaScript, кроме jQuery, передайте контроль за име-нем $ другой библиотеке, используя вызов $.noConflict:

<script type="text/javascript" src="other_lib.js"></script><script type="text/javascript" src="jquery.js"></script><script type="text/javascript">

$.noConflict(); //Код, использующий $ из других библиотек

</script>

Данный прием особенно эффективен в сочетании с возможностью метода . ready опре-делять синоним для объекта jQuery, так как в функции обратного вызова, передаваемой .ready, можно использовать $ без риска возникновения конфликтов:

<script type="text/javascript" src="other_lib.js"></script><script type="text/javascript" src="jquery.js"></script><script type="text/javascript"> $.noConflict();

jQuery(document).ready(function($) { // Код, использующий $ из jQuery }); // Код, использующий $ из других библиотек

</script>

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

Page 479: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 479

остатки

4. Îòëàäêà êîäà jQuery

Отладка кода всегда полезна, особенно если вы работаете над крупномасштабным проектом, в котором используется множество разнообразных объектов, включаемых файлов или API. Нередко бывает нужно узнать содержимое полученного объекта или переменной, но вы не хотите выводить его в окне сообщения или вообще разбираться с получением свойств объекта.

На помощь приходят отладочные модули расширения. Они помогут заглянуть внутрь объектов, чтобы вы могли проследить за интересующими вас свойствами или пона-блюдать за изменением состояния переменной с течением времени, например узнать о непреднамеренном присваивании null. Все эти возможности чрезвычайно полезны при отладке кода JavaScript и jQuery.

При программировании на JavaScript и jQuery нам показались особенно полезными два отладочных модуля расширения — Dump и VariableDebugger.

http://plugins.jquery.com/project/Dump (для просмотра содержимого объектов).http://plugins.jquery.com/project/VariableDebugger (аналогично, но с выводом инфор-мации во временном окне).

Существуют и другие отладочные модули расширения, а со временем наверняка их будет все больше — как и усовершенствований уже существующих модулей. Эти моду-ли показались нам полезными, но если вам захочется поискать что-нибудь получше, посетите сайт jQuery Plug-ins (http://plugins.jquery.com/) и проведите поиск по слову «debug».

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

Page 480: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

480 приложение I

очереди

5. Ðàñøèðåííàÿ àíèìàöèÿ è î÷åðåäè

Очереди в jQuery чаще всего используются для анимации, но вы можете использовать их так, как счи-таете нужным.

Очередь представляет собой массив функций, существующий на уровне элемента и хранящийся в jQuery.data. Очереди работают по принципу FIFO (First In, First Out, т. е. «первым вошел, первым вышел». Функции включаются в очередь вызовом .queue, а исключаются вызовом . dequeue.

Каждый элемент может иметь одну или несколько очередей функций, присоединенных к нему из jQuery. В большинстве приложений используется только одна очередь (fx). Очереди позволяют выполнить с элементом последовательность операций асинхронно, т. е. без прерывания программы. Типичный пример — последовательный вызов нескольких методов анимации для элемента:

$('#my_element').slideUp().fadeIn();

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

Метод .queue напрямую работает с содержимым очереди функций. Особенно удобен вызов .queue с передачей функции обратного вызова; он позволяет поместить новую функцию в конец очереди.

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

$('#my_element').slideUp();$('#my_element').queue(function() { alert('Animation complete.'); $(this).dequeue();});

Эта запись эквивалентна следующей:

$('#my_element').slideUp(function() { alert('Animation complete.');});

Учтите, что при добавлении функции вызовом .queue для выполнения следующей функции в очереди необходимо вызвать функцию .dequeue.

В jQuery 1.4 вызываемая функция передается в первом аргументе другой функции. При ее вызове следу-ющий элемент автоматически выводится из очереди, а очередь продолжает двигаться:

$("#test").queue(function(next) { // Здесь что-то происходит... next();});

По умолчанию в jQuery используется очередь fx.

ПРИМЕЧАНИЕ. Если вы используете пользовательскую очередь, то должны вручную исключать функ-ции из очереди вызовом .dequeue. В отличие от очереди по умолчанию fx, пользовательские очереди не поддерживают автозапуск!

Page 481: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 481

остатки

6. Ïðîâåðêà ôîðì

К сожалению, нам не хватило места для описания такой важной возможности, как использо-вание jQuery для проверки данных форм на стороне клиента/браузера. В главах 9, 10 и 11 был приведен небольшой пример проверки данных на стороне сервера средствами PHP перед вставкой в базу. Проверка на стороне сервера очень важна, и даже можно сказать, необходима. Некорректно построенная команда insert или select может выдать намного больше инфор-мации о ваших данных, чем вы предполагали изначально.

Но вернемся к проверке данных на стороне клиента.

Существует много модулей расширения jQuery, предназначенных для этой цели. Одно из наших любимых решений — модуль «validation», доступный по адресу http://docs.jquery.com/Plugins/validation.

Этот модуль расширения позволяет определить набор правил для каждого элемента формы. В этих правилах вы настраиваете процедуру проверки и уточняете критерии правильности данных. Они могут быть любыми: минимальная или максимальная длина поля, проверка обя-зательных полей, проверка действительного формата адреса электронной почты и т. д. Далее приводятся некоторые примеры с сайта jQuery.

Элемент name определяется как обязательный, а элемент email — как обязательный и содержа-щий действительный адрес электронной почты.

$(".selector").validate({ rules: { // Простое правило, преобразуемое в {required:true} name: "required", // Составное правило email: { required: true, email: true } }});

Элемент определяется как обязательный (required) с минимальной длиной (minlength) 2, причем для обоих правил определяются пользовательские сообщения.

$("#myinput").rules("add", { required: true, minlength: 2, messages: { required: "Required input", minlength: jQuery.format("Please, at least {0} characters are necessary") }});

Page 482: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

482 приложение I

эффекты jquery ui

7. Ýôôåêòû jQuery UI

Библиотека jQuery UI Effects содержит ряд дополнительных анимаций, отсутствующих в ба-зовой библиотеке jQuery. Эти эффекты можно разбить на три категории.

Цветовые анимацииЦветовые анимации расширяют функцию animate так, чтобы она могла анимиро-вать изменения цветов. Поддерживается цветовая анимация следующих свойств:

backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color outlineColor

1

Переходы классовПереходы классов расширяют базовый API классов так, чтобы он мог анимировать переход между двумя классами. jQuery UI изменяет следующие методы для передачи трех дополнительных параметров: speed, easing (необязательно) и callback.

addClass(class) Добавляет класс с анимированным переходом между состояниями.removeClass(class) Исключает класс с анимированным переходом между состояниями.toggleClass(class) Добавляет класс, если он отсутствует, или исключает его, если он входит в группу.switchClass(currentClass, newClass) Заменяет один класс другим с анимацией перехода.

2

Расширенное сглаживаниеРасширенное сглаживание (easing) включено в базовую функциональность Effects. Это jQuery-версия функций сглаживания, созданных Робертом Пеннерсом на ActionScript для Flash. Это математические формулы, позволяющие сделать анима-цию объектов более плавной и точной. Полный список всех функций сглаживания:

3

linear

swing

jswing

easeInQuad

easeOutQuad

easeInOutQuad

easeInCubic

easeOutCubic

easeInOutCubic

easeInQuart

easeOutQuart

easeInOutQuart

easeInQuint

easeOutQuint

easeInOutQuint

easeInSine

easeOutSine

easeInOutSine

easeInExpo

easeOutExpo

easeInOutExpo

easeInCirc

easeOutCirc

easeInOutCirc

easeInElastic

easeOutElastic

easeInOutElastic

easeInBack

easeOutBack

easeInOutBack

easeInBounce

easeOutBounce

easeInOutBounce

Page 483: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 483

остатки

8. Ñîçäàíèå ñîáñòâåííûõ ìîäóëåé ðàñøèðåíèÿ jQuery

Написание модулей расширения jQuery — исключительно полезная возможность, кото-рая экономит массу времени и усилий в ходе разработки. Самые сложные и ответственные функции абстрагируются в модули, предназначенные для повторного использования.

Вместо того чтобы долго объяснять тонкости создания модулей расширения jQuery, мы луч-ше предоставим это дело экспертам. Чрезвычайно содержательный и подробный учебник доступен по адресу http://docs.jquery.com/Plugins/Authoring.

Несколько рекомендаций для тех, кто только начинает заниматься разработкой собствен-ных модулей расширения jQuery.

Всегда заключайте свой модуль расширения в конструкцию (function( $ ){ // код модуля })( jQuery );.

Избегайте лишнего использования ключевого слова this в непосредственной об-ласти видимости функции вашего модуля расширения.

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

Вместо длинного списка аргументов передавайте конфигурацию вашего модуля расширения в виде объекта, поля которого могут заменять настройки по умол-чанию.

Не загромождайте объект jQuery.fn более чем одним пространством имен на каждый модуль расширения.

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

Page 484: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

484 приложение I

замыкания

9. Çàìûêàíèÿ

Замыкания (closures ) — чрезвычайно сложный аспект JavaScript. Хотя замыкания не вошли в книгу, мы твердо убеждены в том, что они заслуживают хотя бы кратко-го упоминания.

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

Для начала пару определений…

Странно, не правда ли?

Замыкания полностью зависят от области видимости переменных и объектов, той области, в которой объекты, переменные и функции создаются и остаются доступны-ми и которая определяет контекст обращения к ним. Переменные, объекты и функ-ции могут определяться либо в локальной, либо в глобальной области видимости.

Локальная область видимости: определение чего-либо в ограниченной части кода (например, внутри функции).

Глобальная область видимости: глобальные переменные, объекты и функции, в отличие от локальных, доступны в любой точке вашего кода.

Рассмотрим следующий пример:

function func1(x) { var tmp = 3; function func2(y) { alert(x + y + (++tmp)); } func2(10);}func1(2);

Замыканием называется локальная переменная функции, которая продолжает существовать после возвращения управления.

Каждый раз, когда ключевое слово function встречается внутри другой функции, внутренняя функция имеет доступ к переменным внешней функции.

Page 485: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 485

остатки

10. Øàáëîíû

Шаблоны jQuery все еще находятся в фазе бета-тестирования, но уже сейчас можно ска-зать, что это полезный механизм, который поможет создавать более гибкие сайты без значительного объема кода HTML или jQuery. Шаблоны получают данные и связывают их с готовой разметкой, чтобы одна и та же разметка могла использоваться для отображения взаимосвязанных и похожих данных.

За дополнительной информацией обращайтесь по адресу: http://api.jquery.com/category/plugins/templates/.

9. Çàìûêàíèÿ (ïðîäîëæåíèå)Переменная tmp объявлена с локальной областью видимости внутри функции func1. В сообщениях будет выводиться значение 16, потому что func2 может обратиться к пере-менной x (определенной как аргумент func1), а также к значению tmp из func1.

Но это не замыкание. Замыкание возникает при возвращении внутренней функции, и эта внутренняя функция «замыкается» над переменными func1 перед выходом.

А теперь рассмотрим другой пример:

function func1(x) { var tmp = 3; return function (y) { alert(x + y + (++tmp)); }}var func2 = func1(2); // func2 is now a closure.func2(10);

И снова tmp определяется в локальной области видимости, но функция func2 имеет гло-бальную область видимости. Приведенная выше функция снова выдаст 16, потому что для func2 значения x и tmp продолжают оставаться доступными, хотя они и не находятся не-посредственно в ее области видимости.

Но поскольку переменная tmp находится в замыкании func2, она тоже будет увеличивать-ся при каждом вызове func2.

Существует техническая возможность создания нескольких функций замыкания, скажем, возвращением списка функций или посредством присваивания глобальным переменным. Все они будут обращаться к одним и тем же экземплярам x и tmp; они не будут создавать собственные копии.

Page 486: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012
Page 487: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Приложение II. Настройка среды разработки

Готовимся к великим свершениямВот начну учиться рано

и всех обгоню...

Вам понадобится среда, в которой вы сможете потренировать свои навыки PHP, но так, чтобы ваши данные не стали уязви-мыми для внешних атак. Разработку приложений PHP всегда жела-тельно начинать с безопасной среды и только потом открывать доступ для внешнего мира. В этом приложении приведены инструкции по установке веб-сервера, MySQL и PHP. После их выполнения в вашем распоряжении появится безопасная среда для работы и экспериментов.

Page 488: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

488 приложение II

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

Состав установленного программного обеспечения сильно зави-сит от платформы компьютера. В Mac OS X веб-сервер установлен по умолчанию, а на большинстве компьютеров Windows его нет.

Прежде чем вы сможете разместить готовое приложение в Web, необходимо разработать его с использованием ваших новых навыков jQuery и Ajax. Однако веб-приложение никогда не сле-дует разрабатывать в Web, где любой желающий сможет получить доступ к нему. Установите программное обеспечение локально, чтобы построить и полностью протестировать свое приложение до того, как переводить его в сетевой доступ.

Для построения и тестирования приложений PHP и MySQL необходимо установить на локаль-ном компьютере три программных продукта:

1. Веб-сервер

2. PHP

3. Сервер баз данных MySQL

PHP — не сервер, а набор правил, которые «понимает» веб-сервер (они нужны, чтобы интер-претировать код PHP). Веб-сервер и сервер MySQL — исполняемые программы, запускаемые на компьютере.

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

×òî ó âàñ óæå åñòü?

Ñîçäàíèå ñðåäû ðàçðàáîòêè PHP

Примечание: материал приложения относитсяк Windows XP, Vista, Windows 7 и Windows Server 2003/2008,а на платформе Mac — к Mac OS X 10.3.x и более новых версий.

Веб-сервер

Сервер баз данных

Серверный компьютер

Сервер баз данных MySQL часто устанавливает-ся на одном компьютере с веб-сервером. В данной ситуации это ваш локаль-ный компьютер!

Поддержка PHP устанавлива-ется как часть веб-сервера и позволяет веб-серверу вы-полнять сценарии PHP.

В среде разработки PHP локальный компьютер вы-полняет функции серверного компьютера в отношении выполнения сценариев PHP.

Для предоставления сценариев PHP в виде веб-страниц потре-буется программный продукт, называемый веб-сервером,например Apache или IIS.

локальная установка php и mysql

Page 489: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 489

настройка среды разработки

Ó âàñ óñòàíîâëåí âåá-ñåðâåð?

Ó âàñ óñòàíîâëåíà ïîääåðæêà PHP? Êàêàÿ âåðñèÿ?

Если вы работаете на новом PC или Mac, возможно, веб-сервер уже установлен. Откройте окно браузе-ра и введите в адресной строке команду адрес http://localhost. Если в браузере откроется заставка, это означает, что веб-сервер установлен и нормально работает.

Если веб-сервер установлен, вы сможете легко проверить, установлена ли у вас поддержка PHP, и какая именно версия. Создайте сценарий с именем info.php и включите в него следующую команду:

<?php phpinfo(); ?>

Сохраните файл в каталоге, используемом веб-сервером. В Windows типичная команда выглядит так:

C:\inetpub\wwwroot\ (для IIS)

или:

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs (для Apache)

А вот как она обычно выглядит на Mac:

/Users/yourname/sites/

Если вы захотите открыть этот файл в своем браузере по адресу http://localhost/info.php,то при установленной поддержке PHP результат будет примерно таким:

На компьютере Windows с IIS заставка выглядит примерно так.

Если вы работаете на ком-пьютере Mac или Windows с установленным веб-сервером Apache, заставка выглядит примерно так.

Установленная версия PHP

Windi dows

вы р баботае

Page 490: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

490 приложение II

$ cd /usr/local/mysql

$ mysqlWelcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 3Server version: 5.0.51b MySQL Community Server (GPL)Type 'help;' or '\h' for help. Type '\c' to clear the buffer.mysql>

File Edit Window Help IHeartPHP

Ó âàñ óñòàíîâëåí MySQL? Êàêàÿ âåðñèÿ?

Чтобы проверить наличие MySQL на Mac, откройте терминал и введите:

cd /user/local/mysql

Если команда работает, значит сервер MySQL установлен. Для проверки версии введите команду:

mysql

Если коман-да выполне-на успешно, значит сер-вер MySQL установлен.

Версия MySQL, установлен-ная в вашей системе

В системе Windows щелкните правой кнопкой мыши на панели задач Windows, выберите Диспетчер задач и перейдите на вкладку Службы.

Проверьте, есть ли MySQL в списке.

Терминал MySQL также называется «монитором» MySQL.

проверка версии mysql

Page 491: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 491

настройка среды разработки

Íà÷íåì ñ âåá-ñåðâåðà

В зависимости от того, какая версия Windows установлена на вашем компьютере, вы можете загру-зить Microsoft IIS (Internet Information Server) или Apache, веб-сервер с открытым кодом. Если вам нужен сервер для Mac, вероятно, стоит остановиться на веб-сервере Apache, потому что он уже уста-новлен на вашем компьютере.

Далее приводится краткое описание установки Apache в Windows.

Откройте страницу http://httpd.apache.org/download.cgi.

Если вы используете Windows, мы рекомендуем загру-зить файл apache_2.2.19-win32-x86-no_ssl.msi. Когда файл будет загружен, сделайте на нем двойной щелчок, чтобы начать автоматическую установку.

Загрузите эту версию и сделайте на ней двойной щелчок после загрузки.

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

Выберите домен, к кото-рому принадлежит ваш компьютер. Если домена нет, введите localhost.

Проще всего выбрать ти-пичный вариант установки.

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

Page 492: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

492 приложение II

Óñòàíîâêà Apache... çàâåðøåíèå

Работа почти закончена. Щелкните на кнопке Install и подождите пару минут. Вот и все!

Веб-сервер настраивается на автоматический запуск при загрузке системы. Впрочем, вы можете останавливать и запускать его по своему усмотрению в диалоговом окне Па-нель управления�Администрирование�Службы. Веб-сервер находится в списке под именем Apache2.2.

Óñòàíîâêà PHPЕсли вы используете Windows, откройте страницу http://www.php.net/downloads.php или http://windows.php.net/download.

Для Windows мы также рекомендуем загрузить соответствующую версию с автомати-ческой установкой. Пользователи Apache загружают файл php-5.2.17-Win32-VC6-x86.msi, а пользователи IIS — файл php-5.3.6-Win32-VC9-x86.msi. Загрузите файл и двойным щелч-ком начните автоматическую установку PHP.

Раздел загрузки версий для Windows в формате .msi Прочитайте описание

и выберите версию.

Загрузите файл и сделайте на нем двойной щелчок. Кнопка Run начинает установку.

установка php

Если эти инструкции вам не подошли, повторите попытку или введите строку «установ-ка Apache в Windows» в поисковой системе.

Page 493: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 493

настройка среды разработки

Äåéñòâèÿ ïî óñòàíîâêå PHP

Для начала необходимо принять несколько три-виальных решений.

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

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

Будьте внимательны. Если вы используете Apache, выберите правильную версию. Если вы используете ISAPI, то, скорее всего, следует выбрать модуль IISAPI. За до-полнительной информацией обращайтесь к документации. В данном примере был выбран веб-сервер Apache 2.2, а на следующем экране вводится путь к установленно-му экземпляру Apache.

Прокрутите список Extensions и выберите MySQL. Это позволит использовать встроенные функции PHP по работе с MySQL, использованные в книге!

Прокрутите список в категории Extensions и щелкните на пункте MySQL. Выберите вариант «Entire feature».

Page 494: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

494 приложение II

Также вам потребуется сервер баз данных MySQL; давайте разберемся, как загрузить и установить его. Бесплатная версия РСУБД MySQL сейчас официально называется MySQL Community Server.

Ниже приведено описание последовательности действий по установке MySQL в Windows и Mac OS X. Эта краткая сводка не заменит превосходных инструкций с сайта MySQL; мы настоятельно рекомендуем посетить сайт и прочитать их! За более подробным описанием и рекомендациями по решению проблем обращайтесь по адресу:

Также вам пригодится программа просмотра запросов MySQL, которая позволяет ввести запрос и ознакомиться с результатами в интерфейсе приложения (вместо консольного окна).

http://dev.mysql.com/doc/refman/5.5/en/windows-installation.html

Èíñòðóêöèè è ðåøåíèå ïðîáëåì

Загрузите версию 5.5 и выше.

Óñòàíîâêà MySQL

Вот и все! Щелкните на кнопках Install и Done, чтобы закрыть программу установки.

Äåéñòâèÿ ïî óñòàíîâêå PHP... çàâåðøåíèå

установка mysql в windows

Если инструкции вам

не подошли,

повторите попытку

или введите

«установка PHP

для Apache [или IIS]

в Windows»

в поисковой системе.

Создайте новый сценарий с именем info.php и включите в него команду:

<?php phpinfo(); ?>

Сохраните файл в каталоге своего веб-сервера. В системе Windows это обычно папка

C:\inetpub\wwwroot\ (для IIS) или

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs (для Apache). На Mac обычно используется /Users/yourname/sites/.

Откройте файл в браузере: http://localhost/info.php,

Если поддержка PHP была установлена успешно, результат должен выглядеть примерно так:

Page 495: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 495

настройка среды разработки

Óñòàíîâêà MySQL â ñèñòåìå Windows

Немного прокру-тите вниз.

Откройте страницу:http://dev.mysql.com/downloads/

И щелкните на кнопке «Download the Beta» в разделе MySQL Installer for Windows. (Примечание: на момент написания книги существовала только бета-версия.)

1

Выберите в списке Microsoft Windows.2

Page 496: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

496 приложение II

Щелкните на ссылке No thanks, just take me to the downloads! (если только вы не хотите зарегистрироваться на сайте или у вас уже имеется учетная запись).

Когда откроетсядиалоговое окно ма-стера установки, щелкните на кнопке Install MySQLProducts.

Çàãðóçêà ïðîãðàììû óñòàíîâêè

Продолжитьбез регистрации.

установка mysql в системе windows (продолжение)

Выберите версию 5.5.13 и выше.

Верхний вариант!

Выберите в списке Windows(x86, 32-bit), MSI Installer.3

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

4

Когда файл будет загружен, щелкните на нем правой кнопкой мыши и выбе-рите команду «Запуск от имени администратора» (если у вас включен меха-низм Windows UAC). Дальнейшая установка будет осуществляться под руко-водством мастера установки. Щелкните на кнопке Next.

5

Page 497: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 497

настройка среды разработки

Âûáîð ïàïêè äëÿ óñòàíîâêè

Прочитайте текст лицензии, согласитесь на ее условия и щелкните на кноп-ке Next.

6

На следующем шаге выполняется автоматическая проверка на наличие новых версий. Если вы хотите пропустить ее, установите флажок Skip Check. Лучше, чтобы приложение устанавливалось в самой последней версии. После обнов-ления нажмите Next, чтобы продолжить установку.

7

Page 498: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

498 приложение II

установка mysql в системе windows (продолжение)

Вам будет предложено выбрать тип установки. Для наших целей идеально подойдет стандартный вариант для разработчиков ( Developer Default). Оставьте пути установ-ки, предложенные по умолчанию, и нажмите Next.

8

Программа установки проверяет совместимость с Microsoft .NET Framework 4 Client Profile. Это необходимо для приложения MySQL Workbench. Если проверка не про-ходит, обновите Windows на сайте http://update.microsoft.com/.

9

В следующем окне перечислены все устанавливаемые компоненты. Щелкните на кнопке Execute, чтобы начать установку.

10

Page 499: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 499

настройка среды разработки

После подтверждения успешной установки всех компонентов нажмите Next, чтобы перейти к настройке конфигурации службы MySQL. Установите переклю-чатель Developer Machine и нажмите Next.

11

Убедитесь в том, что флажки Enable TCP/IP Networking и Create Windows Service установлены. Оставьте в других полях значения по умолчанию. Введите пароль привилегированного пользователя MySQL, нажмите Next.

12

Установка завершается. Если приложение MySQL Workbench не запустилось ав-томатически, запустите его командой меню Пуск�Все программы�MySQL.

13

Page 500: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

500 приложение II

Если вы используете Mac OS X Server, в вашей системе уже должна быть установлена вер-сия MySQL.

Прежде чем продолжать, проверьте, нет ли в вашей системе установленного экземпляра MySQL (выберите команду Applications/Server/MySQL Manager).

Óñòàíîâêà MySQL â Mac OS X

Прокрутите вниз.

установка mysql в системе mac os x

Поддержка PHP входит в Mac OS X версии 10.5+ (Leopard), но по умолчанию она заблоки-рована. Чтобы включить ее, необходимо открыть основной файл конфигурации Apache http.conf и убрать комментарий в одной строке кода. Этот файл находится в папке установ-ки Apache.

Найдите строку кода, которая начинается с «решетки» (#) — признака комментария:

Âêëþ÷åíèå ïîääåðæêè PHP â Mac OS X

#LoadModule php5_module libexec/apache2/libphp5.so

Удалите «решетку» и перезапустите сервер, чтобы активизировать поддержку PHP. Вла-дельцем файла http.conf является пользователь «root», а это означает, что для его измене-ния вам придется ввести свой пароль. Вероятно, вам также придется внести изменения в файл php.ini. За подробной информацией о том, как выполнить эти действия и включить поддержку PHP, обращайтесь по адресу http://foundationphp.com/tutorials/php_leopard.php.

Откройте страницу:http://dev.mysql.com/downloads/

и щелкните на ссылке MySQL Community Server.

В этом описании используется 32-разрядная версия. Убедитесь в том, что за-гружаемая версия соответствует вашей операционной системе.

1

Page 501: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 501

настройка среды разработки

Чтобы найти ее, список придется прокрутить!

Щелкните на кнопке Download для версии Mac OS X v10.6 (x86, 32-bit), DMG Archive.

2

Щелкните на ссылке No thanks, just take me to the downloads! (если только вы не хотите зарегистрироваться на сайте или у вас уже имеется учетная запись).

3

Для ускорения загрузки выберите сервер, расположенный ближе всего к вам.

Продолжить без регистрации.

Page 502: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

502 приложение II

Щелкните на ссылке No thanks, just take me to the downloads! (если только вы не хотите зарегистрироваться на сайте или у вас уже имеется учетная за-пись) и снова выберите зеркальный сервер для загрузки.

Çàãðóçêà óñòàíîâî÷íîãî ïàêåòà

Продолжить без регистрации.

установка mysql в системе mac os x (продолжение)

Вернитесь на страницу:http://dev.mysql.com/downloads/

и щелкните на ссылке MySQL Workbench.

44

Когда загрузка обоих файлов будет завершена, сделайте двойной щелчок на файле mysql-5.5.14-osx10.6-x86.dmg, а затем на файле mysql-5.5.14-osx10.6-x86.pkg, чтобы запустить программу установки пакета.

5

Установочный пакет

Page 503: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 503

настройка среды разработки

Çàïóñê óñòàíîâêè ïàêåòà

Начинается установка. Нажмите Next, чтобы перейти к странице Read Me, а за-тем нажмите Continue, чтобы перейти к странице с лицензионным соглашением.

6

В следующем окне выводится текст лицензионного соглашения MySQL. Если вы согласны на его условия, щелкните на кнопке Continue, а затем на кнопке Agree. Снова щелкните на кнопке Continue, чтобы установить MySQL в каталог по умол-чанию.

7

Page 504: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

504 приложение II

Через некоторое время появляется сообщение об успешном завершении установки.

установка mysql в системе mac os x (продолжение)

Щелкните на кнопке Install, введите имя и пароль администратора и щелкните на кнопке OK, чтобы начать установку.

48

Повторите те же действия для файла MySQLStartupItem.pkg.9

Установочный пакет

Page 505: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 505

настройка среды разработки

Сделайте двойной щелчок на файле MySQL.prefPane, также входящем в образ mysql-5.5.14-osx10.6-x86.dmg, для установки приложения MySQL Preference Pane; за-тем щелкните на кнопке Start MySQL Server.

10

Установочный пакет

Page 506: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

506 приложение II

установка mysql в системе mac os x (продолжение)

Сделайте двойной щелчок на файле mysql-workbench-gpl-5.2.34.osx-i686.dmg (который также был загружен ранее), чтобы запустить процесс установ-ки программы MySQL Workbench.

11

Перетащите значок MySQLWorkbench.app в папку Applications.

Запустите программу Workbench из списка приложений.

Page 507: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

дальше � 507

настройка среды разработки

Убедитесь в том, что сервер работает (панель Server Administration). Если панель пуста, щелкните на ссылке New Server Instance и выберите сервер.

12

Создайте новое подключение в разделе SQL Development: щелкните на ссылке New Connection и введите данные в открывшемся окне. Затем сделайте двойной щелчок на новом подключении, чтобы открыть его.

13

За дополнительной информацией о MySQL и MySQL Workbench обращайтесь по адресу http://dev.mysql.com/doc/.

Page 508: Бенедетти Р., Крэнли Р. - Изучаем работу с jQuery (Head First O'Reilly) - 2012

Райан Бенедетти, Ронан Крэнли

Изучаем работу с jQuery

Перевел с английского Е. Матвеев

Заведующий редакцией А. Кривцов Руководитель проекта А. Юрченко Ведущий редактор Ю. Сергиенко Литературный редактор Б. Файзуллин Художественный редактор Л. Адуевская Корректор В. Ганчурина Верстка Е. Леля

ООО «Мир книг», 198206, Санкт-Петербург, Петергофское шоссе, 73, лит. А29. Налоговая льгота — общероссийский классификатор продукции ОК 005-93, том 2;

95 3005 — литература учебная. Подписано в печать 16.05.12. Формат 84х108/16. Усл. п. л. 55,440. Тираж 2000. Заказ

Отпечатано в ОАО «Первая Образцовая типография», филиал «Дом печати - ВЯТКА» в полном соответствии с качеством предоставленного оригинал-макета.

610033, г. Киров, ул. Московская, 122 Факс: (8332) 53-53-80, 62-10-36


Recommended