/
Author: Вайк А.
Tags: языки программирования компьютерные технологии программирование информационные технологии справочное руководство язык программирования javascript
ISBN: 966-7992-00-04
Year: 2001
Text
Исчерпывающее руководство об основном языке сценариев
для создания полнофункциональных\Л/еЬ-приложений
Исследуется связь JavaScript с другими Web-технологиями
как со стороны клиента, так и со стороны сервера
Э* Своевременные решения
Объектно-ориентированная
методология и ее воплощение в
JavaScript
Фундаментальные основы языка
JavaScript
Операторы, управляющие
структуры, функции и базовые
объекты
¦ Исчерпывающий анализ объектной
модели документов
Объекты, используемые со
стороны клиента и со стороны
сервера
¦ Помещение на Web-страницы
эффектов, характерных для
динамического HTML
Устойчивая работа сценариев в
браузерах Netscape Navigator и
Microsoft Internet Explorer
Сопровождающий CD-ROM
Исходные тексты всех примеров,
рассмотренных в книге
Полезные инструментальные
средства независимых
разработчиков
Многое другое
SAMS
PUBLISHING
.-. книга-почтой [ интернет-магазин
www.diasoft.kiev.ua
JavaScript
тм
THIRD EDITION
R. Allen Wyke, etal.
SAMS
A Division of Macmillan USA
201 West 103rd Street
Indianapolis, Indiana 46290
UNLEASHED
ЭНЦИКЛОПЕДИЯ
¦ ¦¦— ^- Toorono-издательский гагам I ^.дат. ^ _-». ^^ ifjff .Jit ^ ,в$? ^ jf/"W ^iP JFjtM ^^ Ш
1 торгово-издательский жим
DiaSoft
Аллеи Вайк и др.
Основана в 1996 г.
тм
Киев • ООО "ТИД" ДС" . 2001
УДК004.43@31)
ББК 32.973.26-018.1
В 14
ВАЙК Аллен и др.
В14 JavaScript. Энциклопедия пользователя: Пер.с англ./Аллен Взйк.— К.: ООО "ТИД"ДС", 2001,—480с,
ISBN 966-7992-00-04
Книга JavaScript. Энциклопедия пользователя является наиболее полным учебным и справочным руковод-
руководством по всем версиям языка JavaScript, включая JavaScript 1.5и JScript 5.0. На сегодняшний день JavaScript
представляет собой самый распространенный язык для написания сценариев, обеспечивающих поддержку
интерактивного содержимого Web-страниц. Книга охватывает широкий спектр вопросов, начиная с основ
языка и заканчивая сложными вопросами практического применения технологий Web-дизайна. Подробно
рассматриваются: взаимодействие JavaScript и HTML; типы данных, операции, выражения и операторы;
основы объектно-ориентированной методологии и ее реализация в JavaScript; объекты со стороны клиента и
сервера; DHTML; технологии написания устойчивого и надежного кода; методика отладки кода. Особое вни-
внимание в книге уделяется вопросам достижения безопасности Web-приложений.
Книга изобилует множеством практических примеров, которые покрывают всю специфику разработки
Web-сайтов с использованием JavaScript.Справочник по базовым языковым объектам превращает книгу в
истинное настольное руководство.
Сопровождающий CD-ROM содержит исходные коды всех примеров, рассмотренных в книге, а также
множество другой полезной информации.
JavaScript. Энциклопедия пользователя рассчитана на широкий круг разработчиков Web-приложений.
Учебное издание ББК 32.973.26-018.1
ВАЙК Аллен и др.
JAVASCRIPT. ЭНЦИКЛОПЕДИЯ ПОЛЬЗОВАТЕЛЯ
Головний редактор Ю.Н.Артеменко
Верстка Г.А.Булавко
Головний дизайнер О.А.Шадрт
Здано на складання 20.07.2001. Пщписанодо друку 20.09.2001. Формат 84x108/16. ITanip
¦офсетний. Гарнпура Тайме. Друк офсетний. Умовн.друк.арк. 34,80. Обл.-вид.арк. 34,80
Тираж 2000 прим. Замовлення № 1-158.
ТОВ "ТВД"ДС", 04053, Киш-53, вул. Артема 25, а/я 100, тел./факс @44) 212-1254.
e-mail: books@diasoft.kiev.ua, http://www.diasoft.kiev.ua.
Свщоцтво про внесения суб'екта видавничо! справи до Державного реестру видавщв, виготшниюв i роз-
повсюджувач!в видавничо! продукци: сер!я — ДК, №558 вщ 09.08.2001р.
Отпечатано в соответствии с качеством предоставленных
диапозитивов на ОАО «Белоцерковская книжная фабрика»
09117, г. Белая Церковь, ул. Леся Курбаса, 4
Authorized translation from the English language edition published by Sams
Copyright ©2001
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or
mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the
Publisher.
Russian language edition published by DiaSoft Publishing.
Copyright © 2001
Лицензия предоставлена издательством Sams Corporation, подразделение Macmillan Computer Publishing.
Все права зарезервированы, включая право на полное или частичное воспроизведение в какой бы то ни
было форме.
ISBN 966-7992-00-4 © Перевод на русский язык. ООО "ТИД" ДС", 2001
ISBN 0-672-31763-Х (англ.) © Sams Corporation, 2001
© Оформление. ООО "ТИД" ДС", 2001
Гигиеническое заключение № 77.99.6.953.П.439.2.99 от 04.02.1999
Оглавление
Введение13
Часть I. Знакомство
с JavaScript 15
Глава 1. JavaScript и
World Wide Web 16
Знакомство с JavaScript 16
Десять заповедей JavaScript, которые должен
знать каждый создатель сценариев 17
JavaScript можно внедрить в HTML 17
JavaScript зависит от среды 18
JavaScript — интерпретируемый язык 19
JavaScript — слабо типизированный язык 19
Javascript — объектно-ориентированный язык .... 19
JavaScript — язык, управляемый событиями 20
JavaScript — это не Java 20
JavaScript —многофункциональный язык 20
JavaScript — развивающийся язык 20
Сферы использования JavaScript 20
Четыре фазы развития World Wide Web 21
Фаза 1. Символьный гипертекст 21
Фаза 2. Графически-ориентированные
статические HTML-документы 21
Фаза 3. Динамические HTML-документы 21
Фаза 4. Активные HTML-документы 22
Среда разработки Web-приложений 22
Клиентская часть 23
Серверная часть 25
Что можно сделать при помощи JavaScript? 27
Клиентские приложения 27
Проверка допустимости данных 27
Создание интерактивных форм 27
Клиентские таблицы поиска 27
Поддержка состояния 27
Работа с Java-аплетами, элементами
управления ActiveX и подключаемыми
модулями 27
Поддержка JavaScript со стороны браузеров 28
Netscape Navigator. 28
Microsoft Internet Explorer 28
Другие браузеры 28
Сравнение JavaScript и JScript 28
Что такое VBScript? 28
Программирование в VBSript 30
Резюме .. ..31
Глава 2. Совместная работа
JavaScript и HTML 32
Основы HTML 32
Текущая ситуация 32
Основы HTML 33
Структура HTML-документа 33
Основное об атрибутах 34
Внедрение JavaScript в HTML 34
Атрибуты дескриптора <script> 34
Просмотр кода JavaScript 37
Создание JavaScript-кода 37
Выполнение сценариев 37
Учет браузеров, не поддерживающих
JavaScript 39
Написание кода 40
Выполнение сценариев 41
Резюме 41
Глава 3. Создание собственного
набора инструментальных средств
JavaScript 42
Необходимые инструментальные средства 42
JavaScript-редакторы 42
HTML-редакторы 43
Web-браузеры 44
Отладчики сценариев 45
Процесс разработки на JavaScript 45
Серверные инструментальные средства
JavaScript 45
Netscape's Server-Side JavaScript 45
Borland JntraBuilder 45
Резюме 45
Глава 4. Создание
первого сценария 46
Краткое напоминание 46
Перед началом работы 46
Какие браузеры будут поддерживаться? 46
Как следует учитывать браузеры, не
noflaepxHBaioLMHeJavaScript? 47
Встроить код или вынести его в отдельный
файл? 48
Каковы ваши цели? 48
Приступаем к созданию сценария 48
Определение целей 49
Создание шаблона кода 49
JavaScript. Энциклопедия пользователя
щ
Учет He-JavaScript-браузеров 49
Написание кода 49
Вызов функции 50
Первый сценарий 50
Резюме 51
Часть II. Базовое подмножество
языка JavaScript 52
Глава 5. Основы языка JavaScript 53
Краткое резюме 53
Как JavaScript связан с CGI, дополнительно
вставляемыми модулями и Java 53
CGI 53
Подключаемые модули 54
Java 54
Внедрение сценариев в HTML-документы 55
События 56
Синтаксис 56
Версии JavaScript 56
Лексемы 57
Переменные 60
Константы 63
Цвета 63
Типы данных 64
Выражения 64
Комментарии 66
Функции 67
Резюме 68
Глава 6. Операции 69
Операции присваивания 70
Арифметические операции 70
Операции сравнения 71
Строковые операции 73
Условные операции 74
Булевы операции 74
Операция typeof 74
Определение и вызов функций 75
Операции со структурами данных 75
Поразрядные операции 75
Поразрядные логические операции 76
Поразрядные операции сдвига 76
Зачем вообще возиться с разрядами? 77
Приоритеты выполнения операций 79
Резюме 80
Глава 7. Управляющие структуры
и организация циклов 82
Условные операторы 82
if .. .. 82
,if..else 84
try..catch 85
Операторы организации циклов 85
for 85
for..in ! 87
while 88
do..while 88
break и continue 88
Метки 89
Операторы with 90'
Оператор switch 91
Резюме 91
Глава 8. Функции 93
Понятие функций 93
Создание функций 93
Где объявлять функции 94
Вызов функции 94
Использование аргументов 94
Изменение количества аргументов 96
Использование глобальных и локальных
переменных 99
Передача объектов по ссылке 100
Дополнительные сведения о функциях 101
Повторное использование функций 101
Рекурсивные функции 101
.Резюме 102
Глава 9. Объекты со стороны
клиента 103
Понятие объекта 103
Объекты 103
Инкапсуляция 106
Сообщения 107
Классы 107
Объекты JavaScript 109
Точечная нотация 109
Исследование объектной модели JavaScript 110
Отношения содержания в JavaScript 110
Свойства 111
Методы 111
События 112
Дополнительная информация об объектах 113
Объект navigator 114
Объект Window. 116
Объекты верхнего уровня 119
Объекты второго уровня 122
Объекты третьего уровня 126
Объекты четвертого уровня 129
Резюме 130
Оглавление
Глава 10. Основные объекты языка .... 131
Объект Global 131
Объект String 131
Примеры манипуляций со строками 134
Форматирование строк 135
Работа со специальными символами 139
Преобразование строк и чисел 140
Объект RegExp 141
Объект Array 141
Объект Date 144
Объект Math 147
Объект Boolean 148
Объект Number 149
Объект Function 149
Резюме 150
Глава 11. Создание пользовательских
объектов JavaScript 151
Создание объектов 151
Создание экземпляров 153
Работа с экземплярами объектов 154
Создание составных объектов 156
Динамическое создание объектов 159
Расширение экземпляров объектов 162
Резюме 162
Глава 12. Серверная часть
JavaScript 163
Использование архитектуры клиент/сервер 163
Web-приложения с клиент-серверной
архитектурой 163
Передача информации между клиентом и
сервером 164
Управление сеансами 165
Разработка серверных приложений JavaScript 166
Создание исходных файлов 166
Подготовка приложения 168
Исправление ошибок 170
Базовые серверные объекты JavaScript 172
Объект Server. 172
Объект Project 173
Объект Client 173
Объект Request 174
Объект Lock 175
Объект File 175
Объект SendMail 177
Объекты баз данных 178
Резюме .... ..181
Часть III. Использование DOM 182
Глава 13. Основы объектной модели
документа (DOM) 183
'Понятие объектной модели документа 183
От DHTML к DOM 183
Навигация по таблице 184
Управление документами 184
Объектная модель и атрибуты 185
Навигация по документу. 186
Резюме 187
Глава 14. Управление событиями 188
Понятие событий и обработчиков событий 188
Обработчики событий JavaScript 188
Щелчок на объекте (onClick) 189
Отправка формы (onSubmit) 190
Сброс формы (onReset) 190
Изменение данных (onChange) 191
Получение фокуса (onFocus) 191
Выход из фокуса (onBlur) 192
Выделение текста (onSelect) 193
Перемещение мыши по объектам
(onMouseOver и onMouseOut) 193
Загрузка документа (onLoad) 196
Выход из документа (onUnload) 197
Обработка ошибок (onError) 197
Прерывание загрузки изображения (onAbort) 198
Замена обработчиков событий 198
Программная генерация событий 198
События таймера 198
Резюме 199
Глава 15. Объект Window 200
Объект Window. 200
Открытие и закрытие окон 201
Ссылки на окна 202
Определение содержимого окна 202
Определение атрибутов окна 202
Закрытие окон 204
Навигация между окнами 207
Косвенная установка фокуса 207
Прямая установка фокуса 208
Удаление фокуса 208
Отображение окон сообщений 208
Простое уведомление 208
Yes/No-подтверждение 210
Пользовательский ввод 210
Работа с сообщениями строки состояния 212
Резюме .. ...213
JavaScript. Энциклопедия пользователя
Глава 16. Объект Document 214
Объект Document 214
Программное создание HTML-документов 214
Изменение цвета документа 216
Объект Link 218
Ссылки на объекты Link 219
Выполнение JavaScript-кода для ссылок 220
Объект Anchor 223
Объект Image 223
Резюме 224
Глава 17. Объекты Form 225
Объект Form 225
Отправка формы на сервер 225
Проверка элементов в Form 227
Объект Text 229
Присваивание объекту Text значения по
умолчанию 229
Выделение текста в фокусе 230
Захват данных с помощью объекта Textarea 231
Перенос текста в объекте Textarea 231
Объекты Button: Submit, Reset и Button 231
Объект Checkbox 233
Определение заполнения объекта Checkbox 233
Объект Radio 234
Определение значения выбранного
переключателя 234
Объект Select : 235
Создание списка выбора 235
Создание прокручиваемого списка 236
Создание прокручиваемого списка с
мультивыбором 236
Определение значения или текста выбранной
опции 237
Определение значений в прокручиваемых
списках с мультивыбором 237
Выбор опции с помощью JavaScript 238
Объект Password 238
Объект Hidden 239
Резюме 241
Глава 18. Объекты Frame 242
Объект Frame 242
Создание фреймов 243
Размещение дескрипторов 244
Добавление JavaScript-кода ко фреймам 246
Синхронизация фреймов 247
Обновления фреймов 249
Сценарии для фреймов с картами
изображений 252
Работа с фреймовыми URL 254
Ссылки на фреймы 254
Ссылки из дочернего фрейма на
родительский 256
Объект Location 260
Открытие нового URL 260
Работа со свойством protocol 261
Объект History. 262
Определение размеров списка 262
Навигация по списку посещений 262
Объект Navigator 264
Резюме 265
Глава 19. Другие DOM-объекты 266
DOM-браузеры 266
Управление DOM-документами и DOM-методы 268
Использование метода cloneNode 268
Использование метода insertBefore в DOM 269
Использование метода swapNode 269
Использование метода removeNode 269
Резюме 270
Часть IV. Технологии
программирования на
динамическом HTML 271
Глава 20. Динамическая подмена 272
Знание событий 272
onMouseOver 272
¦onMouseOut 272
onMouseDown 272
on MouseUp 272
Виды динамических подмен 272
Rollover-эффекты для изображений 273
ЯоНоуег-эффекты для слоев 274
Резюме 276
Глава21. Визуальные эффекты 277
Бегущие строки 277
Баннеры 278
Постепенное изменение цветов 281
Анимированные командные кнопки 282
Резюме 284
Глава 22. Каскадные таблицы
стилей 285
Основные концепции таблиц стилей 285
Стандарты 285
Наследование 286
Границы и заполнение текста пробелами 286
Комментарии 286
Использование стилей вдокументах 286
Определение стилей 287
Оглавление
Применение стилей 288
¦Смешивание селекторов 289
Определение старшинства стиля 290
Объекты стилей в JavaScript 290
document.tags 290
document.classes. 290
document.ids. 290
Свойства 290
Резюме 292
Глава 23. Слои 293
Универсальные действия 294
Использование таблиц стилей для создания
слоев 294
Управление накладывающимися слоями 298
Создание мультипликационныхэффектов 299
<div> и <iframe> 299
Определение блоков данных 299
Вставка внешних файлов 303
<1ауег> и <ilayer> 305
Пример страницы со вкладками 305
Пример со сталкивающимися шариками 307
Резюме 310
Глава 24. Меню и панели
инструментов DHTML 311
Начальные предположения 311
Выяснение возможностей 311
Планы на будущее 311
Учет API 312
Проектирование меню 312
Определение слоев 312
Обработка действий 314
Использование меню 314
Описание дополнительных возможностей 316
Создание инструментальных панелей 317
Применение событий 317
Описание проблем проектирования 318
Модульное программирование 318
Создание изображений 318
Написание HTML-кода 318
Реализация rollover-эффектов для
изображений 320
Реализация поля адреса 321
Обработка событий, связанных с кнопками 322
Проверка результатов 322
Резюме 325
Глава 25. Взаимодействие с
другими технологиями 326
Подключаемые модули браузера 326
Подключаемые модули и MIME-типы 326
Определение устанавливаемых подключаемых
модулей 327
Элементы управления ActiveX 328
Понятие элемента управления ActiveX 328
Реализация защиты 329
Доступ с помощью JScript 329
Java-аплеты 330
Доступ к Java из JavaScript 330
Доступ к JavaScript из Java 331
Подробнее о Java-аплетах 335
LiveAudio 336
Использование JavaScript-методов 337
Воспроизведение звуков в ответ на
JavaScript-события 337
Резюме 339
Часть V. Избранные
программные технологии 340
Глава 26. Гарантия работы
сценариев в браузерах Netscape и
Microsoft 341
Версии языка и версии браузера 341
Сравнительный анализ JavaScript-диалектов 342
JavaScript от Netscape 342
JavaScript 1.0 342
JScript от Microsoft 348
Ошибки 353
Резюме 354
Глава 27. Методы выяснения типа
браузера 355
Подход "Все или ничего" 355
Подход "Выяснение по месту" 355
1 Тип браузера 356
Версия браузера 356
Версия JavaScript 356
Платформа операционной системы 356
Пример динамического позиционирования 356
Резюме 359
Глава 28. Навигация по сайту с
использованием JavaScript 360
Исследование технологий навигации 360
Создание сценария для динамической
инструментальной панели 360
Создание объекта Toolbar 361
Обсуждение дополнительных возможностей 365
Использование объекта History. 365
Резюме. . . . ....366
JavaScript. Энциклопедия пользователя
Глава 29. Формы и верификация
данных 367
Установка пользовательской обратной связи 368
Создание формы для обратной связи
пользователем 368
Тестирование пользовательской формы 369
Вывод окон сообщений 370
Использование сообщения о состоянии 372
Верификация данных, введенных
пользователем 373
Верификация ввода данных в форму. 373
Обеспечение согласованности 373
Обеспечение бизнес-правил 374
Лроверка на завершенность 375
Создание интерактивных форм 376
Использование вычисляемых полей 377
Создание повторно используемого кода
верификации 378
Целые числа 378
Строки 379
Денежные значения 379
Кредитные карточки 380
Пример: тестер цветов JavaScript 381
Резюме 384
Глава 30. Персонализация и
динамические страницы 386
Статические Web-страницы 386
Немного о cookie-наборах 387
Преимущества cookie-наборов 387
Ограничения и недостатки cookie-наборов 387
Мифы о cookie-наборах 388
Использование cookie-наборов 388
Получение значений cookie-наборов 389
Установка значений cookie-наборов 389
Удаление cookie 391
Пример применения cookie-набора 391
Серверы и браузеры, поддерживающие
механизм cookie-наборов 398
Другие способы поддержки информации о
состоянии 398
Строка запроса 398
Скрытые переменные формы 400
Резюме 400
Глава 31. Выполнение поиска по
шаблону с использованием
регулярных выражений 401
Создание регулярных выражений 401
.Конструктор RegExpO 401
Оператор присваивания 401
Синтаксис регулярных выражений 401
\wm\W 402
\sm\S 402
\dn\D 402
[\Ь] 403
Точка 403
[...]иГ-1 403
[х-у] и [-х-у1 403
{х,у},{х,}и{х} 403
?, + и* 403
Логическое или (|) 403
{...) 403
\х 403
- 4ОЗ
$ 404
\Ьи\В 404
Использование регулярных выражений 404
Тестер регулярных выражений 405
.Пользовательский интерфейс 406
Функция поиска 406
Функция замены 406
Функция очистки 406
Пример: программа проверки правильности
ввода телефонных номеров 407
Резюме 408
Глава 32. Технология обработки
данных со стороны клиента 409
Определение источника данных: клиент или
сервер? 409
Что такое клиентская таблица? 410
Создание таблиц поиска 410
Создание поискового пользовательского
интерфейса 411
Обработка поисковых запросов 412
Отображение результатов поиска 413
Запуск приложения 414
Резюме 419
Глава 33. Обработка ошибок 420
Типы ошибок 420
Синтаксические ошибки 420
Ошибки времени выполнения 421
Логические ошибки 421
Интерпретация сообщений об ошибках 421
Исправление кода 422
Проверка кода HTML 422
Использование комментариев для
идентификации проблем 422
Оглавление
Использование метода alert() для трассировки
кода 423
Тестирование кода 423
Программирование с использованием
устойчивыхтехнологий 425
Высокоуровневая разработка кода проекта и
детальное проектирование 426
Написание модульного кода 426
Написание сильно связанного кода 426
Написание слабо связанного кода 426
Написание повторно используемого кода 426
Написание кода обработки ошибок 426
Использование жестких соглашений по
именованию 427
Использование комментариев 427
Объявление и инициализация переменных 428
Надежная работа кода 428
Резюме 428
Глава 34. Отладка 429
Использование отладчика сценариев Microsoft 429
Обзор возможностей отладчика сценариев
Microsoft 429
Использование отладчика сценариев
Microsoft для отладки файлов 430
Заключительные слова об отладчике
сценариев Microsoft 433
Использование JavaScript-отладчика Netscape 433
Исследование возможностей J
avaScript-отладчика Netscape 433
Использование JavaScript-отладчика Netscape
для отладки файлов 433
Заключительные слова о JavaScript-отладчике
Netscape 435
Использование метода alert() 435
Разбор примера 436
Итоговые слова об использовании
метода alert() 437
Резюме .. ...437
Глава 35. JavaScript и безопасность
в Web 438
Концепции безопасности в клиентской части
JavaScript 439
Атаки на службы 441
Проблемы Netscape Navigator 2.0 441
Более поздние версии Navigator 442
Internet Explorer 3.x 443
Максимизация надежности защиты 443
Безопасные сеансы и цифровые сигнатуры 443
Отключение языков создания сценариев в
браузере 444
Фильтрация через брандмауэр 445
Информационные ресурсы о безопасности
для JavaScript и Java 445
Концепции безопасности в серверной части
JavaScript 446
Java и безопасность 447
Компоненты защиты 448
Ограничения защиты 449
Резюме 450'
Часть VI. Приложение 451
Приложение А. Десять основных
ресурсов в Web, посвященных
JavaScript 452
Netscape DevEdge Online 452
Технологии написания сценариев Microsoft 452
Введение в JavaScript от Voodoo 452
lrt.org 452
Focus on JavaScript 452
SuperScripter 453
JavaScripts.com 453
JavaScript Source 453
Webcoder.com 453
Website Abstraction 453
Сопровождающий CD-ROM 454
Предметный указатель 455
Об авторах
Автор
Аллеи Вайк (Allen Wyke) из Дьюрема, шт. Северная Ка-
Каролина, является главой отдела технологий в Engage
Technology. Упомянутая компания занимается реклам-
рекламным и PR-бизнесом, повсеместно применяя при этом
ведущие Internet-технологии. Аллен Вайк создавал Web-
страницы для интрасетей ведущих сетевых компаний и
разрабатывал множество Web-сайтов. Он программиро-
программировал практически на всех доступных языках и средах, в
частности C++, Java, Perl, Visual Basic, JavaScript и Lingo.
Среди достижений Аллена — соавторство в книгах
Pure JavaScript, The Perl 5 Programmer's Reference, The
Official Netscape Navigator 4 Book, а также в книге для вы-
выпускников колледжей, которая посвящена использова-
использованию Internet. Аллен Вайк немало потрудился над двумя
другими книгами, посвященными разработке Web-стра-
Web-страниц: HTML Publishing on the Internet, Second Edition и The
HTML 4 Programmer's Reference. В свободное время он
пишет статьи в специальную колонку "Webmaster" ("Web-
мастер") для ежемесячного журнала Sun World и ежене-
еженедельно обновляет статью "Windows and UNIX Integration"
("Интеграция Windows и Unix") на сайте ITworld.com.
Соавторы
Ричард Вагнер (Richard Wagner) — вице-президент ком-
компании Product Development for Acadia Software Infuse.
Кроме того, он был главным архитектором продукта
Acadia Infuse, визуального редактора JavaScript, который
вскоре купила компания Net Objects. Помимо авторства
во множестве книг в области компьютерных технологий,
к его заслугам можно причислить создание клиент-сер-
клиент-серверных и Web-приложений. Вагнер — научный редак-
редактор в журнале Delphi Informant, где ежемесячно для его
статей выделяется отдельная колонка "File | New", посвя-
посвященная проблемам разработки программного обеспече-
обеспечения. Вагнер написал Inside Paradoxfor Windows (все ре-
редакции), CompuServe Internet Tour Guide и Inside
CompuServe (все редакции). Он выступил в качестве со-
соавтора в книгах Ultimate Windows 3.1, Inside Windows NT,
Inside Microsoft Access, Inside dBASEfor Windows я Integrating
Windows Applications. В Тейлорском университете Ричард
получил ученую степень бакалавра гуманитарных наук
в области политологии, после чего защитил диплом в
Американском университете. Он доступен по адресу:
rwagner @acadians. com.
Джейсон Джиллиам (Jason D. Gilliam) — разработчик
программного обеспечения в K0Z.com, подразделении
компании Research Triangle Park (шт. Северная Кароли-
Каролина). Джейсон создал множество Web-страниц, а также не
меньшее количество приложений на языке C++, ком-
коммерческих Web-приложений и программ для связи с
базами данных. Он начал программировать в тринадцать
лет, а сейчас является соавтором книги Pure JavaScript.
В Государственном университете Северной Каролины он
получил степень бакалавра в области компьютерной
инженерии. В свободное время Джейсон разрабатывает
аудиопрограммы на базе Windows и сочиняет музыку на
ПК.
Фрэнсис Ботто (Fransis Botto) родился в Свэнси
(Уэллс, Великобритания). Свою карьеру он начал в ка-
качестве автора и исследователя в области новых техноло-
технологий. С середины 80-х годов Фрэнсис известен как один
из первых составителей статей и книг, сохранивших
свою актуальность до сих пор. Сначала они издавались
в Великобритании, после — в Австралии. По сути, его
работа затрагивает сферу пользователя, разработчика и
вопросы концептуального проектирования. Накоплен-
Накопленным опытом Фрэнсис Ботто любезно поделился с чита-
читателями в этой книге.
Посвящения
Все написанное мною — для Мэтта, Джеффа и Грэга.
Ребята, вы не только прекрасные друзья, но и самые
лучшие мужья, найденные моими сестрами.
— Аллен Вайк
Благодарности
Сначала мне хотелось бы поблагодарить Боба Керна (Bob
Kern) из издательства TIPS Publishing и моих соавторов:
Ричарда, Джейсона, Фрэнсиса за их профессионализм,
тяжелый труд и всяческую поддержку во время написа-
написания этой книги. Я весьма благодарен Шелли Джонстон
(Shelley Johnston), проявившей себя в качестве талант-
талантливого и незаменимого редактора, что помогло нам
сконцентрировать все внимание на работе над книгой.
Наконец, мне хотелось бы поблагодарить Кимо
"Кинг" Конга (Kimo "King" Kong) за предоставленную
возможность писать книгу во время работы в Engage,
— Аллен Вайк
Введение
JavaScript в рекордные сроки стал средством разработки
для Web, будь то простое усовершенствование HTML-
страниц, либо создание полнофункциональных Web-
приложений. С другой стороны, Javascript никогда не
станет столь же популярным, как Java или даже HTML.
Однако следует учесть, что JavaScript может обеспечи-
обеспечивать ряд вещей, совершенно не характерных для других
языков программирования, самой главной из которых
следует считать эффективное совместное функциониро-
функционирование абсолютно различных технологий. К JavaScript
вполне применима метафора "мастер на все руки"; она-
то, собственно, и отражает всю неисчерпаемость этого
языка.
Большинство рассматривает JavaScript как клиентс-
клиентский язык. Истинная правда! Многое в данной книге
сфокусировано на внедрении JavaScript в HTML с це-
целью обеспечения работы в среде, поддерживающей бра-
браузерами. Однако JavaScript также известен и как сервер-
серверный язык сценариев. До недавнего времени одними из
первых продуктов, в которых в качестве языка сценариев
для Web использовался JavaScript, были Netscape's
Server-Side JavaScript (SSJS) и Microsoft's Active Server
Pages (ASP).
Ваш покорный слуга является разработчиком, и чем
чаще он использует JavaScript, тем больше отмечается его
пригодность для приложений, создаваемых компанией.
Надеюсь, что способность JavaScript выполнять множе-
множество задач станет для читателей очевидным. А сейчас
самое время перечислить все темы, рассмотренные в
книге:
• Что связывает между собой JavaScript и HTML?
• В чем разница между JavaScript и Java?
• Существует ли какая-либо совместимость между вер-
версиями JavaScript и JScript?
Какие спецэффекты можно создать при помощи
JavaScript?
• Как создать интеллектуальные фреймы с помощью
JavaScript?
• Что такое базовые объекты JavaScript?
• Где применяется ECMAScript?
• Как JavaScript совмещается с элементами управления
ActiveX, программными расширениями и Java-апле-
тами?
¦• Как JavaScript поддерживает текущее состояние?
Как использовать JavaScript на собственном Web-сер-
Web-сервере?
Как при помощи JavaScript подключиться к базе дан-
данных SQL?
Кому адресована эта книга?
Поскольку JavaScript — основной язык сценариев для
Web, то он используется при решении задач различного
рода. Вот лишь небольшой перечень тех, кто применяет
JavaScript: Web-мастера, HTML-дизайнеры, разработчи-
разработчики Java-приложений, разработчики приложений баз дан-
данных, опытные пользователи.
Я уверен, что читатели, относящиеся к любой из этих
категорий, по достоинству оценят книгу. Предполагает-
Предполагается, что читатель обладает базовыми знаниями Web-тех-
Web-технологий и HTML. Какой-то первоначальный опыт ра-
работы с JavaScript не нужен, однако определенные
знания в области программирования на языке сценари-
сценариев все же не помешают. С другой стороны, если вы
никогда раньше не составляли программ, это вовсе не
означает, что данная книга — не для вас. Стоит лишь
помнить, что книга не рассчитана на совершенно начи-
начинающих, поэтому таковым будет не настоль комфорт-
комфортно, как тем, кто обладает определенным опытом. В осо-
особенности последнее касается некоторых главах,
посвященных серверам и базам данных, где базовые
знания обязательны. Все же, набравшись терпения, на-
начинающие программисты смогут успешно изучить эту
книгу и приступить к самостоятельной разработке се-
серьезных бизнес-приложений для Web.
Системные требования
Для работы с JavaScript потребуется компьютер с дос-
доступом в Internet. Авторы книги использовали Windows
(98, 2000, NT), но те же механизмы, касаемые
JavaScript, актуальны и для других платформ (за исклю-
исключением лишь тех, для которых отдельно указано, что
JavaScript на них не поддерживается).
Структура книги
Третье издание книги — всестороннее описание
JavaScript и соответствующих технологий. Книга разде-
разделена на шесть частей, в конце каждой из которых при-
приводится краткое резюме.
Часть 1 Знакомство с JavaScript
Часть 1 — всестороннее знакомство с JavaScript и соот-
соответствующими инструментальными средствами. В главе
1 внимание фокусируется на связи между JavaScript и
разработкой Web-приложений. Кроме того, исследует-
исследуется связь JavaScript с другими Web-технологиями как со
стороны клиента, так и со стороны сервера. О взаимо-
взаимосвязи между HTML и JavaScript, а также об интерпре-
интерпретировании кода браузером в рабочей среде, можно будет
узнать из главы 2. В главе 3 рассматриваются инстру-
JavaScript. Энциклопедия пользователя
ментальные программные средства, требуемые для про-
процесса разработки в JavaScript. В главе 4 описывается пол-
полный процесс составления первого учебного сценария.
Часть 2 Базовое подмножество языка
JavaScript
Здесь подробно рассматривается собственно язык
JavaScript. Главы с 5 по 12 посвящены основам языка,
операторам, управляющим структурам, функциям и
объектам (базовым, клиентским, серверным и пользова-
пользовательским).
Часть 3 Использование DOM
В части 3 подробно исследуется проблематика Document
Object Model (объектная модель документов). Будет рас-
рассмотрен метод размещения элементов на странице, а
также обработка событий (глава 14). Наконец, главы с
15 по 19 содержат подробную информацию по объектам
Window, Document, Form, Frame и другим DOM-объек-
DOM-объектах.
Часть 4 Технологии программирования на
динамическом HTML
В части 4 внимание уделяется различным операциям,
которые выполняются с помощью JavaScript в среде Web.
В главе 21 рассказано о создании анимации, баннеров и
других спецэффектов в JavaScript (без использования
каких-либо Java-аплетов). Глава 22 посвящена каскади-
каскадированным таблицам стилей, а глава 23 — слоям, появив-
появившимся в четвертом поколении браузеров. В главе 24 вся
информация собирается воедино и демонстрируется
методика создания динамических НТМГ-меню и пане-
панелей инструментов. Часть 4 завершается главой 25. В ней
исследуются возможности взаимодействия JavaScript с
другими технологиями, наподобие Java и ActiveX.
Часть 5 Гарантия работы сценариев в
браузерах Netscape и Microsoft
Часть 5 построена именно на том, что интересного чи-
читатель смог вынести из области разработок на JavaScript.
Глава 26 учит, как создавать сценарии, работающие с
браузерами Navigator и Internet Explorer. В главе 27 под-
подробно описывается методика определения браузера, а
глава 28 подскажет, что может предоставить JavaScript
в плане совершенствования навигации Web-сайтов. Гла-
Глава 29 содержит информацию об усовершенствовании
НТМГ-форм с помощью JavaScript, например, за счет
добавления проверки достоверности данных со стороны
клиента. В главе 30 обсуждаются вопросы создания ди-
динамических и персонализированных web-страниц за счет
применения cookie-наборов и других средств сохранения
состояния. В главе 31 представлено сопоставление образ-
образцов в регулярных выражениях, а в главе 32 — способы
сбора и обработки данных. И, наконец, глава 33 посвя-
посвящена обработке ошибок, а глава 34 дает краткие сведе-
сведения об отладке JavaScript-приложений. Книга заверша-
завершается главой 35, в которой обсуждаются вопросы
безопасности в JavaScript.
Часть б Приложение
В приложении А перечислены Internet-ресурсы для
JavaScript. Здесь представлены URT популярных и по-
полезных сайтов, которые помогут лучше разобраться в
JavaScript.
Соглашения, используемые в книге
В книге использованы соглашения, призванные улуч-
улучшить восприятие материала:
• Листинги программ на JavaScript приводятся моноши-
моноширинным шрифтом.
• Имена методов JavaScript, выводимые на экран сооб-
сообщения приводятся полужирным шрифтом.
• Заполнители (слова, подставленные вместо того, 4'iо
необходимо набирать на клавиатуре) выделяются
полужирным курсивом.
• Вновь вводимые термины выделяются курсивом.
• Пункты меню отделяются друг от друга запятыми, на-
например: "Выберите File, Open" означает необходи-
необходимость открыть меню File и в нем выбрать элемент
Open.
• Иногда код JavaScript не вмещается в одну строку. Для
его продолжения на следующей строке используется
знак "стрелочка" (*¦*).
Кроме того, в книге использованы специальные вы-
выделения. Они включают в себя: Примечание, Совет,
Предупреждение, Внимание, Ресурс, Напоминание,
Знакомство
с JavaScript
ЧАСТЬ
Я*
' 1Я*'
* I
, „ >
k -.
i.
2.
3.
4.
В ЭТОЙ ЧАСТИ
JavaScript и World Wide Web
Совместная работа JavaScript и HTML
Создание собственного набора
инструментальных средств JavaScript
Создание первого сценария
-¦?¦
JavaScript и
World Wide Web
В ЭТОЙ ГЛАВЕ
Знакомство с JavaScript
Десять заповедей JavaScript, которые должен
знать каждый создатель сценариев
Четыре фазы развития World Wide Web
Среда разработки Web-приложений
Что можно сделать при помощи JavaScript?
Сравнение JavaScript и VBScript
Как известно, один Internet-год эквивалентен трем
месяцам календарного года. Учитывая это, самой полез-
полезной рекомендацией для читателей будет изучение
JavaScript, что поможет пробиться в первые ряды разра-
разработчиков. Конечно, к этому можно относиться, как к
игре, но для полного понимания работы JavaScript по-
потребуется полностью изучить всю информацию. И как в
любом деле, необходимо бросить все усилия на переработку
информации и понимание приведенных ниже примеров.
Перед углублением во все винтики механизма созда-
создания программ на JavaScript следует разобраться, какова
же цель создания этого языка. JavaScript уже давно вы-
вышел за первоначально планируемые пределы отдельно
взятого браузера. Сейчас его можно найти на серверной
части, а также вместе с последним выпуском операци-
операционной системы Windows. Вариант JavaScript на сторо-
стороне браузера ограничен также, как и другие Web-техно-
Web-технологии: HTML, Java, CSS и подключаемые модули
(plug-ins). JavaScript проявляет себя как исключитель-
исключительно мощное средство, взаимодействующее с другими тех-
технологиями для создания эффективных и обдуманных
решений.
В этой главе предлагается небольшой обзор JavaScript
вместе с кратким анализом среды разработки Web-при-
Web-приложений. После этого будут подробно рассмотрены
сферы использования JavaScript, текущая поддержка
JavaScript в браузерах, а также некоторые отличитель-
отличительные черты JavaScript и VBScript.
Знакомство с JavaScript
Как и все, что связано с Web, новая технология JavaScript
гораздо моложе Java. JavaScript сначала был разработан
компанией Netscape, поэтому его первое имя — LiveScript.
Ожидалось, что этот язык сценариев расширит возмож-
возможности HTML и выступит в качестве частичной альтер-
альтернативы большому числу CGI-сценариев, будет перера-
перерабатывать информацию из формы и добавлять динамику
в пользовательские страницы. После выхода Java ком-
компания Netscape начала работать вместе с компанией Sun
над созданием языка сценариев, чей синтаксис и семан-
семантика по плану должны были тесно связываться с Java.
Отсюда возникло и название JavaScript. В результате
совместных усилий Netscape и Sun и был создан этот
язык.
Одна из причин, послуживших созданию JavaScript,
была связана с потребностью в присутствии логики и
интеллекта не только со стороны сервера, но и клиен-
клиента. В этом случае все выполнение переходит к серверу,
причем даже такие простые операции, как проверка
допустимости данных. Фактически, при отсутствии
логики на стороне клиента Web-среда превращается в
устаревшую хост-терминальную архитектуру, вытеснен-
вытесненную революцией ПК в 80-х годах. Внедрение логики в
браузер существенно усилило клиента и превратило
отношение в истинную клиент-серверную систему.
Java — один из шагов в нужном направлении, одна-
однако Java была внедрена в виде дополнения HTML, и
никто не собирался интегрировать Java с языковой точки
зрения. Хотя Java — строго типизированный язык, он
не подходит для сращивания большого количества тех-
технологий, необходимых Web-мастерам при создании
Web-страниц. Более того, программирование на Java не
требует весьма серьезных знаний и опыта. Поэтому
многие разработчики HTML отказываются от работы,
состоящей лишь в реализации логики для элементов
JavaScript И World Wide Web
формы. Клиентский язык сценариев высокого уровня
казался утерянным звеном на арене Web-технологий.
С момента своего появления (декабрь 1995 г.) язык
JavaScript имел существенную поддержку в лице веду-
ведущих производителей, в числе которых Apple, Borland,
Sybase, Informix, Oracle, Digital, HP и IBM. JavaScript
продолжает развиваться, внедряясь не только в совре-
современные браузеры, но и в приложения, созданные раз-
различными компаниями.
Идея начала скудеть, даже когда присоединилась
компания Microsoft. Понимая всю важность создания
Web-сценариев, Microsoft решила поддержать JavaScript.
Однако компания Netscape предпочла передать
Microsoft лишь только лицензию на право использова-
использования технологии. На основе общедоступной документа-
документации в Microsoft был создан "перепроектированый"
JavaScript — JScript, поддерживаемый Internet Explorer
3.0 и выше. JScript 1.0 плохо совместим с JavaScript 1.1,
используемым Netscape Navigator 3.0 и более поздни-
поздними браузерами. В конечном итоге мириады версий и
различных хитростей, характерных для того или иного
браузера, стали причиной головной боли для разработ-
разработчиков Web-сайтов, использующих JavaScript (см. главу
26). В главе 27 можно найти более подробную инфор-
информацию о работе с различными версиями JavaScript.
К. счастью, огорченные разработчики сценариев
смогли вздохнуть свободно. Компании Netscape,
Microsoft и другие производители решили подогнать
язык под стандарты ЕСМА (European Computer
Manufacturer's Association). В тот период ЕСМА соста-
составила спецификацию языка — ECMAScript, что поддер-
поддержали все производители. Хотя стандарты ЕСМА оказы-
оказывают существенную помощь, все же компании Netscape
и Microsoft продолжают развивать языки JavaScript и
JScript, выходя при этом за пределы стандартов.
Помимо JScript, еще одним конкурентом JavaScript
является VBScript, созданный с целью упрощения Web-
разработок на Visual Basic (VB). VBScript является подмно-
подмножеством языка Visual Basic. Из-за отсутствия поддержки
со стороны Netscape, VBScript используется для интрасе-
тей (или Internet-сайтов). Он пользуются большой попу-
популярностью у пользователей Microsoft Internet Explorer.
Листинг 1.1 Внедрение JavaScript в HTML-файл
Глава 1
Несмотря на появление VBScript, JavaScript стал
стандартным языком сценариев для Web. JavaScript ча-
часто применяется при создании инструментов для раз-
разработки Web-страниц. На стороне сервера Netscape ис-
использует язык, на который часто ссылаются как на
Server Side JavaScript (SSJS). Но к этому мы вернемся
немного позже, в главе 12. Разумеется, компания
Microsoft сочла необходимым минимизировать отстава-
отставание, выпустив технологию Active Server Pages (ASP),
поддерживающую JScript.
Десять заповедей JavaScript, которые
должен знать каждый создатель
сценариев
Изучение JavaScript может оказаться сложной задачей.
Все основы объединены в 10 "заповедей". Они призва-
призваны оказать помощь при овладении JavaScript. Перед
началом работы с языком внимательно изучите их.
JavaScript можно внедрить в HTML
"Бракосочетание" между JavaScript и HTML стало, воз-
возможно, одним из важнейших событий. При работе с
JavaScript на клиентской части можно убедиться, что эта
парочка поистине неразлучна. Программы JavaScript
обычно заключены в HTML-документах, и выполняют-
выполняются в них же. Большинство объектов JavaScript представ-
представлены соответствующими дескрипторами HTML, поэто-
поэтому код находится на уровне клиентской части языка.
Чтобы стать настоящим разработчиком на JavaScript,
следует досконально изучить HTML,
HTML используется в JavaScript как мостик к тому,
что называется средой разработки Web-приложений. Воз-
Возможности HTML расширяются за счет обеспечения
дескрипторов HTML событиями и организации управ-
управляемой событиями среды выполнения.
Позже об этом рассказывается более подробно. В ли-
листинге 1.1 приводится пример внедрения кода JavaScript в
исходный код HTML. Серым выделен текст на JavaScript.
Все остальное — простой HTML.
<html>
<head>
<title>Status Bar</title>
<seript fcypea>!text/5a.vaso
< ! —
window, defaultstatus « "Welcome to the large URL page."
function changes tatus () {
window, status = "Click me to go to the Unleashed home page.
function changeDefaiiltStatus () {
window, detaultstatiis = window, document;
Знакомство с JavaScript
Часть I
""•options [window, document. stattisForni.messageList. selectedlndex] . t
</script>
</head>
<body>
<p>S#160;</p>
<p>K#160;</p>
<p align="center">
<font size=
<strong>http //www. samspublishing . oom</strong>
</fant>
<p align="center">
<a href="http: //www.samspublishiiKj.com"
onmouseover=!;changeStatus() ;return true">
Go...</a>
<p align=center>
<font size="l">
To change the default status bar message, select a message
from the list below and click the Change button.
</font>
<?orm name="statusForm" method="POST">
<select name="messageList" size="l">
<cpticn selected>Welcome to the large URL page.</option>
<option>On route to Sams Publishing</option>
<option>This page intentionally left (nearly) blank. </option>
<option>An exciting example of changing status bar text.
</cptian>
</select>
<input type="button" name:
onclick="changeDefaultStatus ()">
</form>
</body>
</html>
ПРИМЕЧАНИЕ
Готов держать пари, что вы обратили внимание на
type="text/javascript". Действительно, новые стандар-
стандарты HTML и XHTML отказались от языкового атрибута в
дескрипторе <script>. He стоит сейчас беспокоиться, об
этом будет рассказываться в следующих главах.
JavaScript зависит от среды
JavaScript — язык сценариев, а не инструмент. Про-
Программное обеспечение, собственно выполняющее код на
— это механизм интерпретации внутри сре-
среды, к которым относятся браузеры Netscape Navigator,
Microsoft Internet Explorer, а также один из серверных
механизмов. После включения в документы HTML
JavaScript начинает зависеть от браузера (рис. 1.1). Если
же поддержка со стороны браузера отсутствует, тогда
ваш код выполняться не будет. Более того, если пробле-
проблема поддержки браузером решена не будет, код просто
высветится на странице как текст (рис. 1.2) (см. главу 2,
где детально описываются способы предотвращения
вывода кода на экран).
MacOSX
Thenca-generation
operating system.
РИСУНОК 1.1 Microsoft Internet Explorer 4.5ппдд
JavaScript
Очень важно помнить об этой взаимосвязи, если
необходимо использовать JavaScript для создания при-
приложений. Будет ли принято во ннима! : что потребу-
JavaScript u World Wide Web
ется браузер, поддерживающий JavaScript? Если так, то
будет ли организовано уведомление пользователей об
этом? Будет ли создаваться версия, не использующая
JavaScript? При разработке приложений на JavaScript
потребуется ответить на все эти вопросы.
РИСУНОК 1.2. Mosaic не поддерживает JavaScript
ПРИМЕЧАНИЕ
Сразу же после своего появления фреймы оказались
новинкой. Их можно было просматривать только с по-
помощью Netscape Navigator 2.0. Авторы HTML должны
были решить, как использовать фреймы и что делать в
случае, когда браузер их не поддерживает. Их популяр-
популярность существенно возросла в результате поддержки
нией Microsoft в Internet Explorer 3.0, после чего
фреймы стали частью стандарта HTML 4. При использо-
использовании HTML 4 вам обеспечивается браузер, поддержи-
вающийфреймы.
'К счастью разработчиков JavaScript, это та же поддер-
поддержка, что и для JavaScript. Netscape Navigator 2.x, пос-
после — Microsoft Internet Explorer 3.x, затем — Opera 3.x,
а потом — 95% существующих браузеров, поддержива-
поддерживают JavaScript. Если данная тенденция будет и дальше раз-
развиваться, то зависимость от браузеров станет менее зна-
значительной.
¦
JavaScript - интерпретируемый язык
Как и большинство языков сценариев, JavaScript интер-
интерпретируется браузером. JavaScript не компилируется в
'бинарный код наподобие .ехе, но все же остается час-
частью документа HTML. Недостаток интерпретируемого
языка — для выполнения кода затрачивается много вре-
времени, поскольку браузер компилирует директивы во
время выполнения. Однако есть и преимущество -
можно легко и быстро усовершенствовать исходный код.
Не переживайте по поводу старых версий сценариев
JavaScript. Если вы замените их в исходном документе
HTML, то новый код будет выполняться при каждом
получении пользователем доступа к документу.
Глава 1
Небольшая оговорка: разработка на JavaScript, харак-
характерная для Netscape, на стороне сервера потребует ком-
компиляции всех файлов JavaScript и HTML в байт-код,
сохраняемый в файлах .web.
JavaScript - слабо типизированный язык
JavaScript отличается от типизированных языков, таких
как Java и C++, которые требуют объявления всех пе-
переменных определенных типов перед началом их ис-
использования. JavaScript, наоборот, очень гибок. Вы не
обязаны объявлять переменные специального типа.
Если специальный тип вам неизвестен, то можно рабо-
работать с переменной. Последнее утверждение иллюстри-
иллюстрируется фрагментом кода. Например, требуется объявить
переменную myVal, присвоить ей строковое значение и
отобразить ее в окне сообщений. Можно воспользовать-
воспользоваться следующим кодом:
function flexible () (
var myVal // объявляем переменную myVal
mVal = "Pi" // присваиваем myVal некоторое
// значение
alert (itYVal) // используем ее
i
Хотя явное объявление переменных и отражает хо-
хороший тон программирования, вовсе не обязательно
проделывать это. Следующий код, прекрасно функци-
функционирующий в JavaScript, окажется просто немыслимым
в типизированных языках.
function flexible () {
mVal = "Pi" // устанавливаем значение
// необъявленной переменной myVal
alert (iryVal) // используем ее
I
Следующий пример продемонстрирует всю гибкость
языка JavaScript — можно изменить тип значения, пред-
представляемого переменной. Например, переменная myVal
в процессе выполнения функции изменяет строковое
значениеначисленное:
function flexible () (
var myVal = "Pi"
alert (myVal)
myVal = 3.14159
alert (myVal)
Javascript -- объектно-ориентированный
язык
Netscape и другие компании отнесли JavaScript к объек-
объектно-ориентированным языкам (OOP — object-oriented
programming). Как упоминается в главе 9, JavaScript дей-
действительно является объектно-ориентированным языком.
Вы работаете с объектами, которые инкапсулируют
данные (свойства) и поведение (методы). (Если вы уже
Знакомство с JavaScript
Часть I
пользовались точечной нотацией, скажем, в Visual Basic,
Java или Delphi, вам не составит особого труда овладеть
JavaScript.) Однако, хоть и можно работать с объекта-
объектами, их невозможно разделить на подклассы. Объектная
модель JavaScript основывается на экземплярах, а не на
концепции наследования.
JavaScript - язык, управляемый событиями
Большинство составленных кодов будет отвечать на
события, генерируемые пользователем или системой.
Язык JavaScript обладает поддержкой обработки собы-
событий. HTML-объекты, подобные кнопкам и текстовым
полям, усовершенствованы с целью поддержки обра-
обработчиков событий. При переходе к JavaScript из Java
или Visual Basic, эта управляемая событиями среда яв-
является второй натурой. При переходе от процедурной
среды, от среды нисходящего проектирования, потре-
потребуются отдельные знания, связанные с управлением
событиями. В главе 14 подробно описываются собы-
события JavaScript.
JavaScript - это не Java
Путешествуя по просторам Web, читатель мог встретить
фразу: "JavaScript — это не Java". Как обсуждалось ра-
ранее, Java и JavaScript разрабатывались разными компа-
компаниями. Основная причина сходства имен кроется в мар-
маркетинговых соображениях. Мы углубимся в различия
между JavaScript и Java в главе 5, однако сейчас будет
не лишним кратко посмотреть на основные различия и
сходства этих двух языков.
Во-первых, JavaScript тесно интегрирован в HTML,
а Java-аплеты всего лишь связываются с HTML-доку-
HTML-документами через дескриптор <applet>. Сам же аплет хра-
хранится в другом файле, загружаемом из сервера.
Во-вторых, Java — более надежный и функциональ-
функционально полный язык, т.к. ему присущи свойства наподобие
строгого контроля типов, объектной ориентации и на-
наличию компилятора. Если Java предназначен для созда-
создания аплетов и независимых приложений, то JavaScript
— исключительно для написания сценариев.
Синтаксис JavaScript напоминает синтаксис Java.
Если вы привыкните к управляющим структурам
JavaScript, можете считать, что первый шаг к овладению
Java уже сделан.
JavaScript - многофункциональный язык
JavaScript — многоаспектный язык, который может при-
применяться в различных контекстах для решения проблем,
связанных с Web. Немного дальше в этой главе рассмат-
рассматриваются сферы применения JavaScript. Основные цели,
достигаемые при помощи JavaScript:
Усовершенствование и оживление статических HTML-
страниц с помощью спецэффектов, анимации и бан-
неров.
• Проверка данных без передачи на сервер.
• Получение основы для разработки Web-приложений
типа клиент-сервер.
Разработка клиентских приложений.
"Сращивание" со стороны клиента HTML-объектов,
Java-аплетов, элементов управления ActiveX и под-
подключаемых модулей Netscape.
Получение расширения к Web-серверу.
¦• Моделирование связи с базами данных 6e's исполь-
использования CGI.
JavaScript - развивающийся язык
Ранее в главе упоминалось, насколь современен JavaScript
как технология. Учитывая резкие перемены в Web, не-
несложно понять, что JavaScript продолжает свое развитие
в качестве языка. При разработке приложений JavaScript
требуется думать не только о том, поддерживает ли тот
или иной браузер JavaScript, но еще и о том, какое имен-
именно подмножество языка. Не мудрено попасть в безвы-
безвыходную ситуацию, поскольку количество версий пере-
перешло всякие мыслимые пределы: JavaScript — 6 версий
A.0—1.5), JScript — огромное количество версий A.0—5.5
и еще несколько версий наподобие х.х.х).
Посетите страницу Netscape's DevEdge по адресу http://
developer.netscape.com или Mozilla.org (область Open
Source для инструментальных средств браузера Netscape)
по адресу http://www.mozilla.com. Усовершенствования
JScript отражаются на странице Microsoft по адресу
http://msdn.microsoft.com/scripting.
Сферы использования JavaScript
Стоит еще раз напомнить: JavaScript — язык, а не ин-
инструмент. Поскольку это — язык сценариев, его можно
применять в широком диапазоне приложений. Если рас-
рассматривать JavaScript в контексте разработки Web-страниц,
то в большинстве своем применение касается клиентс-
клиентской части. На стороне сервера JavaScript применяется в
средах Netscape Enterprise Server и Microsoft Active Server
Pages. Он является родным языком в наборах инструмен-
инструментальных средств для разработки Web-страниц, таких как
Borland Intra Builder, Macromedia Dreamweaver (начиная
со второй версии). Не следует думать, что JavaScript —
исключительно клиентский язык сценариев. Новейшие
версии Microsoft Windows поддерживают JavaScript на
рабочем столе, вместе со средой Window Script Host
(WSH).
JavaScript u World Wide Web
Глава 1
Четыре фазы развития
World Wide Web
Резкие изменения в Web-технологиях за последние
шесть лет привели к бурному росту Web. Перед обсуж-
обсуждением темы Web-приложений было бы полезно про-
проследить эволюцию Web от простейшего "расширения"
Interene: до уровня "культуры", ставшей частью совре-
современной жизни. Эволюция условно делится на четыре
фазы.
Фаза 1. Символьный гипертекст
Web появилась в 1989 г. и была текстовой гиперссылоч-
гиперссылочной системой. Это ограничение легло в основу потому,
что компьютеры, имевшие доступ к Web, не обладали
качественным способом от ображсния графики на экра-
экране. В первый период существования Web пользователи
должны были вводить числа, представляющие страни-
страницы, которые требовалось просмотреть. Со временем
появилась возможность выбора подсвеченного текста и
перехода к соответствующей странице. Гипертекстовая
сущность Web приобрела революционное значение во
многих областях, связанных с наукой.
Фаза 2. Графически-ориентированные
статические HTML-документы
Вторая фаза развития Web началась в 1993 г. с появле-
появления графического Web-браузера под названием NCSA
Mosaic. Одним из разработчиков Mosaic был студент и
будущий основатель Netscape — Марк Андерсен (Маге
Anderssen). Mosaic разрабатывался для Национального
центра по применению супер-ЭВМ (NCSA — National
Center for Supercomputing Applications). Хотя создание
Web, в основном, было направлено на удовлетворение
нужд научных сообществ, возможность просмотра гра-
графики существенно усилила Internet. В то время графи-
графические среды приобрели гораздо большую популяр-
популярность, нежели настольные символьно-ориентированные
системы. Microsoft выигрывала войну операционных
систем, выпустив на рынок Windows 3.1x.
Графический браузер присоединился к настольной
графической среде и стал именно той "изюминкой",
которую так ждали. Через несколько месяцев компью-
компьютерные компании стали добросовестно и целеустремлен-
целеустремленно проникать в Web.
Web сама по себе осталась статической (см. рис. 1.3).
Содержимое включало в себя текстовые или графичес-
графические документы и ряд других элементов. Возможно, стра-
страница содержала аудио- или видеофайлы. Приходилось
сначала загружать файл, а потом проигрывать его, ис-
используя внешнее приложение.
Welcome to WHkes.Net
эКопе Membership Corporation's
Homo Page
РИСУНОК 1.3 Статическая HTML-страница
Фаза 3. Динамические HTML-документы
В течение первых двух фаз Web-страницы создавались
при помощи текстового редактора НТМГ и помещались
на Web-сервер. После размещения на сервере большин-
большинство страниц оставались статическими до тех пор, пока
автор их не изменял. Статические страницы вполне
подходят для некоторых целей, однако не для всех. Для
динамической генерации НТМГ-документов Web-разра-
Web-разработчики стали использовать CGI-сценарии (CG1 —
Common Gateway Interface, интерфейс общего шлюза),
обеспечивая с их помощью создание НТМГ-докумен-
НТМГ-документов "на лету". Как раз это и стало основой первого уров-
уровня взаимодействия с пользователем в Web. С таким усо-
усовершенствованием Web могла превратиться в платформу
для гипертекстовых документов, и кроме того, служить
средой прикладных приложений. Одним из первых
Web-приложений, демонстрирующих всю мощь новых
технологий, стал Web-сайт курьерской почты Fedrx (см.
рис. 1.4).
[ 3 FmC» I 1i***4 - HiCrO
HE"*-*
Express
all Inlrrrel Ei(Jo=n
Tracking m&
Enter Up To 25 Airbill Numberi
Diter ни Auiiir Nunh-i yer H**.)
BKii
дм I
¦rm Я
I
Forthe latest on serncts,
CUy Г4 pftpWF fOUT
shipments wtJe jWic
urine Yuu can prepare Air .. л
РИСУНОК 1.4. FedEx предложила одно из самых
привлекательных Web-приложений
Знакомство с JavaScript
Часть I
Фаза 4. Активные HTML-документы
Четвертая фаза развития Web началась в 1995 г. с появ-
появлением подключаемых модулей (plug-ins) в Netscape
Navigator и существенно ускорилась за счет внедрения
поддержки Java. Необходимо было усилить клиентскую
сторону и отказаться от опоры исключительно на сер-
сервер при запуске приложений либо обработке информа-
информации, введенной пользователем.
Благодаря Java, Web более не является коллекцией
документов HTML, но может быть истинной клиент-
северной средой, в которой клиент обладает определен-
определенной независимостью от сервера. JavaScript соответству-
соответствует данным требованиям. В JavaScript, Java, ActiveX и
других клиентских расширениях браузер становится
мощнейшей операционной средой, в которой можно
работать с Web-приложениями.
Среда разработки Web-приложений
Использование Web в качестве среды проектирования —
относительно новое явление. С появлением Java, JavaScript,
ActiveX и других технологий, идея развития Web-при-
Web-приложений показалась весьма заманчивой.
Web как среда проектирования может выглядеть
достаточно сложной. Учитывая распределенный харак-
характер Web, Web-приложения могут состоять из множества
частей, в каждой из которых применяется так или иная
технология.
В рамках типичной клиент-серверной архитектуре
на базе локальной сети могут существовать клиентские
приложения, подключенные к сетевому серверу баз дан-
данных. Зачастую клиентское приложение разрабатывает-
разрабатывается с использованием единственного инструмента, ска-
скажем, Delphi или Visual Basic. Как правило, серверная
часть приложения разрабатывается и поддерживается с
помощью инструментальных средств администратора
SQL Server.
На рис. 1.5 показаны элементы, составляющие сре-
среду разработки приложений. Далее каждый из этих эле-
элементов будет рассматриваться более подробно.
Среда разработки web-приложений — реальный при-
пример того, что сумма гораздо лучше, чем отдельно взятые
части.
создание
содержимого
браузеры
Microsoft
Internet
ЕкрЬгег
клиентские
расширения
РИСУНОК 1.5. Среда
разработки Web-
приложений
серверы
серверные
расширения
расширения
баз данных
написание
сценариев
безопасность
управление
содержимым
База данных
Службы
JavaScript U World Wide Web
Сама по себе каждая из этих технологий ограниче-
ограничена и довольно узка в своей области. Но когда эти части
увязываются в единое приложение, повышается эффек-
эффективность средств для развития Internet и интрасетевых
решений.
Клиентская часть
Клиентская часть среды разработки Web-приложений
состоит из 4-х строительных блоков:
• Браузеры
HTML (Hypertext Markup Language, язык гипертек-
гипертекстовой разметки)
• Клиентские расширения (Java-аплеты, элементы уп-
управления ActiveX и подключаемые модули Netscape)
• Языки сценариев (JavaScript и JScript)
Ниже кратко рассматривается каждая из технологий,
а также их совместная работа. Рисунок 1.6 отражает
отношения между ними.
Браузеры
Без сомнений, самая главная часть Web-приложения —
браузер. Браузер — окно в Web для пользователей и
служит пользовательским интерфейсом для вашего при-
приложения. Технология браузеров довольно-таки проста
(чтение HTML и вывод на экран), но появление нестан-
нестандартных усовершенствований, наподобие JavaScript и
Глава 1
слоев Netscape, делает критическим выбор браузера во
время определения платформы разработки.
При создании приложения для интрасети несложно
убедиться, что все пользователи применяют стандарт-
стандартный Web-браузер. Однако при создании Internet-прило-
Internet-приложения для пользователей со всего мира вопросы проек-
проектирования приобретают более сложный характер, с
перевесом функциональных возможностей по отноше-
отношению к совместимости.
Таблица отражает ситуацию с двумя основными
на сегодняшний день браузерами.
HTML
HTML — один из кирпичиков, лежащих в основе Web.
HTML — язык гипертекстовой разметки, создающий
структуру и обеспечивающий форматирование простого
текстового файла. Как "технология", он довольно рутин-
рутинный; некоторые даже заявляют, что он устаревший. Од-
Однако именно эта общность и наделяет язык силой.
Несмотря на то что браузер обеспечивает пользова-
пользователю окно для отображения Web-содержимого, само>
содержимое поступает в форме текста HTML. He име-
имеет значения, представляются ли статические докумен-
документы, возвращается результат запроса, обрабатывается
форма обратной связи или же выводится результат ра-
работы JavaScript-приложения. Какими бы ни были мето-
методы получения этих данных, для их отображения все пре-
превентивно переводится в дескрипторы HTML.
Подключаемые
модули
РИСУНОК1.&
Клиентскаячасть
Браузер
HTML
<html>
<head>
<title>Untitled Normal Page</
title>
<SCRIPT LANGUAGE
"JavaScript">
function
confirmAction(callingObject) {
return
con?irm("Do you really want
this subscription? The
magazine is not really that
good.")
</SCRIPT>
</head>
<body>
Аплеты
элемент
управлении
ActiveX
Языки сценариев
Таблица 1.1. Поддержка клиентских технологий со стороны современных браузеров
Netscape Navigator Microsoft Internet Explorer
Поддержка JavaScnpt/JScnpt
Поддержка VBScript
Поддержка Java
Поддержка ActiveX
Подключаемые модули Netscape
2.0+
Отсутствует
2.0+C.0+для Mac)
3.0+ (подключаемый модуль)
2.0+
3.0+
3.0+
3.0+
3.0+
3.0+
Знакомство с JavaScript
Часть I
Клиентские расширения
По мере возрастания потребностей в активных Web-
страницах, простое расширение браузеров уже не мог-
могло рассматриваться в качестве удобоваримого решения.
Некоторые расширения были подключаемыми модуля-
модулями независимых разработчиков, которые увеличивали
эффективность браузеров. Однако появилась потреб-
потребность работать с выполняемым содержимым (executable
content) в самом браузере. Для самой технологии не обя-
обязательно привязываться к работе конкретного браузера,
хотя он и поддерживает ее.
На сегодняшний день существуют три отдельных
клиентских расширения. У них есть общие черты, рав-
равно как и отличия:
• Java-аплеты
Элементы управления ActiveX
• Подключаемые модули Netscape
Java-аплеты
Если вы никогда не слышали о языке программирова-
программирования Java, вас вполне могут назвать Митрофанушкой. О
Java говорилось гораздо больше, чем о любом другом
языке программирования. Хотелось бы рассказать о нем
в контексте среды разработки Web-приложений.
__ __
РЕСУРС : .. .
.Информация по Java находится на сайте компании Sun
по адресу http://java.sun.com.
:-:¦!
Java — независимый от платформы язык программи-
программирования, разработанный компанией Sun Misrosystems.
Изрядно говорилось о возможности Java создавать со-
содержимое, выполняемое на подавляющем большинстве
платформ.
Внутри среды браузера Java-программы называются
аплетами (applets). Связь с аплетом осуществляется че-
через дескриптор <applet> в документе HTML, в резуль-
результате чего аплет может быть загружен на клиентский
компьютер. Аплет поступает в браузер в виде последо-
последовательности байт-кодов. Если Java браузером поддержи-
поддерживается, байт-код интерпретируется и выполняется на
клиентской машине. Ссылки на Java-аплеты Java-несо
местимыми браузерами игнорируются.
шетьг используются в нескольких сферах. По
мере развития языка применимость его расширяется. На
рис. 1.7 и 1.8 показаны два примера применения Java.
Элементы управления ActiveX
Ранее известные как OCX, элементы управления ActiveX
стали ответной реакцией Microsoft на появление Java-
аплетов. Они напоминают Java-аплеты, поскольку их
можно использовать в качестве средств обеспечения
выполняемого Web-содержимого (см. рис. 1.9). В отли-
отличие от Java, область применения элементов у ipaej
ActiveX ограничена только операционной средой
Microsoft Windows.
га-.- •¦.-
Р
SQIlUlWOStM lines 354 IS Ш ftnf*
rip" ¦-;:¦
a
„:::.._
as
@ |
-¦ *¦"
bib
..,. ,j, i.
E
I
*
:РИСУНОК 1.7. Java-аплетперемещает самолет вдоль экрана.
TjVMuJ H-fL Hrtreopt
3 &';& а) :м* Ш&:
Virtual NYC
РИСУНОК 1.8. Интерактивная карта, реализованная на Java.
Несмотря на то что функционирование элементов
управления ActiveX допускается только в одной опера-
операционной системе, это не означает, что они недоступны
для Web-приложений. Например, один и тот же элемент
управления ActiveX можно использовать в Web-прило-
Web-приложении и запускать его как в браузере с доступным
ActiveX, так и в Delphi или Visual Basic.
Высокое жюри все еще сомневается, что станет ап-
летными стандартами — Java и ActiveX; что будет столь
же известно, как и среда разработки Web-приложений?
Но все же имеет место уклон в сторону ava (по боль-
большей части, из-за опасений инфицирования вирусами,
JavaScript u Worldwide Web
причиной которого могут стать элементы управления
ActiveX). И в том, и в другом случае есть свои преиму-
преимущества и недостатки. К счастью разработчиков JavaScript,
программы могут взаимодействовать с обоими техноло-
технологиями. Глава 25 посвящена совместной работе JavaScript
и элементов управления ActiveX.
РИСУНОК 1.9. 9то это — Javci-аплет или элемент управления
ActiveX?
РЕСУРС
Информация по ActiveX может быть найдена в Internet-
центре Microsoft no адресу http://www.microsoft.com/
com.
. ¦
Подключаемые модули Netscape
Подключаемые модули (plug-ins) — это несколько дру-
другая технология, тем не менее представляющая собой
клиентское расширение Web-браузера. Подключаемые
модули существенно расширяют возможности браузера
Netscape Navigator, связанные с поддержкой дополни-
дополнительных типов данных. В частности, подключаемые мо-
модули применяются для вывода на экран файлов различ-
различных МШЕ-типов (multipurpose Internet mail extension,
многоцелевые почтовые расширения).
После запуска Netscape Navigator начинает поиск
подключаемых модулей в папке program\plugins с целью
их регистрации. Вызов подключаемых модулей выпол-
выполняется по мере необходимости, когда обнаруживается
файл MIME-типа.
После инсталляции подключаемые модули стано-
становятся добавочными модулями браузера и совершенно не
нуждаются во взаимодействии с пользователем для сво-
своего запуска. В действительности они необходимы для
таких мультимедиа-данных, как звук, видео, графика.
На рис. 1.10 показан подключаемый модуль, позволя-
позволяющий просматривать файлы Adobe Acrobat в рамках
Глава 1
Netscape. Для связи с модулями можно использовать
JavaScript.
Г М№ ¦ \b^.lli
. »в a
Pi ' ИХ Т. ч ¦ > и ¦
Adobe JQ&iii Коде и Macintosh
Maw
installing Acrobat ^еш-гг 4.0 tor Macintosh
РИСУНОК 1.10. Просмотр файла PDFnpu помощи подключаемого
модуля.
Клиентские языки сценариев
Последние штрихи магии клиентской части завершают
клиентские языки сценариев. На сегодняшний день ос-
основным таким языком является JavaScript, тем не менее
компания Microsoft выдвигает собственную альтерна-
альтернативу — VBScript. Наибольшей популярностью VBScript
пользуется в кругу разработчиков на Visual Basic. В кон-
конце главы можно найти краткое сравнение возможностей
JavaScript и VBScript.
Серверная часть
Серверная часть среды разработки Web-приложений
состоит из собственно Web-сервера плюс расширения
серверного программного обеспечения. Как будет пока-
показано несколько позже, эти расширения могут принимать
различные формы и работать с различными технологи-
технологиями. На рис. 1.11 показаны взаимосвязи внутри сервер-
серверной части.
Серверы
Web-сервер загружается после отправки со стороны кли-
клиента запроса на требуемые HTML-документы, после
чего возвращает их для просмотра. Программное обес-
обеспечение сервера — это приложение, выполняющееся на
машине с установленным протоколом TCP/IP. Среди
наиболее популярных серверов находятся Netscape
Enterprise Server (NES), Microsoft Internet Information
Server (IIS) и Apache.
Серверные расширения
Собственно Web-сервер обеспечивает передачу статичес-
статических HTML-страниц клиенту при запросе, а также мно-
Знакомство с JavaScript
Часть I
жество других функций. С другой стороны, некоторые
серверные расширения обеспечивают возможности, не
реализованные в самом сервере. К таким возможностям
относятся CGI, серверные API, JavaScript и Java.
Клиенты
Расширения
РИСУНОК 1.11. Серверная часть.
CGI
Интерфейс общего шлюза (CGJ, Common Gateway
Interface) представляет собой стандарт де-факто для
организации взаимодействия внешних программ с Web-
серверами. Запуская CGI-программы и сценарии на
сервере, можно генерировать динамически создаваемое
содержимое и отображать его пользователю.
Типовой сценарий заключается в генерации запро-
запроса из формы HTML и отправка его серверу. Запрос за-
запускает CGI-программу или сценарий, размещенный в
специальном каталоге на сервере. CGl-программа обра-
обрабатывает запрос и возвращает HTML-документ с резуль-
результатами.
GI-программа может разрабатываться на любом
языке программирования: Java, C++, Visual Basic, PHP,
т.е. на том, что способно продуцировать код, могущий
выполняться на Web-сервере. В мире Unix CGI-сцена-
рии принято составлять на языках, подобных Perl или
языкам командных оболочек Unix.
Серверные API
Другой способ интеграции с сервером предполагает ис-
использование его собственного интерфейса прикладного
программирования (API, Application Programming
Interface). Два наиболее используемых API такого рода
- Netscape Server API (NSAPI) и Misrosoft Internet
Server API ASAPI). API обеспечивают более тесную ин-
интеграцию с сервером. Например, в случае Windows для
доступа со стороны сервера потребовалось бы создать
библиотеку DLL, а не отдельный выполняемый модуль
ЕХЕ.
Использование серверных API обладает своим пре-
преимуществом — потоки оказываются гораздо более эф-
эффективными по сравнению с CGI-программами. CGI
требует, чтобы для каждого клиентского запроса выпол-
выполнялся отдельный экземпляр программы. Это приводит
не только к большим издержкам, но также и к ограни-
ограничению максимального объема совместно используемых
данных.
Недостаток использования серверного API шключа-
ется в том, что полученное решение окажется специфи-
специфическим для конкретного сервера. Созданная ISAPI DLL
не будет работать с сервером Netscape. Разумеется, если
работа связана постоянно лишь с одним сервером, упо-
упомянутый негативный момент сводится на нет.
Серверный JavaScript
Повышенное внимание к JavaScript связано с возмож-
возможностями, реализуемыми языком на стороне клиента.
Однако, с не меньшим успехом JavaScript можно ис-
использовать и в качестве серверного инструментального
средства разработки сценариев. Как и следовало ожи-
ожидать, первой средой подобного рода является Netscape.
Среда Netscape SSJS (Server-Side JavaScript) позво-
позволяет использовать сценарии для построения Web-при-
Web-приложений, управляемых Netscape-сервером. Кроме того,
существует несколько серверных расширений для язы-
языка JavaScript, которые обеспечивают дополнительные
возможности генерации динамического HTML, взаимо-
взаимодействия с клиентом, доступа к внешним файлам на
сервере и подключения к базам данных SQL (LiveWire).
Следует отметить, что в ответ компании Netscape,
Microsoft поддерживает JScript в качестве сернерно
языка сценариев в рамках Active Server Pages.
Java
За последние месяцы Java существенно сдала свои по-
позиции на серверной стороне. Компания Sun выпустила
технологию под названием Java Server Pages (JSP), ко-
которая призвана быть конкурентом ASP и SSJS. В насто-
настоящее время компании Sun и Netscape объявили о со-
создании своего рода союза, именуемого iPlanet, цель
которого заключается, помимо прочего, в интеграции
JSP и SSJS в единую технологически мощную среду.
Вы, наверное, слышали о Java-сервлетах (Java Servlets).
Сервлеты представляют собой небольшие компоненты,
более всего похожие на элементы управления ActiveX
в среде ASP, которые могут активизироваться как гото-
готовые страницы либо использоваться для построения
страниц. Это позволяет разработчикам направить на-
накопленные знания Java (который намного проще в изу-
JavaScript u Worldwide Web
Глава 1
чении, нежели С) на построение быстродействующих,
надежных, не зависящих от платформы компонентов,
предназначенных для создания страниц.
Что можно сделать при помощи
JavaScript?
После краткого знакомства с технологиями разработки
Web-приложений самое время посмотреть на роль кли-
клиентской части JavaScript в Web-приложениях.
Клиентские приложения
JavaScript можно использовать для разработки полного
клиентского приложения. Хотя JavaScript и не столь все-
всеобъемлющий язык, каковым является Java, тем не менее,
он проявляет существенные возможности при работе с
дескрипторами HTML и связанными с ними объектами.
Одно из наиболее известных приложений JavaScript,
h Idaho Design's ColorCenter (http://www.hidaho.com/c3),
показано на рис. 1.12. Данное приложение применяет-
применяется для выбора цветов элементов, видимых в браузере, с
возможностью их предварительного просмотра в отдель-
отдельном фрейме. Создание аналогичного приложения с помо-
помощью Java сопряжено с гораздо большими сложностями,
связанными с необходимостью взаимодействия с
HTML. Очевидно, что в отдельных случаях JavaScript
обеспечивает практически идеальную основу для разра-
разработки приложений.
loisfrom Mfcbelow. Sd
ftctive Link. Visited Link or Texture above to set the corresponding
lors/textures. The current link colors arc shown on. the right. The cunent
BODY tag is shown befow:
hies sites by sele themfromthe drop-downlistabove and cEcbng Go,
collect images by clicking the rightmou ton (Mac users click and hold) and
ige Location* from the pep up menu. Then click on the text entry box пей to j|j
v\t the image locabontheie (Ctri-vin Windows). Finally, click Add to add the Щ
РИСУНОК 1.12. hIdaho Design's ColorCenter.
Проверка допустимости данных
JavaScript обеспечивает для Web-разработчиков возмож-
возможность выполнять проверку допустимости данных, вво-
вводимых пользователем, без необходимости обращения к
серверу. Внутри кода JavaScript можно определить, яв-
ляются ли значения, введенные пользователем, коррек-
корректными, или, скажем, соответствуют ли они требуемому
формату. Lopa3flo эффективнее провести проверку дан-
данных в JavaScript, нежели передавать на сервер незавер-
незавершенные данные. Подобного рода подход эффективен не
только для пользователя, вводящего данных, но также и
для сервера. При этом появляется уверенность, что пе-
передаваемые на обработку серверу данные являются пол-
полностью корректными.
Создание интерактивных форм
JavaScript также используется для "оживления" форм
HTML. Одна из задач оживления связана с проверкой
достоверности данных. Другая предполагает реализацию
дополнительных возможностей, недоступных в HTML,
как то поддержка информации в строке состояния, от-
открытие второго окна браузера для отображения, скажем,
справочной информации и т.п.
Клиентские таблицы поиска
Помимо проверки достоверности данных, один из спо-
способов уменьшения потребности доступа к серверу зак-
заключается в использовании JavaScript для генерации и
поддержки клиентских таблиц поиска. Следует по-
помнить, что в таком случае данные должны встраиваться
в сам HTML-документ, поэтому использование таблиц
поиска должно сводится к небольшим информацион-
информационным базам данных, предназначенным только для чте-
чтения.
Поддержка состояния
В Web-среде, не поддерживающей концепцию состоя-
состояния, JavaScript применяется для поддержки состояния
при обмене между сервером и клиентом. Основной спо-
способ поддержки состояния связан с использованием на-
наборов cookies (информации, сохраняемой браузером на
стороне клиента). JavaScript обеспечивает как поиск,
так и хранение cookie-наборов на клиентской части.
Более детальная информация по работе с cookies может
быть найдена в главе 30.
Работа с Java-аплетами, элементами
управления ActiveX и подключаемыми
модулями
По мере развития JavaScript, возрастают возможности
работы с клиентскими расширениями, включая Java-
аплеты, элементы управления ActiveX и подключаемые
модули Netscape. Несложно получить доступ к свой-
свойствам объектов Java и ActiveX, равно как и запускать их
методы. Точно так же несложно определить, установ-
установлен ли конкретный подключаемый модуль. Обладая
подобной возможностью, JavaScript становится своего
Знакомство с JavaScript
Часть I
рода "клеем", соединяющим вместе HTML, аплеты и
клиентские расширения.
Поддержка JavaScript со стороны
браузеров
По сравнению с другими приложениями браузеры -
относительно небольшие части программного обеспече-
обеспечения, однако постепенно они превращаются в мощные
приложения, воплощающие в себе все достижения Web-
технологий. Браузер — это окно в Web, поэтому каким
бы потенциалом на обладал бы JavaScript, однозначно
плохо, если браузер не обеспечивает поддержку этого
языка. Ниже будут рассматриваться особенности под-
поддержки JavaScript в доступных на сегодняшний день
браузерах..
Поскольку JavaScript — язык интерпретируемый и
внедряемый в HTML-документы, он всецело зависит от
работы программы! 'О обеспечения браузера. Устарев-
Устаревшие браузеры не знают, что делать с таким кодом, и
попросту проигнорируют его.
Netscape Navigator
К середине 90-х годов компания Netscape стала одной
из самых влиятельных в Web-индустрии. Она не толь-
только открыла для рынка различные технологические но-
нововведения, но и объединилась с другими лидерами
индустрии, такими как Sun, имея целью продвижение
различных технологий в передние ряды Web.
Поскольку разработчиком JavaScript является
Netscape, вполне можно ожидать, что наилучшим в
плане поддержки языка сценариев станет именно бра-
браузер Navigator. Navigator 2.0 был первым браузером,
поддерживающим JavaScript. Выпущенные позже версии
привнесли важные усовершенствования в сам язык. По-
Поскольку Navigator был перемещен в Mozilla.org, т.е. в
зону Open Source (открытого исходного кода) Netscape,
можно быть уверенным, что разработчики со всего мира
в конечном итоге создадут практически идеальный бра-
браузер. На рис. 1.13 показана бета-версия Mozilla (Netscape
Navigator 5) с отображенной начальной страницей
Mozilla.org.
Microsoft Internet Explorer
Microsoft Internet Explorer 3.0 — первый браузер, создан-
созданный другой компанией, включающий в себя поддерж-
поддержку JavaScript. Более ранние версии Internet Explorer не
обладают поддержкой JScript, т.е. реализации JavaScript
от компании Microsoft.
Другие браузеры
На момент написания книги существовало лишь три
браузера, поддерживающих JavaScript: Sun's Hotlava 3.0
(JavaScript 1.4), Opera (JavaScript 1.1), Be's NetPositive
2.1 (экспериментальная версия).
!Wkn ftb Qflui flA
maznld.org
5 Released
cdioaJ enough for
. Tjsc buyalj.? to report
nrt&Ciypta
Announced
¦.1™*у-И№1
Uc i4« in
РИСУНОК 1.13. Mozilla/Netscap(Navigator5.
Сравнение JavaScript и JScript
Как упоминалось ранее, JavaScript — не единственный
язык сценариев, доступный в Web. На этой арене мо-
могут выступать еще два участника: JavaScript/JScript и
VBScript. Хоть данные языки и отдалились от действи-
действительно конкурентно-способных языков (создается впе-
впечатление, что на данный момент они просто дополня-
дополняют друг друга), все же нелишним будет сравнить все
достоинства и недостатки JavaScript и VBScript. Ниже
рассматривается, что есть VBScript, как он соотносится
с JavaScript, и для примера приводится простое VBScript-
приложение.
ПРИМЕЧАНИЕ
Последние исследования показывают, что количество
Web-сайтов, использующих VBScript, составляют незна-
незначительную часть в общем числе сайтов, поддерживаю-
поддерживающих JavaScript.
Что такое VBScript?
VBScript представляет собой язык сценариев для Web,
разработанный компанией Microsoft, полностью парал-
параллельный языку JavaScript. Все, что находится в основе
VBScript, существенно отличается от первоистоков
JavaScript. В то время как JavaScript создавался практи-
практически "с нуля", слабо основываясь на C++ и Java,
VBScript принадлежит к языковому семейству Visual
Basic. Среди членов данного семейства: Visual Basic -
распространенный язык программирования для
Windows, Visual Basic for Applications — макроязык для
Microsoft Office и других приложений. Если когда-либо
доводилось разрабатывать программное обеспечение на
JavaScript u World Wide Web
Visual Basic, гораздо быстрее получится освоить
VBScript.
Наиболее актуальная информация по VBScript находит-
находится на сайте Microsoft по адресу http.'//
www.msdn.microsoft.com / scripting.
Встроенный язык HTML
Как и JavaScript, VBScript является языком написания
сценариев, внедренным в HTML-файлы. Подобно
JavaScript, VBScript использует дескриптор <script> с
указанием "text/vbscript" в качестве значения описате-
описателя типа. Например, следующий сценарий отображает
диалоговое окно предупреждения после загрузки стра-
страницы:
<html>
<bead>
<script type="text/vbscript">
alert("Is this JavaScript or VBScript?")
</script>
</head>
</html>
Самое интересное, что можно почерпнуть из приве-
приведенного выше примера, так это то, что синтаксис двух
языков совершенно одинаков. Если изменить параметр
type на "text/javascript", результат останется тем же.
Объектная модель
Одним из наиболее важных факторов при сравнении
JavaScript и VBScript является идентичная базовая
объектная иерархия, хотя в других версиях могут суще-
существовать и различия. Для Web-разработчика, использу-
использующего оба языка, это — весьма приятный сюрприз,
поскольку гораздо проще использовать синтаксически
разные языки, нежели принципиально различные пара-
парадигмы. Преобразование кода JavaScript в код VBScript
или наоборот, как правило, носит построчный характер.
В этих двух языках написания сценариев идентичны
не только объектные модели, но также и способ работы с
HTML-объектами. Подобно JavaScript, VBScript может
реагировать на события, генерируемые HTML-объекта-
HTML-объектами. Например, в следующем примере после нажатия
кнопки Convert (листинг 1.2) все буквы текста, введен-
введенного в поле myText, преобразуются в прописные.
Листинг 1.2. Пример на JavaScript.
<html>
<head>
<script type="text/javascript">
function convertText() {
document.SampleForm.myText.value =
document.SampleForm.myText.value.toUpperCase()
Глава 1
</script>
</head>
<body>
<form name="SainpleForm">
<input type="text" name="myText">
<input type="button" value="Convert"
onclick="convertText()">
</form>
</body>
</html>
Та же страница, но с использованием VBScript, выг-
выглядит следующим образом:
Листинг 1.3. Пример на VBScript.
<html>
<head>
<script type="text/vbscript">
< ! —
Sub convertText()
document, SampleForm.myText. value =
UCase (document .SampleForm.myText. value)
End Sub
</script>
</head>
<body>
<form name="SampleForm">
<input type="text" name="myText">
<input type="button" value="Convert"
onclick="convertText()">
</form>
</body>
</html>
Более сложные типы данных
На первый взгляд может показаться, что возможности
работы с типами данных в VBScript существенно огра-
ограничены. Но это лишь кажется, и причина состоит в том,
что VBScript имеет только один тип данных — variant.
При дальнейшем знакомстве с VBScript станет ясно, что
поддержка типов данных здесь оказывается гораздо мощ-
мощнее, нежели в JavaScript. Тип variant содержит инфор-
информацию о значении, с которым он работает, поэтому в
различных ситуациях имеется возможность запросить
этот тип данных. Иными словами, если переменная
типа variant используется как строка (см. следующий
пример), VBScript рассматривает ее (myVar) как стро-
строковое значение.
myVar = "Stringl" + "String2"
Совершенно аналогично, VBScript может рассматри-
рассматривать ту же переменную как числовую:
myVar =1 + 2
Строки и числа рассматриваются как подтипы внут-
внутри типа variant. В таблицу 1.2 сведены подтипы VBScript.
Знакомство с JavaScript
Часть I
Таблица 1.2. Подтипы VBScript-типа variant.
Подтип
Описание
String Строка переменной длины (максимальная длина — примерно 2 миллиарда символов).
Byte Целое число между 0 и 225.
Integer Целое число между-32168 и 32767
Long Целое число между -2147483648 и 2147483647.
¦Single Число с плавающей запятой одинарной точности со следующими пределами: от -3.402823Е38 до
-1.401298Е-45для отрицательных и от 1.401298Е-45до3.402823Е38—для положительныхзначений.
Double Число с плавающей запятой двойной точности со следующими пределами: от -1.79769313486232Е308 до
-4.94065645841247Е-324для отрицательных и от 4.94065645841247Е-324до 1.79769313486232Е308—для
положительных значений.
Date (Time) Число, представляющее дату в пределах от 1/1/100 до 12/31/9999.
Boolean Логическое значение (True или False).
Empty Неинициализированная переменная. Значениями являются 0 для числовых и пустая строка ("")—для
строковых переменных.
Null Вариант содержит недопустимые данные (это не то же самое, что Empty).
Object Объект ActiveX.
Error Номер ошибки VBScript.
VBScript обладает набором функций преобразования,,
которые дополняют встроенные методы parsetFIoat и
parselnt, определенные в JavaScript.
Как и JavaScript, VBScript — слабо типизированный язык.
Различные процедурные типы
В VBScript определены два различных процедурных
типа: подпрограммы и функции. Подпрограмма обозна-
обозначается при помощи Sub..End Sub и представляет собой
процедуру, не возвращающую значение. С другой сто-
стороны, функция, обозначаемая парой Function..End
Function — это процедура, которая возвращает значение.
Например, следующая подпрограмма присваивает тек-
текстовому объекту TextField строковый литерал "See Spot
Run", но не возвращает значения в вызываемую проце-
ДУРУ-
<script type="text/vbscript">
Sub convertText ()
document.MyForm.TextField.value =
"See Spot Run. "
End Sub
</script>
Рассмотрим пример VBScript-функции. Подпрограм-
Подпрограмма showText() вызывает функцию getText(), которая воз-
возвращает значение текстового объекта TextField:
<script type="text/vbscript">
Function get Text ()
getText =
document.MyForm.TextField -value
End Function
Sub showText()
alert (getText ())
EndSub
</script>
В JavaScript определен только один процедурный
тип — метод (также называемый функцией), в котором
ключевое слово function используется вне зависимости
от того, возвращается или нет значение в вызываемую
процедуру.
Программирование в VBSript
Для поверхностного ознакомления с программировани-
программированием в VBScript воспользуемся простейшим примером. В
листинге 1.4 выполняется умножение двух значений,
введенных пользователем, и отображение результата в
диалоговом окне предупреждения:
Листинг 1.4. Пример программы на VBScript.
<html>
<head>
<title>Wizard</title>
<script type="text/vbscript">
Sub calculateValuesO
Dim numl, num2, greaterNum, totalVal
numl = document. forml.Number1.value
num2 = document. f onnl. Number2 . value
totalVal = numl*num2
alert (totalVal)
End Sub
</script>
</head>
<body>
<hl>Stump the Wizard</hl>
Without connecting to a backend server or
JavaScript u World Wide Web
using a Java applet, the Browser Wizard
will multiply the two numbers . . .
<?orm name="forml" method="POST">
<pre>
First Number: <input type="text"
size=" maxlength="S" name="Numberl">
</pre>
<pre>
Second Number: <input type="text"
size=" maxlength=" name="Number2 " >
</pre>
<P>
<input type=button name="WizButton"
value="Multiply" ondick="calculateValues ()
</form>
</body>
</htrol>
На рис. 1.14 показаны результаты выполнения это-
этого сценария в Internet Explorer 5.0.
Для целей сравнения двух языков в листинге 1.5
приводится эквивалентный код на JavaScript.
Stump the Wizard
Without «omectmg tts> aibackemf шнег ty using a Java applet, the Browser "Wizard wulmubpfythe
twonumbeis.
Hist Murtier: JI2 щГтТпТЩТЯТШаП
РИСУНОК 1.14. Результирующее окно сообщений.
Листинг 1.5. JavaScript-версия кода, приведенного в
листинге 1.4.
<html>
<head>
<title>Wizard</txtle>
<script type="text/javascript">
<t —
function calculateValues() {
Глава 1
numl =
parseFloat (document.forms[0] .Numberl .value)
num2 =
parseFloat (document. forms [ 0 ] . Number2 . value)
result = iiiiiiiI * num2
alert (result);
}
II—>
</script>
</head>
<body>
<hl>Stump the Wizard</hl>
<P>
Without connecting to a backend server or
using a Java applet, the Browser Wizard
will multiply the two numbers . .
<form name="?orml" method="POST">
<pre>
First Number: <input type="text"
size=" maxlength="
name="Numberl">
</pre>
<pre>
Second Number: <input type="text"
size=" maxlength=" name="Number2">
</pre>
<P>
<input type="button" name="WizButton"
value="Multiply"ondick="calculateValues () "
</?orm>
</body>
</html>
Резюме
Глава посвящена исследованиям среды разработки Web-
приложений и существующей методики объединения
отдельных частей Web-технологий. JavaScript — одно из
важнейших инструментальных средств в наборе Web-
разработчика. Было показано, что JavaScript взваливает
на себя множество реальных функций, возникающих в
течение цикла создания Web-приложений. JavaScript
неуклонно становится стандартным языком Web-разра-
Web-разработки. Поскольку JavaScript — язык, а не инструмент,
он зависит от программного обеспечения браузера. С
момента захвата браузерами Microsoft Internet Explorer
и Netscape Navigator крепких позиций на рынке, надеж-
надежность поддержки JavaScript существенно увеличилась.
Сейчас вы обладаете вполне достаточными знания-
знаниями, чтобы успешно освоить материал следующей гла-
главы, которая посвящена взаимодействию JavaScript и
HTML.
Совместная работа
JavaScript и HTML
В ЭТОЙ ГЛАВЕ
Основы HTML
Внедрение JavaScript в HTML
Создание JavaScript-кодов
HTML дает возможность создавать замечательные
статические Web-страницы. Хоть эти документы зачас-
зачастую и оказываются высокохудожественными, интерес-
интересными и во многом полезными, JavaScript позволяет пре-
превратить статические Web-страницы в интерактивные и
сделать их более чувствительными к пользовательским
действиям и вводу. Расширение HTML-страниц с помо-
помощью JavaScript усиливает их возможности, а также су-
существенно увеличивает гибкость кода.
JavaScript позволяет разработчику Web-сайта созда-
создавать более динамические Web-страницы за счет вклю-
включения в существующую структуру HTML JavaScript-
сценариев. В этом случае разработчик может назначать
кнопкам некоторые процессы, выполнять вычисления
для введенных в форму данных либо обеспечивать
определенные действия при попадании курсора мыши
на элемент HTML или объект Document. В общем,,
HTML становится значительно интереснее.
JavaScript обладает рядом преимуществ перед фор-
формируемыми на сервере интерактивными документами
при помощи CGI,, поскольку написанные на JavaScript
документы, вообще говоря, не зависят от обработки на
сервере, а следовательно, быстрее реагируют на запро-
запросы пользователя и быстрее взаимодействуют с ним.
Для более глубокого понимания работы JavaScript в
мире HTML стоит сделать обзор основ HTML, пресле-
преследуя цель посмотреть, какое он имеет отношение к это-
этому языку сценариев. Обладая устойчивой базой знаний
по HTML, разработчик сможет более полно овладеть
JavaScript и другими интерактивными возможностями,
а так же высокоуровневыми функциональными возмож-
возможностями HTML.
Основы HTML
Несмотря на очевидную простоту разработки простых
HTML-документов, включающих основные теги и про-
простые формы, преимущество применения HTML состо-
состоит в возможности создания сложных документов на ос-
основе более простых. Если задействовать более сложные
дескрипторы и связанные с ними атрибуты, сложность
и степень применимости документов будет возрастать,
а частота использования метода проб и ошибок -
уменьшаться.
Текущая ситуация
Стандарты HTML изменяются постоянно. Текущие ре-
рекомендации (то бишь, стандарт) охватывают HTML 4.01;
однако, следующее поколение HTML — это XHTML. В
настоящее время XHTML 1.0 — предложенный вариант
стандарта, ожидающий принятия консорциумом Word
Wide Web Consortium (W3C) и основанный на рекомен-
рекомендациях для HTML 4.01.
XHTML — это HTML, существующий в виде при-
приложения XML. После принятия XHTML в качестве
стандарта, прикладные XML-программы получат воз-
возможность обрабатывать данные в XHTML-документах.
Использование XML продемонстрирует, что XHTML
также позволяет включать в документы и другие диалек-
диалекты (типа MathML). В любом случае, развитие этих тех-
технологий породит новые элементы, равно как и усовер-
усовершенствованные новые атрибуты элементов.
Ресурс -,-..- ;^~, „.,; - ¦¦"¦ .->, -, ""т ;1
Рассмотрение XHTML выходит за рамки этой книги.
Подробную информацию о нем можно получить на
Web-сайте W3C по адресу http://www.w3.org.
Совместная работа JavaScript и HTML
Отслеживая самые последние выпуски популярных
браузеров, HTML-разработчик будет равняться на эти
усовершенствования и применять их, как только они
станут доступны широкой публике. К счастью, практи-
практически всегда расширения, включаемые в HTML 4.01/
XHTML 1.0 и последние выпуски браузеров, при про-
просмотре в более старых браузерах проблем не создают.
Однако всегда следует тестировать документ в старых бра-
браузерах, поскольку гарантия правильного восприятия но-
новых дескрипторов в таких браузерах лишней не окажется.
Следует отметить, что существуют дескрипторы,
которые не являются частью стандарта или работают
не во всех браузерах. Пример такого дескриптора -
<marquee>; он работает в Internet Explorer, но не в
Navigator. Последний будет отображать просто текст
документа. С другой стороны, Navigator поддерживает,
например, дескрипторы <1ауег> и <ilayer>, невоспри-
нимаемые Internet Explorer.
Приведенные примеры иллюстрируют важность на-
написания четко определенного и сегментированного до-
документа и обязательного учета различий браузеров при
создании Web-страниц.
Основы HTML
Поскольку клиентский JavaScript работает бок о бок с
HTML, прежде чем приступать к созданию каких-либо
сценариев, необходимо получить основные знания о
структуре НТМ L-документа и его дескрипторах. Знание
основ HTML существенно упростит создание Web-стра-
Web-страниц. Web-страница состоит из текста страницы, деск-
дескрипторов, и может иногда содержать комментариев.
Текст — это понятно и без пояснений. Разработчик
пишет текст, который появляется на Web-странице.
Часть процесса дизайна Web-страниц, которая требует
более подробных пояснений, — это использование деск-
дескрипторов, всегда начинающихся с символа < и заверша-
завершающихся символом >. Дескрипторы определяют поведение
Web-страницы, задают внешний вид текста и позволяют
создавать сложные документы для Web-браузера.
Дескриптором может быть одиночный маркер, на-
например, <hr> — для горизонтальной линии, или <br> —
для перевода строки; подобного рода дескрипторы иног-
иногда называют пустыми. Пустые дескрипторы не обяза-
обязательно каким-то образом форматируют окружающий
текст, хотя и способны корректировать разметку и ди-
дизайн НТМ L-документа.
С другой стороны, <td> нельзя рассматривать как
пустой дескриптор. Он используется для указания на то,
что текст, следующий после этого дескриптора, должен
помещаться в ячейку таблицы. Дескрипторы такого
типа требуют наличия закрывающего дескриптора, уве-
уведомляющего о завершении их действия. Эти дескрипто-
дескрипторы называются контейнерными, поскольку всегда содержат
информацию (обычно текст) между открывающим и зак-
Глава 2
рывающим дескрипторами. Исследуя приведенный ниже
пример, обратите внимание, что закрывающий дескрип-
дескриптор перед именем содержит символ /:
<Ъ>Этот текст
становится
полужирным</Ь>
Закрывающий дескриптор идентичен открывающему,
за исключением того, что он содержит дополнительный
символ.
Более сложные дескрипторы могут также иметь ат-
атрибуты, которые определяют поведение дескриптора.
Если дескриптор располагает подобного рода атрибу-
атрибутам, они необходимы дескриптору для исполнения оп-
определенных требований. Например, <table width=">
определяет таблицу с шириной 3.
Расположение дескрипторов в документах иногда
имеет очень важное значение. Некоторые дескрипторы
необходимо помещать внутрь других. Например, деск-
дескриптор <input> должен находиться внутри <form>. Не-
Некоторые дескрипторы могут включать в себя другие, но
это не является обязательным условием (примером мо-
может послужить дескриптор <head>).
Что касаемо комментариев, они суть ни что иное
как примечания разработчика по поводу собственно-
собственного документа, которые браузером не отображаются.
HTML-комментарии начинаются с символа <!— и за-
заканчиваются на —>. Ниже приводится пример HTML-
комментария:
- вот вам и комментарий —>
Структура HTML-документа
Структура HTML-документа зачастую очень важна. При
неправильном размещении дескрипторов увеличивает-
увеличивается вероятность возникновения нежелательных и неожи-
неожиданных эффектов. Базовый HTML-документ показан на
рис. 2.1. Документ всегда должен начинаться с <html>
и завершаться </html>, что несложно заметить в лис-
листинге 2.1. Два основных дескриптора внутри упомяну-
упомянутых — <head> и <body>. Внутри них можно размещать
остальные дескрипторы.
X ... a
ж
РИСУНОК 21.
Базовый
HTML-
документ,
показанный в
листинге 2.1.
Heading of Basic Document
1, Ooe
2. Two
"Ibis is a basic HTML -iorumetit jbucnirc
:-^я?!Ш^ЕШяЩИгШ38ЁЕ^&м&
Знакомство с JavaScript
Часть I
Листинг 2.1. Базовая HTML-страница.
<html>
<head>
<title>Basic HTML document</title>
<script type="text/javascript"X/script>
</head>
<body>
<hl>Heading of Basic Document</hl>
<form>
<input name="EnterBtn" type="SUBMIT">
</form>
<ol type=l>
<table width=" height=" border>
<tr>
<th colspan=">Table</th>
</tr>
<tr>
<td>celll</td>
<td>cell2</td>
<td>cell3</td>
</tr>
<tr>
<td>cell4</td>
<td>cell5</td>
<td>cell6</td>
</tr>
</table>
This is a Basic HT№ document structure .
</body>
</html>
Основное об атрибутах
Как упоминалось ранее, многие дескрипторы имеют
атрибуты. Атрибуты используются для определения
отображения или исполнения дескриптора. Атрибута-
Атрибутами обладают далеко не все дескрипторы, а некоторые
из них могут иметь атрибуты с одинаковыми именами.
Атрибуты, перечисленные в табл. 2.1, используются во
множестве НТМ L-дескрипторов. Функциональность этих
атрибутов от дескриптора, их использующего, не зависит.
Внедрение JavaScript в HTML
JavaScript-сценарии интегрируются в HTML-докумен-
HTML-документы с использованием пары дескрипторов <script> и
</script>. HTML-документ может содержать множество
подобных пар, причем каждая из них зачастую заклю-
заключает в себе более одного набора операторов JavaScript.
Для <script> обязательно требуется присутствие </script>.
Атрибут type используется для определения языка, на
котором реализован сценарий, а атрибут src — для за-
задания имени внешнего файла, являющегося источником
JavaScript-программы.
Атрибуты дескриптора <script>
Для лучшего понимания принципов функционирования
дескрипторов <script> выполним краткую сводку раз-
различных атрибутов в табл. 2.2. В разделах, приведенных
после этой таблицы, можно отыскать более детальную
информацию, касаемую каждого из перечисленных ат-
атрибутов.
Таблица 2/1 .^Атрибуты, используемые в различных дескрипторах.
Атрибут Описание
class Определяет класс, к которому принадлежит HTML-дескриптор.
id Определяет некоторое уникальное значение для элемента при ссылке на полный документ.
name Присваивает имена экземпляру дескриптора. Это имя часто используется JavaScript для ссылок на конкретные
элементы либо дескрипторами <а> для организации ссылок в пределах одного документа.
style Определяет информацию о стиле.
Таблица 2.2. Атрибуты дескриптора <script>.
Атрибут Описание
defer Это атрибут логического типа, который используется для уведомления браузера о том, генерирует ли
JavaScript-сценарий какое-либо содержимое.
language Отвергнутый в настоящее время, однако применяемый ранее атрибут для определения языка и версии,
используемых внутри дескрипторов.
src Этот атрибут определяет URL внешнего исходного JavaScript-файла.
type Атрибут, пришедший на замену language; он сообщает браузеру, какой язык используется внутри дескрипторов.
Совместная работа JavaScript и HTML
defer
Атрибут defer — это простой атрибут, который сообща-
сообщает браузеру, будет ли код, расположенный между от-
открывающим и закрывающим дескрипторами <script>,,
генерировать какое-либо содержимое. Другими словами,
используется ли в коде метод document.write(). Ниже
приводится пример использования данного атрибута:
<script type="text/javascript" defer>
// Просто объявим переменную; пока не стоит
// ее выводить на страницу
¦var myVar = 500;
//-->
</script>
language
В самой последней версии языков HTML и XHTML
атрибут language отвергнут. Традиционно он использо-
использовался для определения имени языка и версии JavaScript,
которые использовались для кода, расположенного
между парой <script>. Формат этого дескриптора выг-
выглядит так:
<script language="JavaScript">
Таблица 2.3. Текущие значения атрибута language.
Глава 2
Приведенная выше запись уведомляет браузер, что
сценарий необходимо выполнять в режиме, совмести-
совместимом с JavaScript 1.0. Для других версий JavaScript, на-
например, 1.1, следует записать так:
<script language="JavaScriptl.1">
В табл. 2.3 перечисляются значения, которые можно
использовать с атрибутом language. Она также показы-
показывает, какие браузеры будут интерпретировать то или
иное значение.
;;;совет ¦ •/ ' :
Если атрибут language не определен, браузеры при-
принимают JavaScriptl .0. Кроме того, текущая версия
браузера Opera, кажется, вообще игнорирует этот ат-
атрибут, поскольку он был в свое время отвергнут.
Используя атрибут language, можно определить
множество наборов функций JavaScript. Браузеры, под-
поддерживающие JavaScript 1.1, смогут воспользоваться пре-
преимуществами более новых функций, которые недоступ-
недоступны в старых версиях браузеров. Простейший метод
задействования преимуществ подобного рода показан в
листинге 2.2.
Значение language Описание
JavaScript Представляет JavaScript 1.0 и интерпретируется браузерами Navigator 2+ и Internet Explorer 3+.
JavaScripti. 1 Представляет JavaScript 1.1 и интерпретируется браузерами Navigator 3+ и Internet Explorer 3+.
JavaScriptl .2 Представляет JavaScript 1.2 и интерпретируется браузерами Navigator 4+ и Internet Explorer 4+.
По сравнению с 1.1, в JavaScript 1.2изменен способ, в соответствие с которым Navigator
обрабатывает некоторые операторы.
JavaScriptl .3 Представляет JavaScript 1.3и интерпретируется браузерами Navigator 4.05+ и Internet Explorer 5+.
JavaScriptl.4 Представляет JavaScript 1.4 и интерпретируется HotJava 3+ и некоторыми ранними альфа-версиями
(до версии М12) Mozilla/Navigator5.
JavaScriptl.5 Представляет JavaScript 1.5 и интерпретируется браузером Mozilla/Navigatorbeta 1.0(M12+).
Листинг 2.2. Одновременное использование разных версий JavaScript в атрибуте language.
<html>
<head>
<ti 1:1е>Определение версий JavaSoript</title>
</head>
<body>
<script language="JavaScript">
/ / Этот раздел будут читать только браузеры с JavaScript 1.0
document.write ('Браузер поддерживает JavaScript 1.0<br>');
</script>
<script language="JavaScriptl.1">
// Этот раздел будут читать только браузеры с JavaScript 1.1
document.write('Браузер поддерживает JavaScript l.l<br>');
</script>
<script language="JavaScriptl.2">
// Этот раздел будут читать только браузеры с JavaScript 1.2
docjment.write( 'Браузер поддерживает JavaScript 1.2<br>');
</script>
Знакомство с JavaScript
Часть I
ocript languages" JavaScriptl. 3">
// Этот раздел будут читать только браузеры с JavaScript 1.3
document.write('Браузер поддерживает JavaScript 1.3<br>');
</script>
¦<script language^"JavaScriptl.4">
// Этот раздел будут читать только браузеры с JavaScript 1.4
document.write('Браузер поддерживает JavaScript 1.4<br>');
</script>
<script language»" JavaScriptl. 5">
// Этот раздел будут читать только браузеры с JavaScript 1.5
document.write (¦ Браузер поддерживает JavaScript 1. 5<br>') ,•
</script>
</body>
</html>
src
Существуют два пути интегрирования операторов
JavaScript в HTML-документ. Выбор пути зависит от
требований при просмотре и изменении кода. Первый
вариант позволяет рассматривать все коды одновремен-
одновременно и предполагает написание операторов JavaScript не-
непосредственно в HTML-документе, Все эти операторы
встраиваются в HTML-страницу между парой дескрип-
дескрипторов <script>; они носят название встроенных (inline)
сценариев. Второй вариант (доступный только в JavaScript
1.1 и старше) предполагает сохранение JavaScript-кода в
отдельном файле с расширением js. В таком случае по-
появляется возможность обращения к файлу в открываю-
открывающем дескрипторе <script>.
Ниже показан первый вариант—встраивание JavaScript
в HTML-страницу:
ocript type="text/javascript">
function options 0 {
document.write("Встраивание кода");
>
</script>
А сейчас — вариант с размещением сценария во
внешнем файле:
<script src="/jscripts/myscript.js"X/script>
Во втором варианте потребуется создать файл с име-
именем myscript.js, который будет содержать одну строку
кода:
document .write ("Вызов из отдельного файла")
В случае использования последнего варианта между
парой дескрипторов <script> желательно поместить один
оператор, тем самым обеспечивая пользователям воз-
возможность обратной связи на случай, если файл с расши-
расширением .jsоказывается некорректным или недоступным.
Иначе пользователь будет лицезреть неправильное по-
поведение Web-страницы, не понимая его причин.
При загрузке сценария из отдельного файла необхо-
необходимость в указании атрибута language не возникает до
тех пор, пока применяется файл с расширением .js.
Пользуясь этим методом, можно изменять JavaScript-код
без какого-либо открытия и риска возникновения неже-
нежелательных изменений в HTML-страницах. Следователь-
Следовательно, код подобного рода представляется более модуль-
модульным и переместимым, поскольку он размещается за
пределами HTML-документа.
Отрицательная сторона метода состоит в том, что
приходится модифицировать два набора кода, в зависи-
зависимости от изменений в коде JavaScript. Например, если
в JavaScript-коде изменяется имя функции, следует не
забыть изменить соответствующее имя в обращениях к
этой функции и в HTML-коде. Еще один минус связан
с тем, что внешние JavaScript-файлы не могут содержать
дескрипторы HTML; они должны содержать только
операторы JavaScript.
type
Те, кто уже работал с JavaScript ранее, возможно, гово-
говорили: "Что это за птица такая, атрибут type? Я думаю,
здесь следует использовать language." Да, в какой-то сте-
степени это правильно.
Атрибут language был первым атрибутом, который не
только определял язык в дескрипторе <script> напри-
например, javascript или vbscript, но также и версию, скажем,
javascriptl.l или javascriptl.5. Если просмотреть текущий
стандарт HTML или предложенные рекомендации по
XHTML, несложно заметить, что от атрибута language
было решено отказаться, а вместо него использовать type.
Значение, указываемое в этом новом атрибуте очень
смахивает на указание в качестве содержимого внешне-
внешнего исходного файла на JavaScript (js). Так, для JavaScript
необходимо задать type="text/javascript", адля VBScript —
type="text/vbscript". Далее показано, как это работает.
Рекомендации HTML 4.01 говорят, что в часть <head>
документа следует помещать дескриптор <meta>, кото-
который будет определять заданный по умолчанию язык,
используемый во всех сденариях. Это выглядит так:
<meta http-equiv="Content-Script-Type"
content="text/j avascript">
Совместная работа JavaScript и HTML
Глава 2
Здесь можно заменить text/javascript на text/vbscript
или любой другой язык, который планируется исполь-
использовать. Если подобную строчку не указывать вообще,
браузеру потребуется проверить элемент Content-Script-
Type в заголовке HTTP-запроса. Формат выглядит сле-
следующим образом:
Content-Script-Type: text/javascript
Опять-таки, text/javascript можно заменить на кон-
конкретный тип языка, заданный по умолчанию для дан-
данной Web-страницы.
Теперь, когда тип языка по умолчанию установлен,
атрибут type будет применяться для отмены значения
по умолчанию. Это позволяет использовать сразу не-
несколько языков сценариев в одном и том же документе.
Например, можно установить Content-Script-Type рав-
равным text/javascript, а затем указать type="text/vbscript"
в одном из дескрипторов <script>, в пределах которого
в качестве языка будет использоваться VBScript.
Очевидно, что этот атрибут будут учитывать только
новые браузеры, поэтому применять его следует с осо-
особой осторожностью. Возможно, через пару лет все вста-
встанет на свои места и большинство браузеров будут под-
поддерживать этот новый метод. Однако сейчас
рекомендуется использовать в дескрипторе <script> как
type, так и language.
Просмотр кода JavaScript
Поскольку код на JavaScript можно записывать непос-
непосредственно в коде HTML, просматривать и редактиро-
редактировать его легко. Вероятно, вам уже знаком пункт меню
браузера Document Source (или Page Source), который
обеспечивает просмотр исходного текста HTML-страни-
HTML-страницы (он обычно находится в меню View).
При просмотре исходного кода документа можно
также исследовать JavaScript-код, включенный в доку-
документ, как показано на рис. 2.2. (Здесь, очевидно, как раз
тот случай, когда операторы JavaScript вызываются из
файла .js вместо помещения их непосредственно в до-
документ. Все что можно здесь наблюдать — это обраще-
обращение к файлу .js в дескрипторе <script>.) Для JavaScript
не требуется специальное средство просмотра, и по-
поскольку характер языка — интерпретирующий, а не ком-
компилирующий, код отображается в исходном тексте до-
документа.
ПРИМЕЧАНИЕ
Некоторые браузеры, в особенности Navigator 4, при
выборе пункта меню View Source отображают лишь
результаты выполнения кода на JavaScript. В этих слу-
случаях для просмотра и пошагового выполнения сцена-
сценариев рекомендуется воспользоваться отладчиком
Netscape JavaScript Debugger, который обсуждается
в глаз. 34.
<script'langua
Cl Start: ТооЩлг for dam-level browsers—>\
<SPftH ID-"TBDawnl.euelDiu">
<TfiBU MIDTH-'IOOV CELLPflPDINC-Q CELLSPflCIMC-0 BDRDEB-0 DGCOLOfi-'UFFFFFF'>
<TR>
<TD UftUCH-TOP1 HEICMT-6O П01ЛРЛН-2ХЙ
HREF-"/isapt/goi»scon.asp?target-/' TARGET-' top'XIHG
SRC-'/librai-y/hOMPpage/inaqes/bnr all.gif ¦ UIDTH-25O HEIGHTS»
rtLT-'Bici-uiofl.cgn Ионе' DORD?R-Q></AX/TD>
<TD VftLJCH-TOP' HEICHT-20 flLlGH-'RICHl-XIHG
SRC-'/library/tODlbar/inages/curue.gif VIDTH-1B KEIGHT<-2B flLT-"
B0RDERX/TD>
<TD DGCOLOR-'ttOOOOOD' HEIGHT-ZO UflLICM-'MIDDLE" flLlPH-'RIGHT * NQWRflP
C0LSPflH-2>
<FOHT COt_OR-4FFFFFF- FftCE-' Uerdana, Arial' SJZE-1>
ftnbsp;<A
STVLE-*colortBFFFFFFjteKt-decofationinotie;1
IRCr-'/i5api/gonscon.asp?tat-get«/cataIog/(IefauIt.asp7bUtiid-22'
TflRCET-" top'XFDHT COLOR-' BFFFFFF *>Ali Prodtict3</F0HTX/ft> f.nbsp;<F0HI
C0L0R-4tFFFFFF*>|</FOHT>
snDsp:cnDsp;<A
STVLE-"color:BFfFFFF;te«t-decoration:none;*
HRtf-Vlsapi/gonscon.asp?target-/suppot't/' TARGET-1 top'XFOHT
COLOR ' «FFFFFF ' >SupporC</FOHT></A>Anbsp; <FONTCOLOR- ' BFFFFFF ">| </FOHT>
ЕлЬ5р;Г(ПЬ5р;<П
РИСУНОК 2.2. Просмотр JavaScript-кода.
Создание JavaScript-кода
¦Основы создания JavaScript-кода весьма просты. Доста-
Достаточно только создать основную HTML-страницу (или
отредактировать существующую) и затем вставить дес-
дескрипторы <script> в разделы <head> или <body>. Фун-
Функции и другие элементы, которые применяются ко всей
Web-странице, лучшие помещать в раздел <head>. При
наличии необходимости генерировать текст для Web-
страницы при помощи JavaScript, это лучше выполнять
в разделе <body>.
Выполнение сценариев
Выполнение JavaScript-сценариев начинается в разное
время, в зависимости оттого, как они написаны. Если
сценарий влияет на содержимое Web-страницы, напри-
например, вызывает метод document.write(), он выполяется по
мере своего появления. Кроме того, существует обработ-
обработчик событий onLoad, который выполняется только пос-
после полной загрузки HTML-документа в браузер.
Если JavaScript-сценарии сохранены в отдельном
файле, они анализируются во время загрузки Web-стра-
Web-страницы и перед любыми действиями пользователя.
Все операторы JavaScript, содержащиеся в теле фун-
функции, интерпретируются, однако запуск функции не
происходит до тех пор, пока она не будет вызвана ка-
каким-то JavaScript-событием. Операторы JavaScript, на-
находящиеся за пределами тела функции, выполняются
после загрузки документа в браузер, но во время визуа-
визуализации документа. Результат выполнения станет оче-
очевиден для пользователей уже при первом просмотре
Web-страницы.
Загрузка Web-страницы
Операторы JavaScript, которые требуют немедленной
обработки, выполнятся сразу после загрузки Web-стра-
Web-страницы, но до ее отображения в браузере. Код в листинге
Знакомство с JavaScript
Часть I
2.3 обеспечивает отображение диалогового окна предуп-
предупреждения после открытия документа. Вызова функций
не происходит — операторы JavaScript просто обраба-
обрабатываются по мере загрузки Web-страницы.
Листинг 2.3. Отображение диалогового окна
предупреждения за счет непосредственного вызова.
<html>
<head>
<title>Dialog Test</title>
<script type="text/javascript">
< ! —
alert. <"Dialog called") ;
// —>
</script>
</head>
<body>
<b>
Test page of defauJ JavaScript call
</fcody>
</html>
Функция onLoad может рассматриваться как исклю-
исключение из этого правила. В данном случае onLoad вызы-
вызывается не в результате генерации события пользовате-
пользователем, а в результате события, связанного с собственно
загрузкой документа в браузер. Диалоговое окно пре-
предупреждения будет появляться непосредственно после
зафузки Web-страницы (см. рис. 2.3), и это при том, что
окно не вызывается напрямую. В листинге 2.4 показа-
показана функция opendoc(), вызываемую самим документом
после генерации его события Load. Оба листинга B.3
и 2.4) обеспечивают одни и те же результаты, достига-
достигаемые, однако, двумя разными способами написания
сценария.
Листинг 2.4. Отображение диалогового окна
предупреждения через
<html>
<head>
<title>Dialog from onLoad</title>
<script type="text/javas
<! —
functionopendoc() {
alert ("Dialog called ")
)
/ / ^
</script>
</head>
<body onload="opendoc () ">
Test page of onLoad JavaScript call
</body>
</html>
Пользовательские действия
Второй метод, в соответствие с которым выполняются
операторы JavaScript, — это вызов функций. Любой опе-
оператор, содержащийся в функции, не будет выполняться
до тех пор, пока JavaScript-событие не вызс эту фун-
функцию. JavaScript-события генерируются на HTML-стра-
HTML-странице многими способами, включая действия пользова-
пользователя и явные вызовы событий непосредственно изнутри
сценария. Пользовательские действия в документе спо-
способны генерировать JavaScript-события в многих случа-
случаях, даже в самых неожиданных. Всегда следует тщатель-
тщательно протестировать все операторы JavaScript, дабы
убедиться, что пользовательское взаимодействие с Web-
страницей не вызывает нежелательные события.
РИСУНОК 2.3. Диалоговое окно предупреждения в
Navigator 4.7.
В главе 14 JavaScript-события, их реализация и встра-
встраивание в HTML-код рассматриваются более подробно.
В листинге 2.5 приведен код, который обеспечивает
отображение диалога в результате нажатия кнопки.
Листинг 2.5. Вызов функции для отображения
диалога. _
<html>
<head>
<title>Dialog from function call</title>
<script type="text/javascript">
function opendoo () {
("Dialog called by Push Butto
</script>
</head>
<body>
<b>
Test page of function called from Push Button
<form method="POST">
<input type="Button" name="BUTTONl'
value="PUSH" onclick="opendoc () ">
</form>
Совместная работа JavaScript и HTML
Глава 2
</body>
</html>
На рис. 2.4 показаны результаты вызова функции.
Teitpage of font do
¦
©
i caUed from Push Butto
0
is* аи
Ed
ii
ii
РИСУНОК 2.4. Диалоговое окно предупреждения в Internet
Explorer5, вызванное событием submit.
Пользовательские действия или явные вызовы собы-
событий — это часто используемые методы выполнения
JavaScrpt-кода. Исключительное преимущество JavaScript
заключается в том, что он способен увеличивать коли-
количество взаимодействий пользователя с HTML-докумен-
HTML-документом, поскольку обеспечивает способ немедленной обра-
обработки и оценки вводимой пользователем информации.
Учет браузеров, не поддерживающих
JavaScript
Быстрые темпы изменений HTM L и JavaScript требуют
предельно осторожного отношения к браузерам, которые
не поддерживают создаваемые документы. Не все брау-
браузеры поспевают за новыми изменениями в HTML, по-
поэтому программисты вынуждены делать документы мак-
максимально дружественными по отношению ко всем
'браузерам и средам.
СОВЕТ
Тестируйте свои HTML- и JavaScript-страницы в как
можно большем количестве браузеров; такая поли-
политика приведет к максимальной стабильности и приме-
применимости документов.
Хотя применение JavaScript делает усовершенствова-
усовершенствования HTMLflocTynHbiMH для пользователей, необходимо
всегда помнить, что старые браузеры не способны под-
поддерживать JavaScript-код. Если окружить дескриптора-
дескрипторами комментария HTML все операторы внутри пары
<script> и </script>, более старые браузеры смогут ото-
отобразить Web-страницу, не показывая JavaScript-код.
Пользователи не смогут получить полное впечатление от
Web-страницы, но, по крайней мере, в браузере не по-
появится нежелательный текст. Формат использования
этих комментариев таков:
<script type="text/javascript">
<!— скрыть код от старых браузеров
// здесь начинается собственно код
// а здесь код завершается —>
</script>
Листинг 2.6 демонстрирует способ сокрытия кода
JavaScript от старых браузеров. Обратите внимание, что
в этом листинге применяются два следующих друг за
другом оператора HTML-комментариев, а строки кода
на JavaScript размещаются внутри них.
Листинг 2.6. Сокрытие JavaScript-сценариев от
старых браузеров.
<html>
<head>
<title>Hide From Browser</title>
<script type="text/javascript">
- Скрыть
document.write("I can view JavaScript code")
// Завершить сокрытие —>
</head>
<body>
Content goes here.
</body>
</html>
Обратите внимание, что в последней строке коммен-
комментария HTML используется дескриптор JavaScript-ком-
JavaScript-комментария //, поэтому JavaScript не интерпретирует этот
оператор. В случае отсутствия этих маркеров коммен-
комментария JavaScript будет пытаться обрабатывать оператор
и после оценки сгенерирует ошибку.
В листинге 2.7 показан текст базовой Web-страни-
Web-страницы, с которой стоит начать. Обратите внимание на нор-
нормальные HTML-дескрипторы и на <script>, присут-
присутствующий в разделе <head> документа.
Листинг 2.7. Базовый JavaScript-документ для
начинающих.
<html>
<head>
<title>My first HTML page</title>
<script type="text/javascript">
<f — Скрыть
//Здесь должен находиться код
// Завершить сокрытие—>
</script>
</head>
<body>
- Здесь находится содержимое страницы —>
</body>
</html>
Знакомство с JavaScript
Часть I
Открывающий дескриптор <script> должен включать
в себя атрибут type для определения того, что сценарий
внутри дескрипторов реализован именно на JavaScript.
Помните, что до тех пор, пока рекомендации HTML
4.01/XHTML 1.0 не будут В полном объеме реализова-
реализованы в наиболее распространенных браузерах, можно так-
также использовать и атрибут language.
Написание кода
Как и в любом другом языке программирования, опе-
операторы JavaScript могут быть записываться в соответ-
соответствие с различными методами. Очевидно, практика оп-
определения функций JavaScript в разделе <head> и
последующий вызов этих функций в разделе <body> —
самый эффективный способ использования преиму-
преимуществ объектов JavaScript.
Сам по себе язык JavaScript не труден, и разработ-
разработчики, владеющие технологией объектно-ориентирован-
объектно-ориентированного программирования, не встретят слишком много
препятствий. Как только будут схвачены основные кон-
концепции объектной методологии, создание функций
JavaScript становится достаточно простым делом. По-
Посмотрите на следующий пример:
document.write("Я мору видеть код на
*¦• JavaScript!");
¦Оператор document.write() как-будто бы говорит: "За-
"Записать такой-то текст в моем документе".
"примечание ./;¦;, « ^*; '
Несмотря на то что операторы HTML не чувствитель-
чувствительны к регистру (хотя в предложенных рекомендациях
XHTML подобное требование присутствует), операто-
операторы JavaScript — чувствительны. Не забывайте прове-
проверять регистр символов кода, чтобы гарантированно не
иметь проблем из-за столь досадного, но все же рас-
распространенного недоразумения.
Приступая к написанию кода, памятуйте о следую-
следующем:
Повторное использование кода
Удобочитаемость
Простота внесения изменений
Дескрипторы JavaScript можно использовать как в
разделе <body>, так и в разделе <head> документа. Как
упоминалось ранее, помещение дескриптора <script> в
<head>, а не в <body> гарантирует, что все операторы
будут просмотрены (и, в случае необходимости, выпол-
выполнены) еще до того, как пользователь начнет взаимодей-
взаимодействовать с документом. Не следует забывать и о том, чтс»
помещение операторов сценария в раздел <body> доку-
документа имеет массу опасных последствий.
Даже зная конкретный список дескрипторов и поря-
порядок построения документа, нельзя заранее гарантиро-
гарантировать, будет ли пользователь взаимодействовать со сцена-
сценарием предполагаемым способом или отреагирует на
Web-страницу прежде, чем сценарий полностью загру-
загрузится или выполнится. В этом случае предполагаемый
эффект не будет достигнут. (Кому нужна такая ситуация
после всех затраченных усилий?)
Практика определения JavaScript-функций и затем
вызов их из раздела <body> гарантирует, что все функ-
функции оцениваются Прежде, чем пользователь начнет
взаимодействовать с Web-страницей. Листинг 2.8 иллю-
иллюстрирует эту практику, а листинг 2.9 показывает альтер-
альтернативный путь.
Листинг 2.8. Вызов функции. _
<html>
<head>
<title>Page with Pushbutton</title>
<script type="text/javascript">
function pushbutton () {
alert < "pushed") ;
J
// —>
</script>
</head>
<body>
<form>
< input type=" SUBMIT" name="BUTtCONl"
value="POSH" onclick="pushbutton ()">
</form>
</body>
</html>
Листинг 2.9. Помещение JavaScript-сценария
непосредственно в обработчик событий onclick.
<html>
<head>
<title>Page with Pushbutton</title>
</head>
<body>
<form>
<input type="SUBMIT" name="BUTTONl"
value="PUSH" onclicfc="alert('pushed')">
</forra>
</fcody>
</html>
Листинг 2.9 демонстрирует возможность помещения
операторов JavaScript непосредственно в дескрипторы
HTML. Соотнесем недостатки этой практики с принци-
принципами написания кода, о которых было сказано ранее.
Изменение и многократное использование кода в деск-
дескрипторах затруднено. Требуется найти дескриптор и за-
затем вырезать и вставить код. Только тогда его можно
будет многократно использовать или преобразовать в
вызовфункции.
Совместная работа JavaScript и HTML
Удобочитаемость и простота модификации как не-
непосредственно для вас, так и для последующих разработ-
разработчиков, также существенно снизится, если JavaScript-опе-
JavaScript-операторы для функций не поместить в раздел <head>.
Бесконечные поиски кода, который на самом деле
отыскивается легко, в конце-концов выведут из душев-
душевного равновесия даже самого терпеливого.
Стили столь же важны в JavaScript, как и в любом
другом языке программирования. Сохранение строгос-
строгости стиля, своевременное определение переменных и ак-
аккуратность форматирования в будущем сократят время
разработки документов.
Создавая сценарий JavaScript, функцию за функци-
функцией, кусочек за кусочком, можно сформировать устойчи-
устойчивые интерактивные документы, которые будут обладать
большими функциональными возможностями. Посколь-
Поскольку JavaScript интерпретируется, но не компилируется,
процесс отладки не всегда полностью прозрачен. Мно-
Множество проблем или ошибок не будет очевидно до тех
пор, пока документ не подвернется серьезному тестиро-
тестированию. Я бы рекомендовал, чтобы кто-то другой вместо
разработчика занялся тестированием Web-страницы для
¦большей уверенности, что учтены абсолютно все ситуа-
ситуации.
Выполнение сценариев
Глава 2
обходимости явно вызывать код. Поскольку код разме-
размещается в HTML-документе или вызывается в первой
строке сценария, сценарий будет выполняться во время
загрузки Web-страницы. Помните, что сразу же после
загрузки не обязательно выполняется весь код. Код, свя-
связанный с вызовом функции, при загрузке Web-страни-
Web-страницы только оценивается, но не выполняется до тех пор,
пока функция не вызывается явно в результате генери-
генерирования JavaScript-события. Код, не связанный с вы-
вызовом функции, выполняется после полной загрузки
Web-страницы, но до того как пользователь получит воз-
возможность взаимодействовать с ней.
Резюме
Очевидно, что JavaScript столь же просто загрузить, как
и НТМ L-документ. Для выполнения сценариев нет не-
Очевидно, что хотя язык написания сценариев JavaScript
и не зависит от HTML, оба они тесно связаны, если речь
идет о проектировании, написании и выполнении до-
документа в полном объеме. Код JavaScript можно запи-
записывать непосредственно в коде HTML, расширяя таким
образом текущие возможности Web-документов. Код
просматривается и загружается вместе с HTML.
Усовершенствования, постоянно появляющиеся в
самом HTML, увеличивают функциональные возмож-
возможности JavaScript-кода. Это позволяет улучшить доку-
документы, сделать их более интерактивными и дружествен-
дружественными по отношению к пользователю.
Создание собственного
набора инструментальных
средств JavaScript
В ЭТОЙ ГЛАВЕ
Необходимые инструментальные средства
Процесс разработки на JavaScript
Серверные инструментальные средства JavaScript
Подобно любому языку разработки, JavaScript тре-
требует определенную среду проектирования. В то время
как язык Java связан со интегрированной средой разра-
разработки (IDE) Symantec's Visual Cafe, для JavaScript по-
подобного рода среда недоступна. Благодаря изобилию
Web-инструментов, можно скомпоновать собственный
набор инструментальных средств. В данной главе под-
подробно исследуются различные доступные инструмен-
инструментальные средства разработки кода как для клиентской,
так и для серверной сторон.
Необходимые инструментальные
средства
Перед началом разработки все необходимые инструмен-
инструментальные средства потребуется скомпоновать. Например,
при создании приложений в Delphi, Visual Basic,
VisualAge for Java набор инструментальных средств, ско-
скорее всего, будет относительно невелик, поскольку упо-
упомянутые визуальные инструменты уже содержат все не-
необходимое для работы. Однако это не относится к
JavaSctipt. Для создания среды разработки потребуют-
потребуются следующие основные инструментальные средства:
• JavaScript-редактор для написания сценариев
HTML-редактор для создания страниц
Web-браузер для тестирования сценариев и приложе-
приложений
Отладчик сценариев для обнаружения ошибок
JavaScript-редакторы
Выбор редактора для разработчиков программного
обеспечения равносилен выбору клюшки хоккеистом.
Поскольку универсального рецепта не существует, рас-
рассмотрим краткий обзор средств написания JavaScript-
кода; возможно, это окажет необходимую помощь при
выборе из множества текстовых, HTML- и JavaScript-
редакторов.
Текстовые редакторы
Поскольку JavaScript-код располагается внутри HTML-
страниц, то для эффективной разработки потребуется
текстовый редактор. Если говорить о Windows, то реко-
рекомендуется воспользоваться TextPad (рис. 3.1) или
Notepad. Разработчики, установившие у себя I ni> мо-
могут задействовать один из редакторов ешах или vi, а для
пользователей Macintosh вполне неплохим пыбором
будет SimpleText или BBEdit, показанный на рис.3.2.
Использование стандартного текстового редактора
обладает своими преимуществами — соответствующее
программное обеспечение на компьютере уже установ-
установлено.
РИСУНОК 3.1 В качестве JavaScript-редактора можно
использовать TextPad.
Создание собственного набора инструментальных средств JavaScript
Глава 3
Среды разработки для JavaScript
РИСУНОК 3.2 На компьютерах Macintosh наилучшим
редактором для разработки кода на JavaScript no праву
считается BBEdil.
Разумеется, есть и свои недостатки, главный из ко-
которых связан с отсутствием возможности изучения
JavaScript и его расширений (например, библиотек ко-
кодов или мастеров).
Перед выбором из нескольких вариантов стоит вы-
выяснить, какие функции реализует тот или иной редак-
редактор. Например, наличие команд поиска и замены, в осо-
особенности тех из них, что выполняют поиск по шаблону,
записываемому как регулярное выражение.
Следует отдавать предпочтение редакторам, которые
обеспечивают цветовое представление синтаксиса. В
таких случаях гораздо проще различать код, HTML и
комментарии. С учетом перечисленных соображений
TextPad явно выигрывает у Notepad.
Будучи более функциональными, текстовые редак-
редакторы TextPad и BBEdit позволяют разрабатывать в сво-
своих средах и другие коды. При написании кода на HTML,
JavaScript и даже на Java, можно использовать одни и
те же инструментальные средства. Кроме того, HTML-
редакторы от независимых разработчиков, наподобие
Allaire HomeSite, обеспечивают дополнительную под-
поддержку процесса разработки приложений на JavaScript.
За счет использования единой среды исчезает необ-
необходимость задействования множества программных па-
пакетов и, следовательно, уменьшается количество прило-
приложений, которые требуется изучить. Некоторые из
:т^пных редакторов, помимо прочего, допускают
интеграцию с Web-браузерами, обеспечивая быстрый
просмотр и тестирование страниц и сценариев.
РЕСУРС
Web-сайт компании Allaire находится по адресу
http://www.allaire.com.
¦
Помимо текстовых, существует и несколько редакто-
редакторов, ориентированных исключительно на разработку
JavaScript-сценариев. Первым таким редактором на
рынке стал ScriptBuilder, разработанный компанией
NetObjects. He желая терять позиции на рынке, компа-
компания Netscape создала собственный продукт Visual
JavaScript, позволяющий создавать в его среде целые
Web-приложения. Впоследствии его функциональность
практически полностью была перенесена в Application
Builder.
Общая функциональность подобного рода приложе-
приложений включает в себя:
• Применение технологии перетаскивания (drag-and-
drop) для редактирования текста
• Применение технологии перетаскивания для поме-
помещения в текст дескрипторов HTML
• Применение технологии перетаскивания для работы
с методами и свойствами объектов
• Выделение синтаксиса для ключевых слов JavaScript
и дескрипторов HTML
•• Функции поиска и замены
¦• Интеграция с распространенными браузерами для
тестирования и отладки кода
ПРИМЕЧАНИЕ
Испытательную версию NetObjects ScriptBuilder мож-
можно выгрузить из сайта NetObjects по адресу http://
www.netobjects.com.
Не следует рассматривать перечисленные выше ин-
инструментальные средства в качестве замены HTML-ре-
HTML-редактора — лучше, чтобы они использовались в компо-
композиции с ним.
HTML-редакторы
Дабы не забыть о самой природе среды разработки,
добавьте в свой набор инструментальных средств
HTML-редактор. Цели такого редактора заключаются не
в создании сценариев, но в дизайне HTML-страниц, к
которым позже будет добавляться JavaScript-код. Разли-
Различают два вида HTML-редакторов — текстовые и визу-
визуальные. В зависимости от пользовательских вкусов и
предпочтений, выбирается тот или иной редактор, а
иногда и оба.
Текстовые HTML-редакторы
Как обсуждалось ранее в главе, текстовые HTML-редак-
HTML-редакторы реализуют среду, которая позволяет работать с
дескрипторами HTML. Текстовые редакторы HTML не
пытаются скрыть все детали дескрипторов. Наоборот,
¦они обеспечивают поддержку всего процесса разработ-
Знакомство с JavaScript
Часть I
ки кода на HTML, что существенно повышает их эффек-
эффективность по сравнению со стандартными текстовыми
редакторами.
Визуальные HTML-редакторы
Другой тип рассматриваемых редакторов — это HTML-
редакторы, скрывающие от разработчиков детали гипер-
гипертекстового языка форматирования страниц за счет обес-
обеспечения визуальной среды (WYSIWYG — What You See
Is What You Get), которая генерирует HTML-коды "за
кулисами". В нынешнем компьютерном мире, где все
так или иначе основывается на графике, процесс созда-
создания страниц сводится к действиям типа "указать и щел-
щелкнуть".
Компания Netscape располагает визуальным HTML-
редактором, который носит название Composer и встро-
встроен в продукт Communicator. Composer позволяет редак-
редактировать HTML-документы в рамках интегрированной
среды браузера (см. рис. 3.3). Несмотря на то что ви-
визуальная среда Composer позволяет работать с базовой
разметкой HTML-страниц, все же должная поддержка
визуальной работы с мультифреймовыми окнами, сти-
стилями, и пр. обеспечивается явно не достаточно.
РЕСУРС
Последнюю информацию о Netscape Composer мож-
можно найти на Web-сайте компании по адресу: htfp://
home.nefscape.com. Как только Mozilla.org выпустит
первую версию Communicator с открытым кодом, она
станет доступна по адресу http://www.mozilla.org.
Отличительной особенностью еще одного подобно-
подобного рода инструментального пакета Microsoft FrontPage
является сложность. Однако этот пакет включает в себя,
пожалуй, наиболее удачный визуальный HTML-редак-
HTML-редактор. Редактор FrontPage Editor поддерживает не только
расширенные возможности (например, наборы фреймов
и таблицы), но содержит и наборы шаблонов, суще-
существенно ускоряющих разработку Web-страниц.
This is Netscape Composer!
РИСУНОК 3.3 Composer компании Netscape.
FrontPage представляет собой нечто большее, неже-
нежели просто редактор. Он позволяет создавать админи-
администрировать полновесный Web-сайт, рассчитанный на
работу под управлением Microsoft Internet Information
Server (IIS).
РЕСУРС
Актуальная информация по FrontPage находится по ад-
адресу http://www.microsolt.com.
Один из недостатков, присущих в настоящий мо-
момент некоторым визуальным HTML-редакторам, связан
с невозможностью перехода в текстовый режим и редак-
редактирования чистого кода HTML. В текущей версии
Composer потребуется прибегнуть к услугам какого-то
внешнего редактора. Кроме ГОГО, Composer не знает, что
делать с кодом JavaScript, поэтому не вздумайте исполь-
использовать его в качестве среды редактирования кода, в ко-
котором встречаются сценарии JavaScript. HTML-редак-
HTML-редактор всего лишь позволяет быстро создать HTML, а затем
при помощи текстового или JavaScript-редакторн не-
несложно добавить сценарии.
Web-браузеры
Следующий необходимый компонент — Web-браузер,
поддерживающий JavaScript (см. главу 1). Поскольку
различные виды браузеров обеспечивают разную под-
поддержку языка JavaScript, то во время тестирования по-
потребуются многие из них, если не все.
Основное правило гласит: сценарии необходимо те-
тестировать во всех доступных браузерах. Для приложе-
приложений, рассчитанных на работу в интрасети, достаточно'
ограничиться всего лишь одним браузером. Однако со-
создавая Internet-приложения, следует не забывать, что
доступ к сайту, созданному с использованием JavaScript,
могут получить браузеры практически любого iiiu
Самый лучший способ выяснить, в каких браузерах
просматривается ваш сайт предполагает анализ журна-
журнала посещений Web-сайта. Все браузеры отправляют
строку, определяющую тип браузера и установленную
у пользователя операционную систему:
• Истинные JavaScript-браузеры: Netscape Navigator
4.0+ и Microsoft Internet Explorer 4.0+
¦• Ранние версии JavaSript-браузеров: Netscape Navigator
2.0, Netscape Navigator 3.0 и Internet Explorer 3.0
'• Другие браузеры, поддерживающие JavaScript:
HoUava 3+, Opera 3+ и NetPositive 2.1 +
• Браузеры, не поддерживающие JavaScript
Создаваемое JavaScript-приложение необязательно
должно поддерживать все браузеры. Например, может
потребоваться использовать функцию, которая появи-
Создание собственного набора инструментальных средств JavaScript
лась в последней версии Netscape Navigator, поэтому
просматривать страницу необходимо именно в этой вер-
версии браузера. С другой стороны, тестирование резуль-
результатов проделанной работы в браузерах предыдущих вер-
версий приносит несомненную пользу в плане расширения
применимости.
Отладчики сценариев
Последний необходимый элемент в наборе инстру-
инструментальных средств — отладчик. На данный момент
существуют два основных отладчика, выпущенные ком-
компаниями Microsoft и Netscape. Наверняка, захочется заг-
загрузить оба отладчика, в результате чего появится воз-
возможность организовать отладку как в браузере Navigator,
так и в браузере Internet Explorer. В главе 34 оба отлад-
отладчика рассматриваются более подробно.
Процесс разработки на JavaScript
Итак, все необходимые инструментальные средства со-
собраны. Теперь их потребуется скомпоновать в среду
разработки. Давайте вначале разберемся в самой систе-
системе разработки приложений. На рис. 3.4 показан типо-
типовой сценарий, в соответствие с которым начинают с
создания базовых HTML-страниц, а затем добавляют
JavaScript-код. После этого страница тестируется в выб-
выбранном Web-браузере.
HTML-редактор
Создание HTML-страниц,
Разработка
JavaScript-редактор
Добавление кода на JavaScript
Итеративный процесс
Web-браузер
Отображение HTML-страниц,
Тестирование/
Отладка
РИСУНОК 3.4. ПроцеССразработки на JavaScript.
Серверные инструментальные средства
JavaScript
Возможности, которые заложены в язык JavaScript, по-
позволяют отнести его к языкам сценариев, входящим в
состав инструментальных средств Web-разработки для
сервера. Среди последних можно выделить Netscape's
Глава 3
Server-Side JavaScript и Borland IntraBuilder. Чуть ниже
приводится краткий обзор упомянутых инструменталь-
инструментальных средств.
Netscape's Server-Side JavaScript
Server-Side JavaScript (SSJS) — реализация JavaScript
для серверной части, созданная компанией Netscape.
SSJS поддерживает серверные языковые объекты для
доступа к файлам, почтовым сообщениям и базам дан-
данных. SSJS может применяться для разработки пользо-
пользовательских сценариев, запускаемых на сервере Netscape,
что уменьшает потребность приложений в CGI-сцена-
риях. Более подробная информация находится в гла-
главе 12.
. ресурс ,:;-: 1:
Постоянно обновляющуюся информацию, связанную
с Server-Side JavaScript, лучше всего отслеживать на
странице Netscape DevEdge по адресу http://
developer.netscape.com.
Borland IntraBuilder
Borland IntraBuilder — среда визуальной разработки при-
приложений, предназначенная для создания, поддержки и
администрирования Web-приложений баз данных. Если
когда-нибудь доводилось сталкиваться с инструменталь-
инструментальными средствами визуальной разработки под Windows,
то особых проблем с IntraBuilder возникать не должно.
Ha Web-сайте компании Borland (ныне Inprise) всегда
можно отыскать актуальную информацию касательно
технического обслуживания и поддержки IntraBuilder.
Адрес этого сайта таков: http://www.borland.com.
Язык программирования, реализованный в рамках
среды IntraBuilder, представляет собой расширенную
версию JavaScript, которая характеризуется полной под-
поддержкой объектно-ориентированной методологии
(включая наследование) и наличием объектов доступа
к базам данных. Если вы когда-либо работали с Borland
Visual dBase, то найдете у этих сред множество общих
черт.
Резюме
В данной главе были рассмотрены основные вещи, не-
необходимые каждому разработчику: JavaScript-редактор,
HTML-редактор, Web-браузер и отладчики сценариев.
Кроме того, упоминались два известных серверных про-
продукта, использующие JavaScript в качестве встроенного
языка программирования.
Создание
первого сценария
В ЭТОЙ ГЛАВЕ
Краткое напоминание
Перед началом работы
Приступаем к созданию сценария
Первый сценарий
Три предыдущих главы были посвящены JavaScript
в контексте пространства Internet. Исследовались воз-
возможные способы использования языка и его взаимосвязь
с HTML. Упоминались проблемы поддержки языка со
стороны браузеров, а также его реализация для сторо-
стороны сервера. Была представлена информация о методи-
методике написания кодов и всех необходимых инструмен-
инструментальных средствах. Сейчас приступим к реализации
первого сценария.
Для начала необходимо выбрать правильный подход.
Под правильным подходом подразумевается начальное
планирование сценария, его разработка и тестирование.
Перед переходом к собственно созданию сценария сто-
стоит вспомнить некоторые вещи, рассмотренные в преды-
предыдущих главах.
требуется перевести компьютер в режим ожидания,
пока не произойдет что-то совершенно определенное.
Краткое напоминание
Во-первых, вспомните, что JavaScript внедряется в
HTML-документы через пару открывающих и закрыва-
закрывающих дескрипторов <script>. После загрузки страницы
браузер начинает интерпретировать код, начиная с от-
открывающего дескриптора сценария <script> и завершая
закрывающим дескриптором </script>,
JavaScript интерпретирует каждую строку кода в ко-
команды, которым затем и следует. Это очень похоже на
выполнение определенных инструкций для приготовле-
приготовления, скажем, жаркого. Вы читаете каждое указание и
выполняете его, приближаясь к заветному результату (то
бишь, жаркому). Точно так же и JavaScript выполняет
все в строгом порядке.
Пребывая на пути создания чудесного ужина, вы
остановитесь, ожидая, скажем, разогрева плиты. Подоб-
Подобного рода остановы воспроизводит и JavaScript, если
Перед началом работы
Перед написанием кода необходимо принять несколь-
несколько решений, которые будут рассматриваться в следую-
следующих разделах.
Какие браузеры будут поддерживаться?
Так каким же браузерам отдать предпочтение? Этот
вопрос очень важен. Все зависит от объема создаваемо-
создаваемого кода.
Как упоминалось ранее, с момента выпуска первой
версии JavaScript существенно изменился. До стандар-
стандарта ECMAScript JavaScript был чуть ли не единственным
подобного рода языком. ECMAScript определяет толь-
только базовую часть языка, поэтому все, что касается сер-
серверной и клиентской части, остается неизведанным.
Какие браузеры потребуется поддерживать?
Формируя ответ на этот вопрос, следует учесть не-
несколько рекомендаций:
• Обладает ли сервер функциональными возможностя-
возможностями определения типа браузера перед отправкой ему
страницы?
• Имеется ли общая тенденция отказа от браузеров,
которые не планируется поддерживать?
Помощь со стороны сервера
Если можно определить, какие браузеры запрашивают
страницу перед ее отправкой, то это предоставляет оп-
определенные преимущества при создании клиентских
JavaScript-программ и сценариев. Опять-таки, это позво-
Создание первого сценария
лит избежать ошибок на стороне клиента, которые свя-
связаны с отправкой неподдерживаемого кода.
Правда, потребуется создать несколько версий сце-
сценариев, но время загрузки браузера существенно умень-
уменьшится, а вероятность появления ошибки — снизится.
Исчезнет необходимость определения типа пользова-
пользовательского браузера и, соответственно, передачи лишних
строк кода. Подобного рода функционирование позво-
позволит плавно управлять известными неподдерживаемыми
браузерами.
Постепенные сбои
Другой вопрос заключается в том, насколь последова-
последовательно планируется поддерживать He-JavaScript-браузе-
ры. Сюда относятся не только браузеры, вообще не под-
поддерживающие JavaScript, но и браузеры с отключенной
поддержкой JavaScript.
¦
; :
ПРЕДУПРЕЖДЕНИЕ
В окне настройки предпочтений браузера обработка
кода JavaScript может быть отключена. На рис. 4.1
показано окно настроек Navigator 4.7 и соответству-
соответствующий флажок. Об этом очень важно помнить, по-
поскольку придется учитывать и отключенную поддерж-
поддержку JavaScript. Для простоты воспринимайте браузер с
отключенным JavaScript как браузер, вообще не под-
поддерживающий JavaScript.
ii. tAaA г.. N&wsqrcups
Н-Иааттц Аглае я
-Cecha
¦ EmnrtUpdislR
Г Sand i i
пли FTP cojfwoi t
71 пв bafn'tt Ufqcifr'.. 3
РИСУНОК 4.1. Отключение поддержки JavaScript e
Navigator4.7.
Первым делом было бы неплохо для себя выяснить,
какое место хочется занять в Internet-пространстве. Вы
планируете создать сайт, который будет доступен всем
людям на планете? Может быть, вы создаете интрасеть
для компании и знаете, какие браузеры будут у пользо-
пользователей? А, возможно, вы замахнулись на создание сайта
для проверки возможностей JavaScript?
Глава 4
Все, что потребуется определить, так это ограниче-
ограничения, накладываемые на будущих пользователей. Акку-
Аккуратно продумайте свое решение. Оставляя кого-то за
бортом, вы тем самым снижаете потенциальный трафик.
Если принято решение пользователей с не-JavaScript-
браузерами не поддерживать, задача упрощается — их
не придется обеспечивать дополнительным HTML-ко-
HTML-кодом для просмотра страниц. Если же вам дорог любой
пользователь (в том числе и тот, кто по ряду причин
работает в He-JavaScript-браузере), постарайтесь предо-
предоставить им настолько большую функциональность, на-
насколько это в ваших возможностях.
Как следует учитывать браузеры, не
поддерживающие JavaScript?
Самое время посмотреть, как же поддерживать просмотр
страниц в браузерах с отключенной или вообще отсут-
отсутствующей поддержкой JavaScript. Конечно, можно вос-
воспользоваться функциональностью серверной стороны,
о которой упоминалось ранее. Однако, она не поддер-
поддерживает браузеры с отключенной поддержкой JavaScript.
Здесь на выручку может прийти дескриптор <noscript>.
Дескриптор <noscript> позволяет определить HTML-
код, который будет отображаться на экране в случае,,
¦если JavaScript отключен или не поддерживается. Эта
часть кода всегда следует после любого раздела <script>..
Листинг 4.1 демонстрирует один из примеров исполь-
использования этого дескриптора, а рис. 4.2 — результат ото-
отображения примера в Navigator 4.7 при отключенном
JavaScript.
What is returned?
JavaScript is tamed offl
1 i
РИСУНОК4.2. Визуализациядескриптора <noscript>.
Листинг 4.1. Использование дескриптора <noscript>.
<html>
<head>
<meta http-equiv="Content-Script-Type"
content="text/javascript">
Знакомство с JavaScript
Часть I
<title>My First JavaScript Script</title>
</head>
<body>
<hl>What is returned?</hl>
<script>
< ! —
document.write ( '<p>JavaScript is turned
II—>
</script>
<noscript>
<p> JavaScript is turned off!</p>
</noscript>
</body>
</html>
Детально исследуя листинг 4,1 и рис. 4.2, несложно
заметить, что в разделе <noscript> пользователю выво-
выводится сообщение, гласящее что JavaScript отключен.
Если же поддержка JavaScript включена, та же страни-
страница интерпретирует код на JavaScript и игнорирует раз-
раздел <noscript>. Дескриптор <noscript> поистине неза-
незаменим при учете Не-JavaScript-браузеров.
Некоторые устаревшие браузеры, например, Navigator
2 и ранние версии Internet Explorer, дескриптор
<noscript> не воспринимают. Кроме того, ваш по-
покорный слуга неоднократно имел честь наблюдать
проблемы отображения в браузерах с отключенным
JavaScript, когда данный дескриптор на странице ис-
использовался более одного раза. Кажется, эти пробле-
проблемы в большей степени относятся к семейству браузе-
браузеров Navigator.
Встроить код или вынести его в
отдельный файл?
Последний вопрос, который следует решить перед на-
началом составления кода, — как размещать его на страни-
странице. Предполагается, что вы уже располагаете функция-
функциями, переменными и пр., которые требуется разместить
в рамках действия дескриптора <head>. Весь вопрос в
том, поместить ли код во внешний файл (.js) и сослаться:
на него в атрибуте src дескриптора <script>, либо же
разместить код непосредственно в документе.
Как упоминалось ранее, в результате помещения
кода во внешний файл можно будет редактировать один
файл и воздействовать сценарием на все страницы. Сам
я предпочитаю размещать все функции во внешних
файлах. Зачастую я даже компоную функции по груп-
группам и помещаю их в отдельные файлы. Например, один
файл, calculations.js, может содержать функции расче-
расчетов, а другой, formathandling.js, — различные операции
форматирования.
|ПРИМЕЧАНИЕ ^
Атрибут src появился только в JavaScript 1.1, .Это зна-
значит, что полная его поддержка обеспечивается толь-
только браузерами Navigator 3+ и Internet Explorer 4+.
Предпринимались попытки обеспечить должную поддер-
поддержку внешних сценариев и в Internet Explorer 3.02, од-
однако результаты нельзя считать успешными.
Каковы ваши цели?
и
Перед началом выполнения проекта исключительно
важно определить преследуемые цели. Далеко не всегда
этот этап проделывается должным образом. Так сложи-
сложилось, что многие программисты смотрят на задачу раз-
разработки сценария с позиций развлечения, а не с функци-
функциональной точки зрения.
Java Script обеспечиваетширокий простор для развле-
развлечений, и если это для вас главное — нет проблем, впе-
вперед и с песней! Если же на первом месте у вас стоит
функциональность, попытайтесь минимизировать при-
присутствие лишнего кода, ни для чего кроме показухи не
предназначенного. По истечении определенного време-
времени другие разработчики, да и вы тоже, убедятся, что
отслеживать такой код становится сложнее и сложнее.
Подумайте о дополнительных накладных расходах при
внесении изменений в код, который в большей степе-
степени "крутой", нежели функциональный.
Выделяя цели, как можно более полно определите
конечные результаты будущей программы. Например,
может потребоваться проверка ошибок при заполнении
форм пользователями. Поставив эту цель, потребуется
вернуться обратно и определить способы ее достиже-
достижения. Если программа должна содержать форму, задай-
задайтесь вопросами, сколько элементов будет находится на
форме, т.е. сколько переключателей, текстовых полей,
флажков и т.п.
После преодоления второго уровня целей можно
приступать к проблематике кодирования сценария.
Потребуется реализовать код для поддержки переклю-
переключателей, текстовых полей и флажков. Можно создать
функцию, получающую параметр (скажем, radio), ко-
которая возьмет на себя всю необходимую обработку. Не
забывайте о повторном использовании кода — исклю-
исключительно полезная штука, когда требуется уменьшить
объем создаваемого кода, да, собственно, и воспользо-
воспользоваться накопленными знаниями и опытом.
Приступаем к созданию сценария
Вы готовы к написанию кода. Решено, какие браузеры
будут поддерживаться, а какие — нет, как работать с не-
неподдерживаемыми браузерами и где хранить сценарии.
Создание первого сценария
Глава 4
Определение целей
В первом сценарии будет создаваться простой всплыва-
всплывающий диалог, запрашивающий у пользователя пароль.
В случае ввода пользователем некорректного пароля вы-
выполняется переход на страницу, отображающую соот-
соответствующее сообщение. Если введенный пароль —
правильный, пользователь перенаправляется на запра-
запрашиваемую страницу. Для браузеров, не поддержива-
поддерживающих JavaScript, отображается сообщение о невоз-
невозможности доступа к странице. Поскольку сценарии
реализуются на самом общем подмножестве операторов
JavaScript, они будут корректно выполняться в любом
JavaScript-браузере. Кроме того, все сценарии будут
встраиваться, а не выноситься во внешние файлы.
Рассмотрим резюме вышеизложенного:
¦• Поддержка браузеров: Поддерживать все браузеры
¦ • Реакция нане-JavaScript-браузеры: отобразить сооб-
сообщение о невозможности доступа к данной части ва-
вашего сайта
Размещение сценария: встроенный
• Цель: Запросить у пользователя пароль перед досту-
доступом к странице. При вводе корректного пароля
пользователь направляется на защищенную страни-
страницу, а в противном случае — на страницу, уведомля-
уведомляющую сообщение об ошибке.
Создание шаблона кода
После выяснения целей рекомендуется приступить к
созданию шаблона. Когда я занимаюсь такого рода ве-
вещами, я помещаю в него всю необходимую информа-
информацию раздела <head> и готовлю часть, касающуюся
<body>. В листинге 4.2 показан типовой шаблон, с ко-
которого можно начать.
Листинг 4.2. Файл шаблона JavaScript.
<htnvl>
<head>
<meta http-equiv="Content-Script-Type"
content="text/j avascript">
<title>nepBWf сценарий на JavaScript</title>
<script language="JavaScript">
// Здесь следует поместить код на JavaScript
<Jscript>
</head>
<body>
<!— Здесь начинается код содержимого страницы —>
</body>
</html>
Учет He-JavaScript-браузеров
Сначала необходимо выяснить, как относиться к бра-
браузерам, поддержка которых не планируется. Листинг 4.3
демонстрирует подход, выбранный для данного примера.
Листинг 4.3. Работа с неподдерживаемыми
браузерами.
<body>
<noscript>
<b>
Извините, используемый вами браузер либо
не поддерживает JavaScript, либо
упомянутая возможность отключена.
Информацию, связанную с поддержкой
браузером JavaScript, равно как и с
включением/отключением э^ой поддержки,
можно отыскать на сайте компании-
разработчика браузера.
</noscript>
</body>
Несложно заметить, что все действия сводятся к
выдаче на экран простого сообщения. Текст помещен
между парой дескрипторов (<b>...</b>), что обеспечи-
обеспечивает его отображение в полужирном начертании.
Написание кода
Все вопросы, связанные с внешним видом и функцио-
функциональностью страницы, решены. Можно перейти к на-
написанию кода. За счет предварительного решения всех
моментов, связанных с определением целей, созданием
шаблона, учетом неподдерживаемых браузеров появи-
появилась уверенность, что страница должна функциониро-
функционировать нормально и без написания кода. Этот несомнен-
несомненно важен, поскольку зачастую ошибки возникают не по>
причине некорректного написания сценария, но из-за
неправильно записанного кода HTML или присутствия
комментариев не на своих местах.
Основная работа в данном примере выполняется в
разделе <head>. Первым шагом будет создание диало-
диалогового окна ввода пароля. Для этого используется ме-
метод prompt, в результате вызова которого отображается
диалоговое окно, как на рис 4.3, обеспечивающее пере-
передачу введенной пользователем информации в сценарий.
В
i
Qfef Ueai Prompt
0 iUrr
,*
* F*pr JJrt -
' I'*
t
I
РИСУНОК4.3.Диалоговоеокноprompt.
Ключевой момент, связанный с использованием
окна, заключается в том, что оно возвращает информа-
Знакомство с JavaScript
Часть I
цию, введенную пользователем. На основе упомянутой
информации можно протестировать, привел ли ввод
корректного пароля к переадресации на требуемую
страницу.
prompt — это метод объекта window, воспринимаю-
воспринимающий два параметра и имеющий такой синтаксис:
prompt("message","default");
При вызове этого метода потребуется заменить
message на строки, инструктирующие пользователя.
Они будут отображаться над полем ввода данных. Па-
Параметр default определяет для поля ввода значение по
умолчанию. В нашем первом сценарии значение по
умолчанию не предусматривается, поэтому в метод пе-
передается пустая строка.
В дополнение к методу prompt используется свой-
свойство location объекта window, позволяющее перенапра-
перенаправить браузер на соответствующую страницу в зависимо-
зависимости от введенного значения. И последнее, что еще
осталось — поместить код в функцию, вызываемую пос-
после загрузки страницы.
Код, реализующий данную задачу, достаточно неве-
невелик (см. листинг 4.4).
Листинг 4.4. Запрос ввода пароля.
<script language=" JavaScript">
<!--
function passCheckO {
if(prompt("Пожалуйста, введите пароль","") =
'""letmein") {
window.location = "/secure.html";
}else{
window.location = "/error.html";
I
}
II—>
</script>
В листинге 4.4 в дескриптора <script> используется
атрибут language. Поскольку в шаблоне определено
Content-Script-Type в дескрипторе <meta> в разделе
<head> документа, нет необходимости повторно зада-
задавать язык в дескрипторе <script>. Далее рассматривается
процесс создания функции passCheck().
В теле этой функции для проверки пароля, введен-
введенного пользователем, используется условный оператор
if..else. He стоит беспокоиться о том, как он работает.
Данный аспект детально рассматривается в главе 7.
Следует лишь понять, что данная конструкция прове-
проверяет, вводится ли в качестве пароля последовательность
letmein ("ну дайте же войти"). Проверка осуществляет-
осуществляется с использованием операции ==, которая подробно
рассматривается в главе 6.
В результате ввода корректного пароля пользователь
перенаправляется на страницу /secure.html. Если же
пароль оказывается некорректным, браузер отображает
страницу /error.html.
Вызов функции
Последний шаг в построении работоспособного сцена-
сценария — вызов функции. В данном случае сие действие
организуется через обработчик событий onLoad непос-
непосредственно после загрузки страницы. Данный обработ-
обработчик событий определяется в виде атрибута дескрипто-
дескриптора <body>:
<body onload="passCheck()">
'Первый сценарий
Сценарий готов, осталось лишь собрать его в единый
документ. В листинге 4.5 показана полная страница так,
как она выглядит в текстовом редакторе.
Листинг 4.5. Окончательный сценарий.
<html>
<head>
<meta http-equiv="Content-Script-Type"
content="text/javascript">
<title>nepHbtti сценарий на JavaScript</title>
<script language="JavaScript">
<! —
.function passCheck {) {
if (promptf "Пожалуйста, введите
"пароль","") == "letmein") (
window, location = "/secure.html",-
>else{
window . location= " /error. html " ;
i
</script>
</head>
<body onload="passCheck() ">
<noscript>
<b>
Извините, используемый вами браузер либо
не поддерживает JavaScript, либо
упомянутая возможность отключена.
Информацию, связанную с поддержкой
браузером JavaScript, равно как и с
включением/отключением этой поддержки,
можно отыскать на сайте компании-
разработчика браузера.
</noscript>
</body>
</html>
Из листинга несложно заметить, что в дескрипторе
<head> определяются используемый по умолчанию
язык и функция, которая вызывается через атрибут дес-
дескриптора <body>. Для неподдерживаемых браузеров
предусматривается дескриптор <noscript> в части
<body> страницы. На рис. 4.4 показан результат выпол-
выполнения сценария в JavaScript-браузере, а на рис. 4.5 — в
He-JacaScript-браузере.
Создание первого сценария
РИСУНОК 4.4. Результат выполнениякода излистинга 4.5в
JavaScript-браузере.
i
Ш Ш
ШЯЬиШ
IbRiiiniTp, пспользуемып вами браузер либо не поддерживает JavaScript,
либо упомянутая возможность отключена, Ипформяцшо, связанную с
поддержкой браузером JavaScript, равно как и с включением/отключением
этой поддержки, можно отыскать ня сайте komi
Р И СУ Н О К 4.5 Результат выполнения кода из листинга 4.5 в
не-3а vaScript-браузере.
Глава 4
Резюме
Эта глава была посвящена реализации самого первого
сценария. Примите поздравления. Конечно, можно
было бы составить сценарий типа "Hello World", одна-
однако хотелось предоставить нечто большее. Сценарий
"Hello World" сводится, всего-навсего, к вызову метода
document.write() в разделе <body> документа. Вы уже
умеете это делать в результате написания первого сце-
сценария.
Данная глава завершает первую часть книги. Следу-
Следующие части предоставляют дополнительную информа-
информацию по JavaScript. Мы вместе углубимся в синтаксис и
семантику языка.
Базовое подмножество
языка JavaScript
ЧАСТЬ
В ЭТОЙ ЧАСТИ
5. Основы языка JavaScript
6. Операции
7. Управляющие структуры и организация
циклов.
8. Функции
9. Объекты со стороны клиента
10. Основные объекты языка
11. Создание пользовательских объектов
JavaScript
12. Серверная часть JavaScript
Основы языка JavaScript
В ЭТОЙ ГЛАВЕ
Краткое резюме
Взаимосвязь JavaScript с Java, CGI и
подключаемыми модулями
Встраивание сценариев в HTML-документы
События
Синтаксис
JavaScript — высокоуровневый объектно-ориентиро-
объектно-ориентированный язык, при помощи которого Web-дизайнеры и
программисты легко и просто создают интерактивные
Web-документы. Он обладает характеристиками объек-
объектно-ориентированного языка, не имея сложных функ-
функций, столь характерных для Java и C++.
Несмотря на свой относительно небольшой и легко
воспринимаемый словарный запас, возможностей у
JavaScript очень много. Данная глава посвящена осно-
основам языка и его взаимосвязи с двумя известными Web-
технологиями. Ближе к концу главы можно найти ис-
исчерпывающую информацию, необходимую для
создания собственно сценариев.
Краткое резюме
Пока компания Sun разрабатывала хваленый язык про-
программирования Java, Netscape трудилась над созданием
упрощенного языка сценариев LiveScript. Позже, пос-
после внесения существенных изменений, язык был пере-
переименован на JavaScript и совместно выпущен компани-
компаниями Stn и Netscape.
С помощью JavaScript обеспечивается практически
неограниченная интерактивность Web-страниц, т.к. он
дает возможность доступа к таким событиям, как за-
запуск, загрузка документов, выход и нажатие кнопки
мыши. JavaScript применяется при прямом контроле
¦объектов, таких, как браузерная строка состояния,
фреймы, и даже, браузерное экранное окно. JavaScript,
также, обеспечивает интерактивность между дополни-
дополнительно вставляемыми модулями и Java-аплетами.
Как JavaScript связан с CGI,
дополнительно вставляемыми
модулями и Java
Любого вполне может заинтересовать, что может пред-
предложить JavaScript при использовании CGI-программ и
подключаемых модулей такого, чего не умеет делать
Java. Благодаря CGI-программам полуинтерактивные
Web-страницы появились еще до рождения JavaScript.
Позже появились подключаемые модули и Java, придав-
придавшие Web-страницам еще большую интерактивность. Бо-
Более подробное рассмотрение этих технологий обеспечит
лучшее понимание вклада JavaScript в рамки набора ин-
инструментальных средств создания Web-страниц.
CGI
CGI — стандартный интерфейс между программами и
Web-сервером. Используя языки программирования,
такие как Perl, C/C+, Visual Basic или AppletScript, и
применяя стандарт CGI, можно создавать программы,
передающие информацию от клиента на Web-сервер.
Например, многие поисковые утилиты, обеспечива-
обеспечивающие нахождение тех или иных Web-сайтов и необхо-
необходимой информации, создавались в соответствие со стан-
стандартом CGI. Пользователи вводят ключевое слово или
фразу в текстовом элементе HTML и щелкают на кноп-
кнопке Search. Введенный текст передается на сервер, кото-
который запускает CGI-программу. В свою очередь, про-
программа получает входные параметры и выполняет
соответствующие функции. Поиск будет выполняться
через основную базу данных, выдавая в качестве резуль-
Базовое подмножество языка JavaScript
Часть II
тата только те сайты, которые отвечают заданному
критерию поиска. После завершения операции поис-
поиска CGI-программа генерирует новый HTML-документ
с результатами, который и отправляется в Web-браузер
пользователя.
В данном случае вся основная работа выполняется
сервером. В том случае, когда имеется возможность со-
создавать только статические Web-страницы, приходится
учитывать все возможные комбинации поиска. Созда-
Создание Web-документов на каждый запрос было бы непрак-
непрактично, это крайне неудачный способ эмуляции привыч-
привычных поисковых механизмов. Рассмотренное относится
к одной из проблем, решенных при помощи CGI, и это
помогло Web стать более интерактивной средой.
ресурс1 ¦- :"¦" "¦'¦ .''¦¦" '¦': ¦¦ "'"''
Практически всю известную информацию по стандар-
стандарту CGI и существующим CGi-сценариям можно найти по
адресу http://hoohoo.ncsa.uiuc/edu/cgi/overview.hlml.
Подключаемые модули
После щелчка на ссылке браузер генерирует запрос на
загрузку файла. Если файл хранит простой текст,
HTML или графику, он отображается на экране. В слу-
случае когда браузер не может распознать файл, он пред-
предлагает сохранить его на жестком диске или выбрать
приложение для его обработки. Аналогичные моменты
возникают и тогда, когда файлы различных форматов
внедряются в тело одного HTML-документа.
Подключаемые модули, впервые представленные в
Navigator 2.0 и Internet Explorer 3.0, существенно рас-
расширили количество файлов, распознаваемых браузером.
Подключаемые модули представляют собой программы,
применяемые для расширенной обработки файлов (ска-
(скажем, отображение их на экране с дополнительными
способами управления) либо для интерпретации фай-
файлов, невозможной в оригинальной версии браузера. К
упомянутым файлам относятся аудио-, видео-, Acrobat -
и VRML-файлы.
Например, щелчок на ссылке, указывающей на аудио-
аудиофайл, в браузере, не поддерживающем данный формат,
Таблица 5.1. Сравнение Java и JavaScript.
приведет к поиску соответствующего подключаемого
модуля. После загрузки этого модуля начинается про-
проигрывание клипа. Интеграция браузера и аудиопроиг-
рывателя — практически бесшовна.
иРЕСУРС ¦¦ ' ¦ ^ ' .>¦ • f: , *>-.¦ . ;..
Огромный список подключаемых модулей можно отыс-
отыскать на сайте компании Netscape по адресу http://
home.netscape.com/download.
Java
Java — технология, более всего напоминающая JavaScript.
Однако значительные отличия все же существуют. Да-
Давайте немного подробнее рассмотрим Java, как это было
с CGI и подключаемыми модулями.
В отличие от JavaScript, Java не имеет встроенного
механизма прямого доступа к элементам (т.е. объектам)
Web-страницы. Стоит отметить отсутствие клиентской
версии, которая могла бы управлять HTML- и другими
объектами. Структура и синтаксис Java весьма близки
к JavaScript. Зарезервированные слова, операции и опе-
операторы управления потоком данных совершенно иден-
идентичны. Поскольку Java — компилируемый язык, на
кодовые конструкции накладываются более высокие
требования. Существенные отличия Java от JavaScript
имеют место в двух ипостасях: правилах типизации
переменных и методологии инкапсуляции, принятой
для классов. В табл. 5.1 сведены различия между JavaScript
и Java:
В JavaScript переменные и функции объявляются
локально или глобально. Java обеспечивает условие гиб-
гибкого многоуровневого доступа к переменным и методам
(функциям), когда упомянутые элементы представля-
представляются вместе с модификаторами доступа: private, protected
и public. Модификаторы позволяют скрывать атрибуты
объекта и детали разработки от общего доступа к объек-
объекту, предоставляя большую степень свободы в модифи-
модификации кода. В данном случае несложно поддерживать
опубликованный интерфейс объекта и в то же время
обеспечивать обратную совместимость.
JavaScript
Java
Язык написания сценариев
Слабый контроль типов
Рудиментарный доступ
Отсутствие порожденных типов
Отсутствие контроля доступа к массивам
Иерархия экземпляров
JavaScript-объекты
Язык программирования
Строгий контроль типов
Многоуровневый доступ
Объектно-ориентированные возможности и наследуемые атрибуты
Строгий контроль доступа к массивам
Объектная иерархия
Java-классы
Основы языка JavaScript
Глава 5
Переменные экземпляров Java должны объявляться
строго, причем каждой определенной переменной дол-
должно присваиваться значение ее основного или производ-
производного типа. Коды JavaScript, наоборот, не требуют спе-
спецификации. JavaScript имеет встроенные типы данных,
основная задача которых связана с оптимизацией пове-
поведения и размеров переменных.
Еще одна особенность JavaScript связана с более
обобщенной классификационной схемой (number или
string) no сравнению с Java (int, long, float или char). В
то время как объекты JavaScript нельзя эффективно
преобразовать в более сложные объектные типы, в Java
имеется возможность создания классов, группирующих
переменные в объектные компоненты.
ПРИМЕЧАНИЕ
Следующая предлагаемая версия JavaScript (скорее
всего, это будет 2.0) будет обладать более строгой
классификацией элементов. В JavaScript 2.0 было пред-
предложено добавить такие типы, как int, long, float и char.
JavaScript вполне можно посчитать объектно-ориен-
объектно-ориентированным языком, поскольку он поддерживает иерар-
иерархию экземпляров. В нем имеется возможность опреде-
определять объекты, содержащие методы и переменные,
организовывать ссылки в соответствие с точечной нота-
нотацией; единственное, чего нельзя сделать — расширять
объекты, используя механизм порождения подклассов.
Хоть синтаксис Java и напоминает синтаксис JavaScript
в отношении ссылок и создания объектов, все же Java
является истинным языком программирования, смахи-
смахивающим на C++.
При использовании Java-кода определения объектов
могут послужить оболочкой при создании более слож-
сложных архитектур. Объектные классы — это кирпичики,
из которых строится Java-код. В отличие от JavaScript,
каждая функция и переменная Java должна определять-
определяться внутри какого-то класса. Более того, Java позволяет
группировать классы в пакеты взаимосвязанных объек-
объектов, равно как и определять абстрактные интерфейсные
соглашения для заданных категорий объектов.
¦Следующее отличие связано с тем, что разработчик
компилирует исходный код Java в байт-коды, создавая
двоичные компоненты, которыми могут воспользоваться
другие программисты. На основе полученных компонен-
компонентов (т. г. классов объектов) создаются производные клас-
классы, наследующие функциональность и расширяющие
атрибуты базовых классов.
Возможность расширения базового класса является
основой концепции повторного использования кода в
сложных приложениях, что существенно повышает эф-
эффективность программ. Строгий контроль типов обес-
обеспечивает Java-компилятор, который требует от програм-
программиста явного объявления и приведения переменных
экземпляров либо к встроенным, либо к производным
типам. С другой стороны, JavaScript разрешает програм-
программисту прозрачно переключать определитель типа пере-
переменной без учета первоначального определения типа.
Два языка настолько тесно взаимосвязаны, что это
позволяет разработчикам внедрять вызовы JavaScript-
функций в код на Java, а также обеспечивать доступ к
методам Java-классов из JavaScript. Упомянутые воз-
возможности увеличивают ценность тех программистов на
JavaScript, которые обладают определенными знани-
знаниями Java. Данная технология известна под именем
LiveConnect, Основные аспекты этой технологии под-
подробно рассматриваются в главе 25.
Внедрение сценариев в
HTML-документы
Одна из необычных сторон JavaScript связана с тем, что
на этом языке можно создавать программы, работающие
как со стороны сервера (см. главу 12), так и со стороны
клиента, т.е. в среде браузера. С клиентской стороны
JavaScript применяется в соответствие с одним из двух
способов: внедрение в HTML-документ между парой
дескрипторов <script> либо помещение внутрь дескрип-
дескриптора для обеспечения реакции на событие. Каждый раз
когда HTML-страница загружается, JavaScript интерпре-
интерпретируется браузером. В зависимости от действий пользо-
пользователя и других событий, могущих возникнуть во вре-
время просмотра HTML-документа, выполняется сценарий
целиком или его части.
Например, разрабатывается HTML-документ для
сбора данных о посетителях определенной Web-страни-
Web-страницы. Начать стоит с формы, содержащей три текстовых
элемента: имя, название компании и номер телефона.
В конец формы можно поместить стандартную кнопку
Submit (Отправить) для отправки информации в базу
данных, размещенную на Web-сервере. Кроме того,
можно потребовать, чтобы пользователь полностью за-
заполнял каждое поле, а вместе с номером телефона ука-
указывал код города.
После щелчка на кнопке Submit все данные формы
передаются на обработку в серверную часть программы.
Если оказывается, что пользователь опустил какую-
либо информацию, выдается запрос на ввод этих дан-
данных. Затем пользователь может отправить форму, вклю-
включающую требуемые данные, к тому же в корректном
формате. После того как программа получит от пользо-
пользователя удобоваримые данные, она сохраняет их в базе
данных.
Поддержка полей, обязательных для заполнения, как
в данном случае, приводит к существенным задержкам,
которых можно избежать при помощи JavaScript. Име-
Имеет смысл организовать проверку всех данных на клиен-
Базовое подмножество языка JavaScript
Часть II
ТСКОЙ части • - этим не должен заниматься Web-сер-
Web-сервер. Реализация проверки данных — всего лишь один из
примеров того, как JavaScript может дополнять сервер-
серверные программы, обеспечивая более быструю реакцию
на ошибки и при этом освобождая большее количество'
ресурсов на сервере. В главе 14 вопросы, связанные с
проверкой данных, рассматриваются более подробно.
События
Одна из ключевых характеристик JavaScript — возмож-
возможность захватывать ограниченное количество пользова-
пользовательских действий, в большинстве случаев известных
под именем событий (events). Некоторые HTML-элемен-
HTML-элементы уже реагируют на события; примером может послу-
послужить щелчок на хорошо известном элементе ссылки, что
приводит к перенаправлению на другой HTML-доку-
HTML-документ.
Как только указатель мыши попадает на соответству-
соответствующий ссылке текст или графическое изображение, ука-
указатель изменяет свой стандартный вид стрелки на вид
указующей руки. В дополнение к этому, некоторые
браузеры отображают в строке состояния новый URL.
В JavaScript подобного рода действие носит название
события MouseOver, и реакция будет иметь место тог-
тогда, когда возникает любого рода движение мыши поверх
элемента. После щелчка на любой части ссылки брау-
браузер обеспечивает переход на соответствующий Web-ад-
Web-адрес либо открытие нового файла. Описанное действие
называется событием Click, которое будет генерировать-
генерироваться в результате любого щелчка на ссылке. HTML пере-
перехватывает эти события, и точно такой же будет реакция
браузера.
При помощи JavaScript можно обеспечить пользова-
пользовательские реакции на многие события, генерируемые во
время просмотра HTML-документа пользователем. Осо-
Особенностям управления событиями полностью посвяща-
посвящается глава 14.
Синтаксис
Как и в любом языке программирования, в JavaScript
определены собственные способы управления различ-
различными элементами. Разумеется, в языке присутствует
своя специфика представления ключевых слов, зарезер-
зарезервированных слов, символов и т.п.
Версии JavaScript
В результате неутомимой совместной деятельности ком-
компаний Netscape, Microsoft и ряда других, призванной
усовершенствовать стандарт ECMAScript, появились но-
новые версии JavaScript и поддерживающих этот язык бра-
браузеров. В данной книге речь идет, в ОСНОВНОМ, о версии
1.4, а иногда и о версии 1.5, находящейся на стадии бета-
тестирования. Таблица 1.5 предоставляет исчерпываю-
исчерпывающую информацию о поддерживаемых платформах.
Таблица 5.2. Поддержка JavaScript.
Версия Описание
JavaScript 1.0 Поддерживается в Netscape Navigator 2
JavaScript 1.1 Поддерживается в Netscape Navigator 3,
Internet Explorer 3, Opera 3, Netscape
Enterprise Server 2
JavaScript 1.2 Поддерживается в Netscape Navigator
(версии 4-4.04),
Internet Explorer 4
JavaScript 1.3 Поддерживается в Netscape Navigator
(версии 4.05-4.7),
Internet Explorer5
JavaScript 1.4 Поддерживается в альфа-версиях Moziila
<до М 12), HotJava 3.0, Internet Explorer
5.5, Netscape Enterprise Server 4.6
JavaScript 1.5 Планируется поддержка в Navigator 5
(Moziila), т.е. в версии Netscape
Navigator с открытым кодом.
Внимательное исследование табл. 5.3, 5.4 и 5.5 позво-
позволит понять взаимосвязь существующих версий JavaScript,
JScript и ECMAScript.
Таблица 5.3. Взаимосвязь между JavaScript и
JScript.
JavaScript
JScript
1.0
1.1
1.2
¦1,3
¦и
1.5
Не соотносятся
1.0-2.0
3.0^.0
5.0-5.1
5.0-5.1
5.5
Таблица 5.4. Взаимосвязь между JavaScript и
ECMAScript.
JavaScript
¦1.0
11.1
1.2
1 1
-14
'I 5
ECMAScript
He соотносятся
He соотносятся — Фундамент для
стандарта
Не соотносятся — Большая часть
перенята из ECMAScript 1.0
1.0
1.0 B-я модификация)
1.0 C-я модификация)
Основы языка JavaScript
Глава 5
Таблица 5.5. Взаимосвязь между JScript и
ECMAScript._
JScript
1.0
2.0
3.0-3.1
4.0
5.0
5.5
ECMAScript
Не соотносятся
Не соотносятся — Фундамент для
стандарта
1.0
1.0
1.0 B-я модификация)
1.0 C-я модификация)
Каждый разработчик JavaScript должен хорошо знать
особенности целевой платформы, чтобы выбрать для
разработки корректную версию JavaScript, т.е. то, что
потребуется указать в атрибуте language дескриптора
<script>.
ПРИМЕЧАНИЕ ..'¦"¦ - ':
Не следует забывать, что дескриптор <script> в HTML
4.01 и XTML 1.0 был официально упразднен. На дан-
данный момент стандартного дескриптора, позволяюще-
позволяющего определить языковую версию, не существует. Пока
нет никакой определенности, я бы посоветовал вос-
воспользоваться атрибутом language в композиции с ат-
атрибутом type.
Например, если приложение должно работать в
Netscape Navigator 2 и выше, а также в Microsoft Internet
Explorer 3.0, сценарии следует разрабатывать на JavaScript
1.0. Однако если выходной платформой является
Navigator 5.0/Mozilla, и есть желание воспользоваться
всеми преимуществами новой версии языка, то для ука-
указания версии 1.5 следует записать:
<script language="JavaScriptl.5"
type="text/javascript">
Для версии 1.4 воспользуйтесь такой строкой:
<script language = "JavaSeriptl.4"
type="text/javascript">
А для версии 1.3 -такой:
<script language= "JavaScriptl.3"
type="text/javascript">
Для версии 1.2 подойдет строка:
< script language= "JavaScriptl.2"
type="text/javascript">
Выбор версии 1.1 обеспечит строка:
<script language="JavaScriptl.1"
type="text/javascript">
А версии 1.0 — строка:
<script language="JavaScript"
type="text/javascript">
ИрймечАнйе ",-"-, " •'"'"' \ ¦' ¦ s*" •¦; и.. ¦; PJL 'Ц
Не пытайтесь в качестве выбранной версии 1 .0 языка
указывать "JavaScriptl.0" или "JavaScriptl". Подобно-
Подобного рода сентенции не распознаются, и в результате
сценарий игнорируется.
^ВНИМАНИЙ
Перед переходом к исследованию особенностей язы-
языка JavaScript хотелось бы снова напомнить о важности
указания корректного языка в дескрипторе <script>.
Браузер попросту проигнорирует любой сценарий, для
которого определяется нераспознанная им версия
языка.
Лексемы
Лексемы (tokens) — это наименьшие отдельные слова,
фразы, символы, которые может распознать JavaScript.
Во время интерпретации JavaScript-кода браузер разби-
разбивает сценарии на лексемы, игнорируя при этом коммен-
комментарии и лишние пробелы.
Лексемы подразделяются на четыре категории: иден-
идентификаторы, ключевые слова, литералы и операторы.
Как и в любом компьютерном языке, существует мно-
множество способов подачи компьютеру различных дирек-
директив за счет различной компоновки лексем. Синтаксис
(syntax) языка — это набор правил и ограничений, ис-
используемый при комбинировании лексем.
Идентификаторы
Идентификаторы (identifiers) — суть ни что иное как име-
имена переменных, методов и объектов. Они состоят из
комбинации букв и цифр. Некоторые имена уже встро-
встроены в язык JavaScript и поэтому зарезервированы от
использования.
Независимо от ключевых слов, можно определять
собственные, притом значащие идентификаторы. Разу-
Разумеется, для этого существует несколько правил:
¦ • Все идентификаторы должны начинаться либо с бук-
буквы, либо с символа подчеркивания (_).
• Для всех последующих знаков допускается исполь-
использование букв, цифр и символов подчеркивания.
В понятие букв входят заглавные буквы, начиная с
А и заканчивая Z, и строчные буквы, т.е. с а до z.
Имя идентификатора не должно содержать пробелов.
В понятие цифр входят знаки, начиная с 0 и закан-
заканчивая 9.
В табл. 5.6 показаны примеры допустимых и недо-
недопустимых идентификаторов.
Базовое подмножество языка JavaScript
Часть II
Таблица 5.6. Примеры идентификаторов
JavaScript.
Допустимые
Недопустимые
current_WebSite
numberOfHits
in
N
current WebSite
#oflslands
2bOrNotToBe
return
Идентификатор current WebSite является недопусти-
недопустимым по причине присутствия в нем символа пробела.
Этот идентификатор будет рассматриваться не как один,,
но как два. Если по смыслу в идентификаторе должен
находиться пробел, то на его месте обычно ставится
символ подчеркивания.
#oflslands не является допустимым, поскольку сим-
символ # не входит в разрешенное множество символов.
2beOrNotToBe — некорректен, потому как начинается
с цифры. Идентификатор return уже используется в
JavaScript для других целей. В случае его определения,
после запуска приложения выдается ошибка.
Идентификаторы п и N — вполне допустимы, одна-
однако отличны друг от друга. Ввиду того что JavaScript
чувствителен к регистру, упомянутые идентификаторы
интерпретируются как разные, даже несмотря на их, в
общем-то, одинаковое произношение.
Ключевые слова и зарезервированные слова
Ключевые слова (keywords) — предварительно определен-
определенные идентификаторы, составляющие ядро языка про-
программирования. В JavaScript они выполняют особые
функции, например, объявление новых переменных,
функций, принятие решений на основе текущего состо-
состояния компьютера или организация цикла внутри при-
приложения.
Ключевые слова встроены в JavaScript и всегда дос-
доступны программисту, однако в отношении них следует
придерживаться правильного синтаксиса. Ключевое
слово var — одно из первых, о котором будет детально
рассказываться в главе. Позже демонстрируется приме-
применение других ключевых слов для создания более дина-
мичныхпрограмм.
Зарезервированные слова (reserved words) — это иден-
идентификаторы, которые не могут использоваться в каче-
качестве имен переменных, функций, объектов и методов
как сейчас, так и в будущем. Рассмотрим полный спи-
список зарезервированных слов JavaScript:
abstract else instanceof switch
boolean enura int synchronized
break export interface this
byte extends long throw
case false native throws
catch final new transient
char
class
const
continue
debugger
default
delete
do
finally
float
for
function
goto
if
implements
imoort
null
package
private
protected
public
return
short
static
true
try
typeof
var
void
volatile
while
with
Литералы
Литералы (literals) — это числа или строки, представля-
представляющие постоянные значения JavaScript. Это значения,
которые не изменяются во время выполнения сценария.
В следующих пяти разделах рассматриваются различные
виды литералов.
Целочисленные литералы
Целочисленные литералы могут быть представлены в
десятичном (десятичная система счисления), восьме-
восьмеричном (восьмеричная система счисления) или шестнад-
шестнадцатиричном (шестнадцатиричная система счисления)
формате. Целочисленный литерал в десятичном форма-
формате может содержать любую последовательность цифр,
но не начинаться с 0. Ноль в начале целочисленного
литерала определяет восьмеричный формат.
В восьмеричной записи целочисленный литерал
может включать последовательность цифр от 0 до 7. Для
определения шестнадцатиричного формата числа перед
литералом должно ставится Ох или ОХ. Шестнадцати-
Шестнадцатиричные целочисленные литералы могут содержать циф-
цифры от 0 до 9 и буквы а — Гили А — F. Рассмотрим не-
несколько примеров:
Десятичные литералы: зз, 2139
Восьмеричные литералы: cm, 03664
Шестнадцатиричные литералы: 0x7Ь8, 0X395
Литералы с плавающей точкой
Литералы с плавающей точкой представляют десятич-
десятичные числа с дробной частью. Их можно выражать в
стандартном и экспоненциальном форматах. Экспонен-
Экспоненциальный формат подразумевает использование е или
Едля определения порядка числа. И десятиричное чис-
число, и показатель степени могут быть со знаком или без-
беззнаковыми (положительные и отрицательные):
3405.673
-1.958
8.3200е+11
8.3200е11
9.98Е-12
Основы языка JavaScript
Логические литералы
В JavaScript реализован логический тип данных, поэто-
поэтому поддерживаются два литерала true и false, представ-
представляющие соответственно значения логической 1 и 0. Если
вы новичок в области программирования, не отчаивай-
отчаивайтесь — очень скоро вы поймете всю важность true и false.
Ключевые слова true и false должны записываться строч-
строчными буквами. Таким образом, TRUE и FALSE пропис-
прописными буквами остаются доступными для применения
в качестве собственных идентификаторов. Однако, во
избежание недоразумений, использовать их в таком
контексте не рекомендуется.
Строковые литералы
Строковый литерал — это ноль и более символов, зак-
заключенных в двойные ("") или одиночные (") кавычки.
Несмотря на то что JavaScript разрешает использовать
оба типа кавычек, для строки лучше применять один и
тот же тип кавычек как в начале, так и в конце. Рассмот-
Рассмотрим примеры строковых литералов:
"Allen's car"
'virtual "communities"'
"#12-6"
"Look, up in the sky!"
Применение одного из двух видов кавычек достаточ-
достаточно удобно, если вы — сторонник либо первого, либо
второго метода. Во время изучения встроенных методов
JavaScript следует учесть необходимость строгого выпол-
выполнения всех указаний, касающихся строковых литералов,
передаваемых в качестве параметров. В ряде случаев
допускается применять оба типа кавычек при помеще-
помещении одного строкового литерала внутрь другого. После-
Последнее не разрешается при указании управляющих кодов,
речь о которых идет ниже.
Специальные символы
Иногда в сценарии может потребоваться использовать
специальный знак либо их комбинацию, например,
симвох табуляции или новой строки. В этом случае уп-
управляющий код должен предваряться символом наклон-
наклонной черты влево (\), как показано ниже:
\Ь — забой
\f — перевод страницы
— новая строка
\г — возврат каретки
\t — табуляция
\\ - наклонная черта влево
V — одинарная кавычка
\" — двойная кавычка
Глава 5
Если требуется сэмулировать нажатие клавиши та-
табуляции для выравнивания, скажем, двух столбцов
данных, следует использовать знак табуляции (\t). В
листинге 1.5 демонстрируется один из способов вырав-
выравнивания текста при помощи знаков табуляции. Если
сценарий содержит специальные знаки, читать его ока-
оказывается сложнее, но как показано на рис. 5.1, резуль-
результаты выглядят гораздо лучше:
Листинг 5.1. Использование специальных знаков в
JavaScript.
<html>
<head>
<^Ъ1е>Специальные символы в JavaScript-
сценариях</ЫЫе>
</head>
<body>
<!
Специальные символы не возымеют
действия до vex пор, пока не поместить их в
сформатированный блок текста
(т.е. тот, который находится между парой
дескрипторов <рге>..</рге>).
<рге>
<script
type="text/javascript">
document.writeln("\tPersonnel") ;
document.writeln("Name\t\tAddress");
document.writeln("Jeff\t\tjeff@company.com")
document.writeln("Bill\t\tbill@company.com")
document. writeln("Kim\t\tkim@company.com");
</script>
</pre>
</body>
</html>
Bill
Kim
bill@cbmpany.com
fdia@.;omp?ny, com
'РИСУНОК 5.1. Выравнивание текста при помощи табуляции.
ПРИМЕЧАНИЕ
Специальные знаки оказывают воздействие только ког-
когда используются в пределах предварительно отформа-
отформатированного текстового блока, потому-то сценарий дол-
должен помещаться в пару дескрипторов <рге> и </рге>.
Если строковый литерал должен воспроизводить сим-
символы кавычек, применяйте их в паре с символом наклон-
наклонной черты влево.
Базовое подмножество ЯЗЫКп JavaScript
Часть II
document.write("\"*антаэия важнее знаний.\"");
document.write(", Альберт Эйнштейн"),-
Этот сценарий обеспечит отображение на экране
следующей строки:
"Фантазия важнее знаний.", Альберт Эйыптейн
Операции
Операции (operators) — это символы или идентификато-
идентификаторы, которые представляют способ оценки или манипу-
манипуляции комбинациями выражений. Наиболее использу-
используемой общей операцией является далеко не операция
присваивания. В примере х=10 как собственно 10, так
и переменная х — это выражения. Когда JavaScript
встречает операцию присваивания между двумя выра-
выражениями, выполняются действия в соответствие с пра-
правилами оператора присваивания. В рассматриваемом
случае значение выражения в правой части присваива-
присваивается переменной в левой части. Наряду с арифметичес-
арифметическими, JavaScript поддерживает 30 других операций,
которые более подробно рассматриваются в главе 6.
Переменные
Переменная (variable) — это имя, присваиваемое ячейке
памяти компьютера, которая хранит определенные дан-
данные. Праотцы программирования тратили уйму време-
времени на трансляцию данных, наподобие сообщения "Hello
World", в двоичные коды. Затем они искали свободное
место в компьютерной памяти для размещения всех
полученных единичек и ноликов, не забывая запомнить
адрес начала и завершения этих данных. При помощи
упомянутых адресов ячеек памяти можно было нахо-
находить, изменять и считывать данные. В общем, никогда
не завершающийся день сурка. (Да здравствует День
Сурка!!!)
Нынешним программистам повезло больше — им на
помощь пришли переменные, и жизнь их пошла на су-
существенную поправку, поскольку сохранение, измене-
изменение и чтение данных стало теперь как никогда простым.
Благодаря механизму переменных появляется возмож-
возможность присваивать значащие имена ячейкам, которые
хранят данные, явно используемые программистом, в то
время как доступ к остальным ячейкам — забота исклю-
исключительно компьютера.
Проблема именования
Имя переменной в JavaScript состоит из одной и более
букв (A..Z и a..z), цифры @..9) и символов подчеркива-
подчеркивания (_). однако не может начинаться с цифры. Следу-
Следующих два имени JavaScript воспринимает как различ-
различные:
internetAddress
internetaddress
Вот еще корректные имена:
_lastName
л
number_2
Когда имя переменной по смыслу содержит одно
слово, при ее записи принято использовать строчные
буквы, а вот при наличии в имени смысловых двух или
трех слов, то первое слово начинается со строчной, а все
последующие — с прописных. Обычно мои имена пе-
переменных заключают в себе два-три слова, что обеспе-
обеспечивает гораздо лучшее понимание смысла определения
переменной.
Предположим для примера, что требуется перемен-
переменная с логическим значением (true or false), которая уве-
уведомляет, завершил ли посетитель Web-страницы ввод
своего имени в текстовом поле. Если имя переменной
выглядит наподобие finish, другой программист с удив-
удивлением подумает: "Что это — флаг, при помощи кото-
которого можно выяснить, завершены ли пользовательские
действия? А, может быть, это — строковое выражение,
которое записывают после того, как посетитель завер-
завершил операцию, скажем, сообщение о благодарности?"
В данном случае гораздо лучшим выбором будет имя
isDone. Использование в качестве приставки слова is
позволяет рассматривать переменную как вопрос, на
который требуется ответ "да" или "нет", а это, в свою
очередь, означает, что переменная хранит логические
значения. Если посетитель завершил ввод своего имени,
isDone присваивается значение true, в противном слу-
случае false.
Несмотря на то что размер имени переменной
JavaScript ограничивается только объемом оперативной
памяти, все же подходить к данному вопросу лучше с
практической точки зрения. Я советовал использовать
не более 20 символов, т.е. 2-3 слова. При написании
сценария не стоит заходить за конец строки. Этому спо-
способствуют длинные имена переменных, к тому же они
нарушают целостность восприятия кода.
По сложившейся традиции переменные, состоящие
из одного слова и даже из одного символа, представля-
представляют математические значения. Вот несколько примеров
подобного рода имен: п для любого числа, х, у, z — для
координат, i — для заполнителя в рекурсивной функции
или переменной цикла. Поскольку данные способы — тра-
традиционные, их можно использовать каждый раз, когда
сочтете нужным.
Работая в профессиональном окружении, потребу-
потребуется обеспечить удобочитаемость написанного кода для
других разработчиков. В этом смысле существенную
помощь окажут непротиворечивые и осмысленные со-
соглашения об именовании. Плохо или недостаточно про-
продуманные соглашения ничего кроме головной боли не
принесут, да и могут отрицательно сказаться на осно-
Основы языка JavaScript
вополагающих показателях компании как разработчика
программного обеспечения.
Объявление переменных
Для того чтобы уведомить JavaScript о том, что конк-
конкретный идентификатор должен использоваться в каче-
качестве переменной, в первую очередь, его потребуется
объявить. Для объявления переменных в JavaScript ис-
используется ключевое слово var, за которым следует но-
новое имя переменной. Имя будет резервироваться как пе-
переменная, которую можно использовать в качестве
области памяти для хранения любых данных. Следую-
Следующий пример демонстрирует возможность одновремен-
одновременного объявления нескольких переменных (между от-
отдельными именами должны ставится запятые).
var internetAddress;
var n;
var i, j, k;
var isMouseOverLink, helloMessage;
После объявления переменной можно присваивать
начальное значение. Подобное действие носит название
инициализации и выполняется при помощи операцией
присваивания =.
Знак равенства (=) используется для присваивания пе-
переменной определенного значения. Проблемы, связан-
связанные с оператором присваивания, подробно рассмат-
рассматриваются в главе 6.
Переменную можно инициализировать непосред-
непосредственно при ее объявлении либо позже, в любом месте
сценария. Установка начального значения переменной
во время объявления упрощает запоминание, какой тип
значений первоначально планировалось хранить в пере-
переменной. Уточним предыдущий пример, добавив необ-
необходимые инициализации:
var internetAddress = "name@company.com";
var n = 0.00 ;
var i = 0, j = 0, k;
var isMouseOverLink = false;
var hello Message = "Hello, thank you for coming!";
k = 0;
Несложно заметить, что все переменные, кроме к,
были проинициализированы во время объявления, а к
инициализируется позже. JavaScript читает строки кода
сверху вниз, выполняя директивы одну за другой. До
инициализации переменная остается неопределенной
(undefined), поэтому прочитать ее значение нельзя. По-
Попытка чтения значения переменной перед ее инициа-
инициализацией приведет к ошибке во время выполнения при-
приложения. JavaScript дает возможность проверить, было
ли присвоено значение переменной, с помощью опера-
оператора tj'peof (см. главу 6).
Глава 5
В дополнение к ключевому слову var, JavaScript
предлагает и другой способ объявления переменных
при помощи обычной их инициализации. Если присво-
присвоить новой переменной значение перед ее объявлением
при помощи var, то JavaScript автоматически объявит ее.
^примечанйе^Г^^^'^^Ж'Т ^ ' '". " *¦"•¦?..
В ранних версиях JavaScript-браузеров объявление пе-
переменных без слова var означало их автоматическое
объявление с глобальной областью действия (или ви-
видимости). Может возникнуть впечатление, что это
сокращает накладные расходы, однако хорошая прак-
практика программирования предполагает именно явное
объявление переменных. При помощи ключевого слова var
поддерживается концепция области действия переменной.
Типы
При сохранении порции данных (более известных под
именем значения), JavaScript автоматически относит ее
к одной из пяти категорий. В табл. 5.7 сведены различ-
различные типы данных, поддерживаемые JavaScript.
Таблица 5.7. Типы данных JavaScript.
Тип
Пример
number
boolean
string
function
¦object
-19,3.14159
true, false
"Элементарно, дорогой Ватсон",""
unescape, write
window, document, null
Переменные типа number хранят действительные
или целые числа, boolean — значения true или false, a
string содержат строковые литералы, включая пустую
строку. В табл. 5.7 пустая строка представляется с по-
помощью двух двойных кавычек. Функциональный тип
(function) либо определяется пользователем, либо отно-
относится к встроенным функциям. Например, функция
unescape является встроенной в JavaScript. Проблемати-
Проблематике создания функций, определяемых пользователем, по-
посвящается глава 8.
Функции, принадлежащие объектам, в JavaScript
называются методами (methods). Они также относятся к
типу данных function. Базовые клиентские объекты
JavaScript, такие как window или document, имеют тип
данных object. Переменные типа object, или просто
объекты, могут хранить объекты. Переменная со значе-
значением null относится к типу object. Инициализация пе-
переменной значением null позволяет избежать ошибок,
если нет уверенности в будущем ее использовании.
Как правило, в других языках программирования
Требуется определять тип данных, представляемых но-
новой переменной. На протяжении всей программы тип
любого значения, присваиваемого переменной, должен
Базовое подмножество языка JavaScript
Часть II
быть определенным и неизменным. Более того, если
переменной присваиваются значения различных ТИПОВ,
это приводит к ошибке. Для JavaScript, слабо типизи-
типизированного языка, подобное не имеет места. Не потре-
потребуется определять типы данных. Кроме того, одной и
той же переменной можно присваивать значения разных
Типов. Переменная JavaScript способна в любой момент
принять новое значение. Рассмотрим примеры допусти-
допустимого использования переменных JavaScript:
var carLength ;
carLength =4+5;
document.writeln(carLength);
carLength = "9 футов",-
document.writeln(carLength);
После объявления переменной carLength ей присва-
присваивается значение 4+5. В JavaScript число 9 сохраняется
с типом number. Присваивая carLength значение друго-
другого типа "9 футов", в этой переменной сохраняется стро-
строковый литерал (string). Операция подобного рода
уменьшает количество действий, которые могли бы по-
потребоваться в других языках программирования для
уведомления о факте смены типов значений.
Область действия переменных
Область действия (или видимости) переменных (scope) —¦
это участки внутри программы, в которых возможна
ссылка на переменную. Например, рассмотрим случай
внедрения одного сценария в часть <head> HTML-до-
HTML-документа, а другого — в часть <body> того же докумен-
документа. JavaScript считает, что все переменные, объявленные
внутри упомянутых двух участков, принадлежат одной
и той же области действия. Такие переменные являют-
являются глобальными (global), и они доступны любому сцена-
сценарию в текущем документе. Несколько позже речь пой-
пойдет о функциях — отдельных блоках кода. Переменные,
объявленные внутри таких блоков, носят название ло-
локальных (local) и они доступны не каждому сценарию.
Локальные переменные
Переменная, объявляемая внутри функции является
локальной. К значениям этой переменной может иметь
доступ только данная функция. При каждом вызове
функции все локальные переменные создаются, а пос-
после возврата функции — разрушаются. Если в другой
функции присутствует объявление переменной с таким
же именем, она рассматривается как совершенно дру-
другая переменная. Каждая из переменных адресует свой
'блок памяти.
Глобальные переменные
Если требуется, чтобы какая-то переменная совместно
использовалась в более чем одной функции, следует
объявить ее вне функций (но, конечно же, внутри пары
дескрипторов <script>). В этом случае данная перемен-
переменная будет доступна в любой части всего приложения, в
том числе и во всех функциях.
^ПРИМЕЧАНИЕ Г
Рекомендуется объявлять глобальные переменные в
разделе <head> HTML-страницы, тем самым гаранти-
гарантируя, что они загрузятся раньше любой другой части
приложения.
Листинг 5.2 демонстрирует способ объявления и
применения глобальной переменной. Для большего
понимания различий между областями действия пере-
переменных, в программу помещены две функции. Не обя-
обязательно выяснять, как действуют функции, следует
лишь усвоить тот факт, что они представляют собой
отдельные части сценария, заключенные в фигурные
скобки ({}). Более подробную информацию, связанную
с функциями, можно найти в главе 8.
Листинг 5.2. Глобальные и локальные переменные.
<html>
<head>
<title>JavaScript Unleashed</title>
<script type="text/javascript">
<! —
/ / Глобальные переменные
var globalString = "A";
// Функаии
function changeToB() {
document. outputForm. bef oreB . value =
globalString;
globalString = "B";
document.outputForm.afterB.value =
globalString;
1
function changeToCf) {
document. outputForm. bef oreC . value =
globalString;
globalString = "C";
document. outputForm. af terC. value =
globalString;
</script>
</head>
<body>
<script type="text/javascript">
<! —
document, write ("The initial value of
''•globalString is V" + globalString + "\".">;
//-->
</script>
<br>
<form name=" outputForm" >¦
<input name="changeButtonA" type="button"
value="Change To B" onclick= "changeToBO ">
Основы языка JavaScript
Глава 5
<input name="changeButtonB" type="button"
value="Change To C" onclick="changeToC(>">
<p>
Value of globalString
<J»
<input name="beforeB" type="TEXT" size=,l">
<P>
Before clicking on "Change To
<p>
<input name="afterB" type="TEXT" size=,l">
<P>
After clicking on "Change To B"
<P>
<input nanre="be?oreC" type="TEXT" size=,l">
<P>
Before clicking on "Change To С
<P>
<input name="afterC" type="TEXT" size=,l">
<P>
After clicking on "Change To C"
</form>
</body>
</html>
Первым отображается начальное значение globalString.
Несмотря на то что переменная объявляется в разделе
<head> документа, сценарий, расположенный внутри
раздела <body> ее может использовать. Щелчок на кноп-
кнопке "Изменить на В" приводит к тому, что функция
change ТоВ() выводит на экран первоначальное значение
globalString, заменяет его на В и отображает новое зна-
значение globalString (см, рис. 5.2).
i
The initiii value ofglobalString is "A".
Value of globsUSlring
Before clicking он "Change To B"
After clicking OD "Change To B"
Before clicking on "Change To C"
After clicking on "Change To C"
РИСУНОК 5.2. Глобальные и локальные переменные.
Для демонстрации гого, что все функции в докумен-
документе могут использовать одну и ту же переменную, была
добавлена вторая кнопка для вызова другой функции.
Пс'сле щелчка на кнопке "Изменить на С", на экра-
экране отображается текущее значение globalString, на дан-
данный момент равное В, после чего значение globalString
изменяется на С. На рис. 5.2 показаны результаты опи-
описанных действий.
Константы
Константа представляет собой переменную, сохраняю-
сохраняющую свое значение неизменным на всем протяжении
выполнения программы. JavaScript использует встроен-
встроенные константы для представления значений для обыч-
обычных математических действий, скажем, число пи. Дос-
Доступ к таким константам осуществляется через объект
math (см. главу 10).
Константы, определенные пользователем — это суть
определенные пользователем переменные, значения
которых не изменяются. Обычно при именовании кон-
констант используются строчные буквы и они определяют-
определяются в начале программы.
JavaScript не поддерживает константы в традицион-
традиционном смысле. В языках программирования, поддержива-
поддерживающих константы, определяемые пользователем, никакая
другая часть приложения не может изменять значение
константы после его определения. Попытка подобного
изменения приведет к ошибке. В JavaScript все по-ино-
по-иному.
Даже при отсутствии уверенности в том, что перемен-
переменная не изменяется, все же стоит работать с переменными
для сохранения значений, которые будут использоваться
на протяжении всего сценария. Заменяя переменной
множество вхождений простых значений, сценарий го-
гораздо проще изменить впоследствии. Все что потребу-
потребуется предпринять — изменить начальное значение пере-
переменной и сценарий полностью обновится.
Цвета
JavaScript поддерживает цвета, используемые при созда-
создании HTML-страниц. Доступные цвета в виде строковых
литералов (не констант) сведены в табл. 5.8. Перечис-
Перечисленные значения можно присваивать определенным
свойствам объекта.
В листинге 5.3 показано применение этих значений
для установки цветов отображаемых строк. Допускается
использование имени цвета либо его шестнадцатирич-
шестнадцатиричного эквивалента. Хоть это может показаться странно-
странноватым, однако выполняется только установка свойства
fontcolor для отображаемого на экране строкового лите-
литерала. Неплохо было бы внимательным образом изучить
рис. 5.3.
Нельзя изменить цвет текста, уже выведенного в окно
браузера. В таком случае потребуется просто перезагру-
перезагрузить документ с новым установленным цветом шрифта.
Листинг 5.3. Использование цветов в JavaScript.
<html>
<head>
ПРИМЕЧАНИЕ
Базовое подмножество языка JavaScript
Часть II
JavaScript</title>
</head>
<body>
все из них поддерживаются JavaScript. В табл. 5.8 све-
сведены все цвета, поддерживаемые JavaScript.
<h2>
<script type="text/javascript">
document.writeln( "Пикник для сотрудников
.fontcolor("orimson")) ;
</script>
</h2>
<h4>
<script type="text/javascript">
document.writeln(9 июля в час
"¦•дня" . fontcolor ( "blue") > ;
document.writeln ("<br>" + "He забудьте
*• захватит» свою семью!" .fontcolor ("#008000")) ;
</script>
</h4>
</body>
</html>
Шестнадцатиричная строка для каждого цвета пред-
представляет собой комбинацию значений RGB (red/green/
blue — красный/зеленый/голубой), лежащих в основе
каждого цвета. Например, шестнадцатиричное значение
для цвета морской волны (aqua) выглядит как #OOFFFF.
В приведенном значении RGB: 00 — красный, FF — зе-
зеленый и FF — голубой. Две цифры в шестнадцатиричном
значении позволяют определять 256 оттенков каждого
цвета. В цвете морской волны красная составляющая
равна 0, а это означает отсутствие в нем красного цве-
цвета. Интенсивности зеленого и голубого максимальны.
Обеспечив соответствующие пропорции зеленого и го-
голубого в результате приводят к цвету морской волны.
Имея 256 комбинаций красного, синего и зеленого мож-
можно скомпоновать около 16 миллионов цветов, однако не
Пикш для сотрудников компании!
23 апреля в шесть в«ч*ра
Не забудьте захватить семьи!
РИСУНОК 5.3. Изменение цвета текста
в JavaScript.
Типы данных
Несмотря на недавнее обсуждение основных типов дан-
данных, присваиваемых переменным, стоит напомнить, что
функции и объекты относятся к специальным типам
данных. Они предлагают достаточно интересные спо-
способы сохранения и манипулирования данными сцена-
сценария. Особенности использования функций и объектов
рассматриваются в главе 8.
Выражения
Выражение (expression) — это набор операторов, которые
подобно группе объединяется в одно значение. Результи-
Результирующее значение будет относиться к одному из следую-
следующих типов данных: boolean, number, string, function, object.
Таблица 5.8. Значения цветов с их шестнадцатиричными эквивалентами.
Цвет
Я
G
В
Цвет
R
G
В
aliceblue
aqua
azure
bisque
blanchedalmond
blueviolet
buriywood
chartreuse
coral
cornsilk
cyan
darkcyan
darkgray
darkkhaki
FO
00
FO
FF
8A
DE
7F
F:F
\
DO
00
A9
BD
F8
FF
FF
E4
EB
2B
B8
FF
7F
F8
Fl
8B
A9
•;7
FF
;f
Fl
C4
CD
F_2
87
00
SO
IX.
FF
8B
A9
6B
antiquewhite
aquamarine
beige
black
blue
brown
cadetblue
chocolate
cornflowerblue
crimson
darkblue
darkgoldenrod
darkgreen
darkmagenta
FA
7F
F5
00
00
A5
5F
D2
64
DC
00
B8
00
8B
EB
pp
F5
00
00
2A
ЭЕ
69
95
14
00
8G
64
00
D7
D4
DC
00
FF
2A
АО
1E
'El
ЭП
8B
OB
00
HI
Цвет
G
Цвет
Основыязыка JavaScript
Глава 5
G
е
darkolivegreen
darkorchid
darksalmon
darkslateblue
darkturquoise
deeppink
dimgray
firebrick
forestgreeni
gainsboro
gold
gray
greenyellow
Ihotpink
indigo
khaki
lavenderblush
llemonchiffon
lightcoral
lightgoldenrodyellow
lightgray
lightsalmon
lightskyblue
lightsteelblue
lime
linen
maroon
mediumblue
rnediumpurple
mediumslateblue
mediumturquoise
midnightblue
mistyrose
navajowhite
oldlace
olivedrab
orangered
palegoldenrod
paleturquoise
papayawhip
peru
plum.
purple
rosy brown
saddlebrown
sandybrown
seashell
3 1-158
55
99
1: 9
48
00
FF
69
IB2
'22
DC
FF
80'
All
FF
4B
FO'
1 F
IFF
FO'
IFA
D3
iFF
87
IBO
00
IFA
80
00
93
7B
48
19
IFF
ГР
FD
6B
!FF
ЕЕ
AF
FF
¦CD
on
80'
ВС
8B
IF4
FF
6B
32
96
SID
CE
14
69
22
8B
IDC
D7
80'
ГГ
69
00
E6
F0
li A
80
ГА
to
АО
CE
C4
FF
FO'
00
00
7ft
68
D1
19
E4-
DE
IF5
8E
45
E8
ЕЕ
,EF
85
АО
00
8F
45
A4
F5
2F
CC
ТЛ
8B
П
93
69
22
22
IDC
00
80
2F
B4
82
8C
F5
CD
80
02
D3
7A
FA
IDE
00
E6
00
CD
DB
IFF.
CC
70
Ё1
AD
E6
23
00
AA
ЕЕ
D5
3F
DD
80
8F
13
60
ЕЕ
darkorange
darkred
darkseagreeni
darkslategray
darkviolet
deeps kyblue
dodgerblue
floralwhite
fuchsia
ghostwhite
goldenrod
green
'honeydew
indianred
ivory
lavender
lawngreen
lightblue
lightcyan
lightgreen
lightpink
lightseagreen
lightslategray
lightyellow
Ilimegreen
magenta
imediumaquamarine
mediumorchid
mediumseagreen
mediumspringgreen
mediumvioletred
imintcream,
moccasin
navy
olive
orange
orchid
palegreeni
palevioletred
peachpuff
pink
powderblue
red
royalblue
salmon
seagreen
sienna
IFF
8B
8F
2F
94-
00
IE
FF
FF
IF8
DA
00
F0'
CD
IFF
E6
7C
AD
E0
90
Iff
20
77
FF
32
FF:
66
BA
3C
00
C7
F5
FF
00
80
rf
DA
98
DB
,FF
FF
BO
FF
41
FA
2Ё
A0'
8C
00
IBC
4F
00
,BF
90
! A
00
F8
A5
80
FF
5C
IFF
E6
FC
Bo
FF
ЕЕ
B6
B2
88
FF
CD
00
CD
55
B3
Га
15
JT
E4
00
80
A5
70
IFB
70
DA
CO'
E0
00
69
80
8B
52
00
00
8F
4F
03
l F
FF
iO
l_l_
FF
20
00
FO
5C
'FO
II A,
00
f 6
FF
90
C1
AA
99
EO
32
FF
AA
O3
71
9A
85
FA
B5
80
00
00
D6
98
93
B9
CB
E6
00
П
72
57
2D
Базовое подмножество языка JavaScript'
Часть II "
Цвет
R
G
В
Цвет
R
silver
slateblue
snow
steelblue
teal
tomato
violet
white
yellow
1 0
ЪА
FF
46
00
FF
ra.
IFF
FF
CO
5A
ГЛ
182
80'
63
82
,! F
FF
CO
CD
ГЛ
Bl
80
47
1-Е
FF
CD
skyblue
slategray
springgreen
tan
thistle
turquoise
wheat
whitesmoke
yellowgreen
.87
70
00
D2
ID8
40
! 5
F5
?IA
CE
,80
FF
B4
BF
li 0
D?;
1 5
CD
II
90
7F
8C
D8
DO
B3
F5
32
Выражение может быть простым, как отдельное чис-
число или переменная, а также включать в себя переменные,
ключевые слова и операции. Например, выражение х=10
присваивает значение 10 переменной х. Приведенное
выражение дает результат 10, потому применение вы-
выражения в строке а-ля document.writeln(x=10) — впол-
вполне допустимо.
JavaScript мог бы рассматривать информацию, зак-
заключенную в кавычки, как строку и просто отображать
ее на экране, однако в данном случае выполняются не-
некоторые дополнительные действия. Сначала рассчиты-
рассчитываются все выражения, присутствующие в скобках, и
только после этого осуществляется собственно отобра-
отображение значения на экране. В рассматриваемом приме-
примере на экран выводится 10.
Кстати, просто х — тоже допустимое выражение. В
данном случае выполняется только чтение значения
переменной из памяти. Не выполняется ни одного при-
присваивания. Разумеется, в выражениях можно применять
великое множество других операций помимо операции
присваивания (см. главу 6).
Комментарии
До сих пор дескрипторы комментария применялись
только для окружения текста сценариев, что гарантиро-
гарантировало отсутствие их отображения в старых браузерах. А
как насчет воспользоваться комментарием, чтобы про-
проигнорировать часть кода JavaScript? Оказывается, все
сильно смахивает на C/C++ и Java:
// Однострочный комментарий
Две косых черты (//) "скрывают" текст вплоть до
конца текущей строки. Допускаются и многострочные
комментарии:
/* Желаете поместить
¦строк? Так вот
ааы и способ! */
комментарий несколько
В обоих типах комментариев излишние пробелы иг-
игнорируются, поэтому оба следующих примера коррект-
корректны:
// Комментарий
/* Многострочный
комментарий * /
Листинг 5.4 демонстрирует применение обоих типов
комментариев. Две косых черты не обеспечат сокрытие
кода от старых браузеров. Дабы не создавать трудностей
упомянутым браузерам, для обрамления сценариев про-
продолжайте прибегать к паре <!-- и —>. Все, что в лис-
листинге 5.5 закомментировано, на экране отображаться не
будет (см. рис. 5.4).
Листинг5.4.Использованиедескрипторов
комментариев в JavaScript.
JavaScript</title>
<html>
<head>
<title>KoMMeHTapmi
</head>
<body>
<script type=" text/ j avascript" >
<! —
// Переменные
var ?irstName = "Jon" ;
var lastName = "Simpson";
var internetAddress = "jsimpson@company.com";
Отобразить имя и фамилию пользователя
вместе с его адресом электронной почты.
// Скомбинировать три строки
document .writeln (firs tName + " " +
lastName + "<br>") ;
document.writeln ("e-mail address: " +
internetAddress);
// —>
</script>
</body>
</html>
Возможность сокрытия определенного кода от ин-
интерпретации JavaScript дает возможность документиро-
документировать сценарии. Совсем неплохо по ходу пьесы добавлять
заметки, связанные с дизайном, дружеские напомина-
напоминания или предупреждения. Это окажет существенную
Основы языка JavaScript
помощь для других в плане понимания, что означают
те или иные разделы программы.
Щ JavaScript Unleashed - Netscape
¦ -
^E -| tfj'
Jon Simpson
e-mail address: jsimpson@company.com
РИСУНОК 5.4. Комментарии на экране браузера не
отображаются.
Глава 5
ПРИМЕЧАНИЕ
Советую объявлять переменные в разделе <head>
HTML-документа. Это позволит получить уверенность,
что функция загрузится браузером до ее выполнения
в разделе <body>.
¦ .¦ ¦ ¦ . ..¦ - ¦ . ..-¦¦
Для вызова функции достаточно поместить ее имя в
любом месте программы. Главная программа размеща-
размещается внутри раздела <body> и обрамляется парой деск-
дескрипторов <script>. Результат использования функции
показан на рис. 5.5.
Листинг 5.5. Внедрение функции JavaScript.
<html>
<head>
<title>Ilcncwb3OBai»ie функций в
JavaScript</title>
<script type="text/javascript">
<!--
function displayMessage() (
document.write ("Функции JavaScript
^исключительно просты в
-использовании!<Ьг>");
Еще одно применение комментариев касается отлад-
отладки сценариев. Для целей тестирования можно упрятать
часть своего кода, а после его отладки с легкостью вер-
вернуть, удалив всего лишь символы комментария. В отли-
отличие от удаления частей сценария, такие действия суще-
существенно экономят время.
Функции
В простейшей своей форме функции — это сценарии,
вызываемые по имени в любой момент. Разумеется, они
призваны серьезно расширить возможности JavaScript.
После прочтения HTML-документа JavaScript-браузе-
JavaScript-браузером, последний отыскивает все внедренные в документ
сценарии и выполняет инструкции шаг за шагом. Все это
очень удобно до тех пор, пока не потребуется, чтобы
вся программа или ее часть перешла в режим ожидания.
Организация такой части программы в виде поимено-
поименованной функции — один из путей решения упомяну-
упомянутой проблемы.
После генерации определенных событий имеется
возможность запустить сценарий, воспользовавшись
именем, присвоенным функции. Другое преимущество
функции связано с повторным использованием кода
сценария.
В листинге 5.5 показан один из способов использо-
использования функций JavaScript. Первое, на что стоит обратить
внимание— где будет объявляться функция. Объявлять
следуе" не только переменные, но и функции. Не забудь-
забудьте все объявления функций поместить в пару дескрип-
дескрипторов <script>.
</script>
</head>
<body>
<script type="text/javascript">
<! —
document. write < "Вызов функции
*¦»JavaScript.. .<p>");
displayMessage();
document.write("</р>Сделано,
// ">
</scrip t>
</body>
</html>
");
jij Hi* ¦ : ¦,
Вызов функции JavaScript...
Функции JavaScript исключительно просты в использовании!
Вот и все, что было.
»™;
РИСУНОК 5.5. Вызов функции в JavaScript.
Базовое подмножество языка JavaScript
Часть II
Начав с главного сценария, JavaScript, как обычно,
выполняет первую строку, а затем попадает на вызов
функции dispIayMessage(). Выполняется поиск функ-
функции в памяти и переход на ее первую строку. После
вывода на экран фразы Функции JavaScript исключи-
исключительно просты в использовании! отображается разрыв
строки. Как только функция завершается, выполнение
программы возобновляется с точки, где она приостано-
приостановилась по причине обращения к функции.
Как видно на рис. 5.5, каждая строка текста отобра-
отображается в определенной последовательности. Если у вас
громоздкая программа, несколько раз выводящая сооб-
сообщение на экран, вызовы функции можно вставить в
любых требуемых местах. Если позже потребуется из-
изменить текст сообщения, это делается лишь в одном
месте. Поменяйте его внутри тела функции, и прило-
приложение полностью обновится. Преимущества использо-
использования функций подробно описываются в главе 8.
Резюме
JavaScript сделал серьезный взнос в набор инструмен-
инструментальных средств Web-разработчика. Именно в этом язы-
языке доступны многие вещи, кажущиеся невозможными
для CGI, подключаемых модулей и Java. JavaScript обес-
обеспечивает взаимодействие с пользователем во время про-
просмотра HTML-документа.
Сценарии помещаются непосредственно в HTML-
документы и обрамляются парой дескрипторов <script>.
Для того чтобы JavaScript игнорировал отдельные части
сценария, воспользуйтесь корректным типом коммента-
комментариев.
Интерпретатор JavaScript прочитывает каждую строку
сценария, начиная с самой первой. Лексемы представ-
представляют собой небольшие отдельные слова, фразы и знаки,
доступные JavaScript. Лексемами могут быть литералы,
идентификаторы и операторы.
К доступным типам данных относятся: number,
boolean, string, function и object. В один и тот же момент
времени переменная может хранить данные только од-
одного типа. Для объявления переменных либо восполь-
воспользуйтесь ключевым словом var, либо просто проинициа-
лизируйте переменную. Для повышения читабельности
сценариев присваивайте переменным осмысленные
имена.
Выражение — это набор операторов, результатом
выполнения которых является единственное значение.
Наиболее типичные выражения сводятся к присвоению
значений переменным. Операция присваивания = слу-
служит для присваивания значения правого операнда пе-
переменной, записанной как левый операнд. JavaScript
поддержи
Операции
В ЭТОЙ ГЛАВЕ
Операции присваивания
Арифметические операции
¦Операции сравнения
Строковые операции
Условные операции
Булевы операции
Операция typeof
Определение и вызов функций
Операции со структурами даннвгх
Поразряднвю операции
Приоритетв! ввшолнения операций
Основной смысл написания сценариев связан с не-
необходимостью организации ввода, вычислений, отобра-
отображения либо управления данными. До сих пор внимание
акцентировалось на способах отображения данных при
помощи JavaScript. Для создания хороших программ
необходимо научиться также оценивать и изменять дан-
данные, с которыми JavaScript-сценарии имеют дело. Ин-
Инструментальные средства, реализующие подобную рабо-
работу, носят название операций.
Операции — суть символы и идентификаторы, ко-
которые представляют способы изменения данных либо
вычисления комбинаций выражений. Язык JavaScript
поддерживает как бинарные, так и унарные операции.
Бинарные операции работают с двумя операндами в
выражении, например, 9 + х, тогда как для унарных опе-
операций достаточно только одного операнда, например,
Х++.
Оба приведенных примера демонстрируют арифме-
арифметические операции; их использование будет понятно
тем, кто знаком с основами математики. Другие типы
операций JavaScript оперируют со строками и логичес-
логическими значениями. Они не настоль хорошо знакомы
математикам старой закалки, однако их чрезвычайно
Просто изучить и впоследствии предельно удобно
пользоваться при работе с большими объемами текста
в Internet. В этой главе детально рассматривается каж-
каждый тип операций в JavaScript.
ПРИМЕЧАНИЕ
Netscape предлагает консольный режим работы, ко-
который обеспечивает отображение результатов вычис-
вычисления выражений по мере их ввода. В версиях, пред-
предшествующих 4.05, данные отображались в главном окне
браузера. Начиная с версии 4.05, с целью обеспече-
обеспечения свободного доступа и отображения ошибок
JavaScript консоль была реализована в виде отдельно-
отдельного окна.
Этот режим обеспечивает превосходный способ про-
проверки результатов вычисления выражений. Для активи-
активизации режима в поле Location наберите:
javascript:
Теперь можно вводить практически любую строку
JavaScript, включая объявление переменных, функций
и объектов, а также выражения. Пример использо-
использования упомянутой возможности показан на рис. 6.1.
Был выполнен ввод 12 << 1 и дважды нажата клавиша
Enter.
javascript typein
[la « 1;
.
РИСУНОК 6.1. Использование КОНСОЛЫЮго режима в Netscape.
Базовое подмножество языка JavaScript
Часть II
Операции присваивания
Рассмотрим операцию, о которой уже упоминалось ра-
ранее, — операцию присваивания. Ее основная функция
заключается в присваивании переменной некоторого
значения, помещая таким образом это значение в па-
память.
Например, выражение х = 20 обеспечивает присва-
присваивание переменной х значения 20. Когда JavaScript
встречает операцию присваивания (=), вначале анали-
анализируется правая часть с целью определения значения.
После этого рассматривается левая часть — она должна
представлять место для хранения значения. Если слева
находится переменная, ей присваивается значение. В
рассматриваемом случае х получает определенное зна-
значение 20. Операция присваивания всегда выполняется
справа налево, так что выражение 20 = х вызовет ошиб-
ошибку в JavaScript, поскольку будет предпринята попытка
присвоить 20 новое значение. Такое действие невозмож-
невозможно, поскольку 20 не является переменной, но целым чис-
числом, значение которого не может быть изменено.
JavaScript поддерживает 11 других операций присва-
присваивания, которые фактически являются комбинациями
операции присваивания и арифметических или пораз-
поразрядных операций. Сокращенные версии операций по-
показаны ниже:
Комбинации операции присваивания и арифметических
операций:
х += у сокращенная запись для х = х + у
х -= у сокращенная запись для х = х - у
х *= у сокращенная запись для х = х * у
х /= у сокращенная запись для х = х / у
х %= у сокращенная запись для х = х % у
Комбинации операции присваивания и поразрядных
операций:
х «= у сокращенная запись для х = х « у
х »=у сокращенная запись для х = х » у
х >»= у сокращенная запись для х = х >» у
х &= у сокращенная запись для х = х & у
х "= у сокращенная запись для х = х ~ у
х | = у сокращенная запись для х = х | у
Арифметические операции
При работе с числами используются арифметические
операции. К основным операциям этой группы отно-
относятся знак "плюс" (+), суммирующий два значения, знак
"минус" (-), вычитающий одно значение из другого,
звездочка (*), перемножающая два значения, а также
косая черта (/), которая обозначает деление одного зна-
значения на другое.
Когда JavaScript встречает одну из перечисленных
операций, выполняется анализ правой и левой частей
выражения, имеющий целью отыскать значения, с ко-
которыми предстоит работать. В примере 7+9 JavaScript
воспринимает операцию плюс и просматривает обе ча-
части выражения, в результате чего находится 7 и 9. Да-
Далее операция плюс обеспечивает суммирование двух
найденных значений и устанавливает результат выраже-
выражения равным 16. Используя арифметические операции в
комбинации с операцией присваивания, можно задавать
новое значение переменной:
х = 7 + 9
Переменная х будет теперь равна 16, и ее можно
использовать снова, в том числе присваивать ей новые
значения:
х = х + 1
Посмотрите на два последних примера. Переменной
х было присвоено какое-то значение. Затем х присваи-
присваивается новое значение — текущее (в данный момент рав-
равное 16) плюс 1.
Увеличение значения переменной на 1 и затем при-
присваивание ей же этого нового значения представляет
собой достаточно стандартную операцию. Последняя
настолько часто используется в компьютерных програм-
программах, что некоторые языки включают специальные со-
сокращенные операции, чтобы упростить запись увеличе-
увеличения и уменьшения значения переменной. JavaScript -
как раз относится к таким языкам. Для записи инкре-
инкремента применяется ++, а для декремента — —:
++i — то же самое, что и i = i + 1
—i — то же самое, что и i = i - 1
Существует возможность использования этих сокра-
сокращенных операций в префиксной и постфиксной фор-
формах. Таким образом меняется порядок возврата значе-
значения выражения и установки нового значения.
Листинг 6.1 демонстрирует работу операций инкре-
инкремента и декремента.
Листинг 6.1. Пример операций инкремента и
декремента.
<html>
<head>
<title>Onepamm инкремента и декремента
</title>
</head>
<body>
<script type="text/javaScript">
var i = 0;
var result = О
Операции
document.write("Если i = О, ");
document.write("i возвращает свое значение");
document. write (" после инкрементирования : ">;
// Префиксная форма инкремента
result = ++± ;
document.write(result);
/'/ Сбросить значение переменной
i = О;
document.write("<br>i++ возвращает значение
-i") -¦
document.write(" перед инкрементированием : ") ;
// Суффиксная форма инкремента
result = i++;
document.write(result);
Сбросить значение переменной
i = О;
"<br>—i возвращает значение
-i'1);
" после декрементирования : ") ;
// Префиксная форма декремента
result = —i;
document.write(result);
Сбросить значение переменной
i = 0;
document.write("<br>i— возвращает значение
-i11);
document.write(" перед декрементированием : ") ;
// Суффиксная форма декремента
result = i—;
document.write(result);
,'/ —>
</script>
</body>
</html>
После исследования кода, представленного в лис-
листинге 6.1. важно понять, в какой момент увеличивает-
увеличивается значение переменной i — перед или после вычисле-
вычисления выражения.
В первом примере переменная result получает пер-
первоначальное значение i плюс 1. Во втором примере ре-
результат устанавливается равным первоначальному зна-
значению i до выполнения инкремента i. Два следующих
примера работают аналогичным образом, однако при-
применительно к операции декремента.
Результаты вычислений этих четырех примеров по-
показаны на рис. 6.2. Хотя это может показаться и ненуж-
ненужным, рассмотренные особенности принесут несомненную
ПОЛЬЗУ при записи повторяющихся частей сценария. Дан-
Данная тема освещается в главе 7.
Унарная операция отрицания (-) применяется в слу-
случаях, когда требуется заменить положительное значение
на отрицательное и наоборот. Она названа унарной, т.к.
работает только с одним операндом. Если, например,
Глава 6
присвоить значение переменной х (х = 5), применить к
х операцию отрицания, а затем результат присвоить у
'(у = -х), то значение у будет равно -5.
¦ ¦
НЯяШ^
Еспиа - 0. i возвращает свое значение поспаинкрементмроеания: 1
++ возэращает значение I перед ^нфементироеанием: О
i еозвращаетэначение i после декрементирования . Л
I- вивращаетэначение! переддекрембнтмровани&м: о
'РИСУНОК 6.2. Операции инкремента и декремента из
листинга б. 1.
Противоположность также истинна, т.е. при отрица-
отрицании отрицательного числа результат будет положитель-
положительным. В обоих примерах операция отрицания не изменяет
значения переменной х, которое остается равным 5.
)перация взятия по модулю обозначается знаком
процента (%). Найти модуль двух операндов означает
найти остаток после деления первого операнда на вто-
второй. В примере х = 10 % 3 переменная х получит зна-
значение 1, поскольку результатом деления 10 на 3 будет
3 с остатком 1. При помощи операции взятия по моду-
модулю можно легко определить, что одно число является
множителем другого: при этом модуль этих двух чисел
будет равен 0. Это истинно, например, для выражения
х = 25 % 5. 25 разделить на 5 равно 5 без остатка, зна-
значит х будет равно 0.
ПРЕДУПРЕЖДЕНИЕ
В ряде случаев Netscape Navigator возвращает непра-
неправильные значения, когда имеет дело с дробями. На-
Например, 10/3 должно вернуть 3 '/,. В окне консоли
Netscape в качестве результата вычисления 10/3 ото-
отображается 3.3333333333333335. Небольшая погреш-
погрешность в шестнадцатом знаке после десятичной точки
связана со способом, по которому дроби хранятся в
памяти компьютера. Microsoft Internet Explorer реша-
решает эту проблему, отображая только 14 знаков после
запятой. В этом случае результатом того же вычис-
вычисления будет 3.33333333333333.
.. .
¦
Операции сравнения
Операции сравнения используются именно для сравне-
сравнения выражений. Выражения, которые используют one-
Базовое подмножество языка JavaScript
Часть II
рации сравнения, отвечают на вопрос, связанный с дву-
двумя значениями. Ответом может быть true или false.
Два знака "равно" (==) обозначают операцию равен-
равенства. Использовать операцию равенства между двумя
операндами — означает определить, являются ли зна-
значения этих двух операндов равными. Листинг 6.2 де-
демонстрирует способ отображения результатов при вы-
выяснении равенства двух переменных.
Листинг 6.2. Использование операции равенства.
<html>
<head>
<title>Onepautni cpaBHem«i</title>
</head>
<body>
<script type="text/javascript">
// Объявление переменных
var x = 5;
var у = 5;
var z = 10;
// Отображение результатов
document.write ("x = " + x + "<br>") r
document.write("y = " + У + "<br>");
z. = ' h Z + "<br>") ;
document.write("Равны пи значения х и у
w(x = у) ? ") ;
document.write(x = y);
("<Ъг>Равны ли значения
¦-у и z {у = z)? ") ;
document.writeln(у = z);
// —>
</script>
</body>
</html>
Необходимо убедиться, что при написании програм-
программы используется именно требуемая операция. Еще раз
следует подчеркнуть, что операция равенства (==) про-
проверяет, являются ли два значения равными, тогда как
операция присваивания (=) устанавливает значение
переменной. В случае использования не той операции
интерпретатор JavaScript даст об этом знать. На рис. 6.3
показаны результаты выполнения кода из листинга 6.2.
В табл. 6.1 приведен список всех операций сравне-
сравнения.
Таблица 6.1. Операции сравнения.
Операция Описание
Операция равенства. Возвращает true, если
операнды равны между собой.
!= Операция неравенства. Возвращает true, если
операнды не равны между собой.
Операция "больше". Возвращает true, если
значение левого операнда больше значения
правого операнда.
Операция "больше либо равно". Возвращает
true, если значение левого операнда больше
либо равно значения правого операнда.
Операция Описание
Операция "меньше". Возвращает true, если
значение левого операнда меньше значения
правого операнда.
Операция "меньше либо равно". Возвращает
1ше,еслизначениелевогооперандаменьше
либо равно значения правого операнда.
П ¦ js " " ¦
i-5
z=10
¦ счй Hi
Равны пи значения х и у (х — у)? t
Равш пи Энэ
ениЯуи z(y— z)?
SSH^fiVHWPlRfiHMi
¦
rue
alse
•*4
JWWWMi'iiMiwMli'iiilMMM
РИСУНОК 6.З. Операция равенства излистинга 6.2.
Операции сравнения обьгано используются в JavaScript
для принятия решений. Они помогают выбирать путь,
по которому будет следовать сценарий. Более подроб-
подробно эта темя рассматривается в главе 7.
ОПЕРАЦИИ СРАВНЕНИЯ В РЕАЛИЗАЦИИ JAVASCRIPT 12
В NAVIGATOR
До появления JavaScript 1.1 язык был очень терпим к
сравнению операндов различных типов. Например, при
сравнении числа 7 со строкой " JavaScript сначала
преобразовывал, или приводил, операнд строки к чис-
числу и затем выполнялось сравнение. Для примера с 7
и ", операнды считались равными.
В JavaScript 1.2 программист должен сначала преоб-
преобразовать строку в числовую форму либо число в стро-
строку. Если этого не сделать, JavaScript никогда не ска-
скажет, что они равны. Листинг 6.3 показывает способ
сравнения строки и числа, который возвращает одни
и те же результаты для всех версий JavaScript. На рис.
6.4 приведена реакция JavaScript 1.2 на три различных
сценария. Листинг 6.3 может запускаться только в
браузерах, поддерживающих JavaScript 1.2, например,
в Netscape Navigator 4.0-4.04.
Листинг 6.3. Тестирование различных версий
JavaScript.
<html>
<head>
сравне ния</ti tl e>
</head>
<body>
<script language="JavaScript">
Операции
Глава 6
var x = ";
var у = 7 ;
document.write('x = );
document.write("<br>");
document.write("y = 7");
document.write ("<brXhr>">;
document, write ("JavaScript 1.0 и l.KbrV)
document.write("x = 3 :
document.write(x = 3);
document.write("<br>") ;
document .write ('y = " :
documen t.wri te(у =
II—>
</script>
¦< script language="JavaScriptl. 2 " >
<! —
document.write ("<brXbr>JavaScript 1.2<br>") ;
a 3 : ") ;
document.write (x = 3) ;
document.write<"<br>");
' : ') /"
document.write (y =
</script>
<script language="JavaScriptl.3">
<! —
document.write <"<brXbr>JavaScript 1.3
*-»и выше<Ьг>") ,'
document.write("x =3 : ") ;
document .write(x = 3) ;
document.write("<br>");
document.write ('y = " : ' ) ;
document.write (y = ") ;
II—>
</script>
<script language="JavaScript">
document, write ("<ЬгхЬг>Универсальныи код
'-•для всех версий.<br>") ;
document.write ("x -0 = 3: ") ;
document.write(x - 0 = 3);
document.write("<br>");
" + у = " : ') ;
document.write {"" + Y == ") ;
II—>
</script>
</body>
</html>
Строковые операции
Набор строковых операций, доступный в JavaScript,
включает все операции сравнения и операцию конкате-
конкатенации (+). При помощи операции конкатенации стро-
строки соединяются вместе в одну длинную строку (см.
листинг 6.4).
Л истингб.4. Конкатенацижтрок.
<html>
<heac:>
<title>JavaScript Unleashed»:/title>
</head>
<body>
script type="text/javascript">
! —
/ / Объявление переменных
var
var
a = "www";
b = "company";[sr]
с = "
= "com";
equal to
equal to
." + c;
var sumOfParts;
var addressl;
var address2;
document.write ("Part a is equal to \"
'-+ a + "\".">;
document.write("<br>Part b is
*++ b + "\".">;
document.write ("<br>Part с is
*-+ с + "\".\n");
sumOf Parts = a + "." + b +
addressl = "WWW.COMPANX.COM";
address2 = "www.company.com";
// Отображение результатов
document, write ("<brXbr>Is sumOf Parts equal
+ addressl + "? ") ;
document, write (sumOf Parts == addressl);
document.write("<br>Is sumOfParts equal to
*-»+ address2 + "? ") ;
document.write (sumOf Parts == address2) ;
document.write("<br>Is sumOfParts greater
"-than " + addressl + "? ") ;
document.write(sumOfParts > addressl);
</script>
</body>
</html>
JavaScript 1.0и 1.1
x==3 true
y==" true
JavaScript 1 2
x==3 false
y—" false
JavaScript 1 Зи выше
= 3 true
у == ": true
Универсапьный код для всех версий,
х-0 — 3 true
.А.
¦на
1
!
i
РИСУНОК 6.4. Сравнение строк и I
чисел излистинга 6.3.
Сначала сценарий выполняет инициализацию трех
переменных, хранящих три части Web-адреса. Затем все
три части соединяются вместе и разделяются необходи-
необходимыми точками, присутствующими во всех Web-адресах.
Далее выполняется проверка, содержит ли sumOfParts
определенный адрес Internet.
Рисунок 6.5 отражает тот факт, что JavaScript при
сравнении строк учитывает регистр символов. Сравне-
Базовоеподмножествоязыка JavaScript
Часть II
ние выполняется слева направо, по ASCII-кодам каж-
каждого символа в обеих строках. Если все коды соответ-
соответствуют друг другу, строки равны. Все прописные буквы
имеют коды, меньшие, чем их эквиваленты в нижнем
регистре, потому и последнее сравнение в листинге 6.3
возвращает true.
3 JavaSmpt IMaashod - Microsoft Internal I
Part a IS equal to *www*.
Partb is equal to "со
Part с is equal to *co:
Is sur. equal to WWW.C0MPANY.COM? false
Is sun arts equal to www с
is somOJParts greater ihan'WWW. COM PAN Y.COMT But
var resultMsg = (numHits 1000000) ? "Co
чщиток!" : "На щите.";
alert(resultMsg);
При условии, что numHits равен 1000000 в любом
месте программы, это выражение возвращает строку "Со
щитом!"; в противном случае - "На ш те.". Вторая
строка приведенного примера отображает результат для
пользователя при помощи функции alert()
Условное выражение может применяться для возвра-
возврата данных любого типа, например, number или boolean.
Следующее выражение возвращает строку или число в
зависимости от значения useString:
var result = useString ? "семь" : '
document.write(result);
Булевы операции
РИСУНОК 6.5. Результат выполнения кода из листинга 6.4.
Условные операции
Две операции ? и : используются для формирования ОПбОЭЦИЯ
Булевы операции (также называемые логическими)
используются в дополнение к выражениям, возвраща-
возвращающим логические значения. Действие этих операций
проще понять, изучив их использование совместно с
операциями сравнения. Таблица 6.2 содержит описа-
описание трех булевых операций. Приведены примеры с
синтаксисом expressioni [operator] expression! и с
[operator] expression.
условных выражений. Эти условные операции выпол-
выполняют те же действия, что и оператор if. Условное выра-
выражение возвращает одно из двух значений, в зависимос-
зависимости от логического значения какого-то выражения.
Например, следующее условное выражение будет
сообщать пользователю; что он — миллионный посети-
посетитель страницы:
Таблица 6.2. Булевы операции.
Операция typeof возвращает тип данных, хранящихся в
операнде в текущий момент времени. Это оказывается
особенно полезным при выяснении, была ли определе-
определена переменная. Рассмотрим следующие примеры:
typeof unescape возвращает строку ""functioi
typeof undefinedVariable возвращает строку "undefined".
Операция Описание
&& Логическая операция И (конъюнкция). Возвращает true, если оба выражения expressioni и ехрге 2 имеют
значения true. В противном случае возвращается false. Рассмотрим примеры:
A > 0) && B > 1) возвращает true.
A > 0) && B < 1) возвращает false.
Логическая операция ИЛИ (дизъюнкция). Возвращает true, если хотя бы одно из значений expressioni или
expression2 равно true. Если ни одно из expressioni и expression2 не равно true, возвращается false.
Рассмотрим примеры:
A > 0) || B < 1) возвращает true.
A < 0) || B < 1) возвращает false.
Логическая операция НЕ (отрицание) —унарная операция, которая возвращает противоположное значение
булева выражения. Если expression равно true, возвращается false, а если expression — false, возвращается
true. Эта операция не изменяет значения выражения, поскольку работает подобно арифметической операции
отрицания. Рассмотрим примеры:
! A > 0) возвращает false.
! A < 0) возвращает true.
Операции'
typeof 33 возвращает строку "number",
typeof "A String" возвращает строку "string",
typeof true возвращает строку "boolean",
typeof null возвращает строку "object".
^ПРЕДУПРЕЖДЕНИЕ; /_",'¦' j * f . •, J
Операция typeof была добавлена в Navigator 3.0
(JavaScript 1.1). Она будет работать только в JavaScript
1.1 и старших версиях браузеров.
Определение и вызов функций
Функции подробно рассматриваются в главе 8. Сейчас
ознакомимся с двумя операциями, имеющими отноше-
отношение к функциям. Первая — операция, которая обозна-
обозначается круглыми скобками и всегда следует за именем
функции. Например, функция displayName() объявля-
объявляется следующим образом:
function displayName () ^
[операторы]
}
Операция вызова функции также используется при
вызове функции из любого места сценария:
displayName О
Круглые скобки показывают, что используется фун-
функция, а не другой определенный пользователем иден-
идентификатор.
Вторая операция записывается символом запятой.
Она используется для отделения друг от друга аргумен-
аргументов функции. Аргументы всегда заключаются в круглые
скобки. Функция displayName() с двумя аргументами
могла бы выглядеть так:
function displayName
[ операторы]
f
(argumentl, argument2) {
Операции со структурами данных
Операции со структурами данных — термин, который
используется при классификации двух операций, необ-
необходимых для работы со структурами данных. Структу-
Структуры данных — это концептуальные основы, применяе-
применяемые для хранения одной или более базовых частей
данных организованным способом. В JavaScript таковы-
таковыми структурами являются объекты, группирующие дан-
данные для конкретных целей.
Операция, уже знакомая тем, кто имел дело с объек-
объектами, обычно называется "точка". Обозначается она
точкой (.) и носит название операцией взятия члена
структуры. Она позволяет обращаться к члену (коим
1Глава 6
может быть переменная, функция или целый объект),
принадлежащему определенному объекту. Синтаксис
операции таков:
objectName.variableName
ИЛИ
objectName.functionName(>
ИЛИ
objectName.another Ob ject
Часть данных, к которой обращаются, должна стоять
справа от точки. Такой способ обращения к члену струк-
структуры (к переменной, функции или объекту) обычно на-
называется "точечной нотацией".
Операция индексирования применяется при обраще-
обращении к части данных из массива. Обозначается она па-
парой квадратных скобок и позволяет получить доступ к
любому элементу массива. Массивы в JavaScript реали-
реализованы в виде объектов (см. главу 10). Ниже показан
синтаксис операции индексирования:
arrayName[indexNumber]
Операция индексирования предполагает использова-
использование целого числа (индекса элемента массива) indexNumber.
IndexNumber определяет индекс в arrayName и обеспе-
обеспечивает доступ к любому члену массива.
Поразрядные операции
На аппаратном уровне данные хранятся в памяти пораз-
поразрядно. Они записываются в двоичной системе счисле-
счисления, в которой любое целое число может быть представ-
представлено при помощи символов 0 и 1. В зависимости от
размещения, каждый единичный разряд представляет
значение 2 в степени п, где п — номер разряда, считая
справа.
Например, целое число 12 может быть представле-
представлено двоичным кодом 1100:
Для хранения большого числа, скажем 237 A1101101
в двоичном коде), потребуется 8 разрядов памяти:
х 2Ъ + 1 х 26 + 1 X 27 = 237
Для хранения целочисленных значений в памяти
отводится 32 разряда. В памяти число 237 фактически
выглядит как 00000000000000000000000011101101, но
для краткости незначащие нули не указываются. Не-
Несмотря на то что целое число можно записывать в де-
десятичном, восьмеричном или шестнадцатиричном виде,
в памяти оно хранится в двоичной форме.
Базовое подмножество языка JavaScript
Часть II
Для представления отрицательных значений исполь-
используется крайний слева (самый старший) разряд. Взгляни-
Взгляните на следующие примеры:
10000000000000000000000000000001 = -2147483648 +
1 = -2147483647
10000000000000000000000000000011 = -2147483648 +
3 = -2147483645
11111111111111111111111111111111 = -2147483648 +
2147483647 = -1
1111111111111111111111111111111O = -2147483648 +
2147483646 = -2
Работа с двоичными представлениями целых чисел в.
JavaScript обеспечивается через поразрядные операции.
Самая простая из поразрядных операций — унарная опе-
операция дополнения до единицы, которая обозначается тиль-
тильдой (~). Она изменяет значение каждого разряда операнда
на противоположное, поэтому относится к операциям
отрицания. Рассмотрим, как выполняется дополнение до
единицы для числа 6:
X = -6
х = -00000000000000000000000000000110
х = 11111111111111111111111111111001
х = -7
Поразрядные логические операции
Поразрядные логические операции рассматривают опе-
операнды поразрядно. Операция выполняется над каждой
парой разрядов. Например, применение поразрядной
операции И к числам 01111 и 11011 дает в результате
число 01011. В табл. 6.3 показан ход выполнения при-
приведенного примера.
Поразрядные операции сдвига
Все поразрядные операции сдвига требуют двух опе-
операндов. Левый операнд — это целое число, разряды ко-
которого будут сдвигаться. Правый операнд задает коли-
количество разрядов, на которое необходимо сдвинуть
двоичное представление целого числа. Таблица 6.4 со-
содержит список поразрядных операций сдвига.
Таблица 6.3. Использование поразрядных логических операций.
Выражение Результат
0& 1
1&1
1 &0
¦1 &1
1 &1
а
о
\
о
1
1
Поразрядная операция И возвращает 1, если оба операнда равны 1 . Иначе возвращается 0. Например, 15 &
27 возвращает 11 @1111 & 11011 возвращаетОЮИ).
Поразрядная операция ИЛИ возвращает 1, если хотя бы один из операндов равен 1. Иначе возвращается 0.
Например, 15 | 27 возвращает 31 @1111 | 11011 возвращает 11111).
Поразрядная операция ИСКЛЮЧАЮЩЕЕ ИЛИ возвращает 1, если только один из операндов равен 1. но не
оба. Иначе возвращается 0. Например, 15 " 27 возвращает 20 @1111 | 11011 возвращает 10100).
Таблица 6.4. Поразрядные операции сдвига.
Операция Описание
Операция сдвига влево возвращает целое число со сдвинутыми на несколько позиций влево разрядами.
Появившиеся младшие разряды заполняются нулями. Два следующих примера демонстрируют сдвиг числа 15
влево на 1 и на 2 разряда:
15 << 1 возвращает 30 A111 « 1 возвращает 11110)
15 « 2 возвращает 60 A111 « 2 возвращает 111100)
Обратите внимание, что сдвиг положительного целого числа влево на п разрядов эквивалентен умножению'
этого числа п раз на 2. В большинстве случаев компьютер выполняет сдвиг влево быстрее умножения на 2.
По этой причине, вместо многократного выполнения операции умножения обычно отдают предпочтение
поразрядному сдвигу влево. Относительно небольшое увеличение скорости в конечном итоге приводит к
существенной экономии.
Применение сдвига влево к отрицательному целому числу приводит к отрицательному или положительному
целому числу — в зависимости от значения старшего разряда после выполнения сдвига влево.
Операция сдвига вправо с копированием знака (арифметический сдвиг вправо) возвращает значение целого
числа со сдвигом его разрядов на несколько позиций вправо. Все пустые разряды заполняются копией
крайнего левого (т.е. знакового) разряда. Копирование крайнего левого разряда гарантирует, что целое число
останется положительным или отрицательным. Применение данной операции также представляет собой
Операции
Глава 6
Операция Описание
более эффективный способ деления положительного четного целого числа на 2. В случае положительного,
нечетного целого числа арифметический сдвиг вправо —то же самое, что и деление п раз на 2 с
отбрасыванием остатка. Рассмотрим следующие примеры:
15 » 1 возвращает 7 A111 > > 1 возвращает 0111)
-15 » 1 возвращает-8A1111111111111111111111111110001 » 1 возвращает
11111111111111111111111111111000)
>>> Операция сдвига вправо с заполнением нулями возвращает значение целого числа со сдвигом его разрядов
на несколько позиций вправо. При этом все пустые старшие разряды заполняются нулями. Воздействие на
положительные целые числа этой операции обеспечивает тот же самый результат, что и операция логического
сдвига вправо. Так получается ввиду того, что копируемый знаковый разряд для положительных целых чисел
— всегда нуль. Что касается отрицательных целых чисел, то операция логического сдвига вправо изменит
значение старшего разряда с 1 на 0. Результат будет всегда целым числом, большим или равным 0.
Рассмотрим несколько примеров:
15 >» 1 возвращает 7 A111 >» 1 возвращает 0111)
-15>»1 возвращает 2147483640 A1111111111111111111111111110001 >» 1 возвращает
О1111111111111111111111111111000)
Зачем вообще возиться с разрядами?
Поразрядные операции в большинстве сценариев не
нужны. Возможно, иметь дело с разрядами вообще не
придется. Однако, в некоторых случаях без такой воз-
возможности не обойтись.
Примером может послужить перевод числа из деся-
десятичной системы счисления в шестнадцатиричную. Это
потребует некоторых дополнительных усилий, т.к.
JavaScript позволяет отображать только десятичные
представления чисел, хранящихся в памяти. Встроенные
способы отображения чисел в других системах счисле-
счисления отсутствуют. Используя поразрядные операции,
преодолеть упомянутое препятствие относительно про-
просто. Например, переменная х хранится в памяти в дво-
двоичном коде. Показанный ниже код обеспечивает вывод
значения переменной х в десятичном представлении
(т.е. 220):
var х = OxDC;
// Отображение числа 220
document.writeln(x);
В JavaScript не существует какого-либо способа ото-
отображения 220 в шестнадцатиричном формате (т.е. DC).
Функция подобного рода оказалась бы весьма полезной
при оперировании с кодами цветов HTML, которые за-
записываются в шестнадцатиричной системе. Самый про-
простой способ получить шестнадцатиричное число — взять
двоичный код целого числа и перевести его в шестнад-
шестнадцатиричный. Точно также шестнадцатиричные коды
достаточно просто переводятся в двоичные.
Четыре разряда памяти могут определять 16 различ-
различных значений. Поскольку для записи шестнадцатирич-
шестнадцатиричных кодов применяются 16 цифр, для хранения каждой
шестнадцатиричной цифры требуется как раз 4 разря-
разряда. В 32-разрядном целом числе 4 младших разряда па-
памяти представляют цифру младшего разряда шестнад-
шестнадцатиричного целого числа. Следующие 4 разряда хра-
хранят следующую цифру и т.д.
Для того чтобы прочитать только 4 разряда, исполь-
используется операция & и управляющее значение. Управля-
Управляющее значение должно хранить 1 в каждом разряде,
соответствующем читаемому разряду целого числа. По-
Поскольку требуется значение первых 4 разрядов, управ-
управляющее значение должно содержать 1 в первых четырех
разрядах. Все другие разряды должны содержать 0. Для
чтения младших четырех разрядов управляющее значе-
значение должно быть равно 1111 A5 или OxF):
Управляющее значение:
00000000000000000000000000001111 &
Преобразуемое целое:
00000000000000000000000011011100 =
Результат:
00000000000000000000000000001100
Результат — это копия первых 4 разрядов преобра-
преобразовываемого целого числа. Сравните его с каждой из 16
шестнадцатиричных цифр и убедитесь, что оно равно
С. Чтобы найти следующую шестнадцатеричную циф-
цифру, необходимо скопировать следующих 4 разряда это-
этого целого числа. Это лучше всего сделать путем сдвига
всех разрядов целого числа на 4 позиции вправо и за-
затем воспользоваться тем же управляющим значением:
Управляющее значение:
00000000000000000000000000001111 &
Преобразуемое целое:
00000000000000000000000000001101 =
Результат:
00000000000000000000000000001101
Базовое подмножество языка JavaScript
Часть II
Результат соответствует цифре D.
Листинг 6.5 демонстрирует рассмотренный алгоритм
целиком. Используя только операции, упомянутые ра-
ранее, можно преобразовать любое 8-разрядное число в
строковое представление его шестнадцатиричного экви-
эквивалента. Для этого сначала надо присвоить переменной
intValue преобразуемое значение. Затем отобразить зна-
значение, дабы подчеркнуть тот факт, что JavaScript ото-
отображает только десятичное значение DC, т.е. 220. Да-
Далее выполняется перевод двоичной формы числа 220 в
шестнадцатиричную и отображение результата (см. рис.
6.6).
Листинг 6.5. Преобразование десятичного числа в шестнадцатиричное с использованием поразрядных операций.
<html>
<head>
<title>npeo6pasoBaj»re десятичного числа в шестнадц.атиричное</^Ы.е>
</head>
<body>
<script type="text/javascript">
// Объявление переменных
var originallnt;
// intValue хранит любое 8-разрядное число
var intValue = OxDC;
var controlvalue = OxF;
var fourBitValue;
var hexChar = "" ;
var hexString = "";
document.writeln("При отображении целых чисел, хранящихся в памяти,")
document.writeln("JavaScript использует их десятичные ") ;
document.writeln("эквиваленты: " + intValue);
originallnt = intValue;
fourBitValue
hexChar =
hexChar ~
hexChar =
hexChar =
hexChar ™
hexChar =
hexChar ¦
hexChar =
hexChar ~
hexChar ¦
hexChar =
hexChar =
hexChar =
hexChar =
hexChar ¦
hexChar =
controlValue
(fourBitValue =¦=
(fourBitValue ¦=
(fourBitValue =
(fourBitValue =
(fourBitValue =¦
(fourBitValue ==
(fourBitValue ш*
(fourBitValue =
(fourBitValue =
(fourBitValue "¦
(fourBitValue =
(fourBitValue ¦=
(fourBi tValue =
(fourBitValue =
(fourBitValue =¦
(fourBitValue =™
?
0x0)
Oxl)
0x2)
0x3)
0x4)
0x5)
0x6)
0x7)
0x8)
0x9)
QxA)
QxB)
QxC)
OxD)
OxE)
QxF)
intValue
•p HI Q it
? "
i "
1 "
? "
?' "
? 6
? '"
, „8,i
¦p "9"
T' '"A"
,, ..Bi.
? '"C"
1 "D"
•3 "E"
? "F"
hexChar:
hexChar;
hexChar;
hexChar;
hexChar,
hexChar,
hexChar;
hexChar;
hexChar;
hexChar;
hexChar,
hexChar;
hexChar;
hexChar;
hexChar;
hexChar;
// Построить hexString, помещая в нее пифры справа налево
hexString = hexChar + hexString;
// Сдвинуть intValue на 4 разряда вправо
intValue = intValue » 4;
// Получить значение следующих 4 разрядов
fourBitValue = controlValue ? intValue;
// Отыскать соответствующую шестнадцатиричную цифру
// и присвоить ее строке
nexChar
hexChar
hexChar
hexChar
lexChar
nexChar
lexChar
lexChar
lexChar
lexChar
hexChar
— (fourBitValue •
= (fourBitValue =
)вый эквивалент
¦¦ 0x0)
= Oxl)
= i (fourBitValue = 0x2)
= (fourBitValue ¦
¦= 0x3)
= (fourBitValue ¦« 0x4)
= <f ourBi tValue =
= i (fourBi tValue =
s» (fourBitValue ¦
¦ (fourBitValue =
•= '(fourBitValue *
™ (fourBitValue =
= '0x5)
= 0x6)
= 0x7)
= 0x8)
¦= 0x9)
= OxA)
¦5
?
¦p
•¦i
f
•p
1
"
"
"
»3..
"
„5„
6
"
"8"
и gii
"A"
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
hexChar
Операции
Глава б Y
hexChar =
hexChar =
hexChar =
hexChar =
hexChar =
hexString
(f ourBitValue =
(fourBitValue =
(fourBitValue =
• (fourBitValue =
(fourBitValue =
OxB)
OxC)
OxD)
OxE)
OxB)
= hexChar + hexString;
?
?
?
¦a
¦y
"B"
»C"
"D"
"E"
"P"
: hexChar;
: hexChar;
: hexChar;
: hexChar;
: hexChar;
document .write ("<br>lr + originallnt 4- ' отображается в");
document.write(" в шестнадцатиричной формате:
document.writeln(hexString);
// конец сокрытия —>
</script>
< /body >
</html>
При аж
220
в памяти. JavaScript •
¦¦¦формате: >
тихдесятичныеэ
РИСУНОК б.б. Преобразование десятичного числа в
шестнадцатиричное.
ПРИМЕЧАНИЕ '
В к( предыдущего примера при поиске соответствия
многократно используются условные выражения. Бо-
Более эффективный способ сравнения ряда чисел связан
с организацией циклов (см. главу 7).
При исследовании предыдущего примера обратите
внимание на то, сколько нулевых разрядов остались
неиспользованными при хранении относительно не-
небольшого числа. Это — еще одна область, в которой
поразрядные операции оказываются полезными. При
помощи поразрядных операций можно сэкономить па-
память, сохраняя данные в неиспользуемой части любой
переменной.
Например, если сценарий работает с большой груп-
группой положительных целых чисел, не кревышающих 255,
то в одном 32-разрядном слове поместятся четыре та-
таких числа. Используя простую поразрядную операцию,
можно извлекать любое из этих чисел. Стоит отметить,
что с такими объемами ОЗУ, которые имеют на сегод-
сегодняшний день большинство компьютеров, экономия про-
пространства обычно не стоит затраченных на его добыва-
добывание усилий. С другой стороны, поскольку JavaScript
IH для выполнения на различных платформах,
нельзя знать заранее, кто будет выполнять сценарий, —
у кого-то ведь может и не хватить памяти. Но даже при-
принимая во внимание сказанное, волноваться по поводу
нехватки памяти нужно начинать только, когда в памяти
хранится достаточно много данных.
Приоритеты выполнения операций
При создании выражений, которые включают более
одной операции, необходимо помнить, что JavaScript не
обязательно вычисляет выражение справа налево или
наоборот. Каждая часть выражения вычисляется в по-
порядке, основанном на приоритете каждой операции.
Рассмотрим такой пример:
х = а * ь + с
а умножается на 1). после чего полученный результат
прибавляется к с. Наконец, результат сложения присва-
присваивается х. Операция умножения обладает более высо-
высоким приоритетом, нежели операция сложения, поэто-
поэтому умножение выполняется первым. Если вначале
необходимо выполнить сложение, выражение заключа-
заключают в круглые скобки:
х = а * (Ь + с)
Круглые скобки — это операция, которая увеличи-
увеличивает приоритет заключенного в них выражения. Одно-
Однотипные операции вычисляются слева направо.
В табл. 6.5 перечислены операции в порядке их при-
приоритетов — начиная с самого низкого и до самого вы-
высокого..
Таблица 6.5. Приоритеты операций.
Название операции
Операция
Запятая
Присваивание
Условие
Логическое ИЛИ
Логическое И
Поразрядное ИЛИ
Поразрядное ИСКЛЮЧАЮЩЕЕ
»= >»= &=
3= «=
Базовое подмножество языка JavaScript
Часть II
Название операции
Операция
Поразрядное И
Равенство
Сравнение
Поразрядный сдвиг
Сложение/вычитание
Умножение/деление
Отрицание/приращение
Вызов/структурирование данных
8,
<
«
+
*
!
0
5=
<= > >=
: » >»
-
/ %
D ¦
Один из эффектов, связанных с приоритетами опе-
операций, заключается в определении типа данных резуль-
результата выражения. Это станет очевидным при попытке
конкатенации строк и Я (см. листинг 6.6).
Листинг 6.6. Приоритеты операций и типы данных.
<html>
<head>
<ЫЪ1е>Приоритеты onepaiwit</title>
</head>
<body>
<script type=" text/ javascript ">
<!--
var carLength = 2 + 3;
document.write(carLength);
carLength = "<br>" + 2 + 3-1
document.write(carLength);
carLength = "<Ьг>Длина в метрах: "' + 2 + 3;
document.write(carLength);
carLength = "<Ьг>Длина в метрах: " + B + 3) ;
document.writeln(carLength);
//-->
</script>
</body>
</html>
Операции с одинаковыми приоритетами вычисляют-
вычисляются слева направо. Операция сложения обладает таким
же приоритетом, что и операция конкатенации, поэто-
поэтому JavaScript будет выполнять все сложения и конкате-
конкатенации слева направо.
Обратите внимание на показанное на рис. 6.7 резуль-
результирующее окно. Два первых примера работают, как и
следовало ожидать. Третий пример показывает, что мо-
может получиться, когда JavaScript по-своему учтет при-
приоритеты. Первый знак + преобразует число 2 в строку
и добавляет ее в конец "Длина в метрах: ". В результа-
результате получается строка "Длина в метрах: 2". Потом то же
самое происходит с числом 3 и получается "Длина в
метрах: 23". Однако, если вместо этого требуется ото-
отобразить сумму 2 и 3, следует использовать круглые скоб-
скобки, тем самым увеличив приоритет 2 + 3. В этом слу-
случае оба операнда — числа, и JavaScript выполнит
сложение раньше конкатенации (см. рис. 6.7).
Резюме
и присваивания устанавливают значения пере-
переменных. Наряду с простой, JavaScript поддерживает 11
дополнительных операции присваивания, которые на
самом деле являются комбинациями арифметических
или поразрядных операций с простой О] цией при-
присваивания.
" .^1.У1'1ь№ЩЩЩ$&Щу?Е™Я1:'ШЯ] ^
23 метр]
Длина в метр;
Длина в метрах- 5
Л\ *•! ¦ ¦ •
>
РИСУНОК 6.7. Приоритетыопераций и типы данных.
Арифметические операции позволяют выполнять
базовые математические операции в JavaScript. Сюда
входят операции сложения, вычитания, умножения, де-
деления и вычисления по модулю. JavaScript также вклю-
включает операции инкремента и декремента — для корот-
короткой записи двух наиболее частых математических
операций. Математические операции более высокого
уровня также встроены в JavaScript, но к ним следует
обращаться через объект Math.
Операции сравнения сравнивают два значения и
возвращают true или false. С их помощью выясняется,
равно ли одно значение другому, больше или меньше
другого, а так же и любые комбинации этих вопросов.
Условные операции позволяют воз ~ь одно из
двух значений выражений, которые могут содержать
любой тип данных. Возвращаемое значение зависит от
значения определенного логического выражения.
Строковые операции включают в себя операцию
конкатенации и все операции сравнения. Операция
конкатенации используется для связывания двух строк
вместе с целью формирования новой строки. Операции
сравнения могут использоваться со строками для срав-
сравнения их ASCII-значений. Начиная с крайнего левого
символа строки, каждая пара символов сравнивается
друг с другом. Возвращается true или false.
Булевы операции используются в логических выра-
выражениях. Операция И возвращает true, если оба ее опе-
операнда — true, а иначе — false. Операция ИЛИ возвра-
возвращает true, если по крайней мере один из ее операндов
равен true. Иначе она возвращает false. Операция НЕ
возвращает true, если ее операнд false, и false, если опе-
операнд — true.
Операция typeof появилась в JavaScript 1 и пред-
представляет собой встроенную операцию, возвр
Операции
строку, которая представляет тип данных операнда. Это
особенно полезно при выяснении, была ли переменная
определена.
Две операции работают с объявлением и использо-
использованием функций JavaScript. Операция вызова функции
(круглые скобки) всегда следует за именем функции и
заключает в себе список аргументов, которые может
принять функция. Операция "запятая" используется для
отделения аргументов друг от друга.
Для работы с массивами и другими объектами необ-
необходимы еще две операции. "Точкой" обычно обознача-
обозначают доступ к элементу объекта. Это — стандартная
точечная нотация. Операция индексирования исполь-
используется для индексации элементов массива. Она содер-
содержит имя массива и целое число, обозначающее распо-
расположение элемента, к которому обращаются.
JavaScript дает доступ к двоичному представлению
любого целого числа с помощью поразрядных операций.
Глава 6
Поразрядная операция дополнения используется для
изменения значения каждого разряда целого числа на
противоположное. Поразрядные логические операции
применяются для сравнения двух целых чисел. Двоич-
Двоичная форма операнда используется для работы с каждой
парой разрядов в числах. Логическая операция выпол-
выполняется над каждой парой разрядов и возвращается це-
целое число. Поразрядные операции сдвига сдвигают раз-
разряды целого числа вправо или влево на п позиций. При
сдвиге вправо JavaScript позволяет выполнить арифме-
арифметический или логический сдвиг.
Когда все операции в выражении имеют равные при-
приоритеты, JavaScript вычисляет выражение справа нале-
налево. Если же приоритет операций разный, то сначала
выполняется операция с самым высоким приоритетом,
затем следующая по приоритету и т.д. В JavaScript каж-
каждая операция обладает совершенно определенным при-
приоритетом.
Управляющие структуры
и организация циклов
В ЭТОЙ ГЛАВЕ
Условные операторы
¦Операторы организации циклов
Метки
Оператор with
Оператор switch
Проектирование сценариев, предполагающих приня-
принятие решений во время выполнения, — наиболее интерес-
интересная часть JavaScript. В сценарии, где требуется прини-
принимать решения на основе его текущего состояния, просто
обеспечивают вывод вопроса и затем, в зависимости от
ответа, выбирают путь.
Рассмотрим для примера планирование утра моего
рабочего дня. Мне доступны несколько различных ва-
вариантов, из которых на основе определенных факторов
я выбираю один. Я редко готовлю еду, посему наиболее
важный вопрос, который я задаю себе каждое утро, — не
голоден ли я. Если да, я выбираю маршрут, проходящий
через продуктовый магазин. К моменту завершения упа-
упаковки собственного завтрака я, как правило, уже немно-
немного опаздываю. Дабы восполнить потерянное время, я
двигаюсь по направлению к скоростному шоссе, где могу
увеличить скорость. С другой стороны, если я не голо-
голоден (что случается весьма редко), то миную продукто-
продуктовый магазин и еду на работу со скоростью на 10 миль в
час медленнее.
Используя подобного рода планирование, можно со-
создавать и программы на JavaScript, выполняющие раз-
различные операции в зависимости от текущего состояния.
Например, в главе 6 рассматривалось, как проверить, яв-
является ли переменная равной какому-то значению или
даже ряду значений. С использованием управляющих
структур появляется возможность заставить программу
выбирать различные пути в зависимости от результата
упомянутой проверки. Итак, имеем первую тему, кото-
которой посвящена данная глава.
Поскольку размеры программ неуклонно возрастают,
неплохо было бы учесть немаловажный фактор — сколь-
сколько времени потребуется клиенту для их загрузки. Луч-
Лучший способ сэкономить на количестве исходного текста
в сценарии предусматривает применение операторов
цикла. Прибегнув к помощи циклов, можно достигнуть
ситуации, когда всего лишь несколько строк программы
обеспечивают выполнение большого количества одно-
однотипных операций. Это поможет сократить размер сце-
сценариев и избежать многократного набора одних и тех же
команд. Помимо прочего, в главе демонстрируются спо-
способы повышения эффективности сценариев.
Условные операторы
В главе 6 рассматривалась операция ?:. Эта операция
используется для создания двухшагового процесса. Сна-
Сначала выражение оценивается на предмет равенства true
или false. Далее, в зависимости от результата, возвраща-
возвращается одно из двух значений. Если выражение true, воз-
возвращается первое значение, а если — false — второе.
Встречаются сценарии, принимающие решение в за-
зависимости от значения выражения, использующего опе-
операторы if и else. Однако результат будет другим. Вместо
возвращения зависящего от результата значения, про-
программа выбирает один из двух путей выполнения. Так,
можно заставить JavaScript выполнять множество раз-
различных функций, зависящих от любой доступной ин-
информации.
if
Оператор if относится к числу наиболее популярных.
Каждый язык программирования содержит его в той или
иной форме, и его использования избежать, как прави-
правило, не удается. Оператор if применяется следующим об-
образом:
if (условие) {
[ оператора]
Управляющие структуры и организация циклов
Глава 7
В качестве условия может указываться любое логи-
логическое выражение. Если результат условия равен true,
выполняются операторы, посему работа программы про-
продолжается. Если условие возвращает false, операторы иг-
игнорируются и работа продолжается.
В листинге 7.1 приводится сценарий, который от-
отдел маркетинга мог бы предложить разместить на Web-
сайте компании. Сценарий начинается с установки
visitorlnterest в одно из двух значений. В данном примере
выбирается "Technical Support" (то бишь, техническая
поддержка) и комментируются альтернативные варианты.
Сценарий доходит до первого оператора if, который
проверяет, равно ли значение visitorlnterest строке "New
Products" (т.е. новый продукт). Последнее вычисленное
значение этого выражения — false, поэтому блок опера-
операторов после if игнорируется. Затем сценарий доходит до
второго оператора if и сравнивает значение visitorlnterest
со строкой "Technical Support". Выражение возвращает
true, что приводит к выполнению кода, заключенного в
фигурные скобки.
Независимо от того, чему равно значение visitorlnterest,
последний оператор всегда выполняется, поэтому про-
продавец Виктор Франкенштейн делает шаг к посетите-
посетителю. Результирующий вывод показан на рис. 7.1. Если
visitorlnterest присвоить какое-то другое значение, ре-
результат изменится.
Обычно набор операторов заключается в фигурные
скобки. Это придает сценарию логический вид и ока-
оказывается особенно полезным в случае вложенных опе-
ЛИСТИНГ 7.1. Использование оператора if для принятия
раторов if (т.е. при использовании одного оператора if
внутри другого).
меня зовут Виктор
вначале позвольте познакомить вас
| Наша нов.эя продукция удовлетвори
Сейчас доступна и техническая пОДД&ржкз
з новой продукцией
все ваши потребности!
РИСУНОК 7.1. Виктор Франкенштейн делает шаг навстречу
посетителю.
Листинг 7.2 демонстрирует использование логичес-
логических переменных для выбора пути, по которому пойдет
сценарий. Первый оператор if оценивает переменную
needslnfo. В данном случае needslnfo имела значение
true, так что JavaScript выбирает первый блок if и про-
продолжает работу в нем, т.е. выводит на экран "Наши
продукты использует весь мир.". Далее очередь дохо-
доходит до второго (вложенного) блока if, и оценивается
needsMorelnfo.
решения.
<html>
<head>
е решений при помощи оператора if</title>
</head>
<body>
<script type="text/javascript">
<! —
' Объявление переменных
var visitorlnterest;
.// visitorlnterest = "New Products";
visitorlnterest я "Technical Support";
document.writeln("Привет, меня зовут Виктор Франкенштейн!");
// Оценка значения visitorlnterest
if (visitorlnterest "New Products") {
document. writeln ("Спасибо интерес, проявленный к нашим товарам! ");
if (visitorlnterest = "Technical Support") {
йчас доступна и техническая поддержка. ") ;
document.writeln("Однако вначале позвольте познакомить вас
document.writeln("с новой продукцией!");
document, writeln (<br>"Hama новая продукция удовлетворит все ваши")
document.writeln("noTpe6HOCTH!");
// —>
</script>
</bcdy>
</html>
Базовое подмножество языка JavaScript
Часть II
Листинг 7.2. Вложенные операторы if.
<html>
<head>
<title>npiiHHTOie решений при < лот оператора if</title>
</head>
<body>
<script type="text/javascript">
<! —
II Об-ьявление переменных
var needsInfo,-
var needsMorelnf о ,¦
// Если установить одну из приведенных ниже переменных в false- вывод изменится.
needslnfo = true;
needsMorelnfо = true;
document, write In ("Я работаю на Лучшие Продукты Интернешинл! ") ;
if (needslnfo) {
document.writeln("Наши продукты использует весь мир.");
if(needsMorelnfo){
document.writeln ("<Ьг>Япросто не могу понять, как же вы могли") ;
document.writeln("обходиться без них.");
)
document.writeln ("Самый простой способ заказать наши продукты — воспользоваться
^онлайновым магазином.");
//
</script>
</body>
</btml>
Опять-таки, возвращенное значение — true, поэто-
поэтому операторы внутри второго блока будут выполнять-
выполняться. После завершения вложенного блока if JavaScript вы-
выполняет все оставшиеся инструкции первого блока.
Обратите внимание, как фигурные скобки помогают от-
отличать отдельные блоки программы друг от друга.
Из рис. 7.2 видно, что строки программы выполнялись
в порядке их написания. Изменяя значения needslnfo и
needsMorelnfo, можно получить три различных резуль-
результата. Помните, что если needslnfo присвоить значение
false, программа не сможет перейти ко второму блоку if.
В этом случае значение needsMorelnfo роли не играет,
поскольку оцениваться оно не будет. Извините, Виктор,
но если посетителю вообще не нужна информация, ему
уж точно не нужна дополнительная информация.
Я 1Таю на Лучшие Продукты I Наши продукты испольэу«Т| :G0 всем мире
Я просто не могумонять, как : г. могли Самый простой способЗЭХЗЭь
наши продукты - BOci тэться онлайновым
if ..else
Иногда одной конструкции if оказывается недостаточ-
недостаточно. Зачастую требуется также зарезервировать набор
операторов, которые будут выполняться в случае, ког-
когда условное выражение возвращает false. Это можно сде-
сделать, добавив еще один блок непосредственно после
блока if:
if
i
(условие)
операторы
else {
операторы
Кроме т >, имеется возможность скомбинировать
часть else с другим оператором if. Использование тако-
такого метода позволяет оценить несколько разных возмож-
возможных сценариев перед выполнением нужной операции.
Изящество данного метода состоит в том, что в конце
можно определить тот же сегментом else. Формат упо-
упомянутого типа оператора выглядит так:
if (условие) С
оператора
} else if (условие) {
операторы
) else {
операторы
>
Что может быть хуже придирчивого компьютера?
Листинг 7.3 демонстрирует, как можно создать интер-
РИСУНОК 7.2. Один I трех возможных результатов.
Управляющие структуры и организация циклов
Глава 7
активную Web-страницу с помощью всего лишь не-
нескольких строк кода. Здесь жестко задано значение клю-
ключа purchaseAmount, которое определяет ход сценария.
Для настоящего взаимодействования сценария с пользо-
пользователями потребуется обеспечить возможность пользо-
пользовательского ввода. В таком случае purchaseAmount мо-
может принимать любые значения, в зависимости от
желания заказчика. Это делается с помощью JavaScript
и стандартных входных HTML-объектов, таких как пе-
переключатели и текстовые объекты. В главе 17 эта про-
проблема обсуждается более подробно.
В рассматриваемом примере клиент не соизволил по-
потратить достаточную сумму, дабы удовлетворить Викто-
Виктора Франкенштейна. Условный оператор получает значе-
значение false, и программа переходит на блок else. Посмотрев
на рис. 7.3, можно воочию убедиться, как настойчивый
продавец "разогревает" потенциального клиента.
Листинг 7.3. Блок else, соответствующий значению
false.
<htmi>
<head>
<title>npra«roie решений при помощи оператора if
</title>
</head>
<body>
<script type="text/javascript">
<> —
// Объявление переменных
var purchaseAmount;
purchaseAmount = 10.00;
if {purchaseAmount > 500. 00) {
document, writeln ( "Спасибо за покупку!") ;
}else{
document.writeln ( "Спасибо, однако я
'¦•уверен, что у меня есть " > ;
document, writeln ("еще кое-что, от чего
*¦*вы не сможете отказаться. ") ;
</script>
</body>
</html>
try..catch
Оператор try. .catch используется для замены заданного
по умолчанию способа обработки ошибок. Эта тема в
главе подробно не рассматривается.
Операторы организации циклов
Организация цикла внутри сценария преследует широ-
широкий спектр целей. Рассмотрим одно простое, но весьма
распространенное применение цикла. Например, напи-
написание программы, отображающей числа от 0 до 9, — на
первый взгляд, быстрая и простая задача. Просто запи-
записываются 10 команд для отображения каждого числа:
document.writeln
document.writeln
¦("О");
("l");
document.writeln ("9");
Это легко сделать для чисел от 0 до 9, но что если
потребуется сосчитать до 1000? Можно последовать тому
же способу, но тогда программа потребует гораздо боль-
больше времени на написание и загрузку в браузер. Наилуч-
Наилучший способ счета до 1000 или любого другого числа зак-
заключается в использовании той же самой команды
отображения, но с переменной вместо литерала. В дан-
данном случае потребуется обеспечить только одну вещь —
инкрементировать переменную и повторять команду
отображения. JavaScript располагает соответствующими
инструментами.
for
Оператор for используется для организации цикла в сце-
сценарии. Перед детальным изучением оператора for на
основе листинга 7.4, рассмотрим его обобщенный син-
синтаксис:
for ([выраженяе_инициалиэации] ;
"* [ выражение_условия] ; [выраженг*е_цикла] ) (
операторы
)
Три выражения, заключенные в квадратные скобки,
не являются обязательными, тем не менее, если даже уб-
убрать одно из них, точка с запятой все же потребуется.
Именно точка с запятой обеспечивает должное место для
каждого выражения.
Выражение инициализации обычно применяется в
целях инициализации переменной и даже объявления,
что конкретная переменная является счетчиком цикла.
Выражение условия должно иметь значение true перед
каждым выполнением операторов, заключенных в фи-
фигурные скобки. Наконец, выражение цикла, как прави-
правило, инкрементирует или декрементирует значение пере-
переменной, которая используется в качестве счетчика
цикла.
РИСУНОК 7.3. Один и. двух возможных результатов.
Базовое подмножество языка JavaScript
Часть II
Листинг 7.4 демонстрирует использование опера-
оператора for для организации счета от 0 до 99 с отображе-
отображением каждого числа. Для того чтобы уместить резуль-
результат на стандартной странице, после каждых 10 чисел
выводится символ новой строки (см. рис. 7.4).
Листинг 7.4. Использование цикла for для счета от О до 99.
<html>
<head>
<title>Uraui счета от 0 до 99</title>
<body>
<script type="text/javascript">
< !
// Вывести заг( ювочную часть
iocument. write ("Числа от 0 до 9
document.write ( '<hr size=" width=0%"
for (var i = 0; i < 100; ++i) {
// Символ новой строки после каждого
// 10-го числа
if(i%10 = 0) {
document.write( '«сЬгУ ) ;
// Вывести собственно тта
document, write (i + ",");
// Последнее число, следовательно,
//завершаемся. . .
("<ЬгхЬг>После завершения
i равно : + i)
</script>
</body>
</html>
. ;: ..Ssrt R№H H in StM
юла от 0 до 90
! 0.1.2.3.1.5.6,7.8,9.
.12 13 14 15
JO .21.22.23.2-1.25.26.27,23.29.
30,31.32.33,34,35.36,37.38,39.
40.41.42.43 44.45.46.47,48,49,
50.51.52.53.54.55.56.57.58.59,
60.61.62.63,64 65 66.67,68.99
70.71.72.73.74.75.76.77.78.79.
90,91,92,93,^4,95,96 .У7.98,99.
ння цикла i равно 1С
. : '3i
¦ • UfJ' '¦•- J.
e''"'.~PmA'~'
. ¦:$" .
?¦
РИСУНОК 7.4. Результат 100-кратного выполнения цикла.
В листинге 7.4 порядок выполнения операторов выг-
выглядит так: выражение инициализации объявляет пере-
переменную i и устанавливает ее значение равным 0. Затем
переменная i проверяется на предмет, меньше ли она
100. Когда i все еще равна 0, выражение условия возвра-
возвращает true и программа выполняет операторь; в фигур-
фигурных скобках. Как только программа выполнит все опе-
операторы и достигнет закрывающей фигурной скобки, она
вычисляет выражение цикла ++L При этом i увеличи-
увеличивается на 1 и, таким образом, выполнение первого пол-
полного цикла завершается.
Процесс начинается сначала. На сей раз JavaScript
знает, что выполнять раздел инициализации для цикла
уже не требуется. Выражение условия вычисляется сно-
снова. Если i все еще меньше 100, выполняется второй цикл.
Выполнение набора операторов внутри блока for продол-
продолжается до тех пор, пока i не достигнет 31 .1 100.
И в 99-й раз условное выражение возвращает tru
программа выполняется в последний раз. Значение i уве-
увеличивается еще раз и становится равным 100. Вычисле-
Вычисление условного выражения дает в результате false, поэтому
выполнение цикла прерывается. Управление переходит
к операторам, следующим непосредственно за закрыва-
закрывающей фигурной скобкой.
Поскольку значение i было увеличено до 100 до за-
завершения цикла, 100 и представляет собой последнее
значение i. Обратите внимание, что в соответствие с пра-
правилами, рассмотренными в главе 5, i можно I
вать вне цикла.
ПРИМЕЧАНИЕ
Если условное выражение возвращает false при пер-
первом проходе цикла, код в фигурных скобках выпол-
выполняться не Тэудет.
.
Подобно операторам if, циклы for также могут быть
вложенными. Листинг 7.5 содержит код прохода по каж-
каждой координате сетки 10x10. Для каждой итерации пер-
первого цикла имеют место 10 итераций вложенного цик-
цикла. В результате вложенный цикл будет выполняться 100
раз.
Л истинг7.5. Пример вложенного цикла.
<htinl>
<head>
<ti ие>Влохенные
</head>
<body>
<script type="text/javascript">
ent.write("Все координаты х,у
@,0) и (9,9) :<br>");
for (var x = 0; x < 10; ++x) {
for (var у = 0; у < 10; ++y) {
document.write("("+x+","+У+"),");
}
document.write('<br>');
1
"<Ьг>После завершения
цикла х равно : + х)
nent. write ("< >г>После завершения
'¦>цикла у равно : + у) ;
Управляющие структуры и организация циклов
и -->
</script>
</body>
</html>
Переменной х сначала присваивается значение 0.
Затем JavaScript доходит до вложенного цикла и присва-
присваивает переменной у также значение 0. Вложенный цикл
отображает значения х и у и затем увеличивает у на 1.
Вложенный цикл продолжается до тех пор, пока у не
станет равным 10. В этот момент уже сгенерировано 10
наборов координат. Выполнение вложенного цикла пре-
прерывается и управление возвращаются ко внешнему цик-
циклу. Значение х увеличивается на 1, после чего вновь за-
запускается вложенный цикл.
JavaScript знает, что вложенный цикл необходимо
начать с самого начала, в связи с чем выражение ини-
инициализации должно вычисляться повторно. Таким обра-
образом, у присваивается значение 0 и операторы выполня-
выполняются еще 10 раз. Процесс продолжается до тех пор, пока
х не станет равным 10 и выполнение внешнего цикла,
наконеи, завершается. В результате отображается 100 на-
наборов координат (см. рис.7.5).
m ¦ * *^&
Все «оопджаты и.у между @.0) и (Э.Э)
B.0|,B.1).B 2].B3|,B,<1)]B15).B.6),B,7IB.е),B,ЭI
Eтя'.пв'ак5яа№!41'в!я.(вяя!п№!»!в[иГ
После завершения циияа х paБ^
После зав шения цикла у рав
1^—ЧГ7||
^... :,»tv ;i- г;3
РИСУНОК 7.5. 100пар координат, сгенерированных в двух
циклах.
Поскольку каких-либо ограничений на количество
вложенных циклов нет, следовательно, число координат
можно увеличить до трех или, скажем, до четырех. Дан-
Данный метод можно использовать для обращения к элемен-
элементам многомерного массива.
for..in
Для использования цикла for..in потребуются знания
¦объектов JavaScript, исчерпывающая информация о ко-
которых может быть найдена в главе 9.
Конструкция for.an предоставляет возможность вы-
выполнения набора операторов для каждого свойства
объекта. Цикл for..in можно использовать с любым
Глава 7
объектом JavaScript, независимо от его свойств. Если
объект не имеет свойств, цикл не выполняется. Цикл
for..in работает также и с пользовательскими объекта-
объектами. Переменная пользовательского объекта JavaScript
рассматривается как свойство, и поэтому для каждой из
них выполняется цикл. Синтаксис выглядит так:
for ( свойств
операторы
I
in объект)
Тут свойство — это строковый литерал, сгенериро-
сгенерированный JavaScript. При каждом проходе цикла свойству
присваивается имя следующего свойства, содержащееся
в объекте, и так до тех пор, пока не переберутся все свой-
свойства. В листинге 7.6 такая функциональность применя-
применяется для отображения имен и значений всех свойств
объекта Document (см. рис. 7.6).
. t
-I =, V
Г; '. * * *Ф-Чссгп Ь- >
и;.
* -¦¦'- |ГУГ^1-1>-Л.1-».._Т<
:-texts/7- Q.html
location - Н ¦ .'I'l/tiooksfjscnpt/pk
forms - [object FormArrayl
II links - [object LinkArray]
[object ^ncnorAiray]
I applets [object AppletArray]
eHs = [object EmbedArray]
I images -
title Использование цикпа(ог .^ - свойств объекта document
URL = fi
|| referrer =
lastModifietl - Friday. October !:¦ j"'" ¦ 17:50 35
cookie =
domain =
bgColor = #fffW
IgColor - ЙО00000
HinkColor=#OOOOee
ktrtkColor=#55fa8b
alinkColor=#tfOOOO
yjidjh ^ 598
.¦¦¦¦ .
РИСУНОК 7.6. Список свойств объекта Document вместе с
их значениями.
ПРЕДУПРЕЖДЕНИЕ
Цикл for..in работает только в версии JavaScript 1.1 и
выше. Не следует забывать, что этот цикл не отлича-
отличается корректной работой в Microsoft Internet Explorer
3.0 (JScript 1.0).
Листинг 7.6. Использование цикла for..in.
<html>
<head>
<title>JavaScript Unleashed</title>
</head>
<body>
<script language="JavaScriptl.1"
type="text/javascript">
< I
// * переменных
var anObject = document;
var propertylnfo =
for (var propertyName in anObject) {
propertylnfo = propertyName + ' — +
anObject[propertyName] ;
document.write(propertylnfo + "<br>");
Базовое подмножество языка JavaScript
Часть II
</script>
</body>
</html>
while
Оператор while действует подобно циклу for, однако не
включаетвсебяфункцииинициализациииприращения
переменных во время их объявления.
Переменные необходимо объявлять заранее, а инк-
инкремент или декремент их определять в рамках блока
операторов. Рассмотрим синтаксис while:
while (выралсенив_условия) {
операторы
Листинг 7.7 предоставляет пример использования ло-
гическойпеременнойвкачестве флажка, определяющего
продолжениевыполнения цикла. Этапеременная, status,
объявленадо начала цикла и ей присвоено значение true.
Как только i станет равно 10, status получит значение
false, после чего цикл завершается. Результат листинга
7.7, как показано на рис. 7.7, — это сумма целых чисел
от 0 до 10.
Листинг 7.7. Использование цикла while.
<html>
<head>
<title>JavaScript Unleashecl</title>
</head>
<body>
<script type="text/javascript">
/ / Объявление переменных
var i = 0;
var result = С
var status = true;
document.write(") ,-
while(status){
result += Л
document.write(" + " + i)
if (i = 1 )) {
status = false;
document.writeln("
11 + result) ,
</script>
< /body>
</html>
dcwhile
Начиная с JavaScript 1.2, предлагается конструкция
do..while. Она работает подобно оператору while за ис-
исключением того, что условное выражение не проверя-
проверяется вплоть до завершения первой итерации. Этот спо-
способ гарантирует, что набор операторов, здящихся в
пределах фигурных скобок, будет выполнен по крайней
мере один раз.
РИСУНОК 7.7. Результат выполнения листинге 7.7 —
одиннадцать итераций цикла while.
Листинг 7.8 содержит пример, в котором заранее не-
неизвестно, какое значение может принять u; rEntry (как
если бы упомянутое значение вводилось пользователем),
user Entry присваивается значение 0 просто для демон-
демонстрации того, что пользователь вполне может ввести
значение, которое не будет удовлетворять выражению
условия.
Листинг 7.8. Оператор do..whife, обеспечивающий
по крайней мере один проход цикла.
<html>
<head>
<title>JavaScript Unleashed</title>
< /neacl>
<body>
<script language="JavaScriptl.2" type=
javascript">
<• —
Declare variables
var userEntry = 0;
var x я
do{
document.writeln(x);
x++;
}while(x <= userEntry);
</script>
< /body >
</html>
break и continue
Используя циклы, стоит обратить внимание на то, что
по умолчанию цикл не прекращается, а будет выполнять-
выполняться до тех пор, пока определенное условие не будет рав-
равно false. Однако, иногда может потребоваться выйти из
цикла до того, как он дойдет до закрывающей фигур-
Управл! структуры и организации цикло
ной скобки. Подобное достигается за счет помещения
в блок операторов внутри цикла break или continue.
Оператор break завершает выполнение цикла, в то
время как continue пропускает оставшиеся операторы
текущей итерации, вычисляет очередное значение выра-
выражения цикла (если таковое существует) и начинает вы-
выполнение следующей итерации. Различия между этими
двумя операторами продемонстрированы в листинге 7.9,
который содержит достаточно тривиальный сценарий
вычисления приближенного целочисленного значения
квадратного корня числа п.
ЛИСТИНГ 7.9. Использование операторов break и continue.
<html>
<head>
<title>Onepa*popbi break и cantinue</title>
</head>
<body>
<script type="text/javascript">
<! —
// Объявление переменных
var highestNum = 0;
var n = 175 // Тестовое значение
for (var i = 0; i < n; ++i) {
document.write(i + "<br>")¦
if(n < 0) {
document.write ("n не может быть
^отрицательным.");
break;
}
if (i * i <= n) {
highestNum = i;
continue ;
j
document.write("<Ъг>Сделано!") ;
break;
J
document, write ("<Ьг>Целочисленное значение,
'**не превышающее квадратный корень") ;
document.write(" из " + n + " = '
highestNum);
// —>
</script>
</body>
</html>
Сначала i присваивается О, цикл начинается и ото-
бражаегся значение i. Затем сценарий убеждается, что п
не является отрицательным числом. Если п отрицатель-
отрицательно, цикл прерывается и выполняется остаток программы
после закрывающей фигурной скобки. Если п положи-
положительно i умножается на то же i и результат сравнивает-
сравнивается с п. Если результат меньше n, i сохраняется как наи-
наилучшее текущее приближение квадратного корня из п.
Затзм оператор continue пропускает оставшуюся часть
текущей итерации и возобновляет работу цикла с момен-
момента приращения i. Как только квадрат i превысит значе-
значение п, сценарий пропускает continue и переходит к one-
Глава 7
ратору break, который останавливает выполнение цик-
цикла. Аппроксимация квадратного корня из 175 показана
на рис 7.8.
|-№1-|д:».т.>|1Н'1-
№'|;Ш1\;У ™ у.11 eommunic иск .
.:
• '¦¦ ' ¦ ¦¦¦' ¦ ''¦¦'*- ¦¦"¦• ¦¦¦*:¦' ¦¦"¦¦ ш" ¦ ¦ ¦ ¦' ' ; ¦ :- '¦ •' ¦'¦'' ~":'\'::«>:-
Сделано^
we, не превышающее квадратный корень ¦ 175 13
РИСУНОК 7.8. Внешний вид окна после того, как цикл
переходит к оператору break и останавливается.
Метки
Начиная с версии JavaScript 1.2, в языке появился ме-
метод обозначения более специфического места перехода
при использовании операторов break и continue — мет-
метки. Метку можно помещать перед любой управляющей
структурой, которая содержит другие операторы. Это по-
позволяет перейти из рамок условного оператора либо
цикла на совершенно определенное место программы.
Пример применения меток показан в листинге 7.10.
Листинг
7.10.
Использование
меток.
<html>
<head>
<title>McnonbSosaHKe MeTOK</title>
</head>
<body>
<script language=" JavaScript!.. 2" type="text/
javascript">
.// Объявление переменных
var stopX = 3;
var stopY = 8 ;
document. write ("Все пары х.у между @,0) и (")
document, write (stopX + "," + stopY + ") :<br>")
loopX:
for (var x = 0 ; x < 10; ++x) (
for (var у = 0; у < 10; ++y) {
document, write (" ("+x + "," + у +") ") ;
if((x = stopX) is (y = stopY) ){
break loopX;
document.write("<br>");
Базовое подмножество языка JavaScript
Часть III
>cument.write ("<Ьг>После завершения пик.i;i x
'-•равно : " + х)
document.writeln <"<Ьг>После завершения
"цикла у равно : " + у) ;
</script>
</body>
</html>
В листинге 7.10 цикл for "помечен" пользовательс-
пользовательским идентификатором loopX. Это позволяет покидать
цикл for либо, наоборот, продолжать его вне зависимо-
зависимости от вложенности. Та же метка loopX указывается в
операторе break для завершения обоих циклов for. Без
этой метки оператор break остановил бы только цикл,
й значения для у. На рис. 7.9 показан ре-
результат работы программы, когда х и у достигают, со-
соответственно, значений 3 и 8.
Все пары ху мвжяу@ 0) и C I
@.0) @.1) @.2) @.3) @.4) @.5) @.6) @.7) @.8) @.9)
1,2X1.31 A.4) A.5) A.6
[20) B1) B.2) B.3) B.4) B5) B.< I 7) B.8) B,9)
C.0) C.1) C.2) C.3) C.4) C.5) C.6) C.7) C.8)
- ¦ ¦ циклах равно 3
1клзу рЭВно 8
РИСУНОК 7.9. Использованиеоператора\аЪе\ для выхода из
вложенного цикла for.
OnepaTopbiwith
Оператор with применяется во избежание многократного
повторения ссылки на объект при доступе к его свой-
свойствам и методам. Любые свойства или методы в блоке
with, которые JavaScript не может опознать, ассоцииру-
ассоциируются с объектом, указанным в этом блоке.
Синтаксис with таков:
with (объект) {
операторы
)
Объект определяет, какой объект необходимо ис-
использовать в случае отсутствия объектной ссылки в блоке
операторов. Данный оператор особенно полезен при ис-
использовании сложных математических функций, кото-
которые доступны только через объект Math. Поскольку
объект Math будет рассматриваться, начиная с главы 10,
здесь показан оператор with для уже знакомого объекта
Document.
При вызове методов write() или writelnO, принадле-
принадлежащих объекту Document, перед ними необходимо ука-
указывать префикс document:
document.writeln("Привет всем!");
Подобная методика применяется достаточно часто и
в больших количествах. Для экономии на объеме кода
все операторы, которые ссылаются на объект Document,
стоит поместить в блок with. Как это сделать, показано
в листинге 7.11. Поступая таким образом, можно изба-
избавиться от назойливого префикса document в ссылках на
методы и свойства документа.
Обратите внимание, что title и URL — это свойства
объекта Document, которые должны записываться как
document.title и document.URL. При использовании опе-
оператора with необходимость в ссылке на о( ; возника-
возникает только один раз, тем не менее, достигается гот же са-
самый результат, что и при наборе ссылки в каждой
строке. На рис. 7.10 показан результат выполнения кода
из листинга 7.11.
ПРЕДУПРЕЖДЕНИЕ
Internet Explorer 3.0 оператор with не поддерживает.
0-
1
ii. l»
Ьяиий И*
1 Pebad Копи
:
¦¦ ¦.:: '¦¦¦¦
SMnh
"•
¦¦
html
т
i
BBI
BBI
BBB
a-
.fiOP:
_!Г.|*|
a
Цр«вгт!
Заголовок этого документа выглядит как "Использование оператора"witi
JRL этого документа выглядит как "file:///D|/books/jscript/7-1 оГ Теперь от
префикса объекта можно избавиться раз и навсегда!
1 si <г
РИСУНОК 7.10. Отображение информации с использованием
оператора with.
Листинг 7.11. Использование оператора with в
JavaScript.
<html>
<head>
<title>Hcnom>SOBaHMe оператора with</title>
</head>
<body>
<script type="text/javascript">
<• —
with(document) {
write("Привет!");
write ("<Ьг>Заз7оловок этого докуне*
^выглядит как \"" + title + '
write ("<br>URL этого документе» выглядит как
-\"" + URL + "\"."> ;
write ("Теперь от префикса обгьек а можно
|бавиться раз и навсегда!
Управляющие структуры и организация циклов
Глава 7
I/ -->
</script>
</body>
</html>
ПРИМЕЧАНИЕ
В зависимости от конкретного браузера, пример мо-
может отобразить URL в закодированном формате.
Оператор switch
Оператор switch используется для сравнения одного зна-
значения с большим количеством других. На первый взгляд
упомянутая задача решается только за счет применения
большого числа условных операторов, однако оператор
switch тут будет гораздо уместнее. Он быстрее читается
и позволяет определить заданный блок инструкций,
выполняющийся в случае, когда соответствие не найде-
найдено.
В листинге 7.12 предполагается, что переменная
request может изменяться в зависимости от требований
пользователя. В данном примере request присваивается
тестовое значение "Name".
ПРИМЕЧАНИЕ
пера-op switch до версии JavaScript - не существовал.
Листинг 7.12. Оператор switch.
<html>
<head>
<title>JavaScript Unleashed»:/title>
</head>
<body>
<script language="JavaScriptl.2"
type="text/javascript">
<• —
J I Объявление переменных
var request = "Name";
switch(request) {
case "Logo" :
document.write('<img src="logo.gif'
alt="Logo">');
document.write("<br>");
break;
case "Name" :
document.write("Software Inc.");
document.write("<br>");
break ,-
case "Products" :
document.write("MyEditor");
document.write("<br>");
break;
default :
document.write("www.mysite.com");
break;
</script>-
</body>
</html>
Вторая конструкция case совпадает с текущим зна-
значением request, следовательно, выполнятся команды,
перечисленные в ней.
]NDOWS\Deeklap\7S3X07 .L12.html
«- ¦ -----
Software Inc.
¦ - J
РИСУНОК 7.11. Использование оператора switch.
Оператор break используется для прерывания даль-
дальнейшего выполнения кода, оставшегося в switch. Если бы
оператор break не использовался, оставшийся код выпол-
выполнялся бы для каждого случая, независимо от соответ-
соответствия между request и case. Из рис. 7.11 ясно, что request
соответствует значению "Name", при этом на экран
выводится название компании.
Резюме
Для принятия решений в JavaScript используются услов-
условные операторы if и else, if обеспечивает выполнение ча-
части программы на основе вычисления определенного ус-
условия. Если условное выражение возвращает true,
соответствующая часть программы выполняется, в про-
противном случае — нет.
Помещайте оператор else сразу после блока if, что-
чтобы обеспечить выполнение следующего кода, когда вы-
выражение в блоке if возвращает false. JavaScript допуска-
допускает вложенные операторы if и if..else. Такой метод дает
возможность задавать новые вопросы, основываясь на
ответах на предыдущие вопросы.
Циклы for применяются для многократного повторе-
повторения одного раздела сценария. При объявлении цикла
имеется возможность выбора начального значения пере-
переменной, которая будет применяться внутри цикла. Мож-
Можно также выбирать вариант изменения переменной, каж-
каждый раз когда цикл завершается. Используя выражение
условия цикла for, можно определять, когда остановить
выполнение цикла.
Базовое подмножество языка JavaScript
Часть II
Используйте цикл for..in, если требуется выполнить
набор операторов для каждого свойства объекта. JavaScript
автоматически присваивает имя свойства выбранной
переменной. С помощью такой переменной можно оп-
определять операции над этим свойством.
Используйте цикл while для многократного повторе-
повторения раздела сценария. Потребуется лишь задать услов-
условное выражение, которое должно возвращать true перед
выполнением каждого цикла.
Операторы break и continue используются для преры-
прерывания любого цикла, break полностью завершает цикл,
a continue останавливает текущую итерацию цикла, при
этом программа переходит на начало следующей итера-
итерации.
Оператор with используется вместе с объектами
JavaScript. Он позволяет сослаться на объект только
один раз вместо многократных ссылок при обращени-
обращениях к свойствам и методам. Внутри блока with можно ука-
указывать имена свойств и методов объекта безо всякой
ссылки на объект.
И наконец, упомянем оператор switch. Этот опера-
оператор позволяет определять все возможные значения дан-
данной переменной для исполнения всех необходимых задач.
Если текущее значение не равно одному из определен-
определенных заранее, программа переходит к разделу default.
Функции
В ЭТОЙ ГЛАВЕ
Понятие функций
Использование аргументов
Дополнительные сведения о функциях
Организация одной или множества функций отно-
относится к одной из целей всех программ на JavaScript. В
самом простом случае сценарий может читать или при-
принимать данные, выполнять определенные операции на
наборе данных либо отображать и отсылать данные. Как
упоминалось ранее, для достижения требуемых целей
можно использовать комбинацию базовых инструмен-
инструментальных средств JavaScript или просто одно из них.
Для связи с каким-то браузером сначала необходи-
необходимо запросить его возможности и затем направить его по
нужному пути. Для того чтобы у посетителя появилось
желание неоднократно возвращаться на ваш Web-сайт,
лучше всего предоставить ему возможность получать ин-
информацию о всем новом и интересном, появившемся на
сайте. Если вы, например, продаете какие-либо товары,
при помощи JavaScript несложно подсчитать стоимость
любой их комбинации для клиента и сохранить полу-
полученные данные для отдела маркетинга.
Выполнение подобного типа задач требует исполь-
использования большого количества строк JavaScript. Некото-
Некоторые разделы сценария должны выполняться непосред-
непосредственно после загрузки Web-страницы в браузер. Другие
части сценария, возможно, окажутся полезными, если
проявят себя после того, как клиент введет определен-
определенные данные в HTML-форму. Иногда бывает необходи-
необходимо многократно (или даже неограниченное количество
раз) использовать отдельные части сценария, при этом
периодическое повторение одного и того же раздела
программы неизбежно.
Перечисленные проблемы приводят к идее разбие-
разбиения сценария на части, из которых каждая служила бы
одной конкретной цели. Каждая цель на шаг прибли-
приближала бы к успеху в процессе выполнения JavaScript-
сценария. Проверка достоверности введенных в HTML-
форму данных — еще одна задача, которую сценарий
мог бы выполнять, пока посетитель работает с Web-
страницей.
Поэтому имеет смысл разбить сценарий на логичес-
логические разделы, каждый из которых предназначен для од-
одной конкретной цели. Когда подходит время, определен-
определенный раздел сценария начинает выполняться. JavaScript
обеспечивает такую возможность, предоставляя струк-
структуру, известную как функция.
Понятие функций
JavaScript-функция — это просто сценарий, отделенный
от остальной части программы и имеющий свое имя.
Используя это имя, другой сценарий может вызывать его
в любой момент и сколь угодно раз. Некоторые языки
программирования, например, C/C++ или Java, также
используют функции, тогда как другие языки имеют те
же самые семантические единицы, но называют их ме-
методами, процедурами или подпрограммами. Все они
делают в основном те же самые вещи, но имеют неко-
некоторые различия.
Функции служат одной цели — разделению задач,
предназначенных для выполнения в одной программе.
Можно считать функцию уведомлением JavaScript о не-
необходимости выполнения конкретного списка связан-
связанных команд и выдачи сигнала, как только это будет
сделано.
При вызове функции можно передать значения, на-
называемые аргументами (arguments). Аргументы можно
использовать в качестве переменных (variables) в пределах
одного блока операторов. Как только данные присвое-
присвоены переменной, становится возможной обработка дан-
данных либо использование их в вычислениях.
Создание функций
Ниже приводится синтаксис объявления функции в
JavaScript:
function имяфункцил ([аргумент!]
[оператора]
[.. . , аргументы] ) {
Базовое подмножество языка JavaScript
Часть II
Ключевое слово function используется для определе-
определения функции с именем имяФункции, которое служит в
качестве идентификатора для набора операторов, заклю-
заключенных в фигурные скобки. Имена аргументов, храня-
хранящих передаваемые в функцию значения, заключаются в
круглые скобки и отделяются друг от друга запятыми.
С точки зрения программирования, аргументы пред-
представляют собой переменные, которым можно присваи-
присваивать литеральные значения, другие переменные или
объекты, передаваемые в функцию при вызове. Даже в
случае полного отсутствия аргументов все равно необ-
необходимо после имени функции указывать пару круглых
скобок, тем самым обозначая идентификатор как фун-
функцию.
Операторы в теле функции выполняются при каж-
каждом вызове функции. Для повышения удобочитаемос-
удобочитаемости строки внутри блока операторов выравниваются.
Где объявлять функции
Теоретически функцию можно объявлять в любом ме-
месте в пределах раздела < script>. Существует единствен-
единственное ограничение — нельзя объявлять функцию в пре-
пределах другой функции или управляющей структуры.
е в виду, одни блоки HTML-документа
загружаются раньше других, равно как и любые сцена-
сценарии, встроенные в эти HTML-блоки. В этой связи ре-
рекомендуется объявлять функции HTML-документа в
разделе <head>. Объявление всех функций в этом раз-
разделе гарантирует, что функции будут доступны, если
какому-то сценарию потребуется вызвать их неме/
но.
В листинге 8.1 показана функция defaultColors(),
объявленная внутри раздела <head>. Далее эта функ-
функция вызывается в разделе <body> документа.
Листинг 8.1 Объявление функции в разделе
<head>.
<html>
<head>
ocript type:
<!--
function defaultColors () {
document. writeln ("Внутри defaultColor () ") ;
document . fgColor = "black";
document . bgColor — "white" ;
</script>
</head>
<body>
ocript type=" text/javascript" >
<! —
int. writeln ("Функции — это сценарии,
'-•ожидающие выполнения! " ) ;
defaultColors ();
int. writeln ("Все дела переделаны.");
</script>
</body>
</html>
Вызов функции
Листинг 8.1 демонстрирует вызов функции defaultColors()
из второго раздела сценария. Это пример вызова функ-
функции без аргументов. После полной загрузки HTML-до-
HTML-документа функция сохраняется в памяти и находится там
"в состоянии боевой готовности". Она не будет выпол-
выполняться, пока главный раздел сценария не вызовет ее
следующим оператором:
defaultColors()
В этой точке программа сразу же переходит на пер-
первую строку функции <lefau!tColors(). После выполнения
:сх трех строк программа возвращается назад к точке,
в которой она покинула главный раздел, и продолжает
работу там.
Таким образом получается такой же эффект, как и
при помещении всего кода функции непосредственно в
конкретную позицию программы. Теперь, когда функ-
функции присвоено имя, все, что потребуется сделать для
выполнения тех же инструкций — использовать ее имя
снова. Результаты описанного процесса показаны на
рис. 8.1. Мне гократнос использование какого-то кода —
вот наилучшее применение функции.
Функции - это ¦'.» ¦' : . ожидающие выполнения! Btf/TprttJefauKCotor()Bc&A*na ^рэд&лань
РИСУНОК 8.1. Повторное использование кода.
ПРИМЕЧАНИЕ
В отличие от свойства строки fontcolor, свойства до-
документа fgcolor и bgcolor можно изменять без обнов-
обновления или перезагрузки страницы в браузере.
Использование аргументов
Функции с аргументами не менее полезны. Аргументы
дают возможность многократно использовать функцию
Функции'
Глава 8
в разных задачах для достижения одних и тех же целей.
Например, можно создать функцию, необходимость в ко-
которой возникает много раз в ходе выполнения программы;
однако при этом каждый раз при вызове функции требует-
требуется изменять одно из значений внутри функции.
¦Один из способов решения упомянутой проблемы
без задействования механизма аргументов связан с при-
применением глобальных переменных, которые могут из-
изменяться как вне, так и внутри функции. Программа
станет запутанной, если те же самые переменные будут
использоваться внутри более чем одной функции. Вы-
Выгоднее создать функцию с аргументом, принимающим
все необходимые значения. В листинге 8.2 показана
функция, которая пользуется преимуществом примене-
применения аргументов.
Листинг 8.2. Использование аргумента
в JavaScript-функции.
<html>
<head>
<11Ь1е>Функции и apryMeHTbi</title>
<soript type="text/ javascript">
<!-¦•
function getBinary (anlnteger) {
var result = "";
var shortResult = "
for (var i=l; i <= 32; i++) {
if(anlnteger S 1 = = 1) (
result = " + result;
shortResult = result
} else {
result = " + result;
anlnteger = anlnteger
:i
return(shortResult);
</script>
</head>
<body>-
<script type="text/javascript">
var binaryString = '
// Объявление переменной x
x = 9;
binaryString = getBinary(x);
// Запись результатов на страницу
1 + х +
' в двоичном представлении: \п") ;
document.writeln(binaryString);
// Переопределение переменной х
х = 255;
binaryString = getBinary(x);
// Запись результатов на страницу
document.write ("Число " + х +
¦ в двоичном представлении: \п") ;
document.writeln(binaryString);
S переменной х
1 + x) ;
</script>
</body>
</html>
Когда функция вызывается как getBinary(x), она
получает копию значения, хранящегося в переменной
х. Такой процесс называется передачей по значению
(passing by value). Значение присваивается anlnteger —
локальной переменной данной функции. В дальнейшем
эту переменную можно использовать в любом месте
блока операторов как локальную. Как показано на рис.
8.2, если anlnteger изменяет значение внутри функции,
это изменение не затрагивает значение переменной х,
которая играет роль аргумента.
Во* -1 \вп
¦
i
. ¦
Число 9 в двоичном представлении К 01 Числи 255 в двоичном редставлении 11
Значение переменной х все еще равно: 255
РИСУНОК 8.2. Передача по значению не оказывает влияния на
первоначальную Переменную.
Обратите внимание, что anlnteger объявлять с ис-
использованием ключевого слова var не требуется.
JavaScript автоматически объявляет новую переменную
при каждом вызове функции.
Последний оператор в теле функции getBinary() —
это return(shortResuIt). Функция может получать значе-
значение, и точно также она может и возвращать определен-
определенное значение. Оператор return возвращает одиночное
значение в место вызова функции в программе. Возврат
значения функции работает таким же образом, как и
возврат значения вычисленного выражения. Приведен-
Приведенный ниже оператор присваивает переменной binaryString
значение, возвращаемое getBinary():
binaryString = getBinary(x);
В данном случае переменной binaryString присваи-
присваивается последнее значение shortResult.
Можно использовать функции, возвращающие зна-
значение, в обычных выражениях. Некоторые функции
возвращают результат набора вычислений, тогда как
Базовое подмножество языка JavaScript
Часть II
другие — логическое значение, уведомляющее о том, все
ли в порядке (см. листинг 8.3).
Листинг 8.3. Функции, возвращающие значения,
которые можно использовать в выражениях.
<html>
<head>
<script type="text/javascript">
< ! ~
function isPhone(aString) {
var aChar = null;
var status = true;
if(aString.length != 13) {
status = false;
lelse{
for (var i = 0; i <= 12; )
aChar = aString.charAt(i);
If ( 1 = 0 && aChar == " (" )(
continue;
Уelse(
If ( 1 = 4 66 aChar = ")" ) {
continue;
}else{
[ 1 = 8 66 aChar = "-" ){
continue;
}else{
If ( parselnt(aChar.lO) >= 0 SS
parseInt(aChar,10> <= 9 ){
continue;
}else {
status =
break;
I
.
:
return(status);
1
</script>
¦</head>
<body>
<script type="text/javascript">
<! —
var userlnput = "(800M55-1212";
if(isPhone(userlnput)) (
document.writeln("Спасибо за ввод вашего
^•номера телефона. ") ;
document.writeln("Наш представитель
'^подготовит вам") ;
document.writeln("дополнительную
"•¦информацию. ") ;
}else(
document.writeln("Пожалуйста, введите
•¦¦номер телефона повторно,");
documen t.wri teln("используя формат
-(###)###-####.");
)
II—>
</script>
</body>
</html>
Вызов функции isPhone(userlnput) применяется как
условное выражение в операторе if. Функция isPhone()
возвращает логическое значение. Возвращенное значе-
значение дает знать вызывающей программе, в корректном ли
формате был введен телефонный номер. Это полезно
для проверки достоверности данных, вводимых пользо-
пользователями в HTML-форму. Из рис. 8.3 видно, что теле-
телефонный номер был введен корректно, на что указывает
соответствующее сообщение. Подробную информацию,
касаемую проверки достоверности вводимых данных,
можно найти в главе 29.
: - ¦ ¦: . ,¦ ¦ f' ¦ ¦ ¦¦
Ш
¦Z вашего номера t
) информацию
L Наш представитель подгот вам
РИСУНОК 8.3. Использование функции в качестве условного
выражения.
Изменение количества аргументов
Для функции устанавливается определенное количество
аргументов. Несмотря на то что использование в точно-
точности объявленного количества аргументов считается хо-
хорошим стилем программирования, иногда возникает
необходимость установки другого количества аргумен-
аргументов. Иногда это требуется при вызове функции, кото-
которая каждый раз использует одно и то же значение па-
параметра и изменяет его только в специальных случаях.
Если аргументы не передаются, следует использо-
использовать их значения по умолчанию, определенные в теле
функции. Это позволяет вызывать функцию без аргу-
аргументов или определять значение, отличное от значения
по умолчанию. В листинге 8.4 создается функция для
отображения типичного приветствия, появляющегося,
когда пользователь заходит на Web-страницу.
Эта программа отображает одно из двух сообщений,
в зависимости от того, известно ли ей имя посетителя.
Если userName не равно null, это значит, что перемен-
переменная определена. Такое возможно только если в функцию
передается значение, например, Г-н Президент. Если
аргумент функции равен null, переменная в привет-
приветственном сообщении вообще не используется.
Функции
Глава 8
Листинг 8.4. Функция, принимающая один аргумент или не принимающая ни одного аргумента.
<html>
<head>
<title>*yHK4MH</ti tle>
<script type="text/javascript">
<! —
userName является необязательным
function welcomeMessage (userName) {
if (userName != null) {
document, writeln ("\"Еще раз здравствуйте, " + userName + "A"");
}else{
document, writeln ("\"Добро пожаловать на наш Web-сайт! \"") ;
document, write ("ХпЕсли в функцию не перелается значение, ") ;
document, writeln ("в результате отображения ") ;
document.writeln ("переменной \"userName\" будет: ") ;
document,writeln (userName) ;
</script>
</head>
<body>
<sciipt type="text/javascript">
<! —
document .writeln ("Первый вызов welcomeMessage(),\n");
welcomeMessage("Г-н Президент");
ocument.writeln ("<НЯ>\пВторой вызов welcomeMessage () ,\n") ,*
welcomeMessage();
// -->
</script>
</body>
</html>
Как показано на рис 8.4, ее использование приводит
к отображению нежелательных данных. В зависимости
от конкретного браузера, нежелательные данные будут
отображаться как undefined или как пустой символ.
«<*ir:A&xmm
Первый вызов welcomeMessageQ. "Еще раз здравствуйте. Г-н Президент"
Второй Bbl30BwelcomeMessage(). "Добро пожаловать на наш Web-сайт!" Если в
функцию 11а передается значение. в результате отображения переменной "userName"
будет, undefined
РИСУНОК 8.4. Результат использования аргументов.
В настоящее время JavaScript поддерживает операцию
typeof, которая обеспечивает проверку, является ли
userName неопределенным или равным null. Это иде-
идеальный способ проверки, но он не поддерживается в
некоторых устаревших браузерах.
-
4 1-158
РЕСУРС ,
Новые возможности JavaScript подробно описывают-
ся на сайте Netscape DevEdge по адресу http://
developer.netscape.com.
Еще один случай связан с передачей в функцию
большего количества аргументов, чем было определено
в объявлении. Дополнительные значения при этом не
теряются, а сохраняются в массиве arguments, который
представляет собой свойство каждой функции. Все ар-
аргументы, сохраненные в массиве, могут быть извлече-
извлечены в пределах тела функции. Например, первый аргу-
аргумент, переданный в функцию welcomeMessage, можно
получить так:
firstArg = welcomeMessage.arguments[0]
Элементы массивов JavaScript нумеруются, начиная
с 0. Второй элемент в массиве будет иметь индекс 1 и т.д.
Для вычисления общего количества переданных ар-
аргументов можно записать такую строку:
numArgs = welcomeMessage.arguments.length
В листинге 8.5 демонстрируются все упомянутые
возможности, при этом в welcomeMessageO передается
переменное количество аргументов. В данном случае
функция welcomeMessage() приобретает следующий
вид:
Базовое подмножество языка JavaScript
Часть II
welcomeMessage([имяПользователя]
[, дополнительноеСообщение1]
[,дополяятельноеСообщение2] . ..)
Обратите внимание, что в листинге 8.5 ситуация,
при которой userName неизвестно, однако дополнитель-
дополнительные сообщения должны отображаться, все еще поддер-
поддерживается. Переменной US& Name2 присвоено значение
null для того, чтобы заполнить первый элемент в мас-
массиве аргументов так, чтобы сообщение не рассматрива-
рассматривалось в качестве имени пользователя. На рис. 8.5 пока-
показано, что со всего этого вышло.
СОВЕТ
При коллективной разработке все сложные сценарии
необходимо документировать, чтобы все, написанное
лично вами, смогли понять и другие. Без простых и на-
наглядных комментариев чтение приложения отымет го-
гораздо больше времени.
"Еще раз здравствуйте. "Давненько не
"Добро пт ватьна наш Web-сайт!" "Не хотите пи стать членом клуба'*" "Стать ЧП9
клу'ба мажнои в онлайне!"
РИСУНОК 8.5. Передача в функцию множества
отображения множества сообщений.
ептовдля
Листинг 8.5. В функцию можно передать переменное количество аргументов.
<html>
<head>
<t±tle>nepeMeHHoe количество аргументов в функции<^1^1е>
<script type="text/ javascript">
// При определении welcomeMessage воспользуйтесь таким синтаксисом:
// welcomeMessage ([userName] [, extraMessagel] [ ,extraMessage 2] ¦¦¦)
function welcomeMessage (userName) {
If (userName != null) {
document.writeln("\"En(e раз здравствуйте, ' + userName + "A"");
}else{
document.writeln("\"flo6po пожаловать на наш Web-сайт! \"") ;
numArgs = welcomeMessage.arguments.length;
// Если в функцию, помимо userName, передаются дополнительные аргументы,
// отобразить каждый из них.
if (numArgs > 1) (
for (var i = 1; i < numArgs; i++) {
document.writeln("\""+welcomeMessage.arguments[i]+"\"");
"Давненько не встречались!
</script>
</head>
<body>
<script type="text/javascript">
var userName = "Валера", extraMessage
var userName2 = null;
var extraMessagel = "He хотите ли стать членом клуба?";
var extraMessage2 = "Стать членом клуба можно и в онлайне!
welcomeMessage(userName, extraMsg);
document.writeln("<hr>");
welcomeMessage(userName2, extraMsgl, extraMsg2);
// ~>
</script>
-< /body>
</html>
Использование глобальных и
локальных переменных
В главе 5 рассматривались отличия между локальными
и глобальными переменными. Кроме того, было проде-
продемонстрировано, что глобальная переменная может из-
изменяться в любом месте документа, в то время как ло-
локальная — только в пределах функции, в которой она
объявлена. Выбрать подходящий тип переменной мож-
можно, следуя приведенным ниже рекомендациям:
• Если предполагается, что значение переменной бу-
будет использоваться и, возможно, изменяться в любой
части программы (как внутри, так и вне функций),
то переменная должна быть объявлена вне любой
функции. Это называется созданием глобальной пе-
переменной, поддающейся изменению в любой части
программы. Лучше всего объявлять глобальную пе-
переменную в разделе <head> HTML-документа, тем
самым обеспечивая объявление переменной до лю-
любого ее использования. В этом случае исчезает необ-
необходимость повторного объявления этой переменной
внутри какой-либо функции.
• Если переменная необходима только в пределах кон-
конкретной функции, там ее лучше и объявлять. Убеди-
Убедитесь, что при объявлении переменной используется
ключевое слово var. В этом случае ее значение гаран-
гарантированно будет изменятся только в пределах функ-
функции, JavaScript будет считать такую переменную'
уникальной и отличной от любых глобальных пере-
переменных, которые могут иметь то же самое имя. Для
объявления переменных аргументов использовать
ключевое слово var не требуется. Переменные, опре-
определенные в объявлении функции, автоматически счи-
считаются локальными и объявленными с ключевым
словом var.
• Если требуется использовать переменную только в
пределах главного сценария, а не внутри каких-либо
функций, объявляйте переменную где-нибудь вне
Функции
Глава 8
функций. К сожалению, нет средства, которое убе-
уберегло бы сценарий от использования переменной
внутри функций, поскольку переменная будет рас-
рассматриваться как глобальная. Из-за невнимательно-
невнимательности разработчика это может привести к перезаписи
значений, хранящихся в переменных с одинаковы-
одинаковыми именами. Во избежание подобного рода проблем
всегда следуйте приведенным выше указаниям.
Если требуется переменная, изменяющаяся в преде-
пределах одной функции, но не нужная в другой функции,
передавайте ее в эту функцию в качестве аргумента.
Тем самым создается копия переменной и ее значе-
значение присваивается переменной аргумента заданной
функции. Поскольку функция в процессе работы
изменяет свою собственную копию переменной, это
никак не скажется на оригинале. Переменные аргу-
аргумента автоматически объявляются как локальные для
данной функции. Даже если переменная аргумента
имеет то же самое имя, что и передаваемая перемен-
переменная, изменения последнюю не затрагивают. Одно
исключение все же есть — объекты. Когда в каче-
качестве аргумента передается объект, он передается по
ссылке, а не по значению. Вместо создания копии
объекта функция использует первоначальный объект.
Изменения, сделанные в свойствах объекта в преде-
пределах функции, оказывают влияние на первоначальный
объект.
Примеры передачи переменных по значению приведе-
приведены в листинге 8.6. Обратите внимание, как JavaScript раз-
различает переменные с одинаковыми именами. Здесь пере-
переменная пшпЬегВ передается в функцию doublePassedVar().
JavaScript автоматически создает локальную переменную,
также названную пшпЬегВ. Даже при том, что эта локаль-
локальная переменная имеет имя, совпадающее с глобальной,
изменения ее значения никак не затрагивают глобальную
переменную. Результаты выполнения кода из этого ли-
листинга показаны на рис. 8.6.
Листинг 8.6. Использование локальных и глобальных переменных.
<html>
<head>
<title>JIoKcuibHue и глобальные nepeMeHHbie</title>
<script type="text/javasoript">
<! —
// Глобальные переменные, которые можно изменясь в любой функции.
var numberA;
// Глобальные переменные, которые можно изменять только в главном сценарии,
var numberB;
function doubleGlobalVar(){
// Это изменит значение глобальной переменной.
numberA *= 2 ;
function tripleLocalVar ()
Базовое подмножество языка JavaScript
,1
Часть II
// Здесь используется переменная с именем, совпадающим с именем глобальной
// переменной, однако JavaScript будет трактовать их как разные переменные.
var nurrfoerA = 1;
numberA *= 3 ;
function doublePassedVar(numberB) {
// Имя аргумента совпадает с именем передаваемой в функцию переменной.
,// Опять-таки переменные трактуются как разные.
numberB *= 2 ;
II—>
</script>
</head>
<body>
<script type="text/javascript">
numberA = 1 ;
document.writeln("Начальное значение numberA:
doubleGlobalVar();
tripleLocalVar();
document.writeln("Результирующее значение numberA:
numberB = 1;
document.writeln("Начальное значение numberB: ' + numberB);
doublePassedVar(numberB);
document.writeln("Результирующее значение numberB: ' + numberB);
+ numberA);
+ numberA);
</script>
</body>
</html>
Начальное значен,- numberA: 1 Результирующее Значение numberA: 2 Начальное значение
numberB: 1 Результирующее значение numberB: 1
РИСУНОК 8.6. Полученные значения переменных numberA и
numberB.
Передача объектов по ссылке
Формальное введение в создание пользовательских
объектов JavaScript предоставляется в главе II. Имея
дело с функциями, важно знать, что случается при ис-
использовании объекта в качестве одного из аргументов в
вызове функции.
Когда в функцию передаются данные простых ти-
типов, например, строки, числаилилогическиезначения,
передача выполняется по значению. Это означает, что
вместо оригинала функция использует копию перемен-
переменной. Любые изменения, произведенные в копии, ори-
оригинал не затрагивают.
С другой стороны, когда в функцию передается
объект, то передача происходит по ссылке. Следователь-
Следовательно, функция будет изменять первоначальный вид объек-
объекта. Зная это, простые типы данных можно поместить
внутрь объекта, если требуется передать переменную по
ссылке (см. листинг 8.7).
Листинг 8.7. Передача по ссылке по значению.
<html>
<head>
<title>IIepena4a по ссылке по 3Ha4eHKio</title>
<script type="text/javascript">
,// Поместить стандартный тип integer
// в объектную оболочку
function intobject() {
this.i;
return this ;
function start() {
// Два способа хранения данных типа integer
var I ;
var mylntobject = new intObject();
// Присвоить начальные значения
i = 0;
mylntobject.i = 0;
// Отобразить текущие значения
document.write("<Ьг>До<Ьг>");
document.write("i = " + i) ;
J
Функции
document.write("<br>");
document.write("mylntObject = " +
mylntObject.i);
document.write("<br>");
// Передать переменные в функцию
modify(i, mylntObject) ;
// Отобразить текущие значения
document.write("<Ьг>После<Ьг>");
document.write("i = " + i) ;
document.write("<br>");
document.write("mylntObject = " +
mylntObject.i);
document.write("<br>");
function modify (n, obj) {
II—>
</script>
</head>
<body>
Ocript type="text/javascript">
<! —
start () ;
II—>
</script>
</body>
</html>
Функция intObject() используется для помещения
переменной i в объектную оболочку. Экземпляр объек-
объекта создается следующим образом:
var mylntObject = new intobjectf)
Теперь mylntObject может использоваться для обра-
обращения к переменной i при помощи такого кода:
mylntObject.i
Это также позволяет передавать в функцию числовое
значение по ссылке. Функция modify() демонстрирует
различия между изменением простого типа данных и из-
изменением объекта. На рис. 8.7 показано, что начальное
значение i не изменилось, в то время как на первоначаль-
первоначальное значение mylntObject.i воздействие было оказано.
Глава 8
шую выгоду она дает в плане повторного использования
кода.
Lkt
-OperaSoftVMl
Auto Imported Items
Automobiles
JBum«sand Finance
Complement»? Heath
f"_ompuler Genet gl
lefore
myIntObject= 0
¦Aficr
i = 0
mybitObject= 1
РИСУНОК 8.7. Передача пользовательского объекта JavaScript
по ссылке.
В отличие от циклов, которые повторяются много
раз в определенной последовательности, функцию мож-
можно повторно использовать в любое время, просто обраща-
обращаясь к ее имени. Создание функций, которые предназна-
предназначены для одной цели, но полезны в многих ситуациях,
— практичный и предусмотрительный подход.
Например, в листинге 8.4 функция welcomeMessage()
служит одной и той же цели сразу в нескольких слу-
случаях в процессе выполнения программы. Функция
welcomeMessage() пригодилась в большем количестве
ситуаций, т.к. в листинге 8.5 был создан более гибкий
список аргументов. Она еще служит все той же цели, но
это лучший кандидат на повторное использование в
более гибкой форме.
Вспомним, что функции можно хранить во внешних
JavaScript-файлах. Включают эти файлы, используя ат-
атрибут src дескриптора <script>. В результате существен-
существенно снижаются временные затраты разработчика по рас-
распространению новой версии функции на весь сайт,
поскольку ему потребуется отредактировать функцию
только один раз.
Дополнительные сведения о функциях Рекурсивные функции
В главе рассматривались основные понятия, касающи-
касающиеся функций. Без функций JavaScript был бы просто
языком написания сценариев, который использовался
бы только для очень простых сценариев. К уже сказан-
сказанному вполне уместно добавить, что функции могут по-
повторно использоваться и быть рекурсивными.
Повторное использование функций
Функция — наиболее подходящий инструмент для де-
деления приложения на логические части, но еще боль-
Функции JavaScript могут быть рекурсивными, т.е. вы-
вызывать сами себя. Вычисление факториала — лучший
способ демонстрации рекурсивного процесса. Ввиду
того что JavaScript не имеет встроенной операции фак-
факториала, их придется вычислять самостоятельно, при-
причем с использованием механизмарекурсивных функций.
Для нахождения факториала любого положительно-
положительного целого числа п требуется просто найти произведение
всех целых чисел от 1 до п. Например, факториал чис-
числа 6 (записывается как 6!) вычисляется следующим об-
образом:
Базовое подмножество языка JavaScript
Часть II
6! = 6x5x4x3x2x1= 720'
7 • вычисляется так;
7! =7x6x5x4x3x2x1 = 5040
На основе сравнения этих двух выражений можно
записать общую формулу, которая будет использовать-
использоваться в создаваемой функции. Обратите внимание, что 7!
ни что иное как 7х 6!, Для любого положительного це-
целого числа п справедлива запись n! = n х(п - 1)!. Пер-
Первая итерация выглядит так:
7! = 7 х G - 1)!
= 7x6!
Теперь необходимо остановиться и вычислить 6!.
Поступая аналогичным образом еще шесть раз, получим
окончательное решение. Однако гораздо эффективней
воспользоваться рекурсивной функцией, например, та-
такой:
function getFactorial(n) {
var result;
if (n > 0) {
result = n * getFactorial (n — 1) ;
} else if (n=O) {
result = 1 ;
} else {
result = null;
f
return(result)
Функция сначала сравнивает п с нулем. Если выра-
выражение п > 0 истинно, функция умножает п на резуль-
результат, возвращенный из вызова этой же функции с дру-
другим аргументом, в данном случае, п - 1. Вложенные
вызовы функции getFactorial() продолжают ожидать,
пока пне станет равным 0. В этот момент наиболее вло-
вложенное выполнение функции завершается и возвраща-
возвращает первое значение. JavaScript возвращается назад и за-
завершает каждую вложенную функцию, пока не достигнет
первого вызова getFactorial, после чего получится окон-
окончательный результат.
Разработка полезных функций — один из наиболее
существенных и интересных аспектов программирова-
программирования. После того как функция проверена в действии,
стоит возвратиться и подправить ее, попытаться сделать
более гибкой. После не забудьте убедиться, что функ-
функция все еще решает заданную цель и не делает ничего
неожиданного.
Резюме
Получив определенный опыт создания функций, мож-
можно переходить к следующему захватывающему шагу в
программировании на JavaScript — созданию пользова-
пользовательских объектов. Эта тема рассматривается в главе 11.
Однако перед этим необходимо еще многое изучить
касательно объектов, встроенных в HTML и JavaScript.
Кроме того, JavaScript имеет множество встроенных
функций, доступных в любой момент. Перечисленным
темам посвящена глава 10.
JavaScript-функции помогают достичь многих целей.
Они позволяют сохранять код так, чтобы он не выпол-
выполнялся сразу же после загрузки документа. Использова-
Использование аргументов дает возможность легко дублировать код
и применять тот же самый код для выполнения оди-
одинаковых операций на различных наборах данных. Ниже
приводится краткий список возможностей функций и
напоминаний о том, как каждая из этих функций вы-
выполняется.
¦• Функция — это набор JavaScript-кодов, сгруппиро-
сгруппированных и имеющих собственное имя. Для объявле-
объявления функции напишите ключевое слово function, за
которым должно следовать имя функции, набор
круглых скобок и сценарий, который функция будет
содержать. Имя функции должно выбираться в со-
соответствие с общими правилами именования пере-
переменных.
• Функции могут объявляться в любом месте HTML-
документа, но обязательно внутри пары дескрипто-
дескрипторов <script>. Лучше всего объявлять функции в раз-
разделе <head> документа.
• Для вызова функции напишите ее имя вместе с на-
набором круглых скобок. В эти круглые скобки можно
заключать любые аргументы, которые будут переда-
передаваться в функцию.
• Аргументы передаются по значению. Функции мо-
могут принимать переменное число аргументов, неза-
независимо от того, как функция была объявлена. Каж-
Каждая функция имеет массив, называемый arguments.
Этот массив используется для извлечения значений
переданных аргументов.
Функции могут возвращать значения. Функции, воз-
возвращающие значения, можно использовать в выраже-
выражениях.
• Нет необходимости объявлять переменные аргумен-
аргументов. Они автоматически объявляются как локальные
переменные, каждый раз когда функция вызывает-
вызывается. Для объявления глобальных переменных в пре-
пределах функции не следует использовать ключевое
слово var. В данном случае потребуется только ини-
инициализация переменных.
• Функции, решающие одну цель, однако достаточно
гибкие, чтобы иметь дело с различными порциями
данных — верные кандидаты на повторное исполь-
использование.
1 • В JavaScript функции могут вызывать сами себя. Фун-
Функции подобного рода носят название рекурсивных.
Объекты со
стороны клиента
В ЭТОЙ ГЛАВЕ
Понятие объекта
Объекты JavaScript
Дополнительная информация об объектах
В предыдущих главах книги рассматривались базо-
базовые элементы языка JavaScript. Но это далеко не все. Без
сомнений, квинтэссенция JavaScript со стороны клиен-
клиента — это объектная модель. Поэтому в настоящей главе
будет дано общее представление объектной модели
JavaScript и всех существующих на данный момент язы-
языковых объектов.
Перед детальным изучением JavaScript-объектов по-
потребуется выполнить краткий обзор некоторых основ-
основных концепций объектно-ориентированного програм-
программирования (object-oriented programming — ООП).
JavaScript не настолько объектно-ориентированный, как
Java или C++, но и он основан на объектах. Поэтому
знание соответствующей терминологии будет хорошим
фундаментом для понимания использования JavaScript-
объектов.
После раскрытия основных понятий ООП эта глава
переходит к рассмотрению того, что собой представ-
представляет объектная модель JavaScript, а также (что еще
важнее) — того, чем она не является. Наконец, в зак-
заключительной части главы приводится краткое описание
всех объектов объектной модели.
Понятие объекта
Человеку, недостаточно хорошо знакомому с объектно-
ориентированными концепциями, может показаться, что
разработчики, пользующиеся ООП, говорят на другом
языке. Действительно, термины наподобие ООП, мето-
метода, свойства на первых порах выглядят пугающе для
того, кто привык программировать с помощью функций
или макрокоманд. Однако как только вы найдете время
для изучения ООП, вы увидите, что его легко понять
интуитивно. В этом разделе рассматривается ряд основ-
основных концепций, в том числе объекты, свойства и мето-
методы.
Объекты
Программы обычно разрабатываются в специальных
коммерческих целях. Например, система менеджмента
предназначается для обработки заказов со стороны кли-
клиентов. Коммерческие прикладные задачи, в дополнение
к требованиям конечного пользователя, формируют "мир
проблем", или "пространство проблем", или то, на что
ссылаются как на "предметную область" программного
обеспечения. Эта область также включает и такие ком-
компоненты, как графический пользовательский интерфейс
(GUI).
В конструкции объектно-ориентированных @0)
приложений объекты являются центральными логичес-
логическими блоками. Зачастую объекты в коде программы -
это представления реальных объектов, находящихся в
пространстве проблем. При этом существует возмож-
возможность формирования вспомогательных объектов для
решения специальных проблем.
Объектом может быть любое понятие из следующе-
следующего списка:
• Материальная или видимая вещь в предметной об-
области, например, заказ или клиент. Если разраба-
разрабатывается программное обеспечение для автомо-
автомобильного бизнеса, вероятными объектами будут
продаваемые автомобилей, модели автомобилей, слу-
служащие, клиенты и т.п.
• Абстрактная концепция, существующая только в уме
разработчика, или что-то, что можно представить
умозрительно. Например, при разработке приклад-
прикладных программ для химиков потребуются химические
структуры объектов типа молекул, атомов, химичес-
химических моделей и пр. Дату и время также можно рассмат-
рассматривать как умозрительные объекты, т.к. они, конеч-
конечно же, не материальны. Объект Math в JavaScript —
еще один хороший пример чистой логической кон-
Базовое подмножество языка JavaScript
Часть II
цепции. В объекте Math содержатся расширенные ма-
математические функции (арифметические и тригоно-
тригонометрические) для обработки чисел в JavaScript.
• Видимый объект графического пользовательского ин-
интерфейса (GUI-объект). JavaScript содержит много
различных GUI-объектов, например, окна, фреймы,
кнопки, поля ввода.
Исторически сложилось, что ОО модель базируется
на концепции структур данных. Структуру данных мож-
можно рассматривать как более сложный тип данных. Струк-
Структура данных очень похожа на идею объекта. Она пред-
представляет собой модель абстрактной концепции в
информатике для решения простых технических задач
программирования. Структура данных является контей-
контейнером, содержащим соответствующие данные о перемен-
переменных и определенных для них операциях.
Существует множество примеров того, что в книгах
по компьютерным наукам объектами называют по суще-
существу структуры данных, типа протоколов, массивов, ком-
комплексных чисел или стеков. Стек — это контейнер для
хранения значений данных; работа с ним, в основном,
подобна работе со стопкой бумаги. В каждый момент
времени стек может хранить только один элемент дан-
данных, который всегда помещается поверх других элемен-
элементов. Кроме того, удалять элемент данных можно только
из верхней позиции стека.
Другие популярные структуры данных — строки и
даты, которые также рассматриваются в JavaScript как
базовые объекты. Строка — это совокупность одиночных
символов. Строка считается одиночным объектом даже
при том, что некоторые строковые функции извлекают
подстроки из строк. Объект Date включает в себя зна-
значения данных, содержащих дату и время.
Объект содержит значения данных, необходимые для
описания его природы (свойства объекта) и функции,
которые он может выполнять (методы объекта). Можно,
рассматривать объект как нечто, имеющее определенные
границы, как показано на рис. 9.1. Ядро объекта фор-
формируют его значения данных. Элементы данных объек-
объекта описывают специальные характеристики объекта и его
идентификацию. В ОО терминах объектные элементы
данных называются свойствами ('или атрибутами).
Вообще говоря, объекты поддерживают множество
функций. Видимые извне функции объекта формируют
его поведение. В ОО терминах объектную функцию ча-
часто называют методом. Метод — это часть исходного
кода, выполняющая отдельно взятую задачу, которая
относится к важным характеристикам объекта. Метод
представляет собой функцию объекта, к которой мож-
можно обратиться.
Другими словами, методы объекта определяют его
поведение, которое проявляется его видимыми и пред-
предсказуемыми действиями.
Структура объекта на рис. 9.1 показана в виде пиро-
пирога с начинкой. Методы объекта размещаются во внеш-
внешнем круге, поскольку они видимы для других объектов,
т.е. могут вызываться и выполняться для данного объек-
объекта. Атрибуты находятся во внутреннем круге.
Рассмотрим в качестве примера объекта автомобиль.
В объектно-ориентированном пространстве автомобиль
представлен как объект туСаг. Поскольку конкретный
автомобиль — это красный Renault 19 выпуска 1992 г.,
его атрибуты выглядят так:
make
model
age
color
Renault
19
1992
красный
Автомобиль может быть припаркован или находить-
находиться в движении. Это важные для него функции. На рис.
9.2 приведено графическое представление автомобиля
как объекта.
В дополнение к специфическим характеристикам и
идентифицирующим значениям, атрибут объекта может
также отображать состояние объекта или роль, которую
объект играет в данное время. Состояние и роль — спе-
специальные зависящие от времени характеристики объек-
объекта. Состояние (state) — вид элемента данных, который
изменяется во времени и в общем случае показывает
текущее значение для объекта.
РИСУНОК 9.1. Графическое представление объекта.
РИСУНОК 9.2. Графическое представление автомобиля как
объекта.
Добавим в список еще один атрибут шуСаг — position,
который всегда содержит текущее географическое поло-
Объекты со стороны клиента
жение автомобиля. Атрибут position — типичный при-
пример атрибута состояния.
Служащий может стать руководителем группы или
начальником отдела в любой момент его профессиональ-
профессиональной карьеры. Объект "служащий", таким образом, будет
содержать атрибут профессионального состояния, хра-
хранящий различные должности (руководитель группы или
начальник отдела), которые служащий мог бы занимать.
Рассмотрим пример с использованием факториалов.
На рис 9.3 показан простой графический пользователь-
пользовательский интерфейс для вычисления факториалов. Исходный
код HTML-формы приводится в листинге 9.1, Обратите
внимание, что исходный код вычислений в этот листинг
не включается.
Листинг 9.1. Программа вычисления п!
<body>
<h3>
Вычисление факториала для целых
положительных чисел
</h3>
<hr>
<form>
Введите целое число:
<input type="text" name="fn" size=">
результат:
<:.nput type="text" name="f result" size=0">
<input type="button" name="compute"
value="Вычислить n!"
onClick="xcompute (this . form) ">
</fotrm>
</body>
Вычисление факториала для целых положительных чпеел
Зведите ^ i ос число J ' результат |
РИСУНОК 9.3. Графический пользовательский интерфейс для
задачи вычисления п!
В JavaScript атрибуты объекта называются свойства-
свойствами (properties).Например, кнопка compute в приведенном
выше примере — GUI-объект JavaScript. Кнопка имеет
свойстза name и value. В рассмотренном примере
Глава 9
HTML-документа (листинг 9.1) свойства определяют-
определяются атрибутами name и value.
Пользователь может щелкать на кнопке GUI, следо-
следовательно, объект compute поддерживает функцию click.
Функция click позволяет работать с объектом compute че-
через сценарий. Все функции объекта определяют его по-
поведение. В 00 терминах функция объекта зачастую на-
называется методом. Однако в JavaScript применяется
ключевое слово function. На рис. 9.4 приводится графи-
графическое представление объекта JavaScript в виде все того
же пирога с начинкой.
РИСУНОК 9.4. Графическое представление объекта
JavaScript.
Встроенный объект "строка" — это специальный тип
объекта. Строку myString можно создать с помощью var.
Инструкция var создает новые переменные в JavaScript,,
например:
var myString = "Мой и только мой текст.
Исключительно для целей демонстрации объекта
строки";
myString, как и все строки, имеет свойство length.
Атрибут length содержит длину строки myString, в дан-
данном случае — число 75. Строки имеют несколько раз-
различных методов (подробности можно найти в главе 10),
в том числе blink(). обеспечивающий мигание строки.
Рассмотрим такой дескриптор HTML:
<blink>
Мой и только мой текст. Исключительно для
целей демонстрации объекта строки
</blink>
Следующая строка создает мигающий на экране текст
"Мой и только мой текст. Исключительно для целей
демонстрации объекта строки":
myString.blink();
Свойства объекта могут содержать простые типы пе-
переменной, такие как символы, целые числа и т.д., а так-
также другие объекты (см. рис. 9.5).
Например, объект myCar может быть определен че-
через атрибуты make, model, year, owner, где owner —
Базовое подмножество языка JavaScript
Часть II
объект персоны, определенный в свою очередь через
атрибуты name, age и address. Включение объектов в
атрибуты других объектов обычно называют агрегирова-
агрегированием (aggregation) или отношением "целое-часть" (whole-
part). Выражение "целое-часть" показывает типичный
пример содержания, когда машина состоит из несколь-
нескольких меньших частей, как автомобиль — из двигателя,
четырех колес и т.д.
Инкапсуляция
РИСУНОК 9.5. Графическое представление содержания
объектов.
В JavaScript имеется множество различных объектов,
среди которых String, Date, Button, Math. Их все мож-
можно использовать. Можно даже иметь несколько различ-
различных объектов, принадлежащих одному типу.
Например, рассмотрим HTML-форму, содержащую
несколько кнопок. Каждая кнопка обладает одними и
теми же свойствами и методами; т.е. каждая кнопка име-
имеет значение и поддерживает метод click. Объект кнопки
— это только план конструкции реальных кнопок фор-
формы. Подобная спецификация конструкции в 00 терми-
терминологии называется классом (class). Различные встроен-
встроенные объекты в JavaScript фактически и формируют
набор классов, которые можно многократно использо-
использовать. Такой набор классов называется библиотекой клас-
классов (class library). Поскольку JavaScript в действительно-
действительности не имеет дело с классами, как это имеет место в
истинных объектно-ориентированных языках, на сово-
совокупность встроенных объектов в JavaScript зачастую
ссылаются как на библиотеку объектов JavaScript
(JavaScript object library).
* СОВЕТ ¦ ¦¦ ¦¦' ¦ ¦'-1-0-4 . ¦¦"^«S*- -
Для того чтобы сберечь время и силы, затрачиваемые
на разработку программы, используйте побольше
JavaScript-объектов в подходящих ситуациях. Тщатель-
Тщательно изучите библиотеку объектов JavaScript. He изоб-
изобретайте собственные типы объектов, если в этом нет
необходимости. Повторное использование уже суще-
существующих программных компонентов — одна из наибо-
наиболее выгодных стратегий в объектно-ориентированном
программировании.
Атрибуты данных и функции объекта формируют одну
неделимую сущность, как показано на рис. 9.6. На рис.
9.6 показано то же графическое представление объекта,
которое уже встречалось ранее на рис. 9.1. Информация
о внутренней работе объекта должна быть сокрыта.
РИСУНОК 9.6. Графическое представление объекта в виде
инкапсулированной сущности.
Объект взаимодействует с внешним миром через свои
опубликованные общедоступные методы, которые и
формируют интерфейс. Рассмотрим еще раз объект
myCar.
¦Опубликованными методами объекта myCar являют-
являются park и drive; они представляют собой функции, кото-
которые поддерживает объект myCar. Эти методы называются
общедоступными (public), поскольку они доступны извне.
Они могут вызываться другими объектами для реализа-
реализации своих задач. Интерфейс объекта — это, по сути дела,
набор предлагаемых им общедоступных методов.
Противоположностью общедоступных методов явля-
являются приватные (private) методы. Приватные методы —
это вспомогательные функции объекта. Они использу-
используются только внутри конкретного объекта. Приватные
методы не могут вызываться извне. JavaScript не поддер-
поддерживает приватных методов, так что все функции, объяв-
объявленные в объекте, являются общедоступными.
Даже атрибутами объекта нельзя управлять извне. В
контексте разработки программного обеспечения такой
принцип называется сокрытием информации (information
hiding). Вернитесь к объекту myCar и расширьте список
существующих атрибутов (make, model, age, color) допол-
дополнительными атрибутами, например, engine и wheels.
Правда, лично я особенно не интересуюсь типом колес,
которые имеет myCar. Единственная вещь, которая дей-
действительно важна для меня, — что мой автомобиль ра-
работает хорошо и управляем. Смена типа двигателя не
должна повлиять на рабочее состояние myCar. Кроме
того, тип нового двигателя меня ничуть не интересует.
Все что я только хочу — так это только ездить на myCar.
Объекты со стороны клиента
Построение абстрактного представления объекта
должно предшествовать решению о его реализации. Из-
Изменения исходного кода внутренностей объекта не дол-
должны оказывать влияние на абстрактное представление.
Для создания хорошего и простого программного про-
проекта необходимо, чтобы никакая часть сложного прило-
приложения не зависела от внутренних кодов любого объек-
объекта, задействованного в приложении.
Инкапсуляция и сокрытие информации приносят
несомненную пользу в двух важных аспектах:
• Будем считать объект небольшим программным ком-
компонентом. Его легко использовать во многих ситуа-
ситуациях и местах программы. Повторное использование
программных компонентов хорошо поддерживается
через механизм инкапсуляции. Возможность повтор-
повторного использования — одно из самых больших пре-
преимуществ ООП. При правильном использовании это
позволит существенно сэкономить время и деньги
при разработке больших программных систем.
¦ • Сокрытие подробностей реализации объекта дает про-
программисту возможность позже изменять представле-
представление данных без изменений представления объекта во
внешнем мире. То же самое можно сказать и об из-
изменениях внутренних методов. Интерфейс объекта
остается тем же самым. Исходный код, касающийся
организации взаимодействия объектов, остается тем
же самым. Это означает ощутимое сокращение уси-
усилий ю поддержке объектов, равно как и большую ус-
устойчивость архитектуры программной системы по
сравнению с традиционными приложениями.
Сообщения
Если требуется, чтобы объект сделал что-нибудь полез-
полезное, ему посылают соответствующее сообщение. Сооб-
Сообщение приводит к вызову определенной функции объек-
объекта. На рис. 9.7 показана передача сообщений между
объектами.
Например, если требуется установить текущее время
в приложении, создается новый объект currTime типа
Date и в нем устанавливается текущая дата и время:
var currTime = new Date () ;
РИСУНОК 9.7. Графическое представление передачи
сообщений между объектами.
Инструкция var просто создает новую переменную.
Новые объекты создаются методом объектного типа new.
Глава 9
Метод new в данном случае создает новый объект Date.
Этот новый объект автоматически получает текущую
дату и время. Поскольку в инструкции применена опера-
операция присваивания (=), переменная currTime будет содер-
содержать объект типа Date с текущей датой и временем.
Если необходимо установить текущее время в часах
и минутах, то это делается так:
var hours ;
var minutes ;
hours = currTime.getHours();
minutes = currTime. getMinutes () ;
Все, что потребуется предпринять — это отправить
сообщение getHours объекту currTime и в качестве ре-
результата получить количество часов. Затем послать со-
сообщение getMinutes, чтобы получить количество минут.
Сообщения JavaScript — это, по сути дела, вызовы фун-
функции. Из документации по базовым объектам JavaScript
ясно, что объект типа Date понимает сообщения
getHours и getMinutes. Это означает, что объект типа
Date инициирует вызовы функций »etHours() и
getMinutes().
При создании пользовательских объектов необходи-
необходимо также определить и методы. Внутри одного метода
может возникнуть потребность в других объектах для
гния некоторых задач. Например, в приложении
для автомобильного бизнеса имеется объект currSale,
ответственный за автомобильную продажу, и метод
getSaleData(), выдающий данные по продажам. Внутри
функции getSaleData() присутствуют обращения к
объектам типа С ir и Customer. Обоим объектам посы-
посылаются сообщения с целью получения необходимой ин-
информации. Если продолжить разработку данной концеп-
концепции, можно увидеть, что объектно-ориентированное
приложение — это мир объектов, поддерживающих связь
через механизм сообщений.
Классы
Объект — это реально существующая сущность в про-
программе. Например, okButton, myWindow, currTime -
объекты. Объект — конкретная сущность, существующая
во времени и пространстве, а вот класс представляет
собой только лишь абстракцию нескольких подобных
объектов, как показано на рис. 9.8.
1РИСУН0К 9.8. Графическое представление класса.
Базовое подмножество языка JavaScript
Часть II
Объекты с одинаковыми свойствами и поведением
формируют класс или объектный тип. Класс содержит
конструктивный план принадлежащих ему объектов. Это
означает, что класс определяет количество, имена и
структуры атрибутов и методов.
Кроме того, класс обеспечивает выполнение функ-
функций. Новые объекты создаются прежде всего по опре-
определенному конструктивному плану. Каждый объект —
член некоторого класса; говорят, что объект является эк-
экземпляром (instance) данного класса. Свойство объекта
также называется переменной экземпляра (instance variable)
класса или объекта.
Например, ваш автомобиль, мой автомобиль и авто-
автомобиль вашего соседа — все являются автомобилями,
хотя имеют разные марки, года выпуска и цвета. Каж-
Каждый автомобиль обладает маркой, названием модели,
годом выпуска и цветом. Кроме того, каждый автомо-
автомобиль может двигаться или находиться в месте парковки.
Возможности и функции у них одинаковые. Класс саг
описывает характеристики данных и методы для всех ав-
автомобилей.
Язык JavaScript нельзя назвать объектно-ориентиро-
объектно-ориентированным языком, основанным на классах, поскольку он
не имеет операторов для работы с классами. Однако,
JavaScript содержит похожую концепцию — объектный
тип. Клиентские типы объектов включают в себя различ-
различные объекты GUI или базовые объекты типа Date,
String, Math. Новые объекты создаются с помощью ме-
метода new. Это верно для всех объектов. Следующий код
создает объект currTime как новый экземпляр объекта
типа Date:
var currTime = new Date ();
В JavaScript существует возможность определения
собственных объектных типов. Например, если система
должна отображать значения времени, можно создать
новый объект типа Clock. Объект Clock должен содер-
содержать часы и минуты, следовательно, свойствами объек-
объекта Clock будут hours и minutes. Методы, которые объект
Clock должен выполнять — dispIayTime() и setTime().
Следующий фрагмент демонстрирует определение
объекта типа Clock:
function Clock (hours, minutes) {
this.hours = hours;
this.minutes = minutes;
this.setTime = setTime ;
this. displayTime = displayTime;
function setTime (hours, minutes){
this.hours = hours;
this.minutes = minutes;
function displayTime(){
var line = this.hours +
+ this .minutes;
document.write <"<пгХр>Текущее время: " + line) ;
1
JavaScript является языком, основанным на экземп-
экземплярах, поскольку в нем нет конструкций классов. Осно-
Основанный на экземплярах (instance-based) — это термин ООП,
означающий, что язык программирования содержит
объекты, но не классы.
JavaScript не особенно хорошо структурирован в этом
смысле. Он не содержит классов, но имеет концепцию
типа объекта. Кроме того, новые объекты не могут со-
создаваться через существующие; они могут создаваться
только с помощью new. Компания Netscape называет
JavaScript языком программирования, основанным на
экземплярах.
Обратите внимание, что оператор function в JavaScript
предназначен сразу для многих целей. Создание новых
типов объектов означает определение функции с именем
объектного типа в качестве имени функции. 13 резуль-
результате код всегда выглядит немного запутанным с точки
зрения читателя. Свойства нового типа объекта объяв-
объявляются как параметры функции. Это означает, что есть
только один конструктор для нового класса. Конструк-
Конструктор — метод класса, который создает новый объект в
соответствие с шаблоном класса. Конструктор инициа-
инициализирует новый объект с определенными значениями
данных согласно параметрам, передаваемым в конструк-
конструктор. В следующем коде показан шаблон для объявления
нового типа объекта в JavaScript:
function Ob jectType (instVarl, instVar2, ...){
this.propertyl = instVarl;
this.property2 = instVar2;
this. me thodl = functionl ;
this.method2 = ?unction2;
functionl (paraml, param2, . . .) {
here goes the implementation
?unction2 (paraml, param2, . . .) {
here goes the implementation
Специальный объект this указывает на текущий
объект. Свойства и методы нового объекта определяют-
определяются при помощи присваивания this. Начальные свойства
для нового объекта передаются в качестве параметров
создающей функции; в шаблоне они названы instVarl и
instVar2. В определении типа объекта присутствуют
только имена методов (methodl и method2). Реализация
методов, таких как функции (function 1 и function2), рас-
рассматривается позже.
Объявления новых объектных типов лучше помещать
в раздел <head> HTML-документа, чтобы они читались
в начале процесса загрузки документа. Это гарантиру-
Объекты со стороны клиента
Глава 9
ет, что объявления класса будут известны во время ин-
интерпретации остальной части программы. Код, выпол-
выполняющий действия, обычно помещают в раздел <body>
HTML-документа.
Для более полного понимания классов рассмотрим
листинг 9.2, делающий короткое описание класса Clock
в простом, но полном HTML-документе.
Листинг 9.2. Создание объекта Clock и отображение
результатов на Web-странице.
<html>
<head>
<title>JavaScript Unleashed</title>
ocript type="text/javascript">
function Clock (hours, minutes) {
this, hours = hours;
this, minutes = minutes;
this . setTime = setTime;
this. displayTime = displayTime;
i
function setTime (hours, minutes) {
this.hours = hours;
this, minutes = minutes;
function displayTime (> {
var line = this.hours + ":" + this.minutes;;
document.write ("<Ьг>Текущее время: " +
line) ;
,1
II—>
</script>
</head>
<body>
<script type="text/javascript">
var currTime = new Date (> ;
var myClock = new Clock (currTime. ge tHours () ,
^currTime. getMinutes ()) ;
myClock.displayTime();
II—>
</script>
</body>
</html>
При помощи следующего оператора в разделе <body>
документа создается и инициализируется в соответствии
с текущим системным временем новый объект myClock
типа Clock:
var myClock = new Clock (currTime.getHours (),
currTime.getMinutes() );
«ПРИМЕЧАНИЕ !' /V . ' Ч| ; , !%
Поскольку JavaScript — это язык, основанный на экзем-
экземплярах, в нем имеется возможность расширения лю-
любого существующего объекта новыми свойствами и ме-
методами во время выполнения. При этом новые
возможности добавляются только в один определен-
определенный объект и не затрагивают другие объекты того же
типа.
Объекты JavaScript
Как обсуждалось в начале этой главы, JavaScript — не
объектно-ориентированный язык, а язык, лишь только
основанный на объектах. Он содержит понятия объек-
объектов, свойств, методов и инкапсуляции. Однако он не
поддерживает строгую типизацию, поскольку перемен-
переменные не объявляются вместе с типами. Например, пере-
переменная currTime объявляется так:
var currTime;
Здесь не указывается тип переменной (например, int,
char или какой-то объектный). В переменную currTime
можно поместить значение любого типа, в том числе и
объектного.
Интерпретация всегда предполагает динамическое
связывание во время выполнения. Динамическое связы-
связывание означает, что до выполнения программы типы всех
переменных и выражений не известны.
JavaScript не поддерживает концепцию классов, а
вместо этого в значительной степени основывается на
экземплярах. Наиболее существенный недостаток этого
— отсутствие наследования. Потому-то JavaScript и от-
относится к категории основанных на объектах, но не
объектно-ориентированных, языковпрограммирования.
Точечная нотация
Доступ к свойствам и методам объекта в JavaScript осу-
осуществляется в соответствие с точечной нотацией. Эта
запись, показанная в следующем синтаксическом при-
примере, обеспечивает иерархический способ доступа к
свойствам и выполнениям методов.
имяобгьекта. иыяСвойства
имяОбгьекта. имяМетода (аргументы)
К текущему объекту обращаются через специальную
переменную this. В объявлении типа объекта (класса)
переменная this ссылается на сам объект. Этот объект
(текущий объект) является объектом, для которого
объявляется метод.
В типе объекта, определяющего комплексные числа,
метод сложения двух комплексных чисел записывается
следующим образом:
// сложить х и у и вьщать rz
function add(z){
var a ;
var b ;
var rz;
a = this.real + z.getReal(z);
b = this.img + z.getlmg(z);
rz = new Complex (a,b) ;
return rz;
Базовое подмножество языка JavaScript
Часть II
Оператор, вычисляющий сумму чисел х и у записы-
записывается так:
x.add(y);
В методе add конструкция this.real указывает на свой-
свойство real текущего объекта х, в данном случае — x.real.
Точно так же this.img указывает на свойство img объек-
объекта x.img, которое хранит мнимую часть х.
Исследование объектной модели JavaScript
JavaScript-объекты — действительно объекты, в том
смысле, что они имеют свойства и методы и могут отве-
отвечать на события. Однако, как было показано в этой гла-
главе, JavaScript не имеет существующей в ООП возможно-
возможности наследования. При изучении объектной модели
JavaScript необходимо рассматривать ее как раз в этом
контексте. Вместо иерархии классов, которая является
основой наследования, объектная модель JavaScript -
это иерархия контейнеров (см. рис. 9.9). Если вы хоро-
хорошо знакомы с объектно-ориентированными языками
программирования, такими как Java, C++ или Delphi,
то это самое значительное уточнение, о котором необ-
необходимо постоянно помнить при разработке программ на
JavaScript.
Принцип отношения содержания (containershipJsaKnm-
чается в том, что один объект содержит другие объекты.
На рис. 9.9 отношения между объектом Form и объек-
объектом Radio не являются отношениями предка и потомка
(или класса и подкласса), это отношения контейнера (со-
(содержащего) и содержимого. Иначе говоря, между этими
объектами нет родственных связей, поскольку ни один
из них не наследуется от другого. В результате один
объект не может наследовать свойства и методы друго-
другого, поэтому в такой иерархии нельзя разбить объекты на
подклассы.
РИСУНОК 9.9. Иерархия
встроенных JavaScript-объектов.
j- 0 location
Н-© document
: - -0 ancha
! r© applet
;
в-
j
i™
-.Щ button
Ш checkbox
0 NaUpload
Ш hidden
0 option
raria
Н
. Ш *иЬ«й
- m м
Я
H в% Language
;¦& tov
'-Q Funclkm
Q Dale
0 Math
Отношения содержания в JavaScript
Отношения содержания — важный для понимания тер-
термин. При разработке JavaScript-сценариев и прикладных
программ необходимо не только понимать, как один
объект соотносится с другим, но и (для практических
целей) знать, каким образом ссылаться на объект. Как
упоминалось ранее в главе (при обсуждении точечной
нотации), при ссылке на свойства или методы объекта
точка используется для обозначения принадлежности.
Например, в следующей примере метод write принад-
принадлежит объекту Document:
document, write ("<М>По небу плавно летел
Однако, эту принадлежность можно расширить с
целью включения не только свойств и методов данного
объекта, но и других объектов, содержащихся в нем. При
необходимости возврата имени объекта Button восполь-
воспользуйтесь следующей строкой:
ButtonName = document . f ormMain. okButton. name г
document — заданное по умолчанию имя объекта
Document, a formMain — имя объекта Form, который
содержит кнопку okButton.
При работе с объектами важно знать, когда есть не-
необходимость в ссылке на содержащий объект и когда
такой необходимости нет. Например, объект Window -
по существу, объект самого высокого уровня, с которым
можно работать со стороны клиента. Большинство ссы-
ссылок на объекты выполняются в пределах их отношений
содержания. Предыдущий пример document.write мож-
можно записать и по-другому:
window, document.write("<Ы>По небу плавно летел
**напильник</Ы>") ;
Хотя в большинстве случаев ссылку на window мож-
можно проигнорировать, она станет необходимой при работе
со множеством окон или фреймов. Например, в листинге
9.3 создается объект Window в функции showStats(), за-
затем этот объект разрушается в функции closeWindow().
Листинг 9.3. Создание нового окна и запись в него
информации.
<html>
<head>
<title> JavaScript Unleashed</title>
<script type="text/javascript">
<! —
var windowObject
function showStatsO {
windowObject = window . open ("", "ViewStats",
"toolbar=0, width=300, height=50,
resizable=l");
windowObject. document.write ( "<Ь2>Вэтом
месяце мы перевыполнили план по
Объекты со стороны клиента
составлению планов на следующий
месяц. Примите поздравления!</h2>")
J
function closeWindow()(
windowObject.close()'
1
// ~>
</script>
</head>
<body OnUnload="closeWindow(>">
Щелкните на следующей кнопке для
получения статистики за месяц.
<fortn>
<input type="button" value="Show Stats"
onclicfc="showStats()">
</form>
</body>
</html>
He следует забывать, что объект Window — един-
единственный высокоуровневый объект, который можно не
указывать в ссылках на другие объекты. Например, для
ссылки на HTML-форму необходимо добавить ее роди-
родительский объект (Document) для обозначения, на какой
объект выполняется ссылка. Если требуется сослаться на
первую форму в объекте Document и подсчитать коли-
количество элементов в ней, используется следующая коман-
команда:
var пшп = document. forms [ 0 ] . length ;
Даже в случае, когда форма имеет установленный
атрибут name, все равно следует добавлять ссылку на
родительский объект:
var nuift = document. queryForm. length;
Свойства
Свойства в JavaScript похожи на атрибуты данных
объекта. Свойства объекта выражают характеристики и
идентификацию данного объекта. В дополнение к опре-
определенным характеристикам и идентифицирующим зна-
значениям, атрибуты объекта могут также обозначать состо-
состояние объекта или роль, которую объект играет в данное
время.
Ниже показано, как при разработке проекта можно
определить тип объекта Project:
function Project (members, leader,
currentMilestone, time) {
this, members = members;
this, leader = leader;
this . currentMilestone = currentMilestone;
this . time = time ;
}
После этого можно создавать специфическое про-
программное обеспечение проекта myProject:
Глава 9
var myProject = new Project (memberGroup,
"Шариков", "начало", currTime) ;
Объект myProject состоит из группы людей, описан-
описанных в объекте memberGroup. Руководитель проекта -
Шариков, текущий этап — начало (т.к. проект начат не-
недавно). Переменные memberGroup и currTime содержат
и другие объекты, которые здесь не описаны.
Помимо точечной нотации, существуют и другие
способы обращения к свойствам объекта. Следующий
пример показывает способ доступа к объекту как к мас-
массиву:
иняОб'ьекта [ "имяСвойства" |
А вот доступ через индексацию:
имнОбъекта[целочисленкыйИндекс]
Последняя методика возвращает атрибут с номером
целочисленныйИндекс.
Вне объекта не стоит обращаться к атрибутам объекта
непосредственно, поскольку это противоречит принци-
принципу инкапсуляции. (Обратитесь в раздел "Инкапсуляция"
выше в этой главе.)
Методы
Метод означает определенный сервис, который класс
предоставляет другим объектам. В общем случае, мето-
методы можно разбить на следующих четыре категории:
• Модификатор (modifier). Это метод, который изменя-
изменяет состояние объекта. Модификатор изменяет значе-
значение одного и более атрибутов данных объекта. Рас-
Распространенная функция модификатора — функция
set, устанавливающая значение определенного атри-
атрибута объекта.
• Селектор (selector). Это метод, который ссылается на
атрибуты данных объекта, но не осуществляет ника-
никаких изменений. Важная функция селектора — функ-
функция get, которая возвращает (получает) значение оп-
определенного атрибута объекта.
¦• Итератор (iterator). Это метод, который обращается
к всем частям объекта, т.е. ко всем атрибутам данных,
в некотором определенном порядке. В соответствие со
своим названием, итератор выполняет итерации по ат-
атрибутам данных объекта.
• Конструктор (constructor). Это метод объектного
типа, который создает новый объект по шаблону
класса. Конструктор инициализирует новый объект
определенными значениямиданных,полученнымив
области параметров метода.
В JavaScript объектные методы — нормальные фун-
функции JavaScript. Обращаться к ним можно в соответствие
с точечной нотацией:
Базовое подмножества языка JavaScript
Часть II
имяОб-ьехта.имяфункции (аргументы)
Напомним, что HTML-файл содержит раздел <body>,
который создает специальный объект Document на
JavaScript. Объект Document поддерживает метод write().
При помощи этого метода можно динамически расши-
расширять текстовое содержимое HTML-страницы через сце-
сценарии JavaScript. Приведенный ниже оператор печата-
печатает строку Пример строки:
document.write("Пример строки");
При создании новых объектных типов в JavaScript
применяется такой шаблон:
function ObjectType(instVarl,
this.property1 = instVarl;
this . property2 = instVar2;
this.methodl = function].;
this.method2 = function2;
instVar2,
f
b = this.img + z.getlmg
rz = new Complex (a,b);
return rz;
(z) ;
// методы для вычитания, умножения и деления
// комплексных чисел пока не реализованы
Объектный метод add принимает один параметр типа
Complex. Сложение двух комплексных чисел х и у вы-
выполняется следующим образом:
var х = new Complex (a,b) ;
var у = new Complex(c,d) ;
var z = x.add(y) ;
Внутри объявления функции на свойства текущего
объекта можно ссылаться через специальный объект this:
а = this, real + z.getReal(z) ;
События
functionl(paraml, param2, . . .){
здесь следует реализация
1
function2(paraml, param2, . . .){
здесь следуем реализация
]
Реализация методов объекта приводится позже в
объявлении функции по всем правилам для обычных
функций JavaScript. Параметрами функции могут быть
строки, числа или целые объекты. Следующий фрагмент
кода демонстрирует пример определения класса, пред-
представляющего комплексные числа:
// определение комплексных чисел
function Complex(real, img) {
this. real = real;
this.img = img;
this.getReal = getReal;
this.getlmg = getlmg;
this, add = add;
this.subtract = subtract;
this.multiply = multiply;
this.divide = divide;
i
II получить вещественную часть
function getReal () {
return thi s.real;
// получить мнимую часть
function getlmg () f
.return this. img;
}
II сложить x и у и получить rz
function add(z){
var a;
var Ь;
var rz ;
a = this.real + z.getReal (z)
Зачастую операторы JavaScript создают или управляют
элементами графического пользовательского интерфей-
интерфейса, такими как формы или окна. На рис. 9.10 показан
простой графический пользовательский интерфейс
(GUI).
Листинг 9.4 предназначен для создания формы, по-
показанной на рис. 9.10. Некоторые части еще не полнос-
полностью запрограммированы, поэтому они выдают сообще-
сообщение Функция пока не реализована, так что заходите
позже.
Листинг
9.4.
GUI.
Простой
<html>
<head>
<title>npraiep GOK/title>
<script type="text/javascript">
У/ функция поиска пока не реализована;
// выдать соответствующее сообщение
function f search (aForm) {
alert ("Функция пока не реализована,
^¦так что заходите позже") ;
// функция отображения опций пока
// не реализована
function foptions(aForm) {
alert ("функция пока не реализована,
'•так что заходите позже") ;
}
II—>
</script>
¦</head>
<body>
<h3>
Поисковая форма
</h3>
<hr>
<form>
Най*ги:
Объекты со стороны клиента
<input type="text" name="tfield" size=0">
<br>
<input type="radio" name="search">
Простой поиск
<br>
<input type="radio" name="search">
Распдфенный поиск
<br>
<:input type="button" name="bsearch"
уа1ие="Поиок"
onclick="fsearch(this.form)">
<input type="button" name="boptions"
value=" Дополнительные оипут"
onclick="foptions(this.form)">
</body>
</html>
Поисковая форма
Найти (
Л Простой imi
г Расширенный поиск
РИСУНОК 9.10. Графический пользовательский интерфейс.
В контексте GUI событие — это результат определен-
определенных пользовательских действий. Событие генерируется
тогда, когда пользователь совершает действие. Напри-
Например, когда пользователь щелкает на кнопке интерфей-
интерфейса, генерируется событие click. Кдругим событиям GUI
относятся: щелчок на флажке, выбор строки из списка,
двойной щелчок на элементе, открытие или закрытие
окна.
Наилучший способ управления GUI реализуется с
использованиемпрограммирования,управляемогособы-
тиями События могут перехватываться (captured) и об-
обрабатываться обработчиками событий JavaScript. Допол-
Дополнительная информация может быть найдена в главе 14.
В общем случае, события не рассматриваются как
особенности, относящиеся к ООП, хотя некоторые
объек"но-ориентированные языки программирования
также поддерживают события. Большинство элементов
U1 (экна, кнопки, текстовые поля, флажки) реагиру-
реагируют на определенные события. Эти элементы существу-
существуют в JavaScript как встроенные объектные типы. Напри-
Глава 9
мер, в JavaScript можно создать кнопку, генерирующую
событие onClick в результате щелчка на ней:
<form>
<input type="button" value="Hai»ei меня"
onClick="myfunc()">
</form>
В этом примере функция myfunc() выполняется, ког-
когда пользователь выполняет щелчок на кнопке "Нажми
меня". Некоторые встроенные объекты имеют методы,
эмулирующие события. Например, в объекте Checkbox
определен метод click(), который эмулирует щелчок на
флажке. То же самое можно сказать и об объекте Button.
Метод эмуляции события не генерирует событие, объяв-
объявленное в другом месте для объекта. Если с событием
необходимо связать определенное действие, обрабаты-
обрабатывать такое событие придется явно.
Поскольку обработчики событий разрешены только
для НТМ-дескрипторов, все недавно созданные объек-
объектные типы обработчиков событий не имеют. Более под-
подробную информацию по событиям и обработчикам со-
событий в JavaScript можно найти в главе 14.
Дополнительная информация
об объектах
При детальном рассмотрении полной иерархии объек-
объектов JavaScript несложно заметить, что большинство
объектов являются либо объектами со стороны клиента,
либо со стороны сервера, либо же базовыми. В этом раз-
разделе книги описаны объекты со стороны клиента и пред-
представлены свойства и методы для каждого из них. Главы
10 и 12 посвящены другим типам объектов JavaScript.
ПРИМЕЧАНИЕ
В дополнение к упомянутым трем типам объектов
Microsoft предлагает и ряд собственных языковых рас-
расширений для Windows Scripting Host. Эти расширения
дают возможность пользователям организовывать до-
доступ к файлам, перемещать папки и открывать при-
приложения практически так же, как и пакетные файлы
(но эти средства мощнее). Расширения Microsoft в
книге не рассматриваются.
¦ -¦ .....
Встроенные в JavaScrip функциональные возможно-
возможности со стороны клиента всецело зависят от действий,
выполнение которых обеспечивают HTML-страницы.
Первый набор объектов вообще зависит от вида браузе-
браузера и HTML-дескрипторов в нем. На рис. 1> ! ! показан
исходный текст HTML для некоторой Web-страницы с
помеченными при помощи стрелок объектами JavaScript.
Как видно из рисунка, большинство объектов
JavaScript — объектные представления дескрипторов
HTML. В табл. 9.1 приводится список объектов со сто-
Базовое подмножество языка JavaScript
Часть II
рОНы клиента и соответствующих им дескрипторов
HTML.
Document Form
II
Form —
>U nt кии J]t* to ftte a 4at«tl*a picture ci см leOWJ ос Какаса Hat
Text Tent
Button
РИСУНОК 9.11. Очень многие объекты JavaScript
соответствуют дескрипторам HTML.
Таблица .1. Объекты JavaScript со стороны
клиента и соответствующие им дескрипторы
HTML.
JavaScript-объект
Button
Checkbox
Hidden
Fileupload
Password
Radio
Reset
Select
Листинг 9.5. Доступ
Соответствующий
HTML-дескриптор
< input type:
< input type=
<input type="hidden":
< input type=
<inputtype="password">
<input type="radi
< input type=" reset" >
<select>
к свойствам объекта navigator.
JavaScript-объект
Соответствующий
HTML-дескриптор
Frame
Document
Layer
Link
Image
Area
Anchor
Applet
Plugin
Form
Submit
Text
Textarea
Option
<frame>
<body>
<layer> or <ilayer>
<a href="
<img>
<map>
<a name
< applet >
<embed>
<form>
< input type=
<input type=
<textarea>
<option>
Во время исследований этих объектов обратите вни-
внимание на различные способы, по которым они представ-
представляются пользователям и разработчикам.
Объект navigator
Объект navigator, смело названный так изобретателя-
изобретателями JavaScript (Компания Netscape), представляет ис-
используемый браузер. С помощью этого объекта можно
получить информацию об имени и версии браузера, а
также другую дополнительную информацию (см. рис.
9. 12). Объект navigator поддерживается как в Netscape
Navigator, так и в Microsoft Internet Explorer. Этот объект
имеет еще и два дочерних объекта: Plugin и Mimetype.
Код, который был использован для получения ин-
информации, показанной на рис. 9.12, При !н в листин-
листинге 9.5. Таблица 9.2 содержит список методов и свойств
объекта navigator.
<html>
<head>
<title>JavaScript
</head>
<body>
<script language^"JavaScript">
nt.write (" ) + navigator. appCodeName + "
) + navig itor. appName + "<bi
document.write ("navigator.appVersii ) + navigator appVersion[srj + "<br>
".bold(> + navigator.language [sr] + "<br>") ;
I + navigator 5 + "<br>
+ navigator.platfo a + "<bi
) + navigator.plugins + "
it.write ("navigator ) + navigator . userAgent + "
document, closet) ;
Объекты со стороны клиента
Глава 9
II—>
</script>
</body>
</html>
Таблица 9.2. Методы и свойства объекта navigator.
Тип
Элемент
Описание
Функция, проверяющая, поддерживается ли данный браузер Java. Метод
в JavaScript 1.1.
Перестраивает массив установленных подключаемых модулей. Метод появился в
JavaScript 1.2.
Позволяет читать и устанавливать пользовательские предпочтения в браузере.
Метод появился в JavaScript 1.2.
Проверяет, включено ли искажение нежелательных данных. Метод появился в
JavaScript 1.1.
Представляет кодовое имя браузера.
Представляет официальное имя браузера.
Выдает информацию о версии браузера.
Выдает язык браузера. Свойство появилось в JavaScript 1.2.
Ссылается на массив объектов Mimetype, который содержит все поддерживаемые
данным браузером типы MIME. Свойство появилось в JavaScript 1.1.
Строка, указывающая на платформу, на которой выполняется браузер. Свойство
появилось в JavaScript 1.2.
Ссылается на массив объектов Plugin, который содержит все подключаемые
модули браузера. Свойство появилось в JavaScript 1.1.
Строка, содержащая значение заголовка "user-agent".
Метод
Свойство
javaEnabled()
появился
plugins.refreshQ
preference()
taintEnabled()
appCodeName
appName
appVersion
language
mimeTypes
platform
plugins
userAgent
p: Netscape
navigatorappVcrriom A OS flerj (WinHT, I .Na*)
navigator.hiiiiuagu: en
navigator.minieTypes: [ubjectMiitieTypeAiray]
navifsitor.plarronn: Win32
iviripator.pl» jini: [object Pinguid»
MTigator.userAa8nt: МояЛзЛ OS [en] C.VinrTT. I :Mav)
.'; I.'::-'- ¦ >¦¦
:¦:¦¦¦¦¦::.¦.
РИСУНОК 9.12. Использование объекта navigator для
получения информации о браузере
Объект Mimetype
Объект MIME (multipurpose Internet mail extensions, мно-
многоцелевые почтовые расширения II ;t), который яв-
является подобъектом объекта navigator, появился в.
JavaScript 1.1. Объект позволяет обращаться к информа-
информации о MIME-типах, поддерживаемых подключаемыми
модулями. Как и объект Plugin, он не поддерживается
Internet Explorer. Свойства объекта Mimetype перечисле-
перечислены в табл. 9.3.
Таблица 9.3. Свойства объекта Mimetype.
Свойство Описание
description Содержит описание Mimetype.
enabledPlugin Содержит подключаемый модуль для
определенного Mimetype.
suffixes Содержит расширение файла для Mimetype.
type Содержит строку, представляющую
Mimetype.
Объект Plugin
Объект Plugin, появившийся в JavaScript J. 1 и не поддер-
поддерживаемый Internet Explorer, создается при наличии под-
подключаемых модулей, установленных в браузере. Этот
объект содержит массив элементов и MIME-типоб об-
обрабатываемых подключаемыми модулями. Как показа-
показано в табл. 9.4, он имеет только свойства, однако в объек-
объекте navigator существует метод pjugins.refresh(), который
Базовое подмножество языка JavaScript
Часть II
дает возможность повторно построить массив подклю-
подключаемых модулей. На рис. 9.13 показан пример того, как
можно задействовать этот объект и метод document.writeQ
для отображения информации об установленных под-
подключаемых модулях.
Java ..2.2 for Nei
RealPlayci(tm) Livc'-Jwm
ф №ms«tnr vid> JDK/.TRE 1.22
mpatm-with JDK/JRE l.Z 2 (DLL Helper)
rape Navigator wHh ЛЖЛНЕ 1.12 fl>LL Helper)
t-Elrtbledplug In
Netscape Navigator Plug-in for Acrobat
Shockwave IJash з о г?
Siwnd Player to Netscape Navigator, v. | 1,1515
QuickTime 'lug-In tor Win32 v 1 1 и
14 phiaa DLL
РИСУНОК 9.13. Отображение установленных подключаемых
модулей при помощи объекта Plugin.
Таблица 9.4. Свойства объекта Plugin.
Свойство
Описание
description Ссылается на описание подключаемых
модулей.
filename Ссылается на имя файла подключаемого
модуля.
length Ссылается на количество MIME-типс
содержащихся в массиве.
name Ссылается на имя подключаемого модуля.
Объект Window
Web-браузеры (Netscape Navigator, Microsoft Internet
Explorer или любой другой) представляются пользовате-
пользователям в окне. Все, что пользователь делает с браузером,
выполняется в пределах этого окна. Кроме того, каждый
экранный элемент также содержится внутри этого окна.
Таблица 9.5. Свойства и методы объекта Window.
Объект Window использует прямое значение этой
метафоры (см. рис. 9.14). Он считается самым главным
объектом в иерархии объектов со стороны клиента в
JavaScript и содержит все другие клиентские объекты
{кроме собственно объекта navigator). Точно так же, как
можно открывать множество окон в браузере, в коде
можно работать сразу со многими объектами Window.
Кнопка Текст Ссылка
РИСУНОК 9.14. Объект Window содержит все )ругие
элементы — как визуально, так и в коде.
Объект Window не имеет эквивалентного дескрипто-
дескриптора HTML, тем не менее, он создается при открытии
нового окна браузера. Следующий пример показывает,
как работать с объектом Window в коде JavaScript. Пред-
Предположим, что требуется добавить текст в строку состоя-
состояния окна:
window.status = 'Добро пожаловать на мою
домапшюю страницу' ' ;
Подобно другим объектам, Window имеет несколько
различных свойств и методов. Поскольку Window — это
объект самого верхнего уровня, некоторые из объектов
могут вызываться или упоминаться без window, перед
ними. Пример — метод alert(). В табл. 9.5 перечислены
все методы и свойства объекта Window.
Тип
Элемент
Описание
Метод
atob()
alertO
back()
blur()
Декодирование строки, закодированной с помощью кода base 64. Метод появился
в JavaScript 1.2.
Выводит диалоговое окно предупреждения, отображающее переданную в метод
текстовую строку.
Загружает предыдущую страницу вместо экземпляра window. Метод появился в
JavaScript 1.2.
Убирает фокус из окна.
Объекты со стороны клиента
Глава 9
Элемент
Описание
btob()
captureEvents()
clearlnterval()
clearTimeout()
close()
confirm()
crypto. random()
crypto.signText()
disableExternalCapture()
enableExtemalCapture()
find()
focus()
forward ()
handleEvent()
ihome()
moveByf)
moveToQ
open{)
,print()
prompt()
releaseEvents()
resize By().
resizeTo()
route Event()
scrollByO
scrollToQ
setHotKeys()
setlnterval()
setResizableQ
Кодирует строку с использованием кода base 64. Метод появился в JavaScript 1.2.
Заставляет окно перехватывать все события указанного типа. Метод появился в
JavaScript 1.2.
Обнуляет интервал, установленный методом setlntervalQ. Метод появился в
JavaScript 1.2.
Удаляет тайм-аут, установленный методом setTimeout().
Закрывает экземпляр окна. Метод появился в JavaScript 1.1.
Отображает диалоговое окно подтверждения.
Генерирует случайную строку данных заданной длины. Метод появился
в JavaScript 1.2.
Возвращает строку закодированных данных, которая представляет указанный
объект. Метод появился в JavaScript 1.2.
Запрещает внешний перехват событий. Метод появился в JavaScript 1.2.
Разрешает внешний перехват событий для страниц, загруженных с других
серверов. Метод появился в JavaScript 1.2.
Отображает диалоговое окно поиска, в которое можно вводить текст для поиска
на текущей странице. Метод появился в JavaScript 1.2.
Устанавливает фокус на указанное окно. Метод появился в JavaScript 1.1.
Загружает следующую страницу вместо экземпляра window. Метод появился в
JavaScript 1.2.
Вызывает обработчик для передаваемого события. Метод появился в JavaScript
1.2.
Загружает определенную пользователем страницу в экземпляр window. Метод
появился в JavaScript 1.2.
Перемещает окно в соответствие с заданным смещением. Метод появился в
JavaScript 1.2.
Перемещает окно в заданную позицию. Метод появился в JavaScript 1.2.
Открывает новый экземпляр окна.
Вызывает диалоговое окно печати, позволяющее вывести на печать текущее окно.
Метод появился в JavaScript 1.2.
Отображает диалоговое окно приглашения на ввод команды.
Освобождает захваченные события указанного типа. Метод появился
в JavaScript 1.2.
'Изменяет размеры окна в соответствие с указанным смещением. Метод появился
в JavaScript 1.2.
Изменяет размеры окна до указанных. Метод появился в JavaScript 1.2.
Передает события указанного типа на обработку собственными средствами.
Метод появился в JavaScript 1.2.
Выполняет прокрутку документа в окне к указанной позиции. Метод появился в
JavaScript 1.1.
Выполняет прокрутку документа в окне в соответствие с заданным смещением.
Метод появился в JavaScript 1.2.
Выполняет прокрутку документа к указанной позиции в окне. Метод появился
в JavaScript 1.2.
Назначает или отменяет назначение комбинаций клавиш окна в случае отсутствия
меню. Метод появился в JavaScript 1.2.
Вызывает функцию или вычисляет выражение каждый раз по прошествии
определенного числа миллисекунд. Метод появился в JavaScript 1.2.
Определять, может ли пользователь изменять размеры окна. Метод появился
в JavaScript 1.2.
Базовое подмножество языка JavaScript
Часть II
Тип Элемент
Описание
setTimeout()
setZOptionsQ
stop()
Свойство closed
crypto
defaultStatus
document
frames
history
innerHeight
«nnerWidth
length
location
locationbar
locationbar.visible
menubar
menubar.visible
name
offscreenBuffering
opener
outerHeight
outerWidth
pageXOffset
pageYOffset
parent
personal bar
personalbar. visible
screenX
screenY
scrollbars
scrollbars.visible
Вызывает функцию или выполняет выражение по прошествии определенного числа
миллисекунд.
Позволяет определять z-порядок расположения элементов в окне. Метод появился
в JavaScript 1.2.
Останавливает загрузку элементов в текущем окне. Метод появился в JavaScript 1.2.
Определяет, был ли экземпляр window закрыт.
Обеспечивает доступ к возможностям кодирования Navigator. Свойство появилось
в JavaScript 1.2.
Определяет заданное по умолчанию сообщение в строке состояния окна.
Ссылается на всю информацию относительно документа, находящемся в данном
окне. Обратитесь к описанию объекта Document для получения дополнительной
информации.
Ссылается на всю информацию относительно фреймов данного окна. Обратитесь
к описанию объекта Frame для получения дополнительной информации.
Ссылается на URL-адреса, которые посетил данный пользователь. Свойство
появилось в JavaScript 1.1.
Содержит высоту в точках области отображения, занятой текущим окном.
Свойство появилось в JavaScript 1.2.
Содержит ширину в точках области отображения, занятой текущим окном.
Свойство появилось в JavaScript 1.2.
Определяет количество фреймов в текущем окне.
Содержит текущий URL страницы, загруженной в окно.
Ссылается на окно адреса в браузере. Свойство появилось в JavaScript 1.2
Содержит логическое значение, которое сообщает, видно ли пользователю окно
адреса браузера. Свойство появилось в JavaScript 1.2.
Ссылается на меню браузера. Свойство появилось в JavaScript 1.2.
Содержит логическое значение, которое сообщает, видно ли пользователю меню
браузера. Свойство появилось в JavaScript 1.2.
Содержит имя окна.
Содержит логическое значение, которое позволяет определять, выполнялось ли
обновление окна в экранном буфере. Свойство появилось в JavaScript 1.2.
Содержит имя окна, из которого было открыто вторичное окно.
Содержит высоту в точках внешней области текущего окна. Свойство появилось
в JavaScript 1.2.
Содержит ширину в точках внешней области текущего окна. Свойство появилось
в JavaScript 1.2.
Содержит координату х текущего окна. Свойство появилось в JavaScript 1.2.
Содержит координату у текущего окна. Свойство появилось в JavaScript 1.2.
Ссылается на родительское окно, которое отображает текущий фрейм.
Ссылается на полосу Personal браузера. Свойство появилось в JavaScript 1.2.
Содержит логическое значение, которое сообщает, видна ли пользователю полоса
Personal браузера. Свойство появилось в JavaScript 1.2.
Ссылается на координату х на левого верхнего угла окна браузера. Свойство
появилось в JavaScript 1.2.
Ссылается на координату у на левого верхнего угла окна браузера. Свойство
появилось в JavaScript 1.2.
Ссылается на полосы прокрутки браузера. Свойство появилось в JavaScript 1.2.
Содержит логическое значение, которое сообщает, видна ли пользователю полосы
прокрутки. Свойство появилось в JavaScript 1.2.
Объекты со стороны клиента
Тип
Элемент1
Глава 9
Описание
self
status
statusbar
statusbar.visible
toolbar
toolbar.visible
top
window
Ссылается на текущее окно.
Ссылается на сообщение, отображаемое в строке состояния окна.
Ссылается на строку состояния браузера. Свойство появилось в JavaScript 1.2.
Содержит логическое значение, которое сообщает, видна ли пользователю строка
состояния браузера. Свойство появилось в JavaScript 1.2.
Ссылается на панель инструментов браузера. Свойство появилось в JavaScript 1.2.
Содержит логическое значение, которое сообщает, видна ли пользователю панель
инструментов браузера. Свойство появилось в JavaScript 1.2.
Ссылается на родительское окно, отображающее текущий фрейм.
Ссылается на текущее окно.
Объекты верхнего уровня
Объект верхнего уровня со стороны клиента Window
содержит четыре дочерних объекта. Эти объекты явля-
являются основой для всех других объектов, с которыми при-
придется сталкиваться при программировании на JavaScript.
Очень важно хорошо знать и сами объекты, и способы
их совместного функционирования. Список объектов
выглядит так:
Document
• Frame
• History
Location
Объект Document
Несмотря на то что объект Window является объектом
верхнего уровня в иерархии, Document, возможно, -
один из наиболее важных. Объект Document, показан-
показанный на рис. 9.15, ответственен за все фактическое содер-
содержимое, отображаемое на данной странице. При исполь-
Таблица 9.6. Методы и свойства объекта Document.
зовании объекта Document появляется возможность ото-
отображать динамические HTML-страницы. Все, что содер-
содержится в документе — это типовые элементы пользова-
пользовательского интерфейса Web-приложения. В табл. 9.6
перечислены методы и свойства объекта Document.
Text
Checkbox-
. tt.tv, 'с* it*
Information Survey
Li ЕЬгШ&ол 4ut ш!ш.1Ьи ш
Kn Г 5-10 hoius Г 10-20 burs с Ыме tt
РИСУНОК 9.15. Объект Document отвечает за содержимое
страницы.
Тип
Элемент
Описание
Методы Захватывает события, которые будут обрабатываться документом. Метод появился в
JavaScript 1.2.
close() Закрывает поток вывода документа.
Позволяет выборочно применять стиль к HTML-элементу, который появляется в
определенном контексте. Метод появился в JavaScript 1.2.
getSelection() Возвращает выделенный текст. Метод появился в JavaScript 1.2.
Вызывает обработчик для указанного события. Метод появился в JavaScript 1.2.
ореп() Открывает поток вывода документа.
releaseEvents() Освобождает события, захваченные документом. Метод появился в JavaScript 1.2.
routeEvent() Перенаправляет перехваченные события к другим объектам. Метод появился в
JavaScript 1.2.
write() Добавляет текст к документу.
Базовое подмножество языка JavaScript
Часть II
Элемент
Описание
writeln() Добавляет к документу текст и символ новой строки.
Свойства alinkColor Цвет активной ссылки.
all Массив всех HTML-дескрипторов документа. Метод появился в Jscript 3.0.
anchors Массив объектов Anchor. Свойство появилось в JavaScript 1.2.
applets Массив объектов Applet. Свойство появилось в JavaScript 1.1.
bgcolor Цвет фона документа.
classes Массив классов таблиц стилей. Свойство появилось в JavaScript 1.2.
cookie cookie-набор, связанный с документом.
domain Домен документа. Свойство появилось в JavaScript 1.1.
embeds Массив встроенных объектов. Свойство появилось в JavaScript 1.1.
fgcolor Цвет текста в документе.
forms Массив объектов Form.
formName Определяет экземпляр Form, к которому обращаются с использованием атрибута
name в дескрипторе <form>. Свойство появилось в JavaScript 1.1.
height Определяет высоту документа в точках. Свойство появилось в JavaScript 1.2.
ids Массив идентификаторов таблиц стилей. Свойство появилось в JavaScript 1.2.
images Массив объектов Image. Свойство появилось в JavaScript 1.2.
lastModified Дата последней модификации документа.
layers Массив объектов Layer. Свойство появилось в JavaScript 1.2.
linkColor Цвет ссылок.
links Массив объектов Link.
plugins Массив подключаемых модулей. Свойство появилось в JavaScript 1.1.
referrer URL документа, с которым был связан текущий документ.
tags Массив дескрипторов таблиц стилей. Свойство появилось в JavaScript 1.2.
title Заголовок документа.
URL URL текущего документа. Свойство появилось в JavaScript 1.1.
vlinkColor Цвет посещенных ссылок.
width Определяет ширину документа в точках. Свойство появилось в JavaScript 1.2.
ПРИМЕЧАНИЕ
Ж-!1' I
Многие из перечисленных выше свойств обладают под-
свойствами и подмечодами. Для получения дополни-
дополнительной информации обратитесь в документацию
Netscape (http://developer.netscape.com) или
Microsoft (http://msdn.microsoft.com).
Чаще всего объект Document используется для гене-
генерации HTML-страниц при помощи JavaScript. Для упо-
упомянутых целей можно применять методы document.write()
или document.writeln(). Например, приведенный ниже
код отображает HTML-текст, переданный в качестве
параметра:
<html>
<body>
<script
type="text/javascript">
document. wri te ( "<Ы>Текс»,
i«JavaScript</hl>") ;
</soript>
созданный
</body>
</html>
Объект Frame
Как будет показано далее в книге, фреймы — очень важ-
важные объекты, предназначенные для совершенствования
внешнего вида Web-приложения. Объект Frame пред-
представляет собой рамку в наборе рамок. В многофреймо-
многофреймовом представлении объект Window — это страница, ко-
которая содержит определение <frameset>. В табл. 9.7
перечислены методы и свойства объекта Frame.
Объект History
Еще одна возможность браузера связана с отслеживани-
отслеживанием перечня сайтов, которые посетил пользователь во
время данного сеанса. Эта особенность известна как спи-
список хронологии (history list), или список посещений сайтов;
эквивалентом упомянутого списка в JavaScript является
объект History.
Объекты со стороны клиента
Глава 9
Таблица 9.7. Методы и свойства объекта Frame.
Тип
Элемент
Описание
Убирает фокус из данного фрейма. Метод появился в JavaScript 1.1.
Отменяет повторное выполнение. Метод появился в JavaScript 1.2.
Отменяет любое отложенное выполнение.
Устанавливает фокус на фрейм. Метод появился в JavaScript 1.1.
Вызывает диалоговое окно Print. Метод появился в JavaScript 1.2.
Планирует функцию для повторного выполнения. Метод появился в JavaScript 1.2.
Устанавливает список функций для отложенного выполнения.
Текущий документ, загруженный в фрейм.
Массив, содержащий ссылки на дочерние фреймы.
Длина массива фреймов.
Атрибут name дескриптора <frame>.
Главное окно или фрейм, из которого создаются дочерние фреймы.
Ссылка на текущий фрейм.
Окно браузера, которое выполняет сценарий.
Ссылка на текущее окно или фрейм.
Метод
Свойство
blurQ
clearlntervalQ
clearTimeoutQ
focus()
print()
setlnterval()
setTimeout()
document
frames
length
name
parent
self
top
window
Предположим, необходимо обеспечить, чтобы пос-
после щелчка на кнопке выполнился возврат на две стра-
страницы назад в списке хронологии. Обработчик событий
для этой кнопки должен вызывать функцию, текст ко-
которой приводится ниже. Все методы и свойства этого
объекта сведены в табл. 9.8.
< script type=" text/ javascript ">
function goBaekTwoPages () {
window.history.go(-2);
II—>
</script>
Объект Location
World Wide Web дает представление обо всем. Каждый
объект Window предназначен для передачи содержимо-
содержимого пользователю, однако это содержимое должно отку-
откуда-то исходить. Местонахождение Web-страницы содер-
содержится в объекте Location. Этот объект используется для
хранения всей информации об URL для данного окна.
Таблица 9.8. Методы и свойства объекта History.
Хотя пользователи видят информацию об URL на эк-
экране в окне адреса (см. рис. 9.16), с этой же информа-
информацией можно работать и через объект Location.
Если из текущего URL требуется выделить часть,
касающуюся протокола, воспользуйтесь таким кодом:
< soript type="text/javascript">
< ! —
function evalProtocol() {
¦curProtocol = window.location.protocol;
if (curProtocol = "http:"){
alert("Документ был загружен из Web.");
}else{
if (curProtocol = "?ile:"){
alert("Документ был загружен из
^локального жесткого диска. ") ;
>else{
alert("Документ был загружен
*¦* откуда-то еще.") ;
j
>
II—>
</script>
Методы и свойства этого объекта перечислены в табл. 9.9.
Тип
Элемент
Описание
Загружает предыдущий URL в списке хронологии.
Загружает следующий URL в списке хронологии.
Загружает URL из списка хронологии, расположенный по указанному смещению.
Ссылается на текущий URL в списке хронологии. Свойство появилось в JavaScript 1.1.
Возвращает количество элементов в списке хронологии.
Ссылается на следующий URL в списке хронологии. Свойство появилось в JavaScript 1.1.
Ссылается на предьиущий URL в списке хронологии. Свойство появилось в JavaScript 1.1.
Метод
Свойство
back()
forward ()
ДО()
current
length
next
previous
Базовое подмножество языка JavaScript
Часть II
Таблица 9.9. Методы и свойства объекта Location.
Тип
Элемент
Описание
Метод,
Свойство
reloadQ
replace()
hash
host
ihostname
href
pathname
port
protocol
search
Перезагружает текущий URL в окне браузера. Метод появился в JavaScript 1.1.
Загружает новую страницу вместо текущей. Метод появился в JavaScript I
Представляет имя привязки в URL, которое начинается с символа ";
Представляет имя хоста и номер порта, указанные в URL.
Представляет имя хоста, указанное в URL.
Представляет полный URL.
Представляет часть PATHJNFO из URL.
Представляет номер порта, указанный в URL.
Представляет протокол, указанный в URL.
Часть URL, касающаяся поиска, включая символ ?.
Адрес
\VeIcometo Acadia Software
tioniwe
;cal5 Ъо'блу must w>tlr will teycuitlie T.txl point rrieaso.
vAij we '^ml
tecbnolasr^ftoJjywwsllas
aaAJaraScfipt. but
sea
РИСУНОК 9.16. Пользователи работают
с окном адреса, но можно работать и с объектом Location.
Объекты второго уровня
Точно так же как объект Window имеет подобъекты,
объекты второго уровня существуют и в Document. Ниже
эти объекты рассматриваются более подробно.
ОбъектAnchor
Объект Anchor соответствует тексту или изображению на
HTML-странице, на которые можно ссылаться через
гипертекстовую ссылку. На практике этот объект ис-
используется редко, посему он — наименее важный из всех
объектов со стороны клиента. В табл. 9.10 содержится
список свойств этого объекта.
Объект Area
Объект Area, который стал доступен в JavaScript 1.1,
позволяет определять на изображении область, которая
будет рассматриваться в качестве карты изображения. То,
что задано атрибутом href дескриптора <агеа> будет заг-
загружаться в окно после щелчка мышью на определенной
области изображения. Таблица 9.11 содержит свойства и
методы этого объекта.
Таблица 9.10. Свойства объекта Anchor.
Свойство Описание
name Имя, обеспечивающее доступ к привязке
из ссылки.
text Текст, который появляется между
дескрипторами <а> и </а>.
х Координата х привязки,
у Координата у привязки.
Объект Applet
Объект Applet, впервые введенный в JavaScript I. I, пред-
представляет собой JavaScript-эквивалент HTML-дескрипто-
HTML-дескриптора <applet>. В общем смысле подобные JavaS
ты не имеют собственных методов, но это явное
несоответствие, поскольку из JavaScript можно обра-
обращаться к определенным методам конкретного Java-an-
лета. Поэтому свойствами объекта Applet являются все
общедоступные поля Java-аплета, а методами — все об-
общедоступные методы.
Объект Form
Забудьте ненадолго о таких надстройках, как Java-апле-
ты или элементы управления ActiveX, которые могут вза-
взаимодействовать с пользователем. Если мыслить только
в терминах HTML-мира, единственный способ взаимо-
взаимодействий с пользователем — через форму и ее элементы
(см. рис. 9.17). Формы оживляют статические страницы,
обеспечивая возможность пользователям взаимодейство-
взаимодействовать с интерфейсом через элементы управления. На
форму можно помещать кнопки, текст и другие интер-
интерфейсные элементы. Объект Form представляет собой сред-
средство взаимодействия в сценариях с HTML-элементами. В
табл. 9.12 перечислены методы и свойства объекта Form.
Таблица
Тип-
9.
11. Методы
¦Элемент
и
свойства объекта Area.
Описание
Объекты со стороны клиента
Глава 9 ЕШ
Метод Вызывает соответствующий обработчик данного события. Метод появился в
JavaScript 1.2.
hash Часть URL, которая является привязкой, включая и символ #.
host Имя хоста (IP-адрес) и порт, указанные в URL.
hostname Имя хоста, указанное в URL
href Полный URL
pathname Путь для файла, указанного в URL, начиная с символа /.
port Порт, указанный в URL.
protocol Протокол, указанный в URL, включая завершающее двоеточие (:).
search Часть URL, касающаяся поиска, включая начальный вопросительный знак (?).
target Имя выходного окна, в котором должен отображаться URL.
text Текст, который встречается между дескрипторами <агеа> и </агеа>.
х Координата х области.
у Координата у области.
Таблица 9.12. Методы и свойства объекта Form.
Тип
Элемент-
Описание
Метод Вызывает соответствующий обработчик событий. Метод появился в JavaScript 1.2.
reset() Устанавливает для элементов формы их значения по умолчанию.
Метод появился в JavaScript 1.1.
Генерирует событие submit, которое приведет к отправке браузером данных в
серверную программу, указанную в атрибуте action дескриптора <form>.
Свойство action Содержит атрибут action экземпляра <form>.
elements Массиз, содержащий все элементы <form>.
encoding Содержит атрибут enctype экземпляра <form>.
length Количество элементов, содержащихся в форме,
method Содержит атрибут method экземпляра <form>.
name Содержит атрибут name экземпляра <form>.
target Содержит атрибут target экземпляра <form>.
Объект Image
Объект Image является инкапсуляцией HTML-изображе-
HTML-изображения. Возможно, наиболее эффективное использование
этого объектного типа заключается в Квитировании изоб-
изображений, предназначенных для отображения на экране.
Для этого потребуется создать объект Image и загрузить
в него с сервера данные изображения до того, как их
потребуется отобразить в браузере. Как только возник-
возникнет потребность в изображении, то вытолкнуть его из
кеша окажется гораздо быстрее, нежели загрузить из
сервера. В табл. 9.13 приведены методы и свойства
объекта Image.
РИСУНОК 9.17. Формы помогают создавать интерактивные
HTML страницы.
Базовое подмножество языка JavaScript
Часть II
Таблица 9.13. Методы и свойства объекта Image.
Тип
Элемент
Описание
Вызывает обработчик для указанного события. Метод появился в JavaScript 1.2.
Ширина границы изображения.
Сообщает, завершена ли загрузка изображения.
Высота изображения.
Отступ от левого и правого краев изображения.
Альтернативное изображение для мониторов с низким разрешением.
Имя изображения.
URL изображения.
Отступ от верхнего и нижнего краев изображения.
Ширина изображения.
Метод
Свойство
handleEvent()
border
complete
Iheight
hspace
lowsrc
name
src
vspace
width
Объект Layer
Объект Layer, появившийся в JavaScript 1.2 и поддержи-
поддерживаемый только браузерами Navigator, позволяет JavaScript
Таблица 9.14. Методы и свойства объекта Layer.
работать со слоями (layers) документа. Для получения
исчерпывающей информации о слоях обратитесь в часть
III книги. Таблица 9.14 содержит список методов и
свойств объекта Layer.
Тип
Элемент
Описание
Метод
Свойство
captureEvents()
handleEventO
load()
moveAbovef)
moveBelowQ
moveByO
moveToQ
moveToAbso!ute()
releaseEvents()
resize By ()
resizeTo()
routeEvent()
above
background
below
bgColor
clip.bottom
clip.height
clip.left
clip.right
clip.top
clip.width
document
left
name
Определяет типы событий для захвата.
Вызывает обработчик для указанного события.
Загружает новый URL.
Перемещает слой поверх другого слоя.
Перемещает слой под низ другого слоя.
Перемещает слой в указанную позицию.
Перемещает верхний левый угол окна к указанным экранным координатам.
Изменяет позицию слоя в соответствие с указанными в точках координатами в
пределах страницы.
Освобождает захваченные события указанного типа.
Изменяет размеры слоя на заданные значения высоты и ширины.
Приводит размеры слоя к заданным значениям высоты и ширины.
Передает перехваченное событие далее по
нормальной иерархии событий.
Определяет слой выше данного.
Ссылается на фоновое изображение слоя.
Определяет слой ниже данного.
Ссылается на цвет фона слоя.
Ссылается на нижнюю границу области отсечения слоя.
Ссылается на верхнюю границу области отсечения слоя.
Ссылается на левую границу области отсечения слоя.
Ссылается на правую границу области отсечения слоя.
Ссылается на вершину области отсечения слоя.
Ссылается на ширину области отсечения слоя.
Ссылается на объект Document, который содержит данный слой.
Ссылается на координату х слоя.
Ссылается на имя слоя.
Объекты со стороны клиента
Тип
Элемент
Глава 9
Описание
радеХ Ссылается на координату х левой границы окна документа.
pageY Ссылается на координату у левой границы окна документа.
parentLayer Ссылается на родительский слой.
siblingAbove Ссылается на слой, находящийся выше zlndex.
siblingBelow Ссылается на слой, находящийся ниже zlndex.
src Ссылается на URL с исходным кодом слоя.
top Ссылается на координату у слоя.
visibility Ссылается на состояние видимости слоя.
window Ссылается на объект Window или Frame, который содержит данный слой.
х Ссылается на координату х слоя.
у Ссылается на координату у слоя.
zlndex Ссылается на расположение этого слоя относительно других слоев в z-порядке.
Объект Link
Вспомните, что World Wide Web ("всемирная паутина")
была разработана в 1989 г. с целью обеспечения простых
гипертекстовых связей HTML-страниц. Возможно, из-
за всеобщего увлечения Web-приложениями ссылка ос-
остается основой Web-технологии. Объект Link позволяет
работать с ссылками в JavaScript-коде. Поскольку ссыл-
ссылка — это просто путь к другой HTML-странице или сай-
сайту, объект Link очень похож на объект Location (кото-
(который содержит ту же самую информацию, но для текущей
Таблица 9.15. Методы и свойства объекта Link.
HTML-страницы). Методы и свойства этого объекта
собраны воедино в табл. 9.15.
Объект Plugin
Подобно объекту Applet, объект Plugin — это способ
получения доступа ко всем подключаемым модулям,
установленным в браузере в текущий момент. Обрати-
Обратите внимание, что этот объект, впервые введенный в
JavaScript 1.1, в Internet Explorer не поддерживается. В
табл. 9.16 перечислены свойства этого объекта.
Тип
Элемент
Описание
Вызывает обработчик для указанного события. Метод появился в JavaScript 1 .2.
Представляет имя привязки в URL для ссылки, начинающееся с символа #.
Представляет часть URL ссылки, касающуюся хоста.
Представляет часть URL ссылки, касающуюся имени хоста.
Представляет полный URL ссылки.
Представляет часть URL ссылки, относящуюся к имени пути.
Представляет часть URL-ссылки, относящуюся к порту.
Определяет часть URL ссылки, относящуюся к протоколу.
Представляет часть URL-ссылки, относящуюся к запросу.
Представляет имя объекта Window, отображающего ссылку.
Текст ссылки. Свойство появилось в JavaScript 1.2.
Ссылается на координату х ссылки.
Ссылается на координату у ссылки.
Таблица 9.16. Свойства объекта Plugin.
Метод
Свойство
handletventO
hash
host
hostname
href
pathname
port
protocol
search
target
text.
Свойство
Описание
description Содержит описание подключаемого модуля.
filename Содержит имя файла подключаемого модуля.
length Содержит количество типов MIME, поддерживаемых подключаемым модулем.
name Содержит имя подключаемого модуля.
Базовое подмножество языка JavaScript
Часть II
Объекты третьего уровня
Следующий уровень JavaScript-объектов со стороны
клиента — объекты третьего уровня. Все эти объекты
являются подобъектами объекта Form. Они вложены в
объект Form по тому же способу, по которому элемен-
элементы HTML вкладываются между парой дескрипторов
<form>.
Объект Button
Если только вы не перешли к Web-разработке от сим-
символьно-ориентированных сред, вы несомненно знакомы
с кнопками. JavaScript содержит три "кнопочных" объек-
объекта: Button, Submit и Reset. Каждый из них реально пред-
представляется с помощью HTML-дескрипторов.
Объект Button — универсальная кнопка, к которой
необходимо добавлять используемый код, в то время как
две другие предназначены для строго определенных це-
целей. Однако, объект Button возможно использовать в той
же роли, что и объекты Submit (вызывая Form.submit())
или Reset (вызывая Form.reset()). Таблица 9.17 содержит
методы и свойства объекта Button.
:.. СОВЕТ ..? а :• ¦ ¦ . ¦¦ .- ...'¦¦¦ _ ' ,=¦
Ширина кнопки определяется длиной текста, передава-
передаваемого через параметр value. Для увеличения ширины
кнопки следует добавить пустое место вокруг текста:
<1NPUT type=button value=" OK "
onClick="doThis()">
Объект Checkbox
Другой распространенный элемент управления в стан-
стандартном пользовательском интерфейсе — это флажок.
Упомянутый элемент позволяет задавать значения yes/
по или true/false, выполняя щелчок на флажке. В табл.
9.18 перечислены свойства и методы объекта Checkbox.
Объект FileUpload
Объект FileUpload, впервые появившийся в JavaScript
1.1, представляет собой эквивалент HTML-элемента, ре-
реализующего загрузку файла. Очень немногие действия
можно выполнить с этим объектом в JavaScript — мож-
можно только сослаться на его свойства. Объект FileUpload
не содержит реальных методов. В табл. 9.19 перечисле-
перечислены свойства объекта FileUpload.
Объект Hidden
Еще один объект типа поля — Hidden; он подобен тек-
текстовому объекту с установленным в false свойством
visible. Этот объект используется для сохранения значе-
значений с целью передачи их серверному процессу. Объект
Hidden происходит из тех времен, когда HTML суще-
существовал без JavaScript, когда не было таких вещей, как
переменные, массивы и объекты, предназначенных для
хранения значений. Хотя этот объект все еще можно
применять для передачи данных между страницами в
многостраничных приложениях, многие из полей дан-
данных объекта Hidden в JavaScript уже не нужны. В табл.
9.20 сведены свойства объекта Hidden.
Объект Password
Если бы в JavaScript поддерживался механизм наследо-
наследования, объект Password был бы подклассом объекта Text.
Единственное различие между этими двумя объектами
— так это то, что любые символы, введенные в объект
Password, отображаются звездочками вместо своих ре-
реальных значений. В табл. 9.21 перечислены методы и
свойства объекта Password.
Объект Radio
Переключатели представляют собой взаимоисключаю-
взаимоисключающие элементы управления, т.е. если один переключатель
выбран, все другие переключатели в том же наборе ста-
становятся невыбранными. Объект Radio обеспечивает пе-
переключатель, используемый в HTML-формах. Разработ-
Разработчик определяет набор переключателей, устанавливая
одно и то же значение их свойства name. Таблица 9.22
содержит свойства и методы объекта Radio.
Таблица 9.17. Методы и свойства объекта Button.
Тип
Элемент
Описание
Убирает фокус из кнопки. Метод появился в JavaScript 1.1.
Вызывает событие click для данной кнопки.
Устанавливает фокус на кнопку. Метод появился в JavaScript 1.1.
Передает событие соответствующему обработчику, связанному с кнопкой.
Метод появился в JavaScript 1.2.
Возвращает объект Form, которому принадлежит данная кнопка.
Возвращает строку, которая определена в атрибуте name HTML-дескриптора <input>.
Возвращает строку, которая определена в атрибуте type HTML-дескриптора <input>.
Для объекта Button эта строка — всегда button. Свойство появилось в JavaScript 1.1.
Возвращает строку, которая выводится в графическом представлении кнопки.
Метод
Свойство
Ыиг(>
click()
focus()
handleEventQ
form
name
type
value
Таблица
Тип
9.
18. Методы
Элемент
и
свойства объекта
Описание
Checkbox.
иоъекты со стороны клиента ШКЕМ
Глава 9 1Ш
Метод blur() Убирает фокус из флажка. Метод появился в JavaScript 1.1.
click() Вызывает обработчик событий onClick. Метод появился в JavaScript 1,1.
focusQ Устанавливает фокус в данный флажок.
handleEvent() Передает событие соответствующему обработчику событий, связанному с флажком.
Метод появился в JavaScript 1.2.
Свойство checked Возвращает логическое значение, которое определяет, установлен ли флажок.
defaultChecked Возвращает логическое значение, которое содержит начальное состояние флажка.
Это значение устанавливается"через атрибут checked.
form Возвращает объект Form, которому принадлежит флажок.
name Возвращает строку, которая определена в атрибуте name HTML-дескриптора <input>.
type Возвращает строку, которая определена в атрибуте type HTML-дескриптора <input>.
Для объекта Checkbox эта строка — всегда checkbox. Свойство появилось в
JavaScript 1.1.
value Возвращает значение, переданное при отправке формы.
Таблица 9.19. Методы и свойства объекта FileUpload.
Тип Элемент Описание
Метод Ыиг() Убирает фокус из окна FileUpload.
focus() Устанавливает фокус на окно FileUpload.
handleEvent() Вызывает заданный по умолчанию обработчик для указанного события.
Метод появился в JavaScript 1.2.
select() Выбирает область ввода в окне FileUpload.
Свойство name Содержит значение атрибута name для окна FileUpload.
form Ссылается на объект Form, содержащий FileUpload.
type Содержит значение атрибута type для FileUpload.
value Строка, определяющая путь к выбранному файлу.
Таблица 9.20. Свойства объекта Hidden.
Свойство Описание
form Определяет форму, содержащую объект Hidden.
name Содержит имя объекта Hidden.
type Содержит значение атрибута type объекта Hidden. Свойство появилось в JavaScript 1.1.
value Содержит значение атрибута value объекта Hidden.
Таблица 9.21. Методы и свойства объекта Password.
Тип Элемент Описание
Метод
Свойство
blur()
focus()
IhandleEventO
select()
defaultValue
form
name
Убирает фокус из окна Password.
Устанавливает фокус на окно Password.
Вызывает заданный по умолчанию обработчик для указанного события.
Метод появился в JavaScript 1.2.
Выделяет текст, введенный в окно Password.
Ссылается на атрибут value окна Password.
Ссылается на форму, которая содержит окно Password.
Ссылается на атрибут name окна Password.
Базовое подмножество языка JavaScript
Часть II
Элемент
Описание
туре
value
Ссылается на атрибут type окна Password. Свойство появилось в JavaScript 1.1.
Ссылается на текущее содержание окна Password.
Таблица 9.22. Методы и свойства объекта Radio.
Тип
Элемент
Описание
Метод Ыиг() Удаляет фокус из объекта Radio.
clickQ Моделирует щелчок мыши на переключателе.
focusO Устанавливает фокус на переключатель.
handleEvent() Вызывает заданный по умолчанию обработчик для указанного события.
Метод появился в JavaScript 1.2.
Свойство checked Определяет, выбран ли переключатель.
defaultChecked Ссылается на атрибут checked HTML-дескриптора <input>.
form Ссылается на объект Form, который содержит объект Radio,
name Ссылается на атрибут name HTML-дескриптора <input>.
type Ссылается на атрибут type HTML-дескриптора <input>.
value Ссылается на атрибут value HTML-дескриптора <input>.
ПРИМЕЧАНИЕ ¦¦¦' '"" ~"'~~ :.
Переключатели группируются на основе общего свой-
свойства name.
Объект Reset
Второй вид связанного с кнопками объекта — объект
Reset, впервые введенный в JavaScript 1.2. В результате
щелчка объект инициирует событие, которое обеспечи-
обеспечивает установку всех элементов формы в их первоначаль-
первоначальные значения. Таблица 9.23 содержит список методов и
свойств этого объекта.
Объект Submit
Последний связанный с кнопкой объект — это Submit.
В результате щелчка этот объект генерирует событие,
передающее все значения формы в программу, опрсде-
Таблица 9.23. Методы и свойства объекта Reset.
ляемую атрибутом action дескриптора <form>. В табл.
9.24 приведен список методов и свойств этого объекта.
Объект Select
Существуют и другие стандартные элементы управления
оконных сред — выпадающий список и список выбора,
которые позволяют пользователю выбирать значения из
заранее определенного списка. Отличие между ними
состоит в том, что в выпадающем списке пользователь
может выбирать только одно значение, в то время как в
списка выбора — сразу несколько значений. Поведение
обоих упомянутых интерфейсных элементов инкапсули-
инкапсулирует объект Select. Другими словами, Select может выс-
выступать как выпадающий список (значение по умолча-
умолчанию) или как список выбора (если его свойстве multiple
установлено в true). Таблица 9.25 содержит свойства и
методы объекта Select.
Тип
Элемент
Описание
Удаляет фокус из кнопки.
Моделирует щелчок мыши на кнопке.
Устанавливает фокус на кнопку.
Передает событие соответствующему обработчику событий, связанному с кнопкой.
Метод появился в JavaScript 1.2.
Возвращает объект Form, содержащий данную кнопку.
Содержит атрибут name кнопки.
Содержит атрибут type кнопки.
Содержит атрибут value кнопки.
Метод
Свойство
Ыиг()
¦ciickQ
focus()
ihandleEvent()
form
name
type
value
Объекты со стороны клиента
Глава 9
Таблица 9.24. Методы И свойства объекта Submit.
Тип
Элемент
Описание
Метод.
Свойство
lblur()
click()
focus()
ihandleEventQ
form
name
type
value
Удаляет фокус из кнопки Submit. Метод появился в JavaScript 1.1.
Моделирует щелчок мыши на кнопке.
Устанавливает фокус на кнопку Submit. Метод появился в JavaScript 1.1.
Вызывает обработчик для указанного события. Метод появился в JavaScript 1.2.
Возвращает форму, которой принадлежит кнопка Submit.
Возвращает имя кнопки Submit, определенное в атрибуте name.
Возвращает тип данной кнопки Submit, определенный в атрибуте type.
Возвращает значение данной кнопки Submit, определенное в атрибуте value.
Таблица 9.25. Методы И свойства объекта Select.
Тип
Метод
Свойство
Элемент
Ыиг()
focus()
,handleEvent()
form
length
name
options
selectedlndex
type
Описание
Убирает фокус из списка.
Устанавливает фокус на список.
Вызывает обработчик для указанного события. Метод появился в JavaScript 1.2.
Возвращает форму, которой принадлежит список.
Возвращает количество вариантов в списке.
Возвращает имя данного списка, указанное в атрибуте name.
Возвращает массив, содержащий все элементы списка. Эти элементы создаются при
помощи HTML-дескриптора <option>. Это свойство обладает также и подсвойствами
— length и selectedlndex.
Возвращает целое число, определяющее индекс выбранного в списке варианта.
Возвращает тип данного списка, заданный в атрибуте type. Для экземпляров
<select>, которые содержат атрибут multiple, это свойство возвращает select-
multiple. Экземпляры без этого атрибута возвращают значение select-one. Свойство
появилось в JavaScript 1.1.
Объект Text
Основным элементом для любого приложения, предус-
предусматривающего ввод данных, по праву считается поле, в.
котором пользователь может набирать информацию.
Объект Text служит в качестве своего рода устройства
захвата данных. В табл. 9.26 перечислены свойства и
методы объекта Text.
Объект Textarea
Рассмотрим связанный с объектом Text объект Textarea,
который вместо одной позволяет вводить множество
Таблица 9.26. Методы и свойства объекта Text.
строк. Тем, кто имел дело с другими средами програм-
программирования, гораздо проще считать объект Textarea
memo-полем (т.е. полем для заметок). В табл. 9.27 пере-
перечислены свойства и методы объекта Textarea.
Объекты четвертого уровня
В JavaScript 1.4 был введен единственный объект четвер-
четвертого уровня — подобъект объекта Select. Поскольку
информация о нем пока не устоялась, стоит подождать
завершения разработки ECMAScript и Document Object
Module (DOM).
Тип
Элемент
Описание
Убирает фокус из текстового поля.
Устанавливает фокус на текстовое поле.
Вызывает обработчик для указанного события; метод появился в JavaScript 1.2.
Выделяет текст в текстовом поле.
Возвращает значение текстового поля, определенное атрибутом value. Обратите
внимание, что это свойство не поддерживается браузерами Opera.
Метод
СВОЙСТВО'
5 '"'58
biur()
focus()
handleEvent()
select()
defaultValue
Базовое подмножество языка JavaScript
Тип
Часть II
Элемент
Описание
form
name
type
value
Возвращает форму, которой принадлежит текстовое поле.
Возвращает имя текстового поля, определенное атрибутом name.
Возвращает тип текстового поля, заданный в атрибуте type (всегда text).
Свойство появилось в JavaScript 1.1.
Возвращает значение, которое фактически отображается в текстовом поле.
Таблица 9.27. Методы и свойства объекта Textarea.
Тип
Элемент
Описание
Метод
Свойство
Ыиг()
focusQ
handleEvent()
selectQ
defaultValue
form
name
type
value
Убирает фокус из текстовой области.
Устанавливает фокус на текстовую область.
Вызывает обработчик для указанного события. Метод появился в JavaScript 1.2.
Выделяет текст в текстовой области.
Возвращает для текстовой области значение, находящееся между парой
дескрипторов <textarea>. Это свойство не поддерживается браузерами Opera.
Возвращает форму, которой принадлежит текстовая область.
Возвращает имя данной текстовой области, определенное в атрибуте name.
Возвращает тип данной текстовой области, указанный в атрибуте type (всегда
textarea). Свойство появилось в JavaScript 1.1.
Возвращает значение, которое фактически отображается в текстовой области.
Объект Option
Объект Option обычно используется для ссылки на раз-
различные элементы <option>, которые находятся между
открывающим и закрывающим дескрипторами <select>.
Таблица 9.28 содержит свойства объекта Option.
Резюме
Объекты языка JavaScript со стороны клиента служат в
качестве фундаментальных инструментальных средств
для создания сценариев. В главе было дано представле-
Таблица 9.28. Свойства объекта Option.
ние об иерархии JavaScript-объектов и о каждом из при-
принадлежащих ей объектов.
Существенная часть объектной модели — ни что иное
как элементы HTML, которые "превращены" в объекты
для организации работы с HTML-дескрипторами на
объектно-ориентированный манер. Если вы пришли из
мира HTML, начинайте воспринимать эти элементы не
как дескрипторы, но как объекты. В главе 10 рассмат-
рассматриваются базовые языковые объекты, в главе 11 обсуж-
обсуждаются проблемы создания собственных объектов и,
наконец, в главе 12 дается представление о серверной ча-
части JavaScript и объектах, присутствующих в этой среде.
Свойства
Описание
defaultSelected Ссылается на опцию, которая выбрана по умолчанию в блоке выбора.
Свойство появилось в JavaScript 1.1.
index Ссылается на отсчитываемый от нуля индекс элемента в массиве Select.options.
selected Ссылается на выбранное значение списка выбора. Свойство появилось в JavaScript 1.2.
text Ссылается на текст опции,
value Ссылается на значение, возвращаемое в случае выбора опции.
Основные объекты языка
В ЭТОЙ ГЛАВЕ
Объект Global
Объект String
Объект RegExp
Объект Array
Объект Date
Объект Math
Объект Boolean
Объект Number
Объект Function
Любой читатель вправе заявить, что клиентские
объекты • - основа JavaScript. При создании сложных
приложений JavaScript разработчик сталкивается с ос-
основными объектами языка, отличительные особеннос-
особенности которых — непротиворечивость объектов различных
поставщиков (Microsoft, Netscape, Sun, Be, Opera
Software) и поддержка различных платформ, как сервер-
серверных, так и клиентских. Эти объекты подчиняются стан-
стандарту ECMAScript 1.0.
В данной главе рассматриваются объекты String,
RegExp, Array, Date, Math, Boolean, Number, Function,
а также особенности их использования в различных вер-
версиях JavaScript.
'' ПРИМЕЧАНИЕ „ ¦ ". vp^f-i^'1"" '" '' " " " > ' '"'¦¦*
Полный синтаксис каждого объекта в книге не приво-
приводится, поскольку его можно найти на сайтах http://
developer.netscape.com для платформы Netscape и
http://msdn.microsoft.com/scripting для платформы
Microsoft. Кроме того, на сайте http://www.mozilla.org/js
всегда доступна информация по версии Navigator с
открытым кодом (известной также как версия 5.0).
Объект01оЬа1
Даже программистов, имеющих опыт работы с
JavaScript, должно заинтересовать, что же это за зверь
такой, объект Global. Действительно, не каждый слы-
слышал о нем. Перед тем как приступить к углубленному
изучению свойств и методов объекта, стоит вспомнить
некоторые основные понятия.
Объект Global впервые появился, когда ECMAScript
1.0 стал восприниматься в качестве стандарта. А потом
компания Microsoft достаточно "внезапно" объединила
высокоуровневые свойства и методы в объект Global, да
и Netscape упомянула о нем в нескольких своих доку-
ментациях. Вот так и появился объект Global — высо-
высокоуровневые свойства и методы и при этом отсутствие
родительского объекта.
Объект Global имеет множество свойств и методов,
которые перечислены в табл. 10.1. Несложно убедиться,
что большинство из них используется в сценариях
JavaScript.
Объект String
Строки — это фундаментальное понятие любого языка
программирования. Строка, представляющая собой на-
набор алфавитно-цифровых символов, может быть либо
текстовой (литеральной) строкой, такой как "Не морочь-
морочьте голову", либо строковой переменной, например,
thePhrase. В главе 5 строки рассматривались с точки зре-
зрения типа данных, однако в JavaScript строки могут быть
также и объектами со своим набором методов и свойств.
По мере совершенствования JavaScript, строки при-
приобретали все большее значение. В начальной версии
JavaScript они не являлись реальными объектами, но
начиная с JavaScript 1.1 ситуация изменилась. Напри-
Например, для создании строки и проверки ее длины в JavaScript
1.1 можно воспользоваться следующим кодом:
<script type="text/javascript">
<!--
var str = "Здравствуйте, я — король.";
alert(str.length);
//-->
</script>
Начиная с JavaScript 1.1, для создания экземпляра
объекта String можно пользоваться оператором new.
Применение браузера, не поддерживающего определе-
определение объекта String, приведет к ошибке, гласящей, что
String не определен.
Базовое подмножество языка JavaScript
Часть II
Следующий пример показывает, как будет выглядеть
приведенный выше код для браузеров, поддерживающих
JavaScript 1.1:
<script type="text/javascript"
language="JavaScriptl.1">
<! --
var str = "Здравствуйте, я — король." ;
alert (str.length) ;
</script>
Какова же цель явного объявления объекта String?
Все дело в том, что доступ к объекту String может про-
производиться из других фреймов, а это более удобно и эф-
эффективно по сравнению с JavaScript 1.0. Например, если
требуется получить доступ к переменной CUStName из
родительского окна, необходимо записать такой код:
¦var customer = new String () ;
customer = parent. custName;
В случае JavaScript 1.0 для успешной работы с вы-
выражением в его конце следует добавить пустую строку:
Таблица 10.1. Методы и свойства объекта Global.
var customer = parent. custName + "";
Кроме преимущества своей простоты, данный метод
относится к понятию хорошего тона в программирова-
программировании. В настоящий момент ECMAScript является стан-
стандартом, a JavaScript и JScript — его воплощениями.
Программист должен иметь уверенность, что в коде
используются корректный синтаксис и семантика, а
работа кода — безукоризненна. JavaScript позволяет ма-
манипулировать строками. Соответствующие свойства и
методы сведены в табл. 10.2. Поскольку строки — весь-
весьма частые гости, с особенностями их использования
стоит познакомиться поподробней.
Строки относятся к одному из важнейших типов
данных, поэтому просто необходимо уметь выделять
данные из строки получать о них информацию. Напри-
Например, для определения размера строки можно восполь-
воспользоваться свойством length. В рассмотренном примере
возвращается 13:
var myString = new String ("Это мой день.");
var len = myString.length;
Tun
Метод
Свойство
Элемент
escape()
eval()
isFinite()
isNaN()
parseFloat()
parselntQ
unescapeO
Infinity
NaN
Описание
Возвращает объект String, в котором все алфавитно-цифровые символы
преобразовываются в их цифровые эквиваленты.
Принимает строку с операторами JavaScript и тестирует ее на предмет корректности
синтаксиса.
Определяет, имеет ли переменная конечные границы. Метод появился в JavaScript 1.3.
Определяет, содержит ли переменная допустимое число. Метод появился в JavaScript 1.1.
Выполняет преобразование строкового аргумента в число с плавающей точкой (float).
Выполняет преобразование строкового аргумента в целое число.
Принимает шестнадцатиричное значение и возвращает ASCII-эквивалент в кодовой таблице
ISO-Latin-1.
Ключевое слово, используемое для представления плюс бесконечности. Свойство
появилось в JavaScript 1.3.
Представляет объект, не имеющий эквивалентов ни с одним из чисел. Свойство
появилось в JavaScript 1.3.
Таблица 10.2. Методы и свойства объекта String.
Тип
Элемент
Описание
Метод anchor() Создает экземпляр дескриптора <а> с атрибутом name, принимающим значение строки,
передаваемой методу.
big() Преобразует строку в экземпляр дескриптора <big>.
blink() Преобразует строку в экземпляр дескриптора <blink>.
bold() Преобразует строку в экземпляр дескриптора <bold>.
charAt() Возвращает символ строки, расположенный по заданному индексу.
CharCodeAt() Возвращает код символа ISO-Latin-1, расположенного по индексу, переданному в метод.
concat() Связывает две переданные строки в одну новую. Метод появился в JavaScript 1.2.
fixed() Преобразует строку в экземпляр дескриптора <tt>, определяющего шрифт фиксированной
ширины.
Основные объектны языка
Глава 10
Тип
Элемент
Описание
fontcolor() Устанавливает атрибут color экземпляра дескриптора <font>.
fontsizeQ Устанавливает атрибут size экземпляра дескриптора <font>.
fromCharCode() Возвращает строковое значение числа ISO-Latin-1, переданное методу.
indexOf() Возвращает позицию первого вхождения строки, переданной методу, в экземпляре объекта
String.
italicsQ Преобразует строку в экземпляр дескриптора <i>.
lastlndexOfQ Возвращает позицию последнего вхождения строки, переданной методу, в экземпляре
объекта String.
link() Преобразует строку в экземпляр дескриптора <а> и устанавливает атрибут href в значение
URL
match() Возвращает массив, основанный на регулярном выражении, переданном в метод. Метод
появился в JavaScript 1.2.
replace() Выполняет операцию поиска и замены, заданную регулярным выражением, и заменяет на
строку, переданную в метод. Метод появился в JavaScript 1.2.
search() Возвращает позицию совпадения с заданной строкой в экземпляре объекта String. Если
строка не найдена, возвращается значение -1. Метод был добавлен в JavaScript 1.2.
slice() Возвращает часть строки между заданными начальной и конечной позициями. При
передаче отрицательного числа отсчет будет выполняться с конца строки. Метод появился в
JavaScript 1.2.
small() Преобразует строку в экземпляр дескриптора <small>.
split() Выполняет разделение строк на сегменты. Размеры сегментов определяются границами
строки и экземпляров. Метод появился в JavaScript 1,1.
strike() Преобразует строку в экземпляр дескриптора <strike>.
sub() Преобразует строку в экземпляр дескриптора <sub>.
substr() Возвращает часть строки, которая начинается с заданной позиции и содержит заданное
количество символов. При передаче отрицательного числа отсчет будет выполняться с
конца строки. Метод появился в JavaScript 1.2.
substringO Возвращает часть строки между начальной и конечной позициями.
sup() Преобразует строку в экземпляр дескриптора <sup>.
toLowerCase() Преобразует символы исходной строки в нижний регистр.
toSource() Возвращает строковое представление объекта String. Метод появился в JavaScript 1.3.
toUpperCase() Преобразует все символы строки в верхний регистр.
Свойство Iength() Возвращает длину строки.
prototype() Позволяет добавлять новые свойства в экземпляры объекта String. Свойство появилось в
JavaScript 1.1.
Кроме того, можно выполнять поиск текста внут-
внутри строки, прибегнув к помощи методов indexOf(),
lastIndexOf(). Вызывайте их, если требуется отыскать
определенные символы или подстроки внутри строки и
возвратить соответствующую позицию (или индекс). В
то время как indexOf() начинает с левой стороны стро-
строки и продвигается вправо, lastIndexOf() выполняет ана-
аналогичные действия, но в обратном направлении. Оба
метода начинают действовать с позиции 0 и возвраща-
возвращают значение -1, если текст не найден. Код в приведен-
приведенном ниже примере устанавливает значение переменной
results равным 8:
var myString = new String ("Каждый день
*-> приближает нас к ... светлому будущему.");
var results = myString.indexOf("e");
А вот следующий код установит значение перемен-
переменной results равным 47:
var myString = new String ("Каждый день
^приближает нас к ... светлому будущему.");
var results = myString.lastlndexOf("e");
Оба метода имеют второй необязательный параметр,
позволяющий определить, с какого места строки начи-
начинать поиск. Например, в сценарии из листинга 10.1 ре-
реализован поиск в переменной graf и подсчет количества
вхождений буквы е.
Лазовое подмножество языка JavaScript
Часть II
Листинг 10.1. Применение метода indexOf() для
поиска всех букв е, встречаемых в предложении.
<SCript type=" text/ javascript"
language="JavaScriptl.1">
<! —
// Объявление переменных
var pos = 0;
var num = -1;
var i = -1;
var graf = "Деньш не приносят счастья," +
"однако обеспечивают спокойствие и
Суверенность." ;
// Поиск в строке с подсчетом количества
// встречаемых "е"
while (pos != -1) {
pos = graf.indexOf("e", i + 1) ;
num += 1 ;
i = pos;
:
// Поместить ответ на страницу
document.write(graf)
document.write("<hr size='l'>")
document.write("В параграфе найдено
" букв s.") ;
document.close()
</script>
+ num +
На рис. 10.1 показан результат выполнения сцена-
сценария.
•1 (Thwart
Деньги не приносят СЧЭСТЬЯ.ОДНЗКО обеспечивают спокойствие и уверенность
В параграфе найдено 7 букв 6
РИСУНОК 10.1 Пример использования
метода indexOf().
Если требуется достичь большего, нежели поиск
позиции определенного символа, с помощью метода
substring() можно получить часть строковой переменной
или литерала. substring() принимает два параметра -
начальную и конечную позиции подстроки. Точно так
же как и indexOf() и lastIndexOf(), данный метод начи-
начинает отсчет с нуля, т.е. первая позиция в строке рассмат-
рассматривается как 0-вая. В следующем коде переменная
results получит значение Новая:
var myString = new String ("Новая Англи:
var results = myString.substring@,3);
Для получения одиночного символа используйте
charAt(). Метод CharAt() возвращает символ по указан-
указанной позиции, переданной в качестве параметра. В при-
приведенном ниже примере results получит значение и:
var myString = new String("Слоны и е
var results = myString.charAtF);
В случае указания позиции, выходящей за пределы
строки, возвращается значение -1:
var myString = new String ("Агент С
var results = myString.charAtB0102);
Сущность программ управления строками раскрыва-
раскрывается при их объединении с целью решения определен-
определенных задач. Давайте рассмотрим обычную программу в
JavaScript, которая обеспечивает замену текста внутри
строки на какой-либо иной текст. Сначала потребуется
создать обобщенную функцию замены строки, исполь-
использующую свойство length, а также методы indexOf() и
substring(). При решении данной проблемы будут про-
продемонстрированы и процедурный, и объектно-ориен-
объектно-ориентированный подходы.
ПРИМЕЧАНИЕ
Поскольку мы намереваемся создать функцию, выпол-
выполняющую поиск и замену в строке, нелишним будет упо-
упомянуть, что JavaScript ! .2 поддерживает новый объект
RegExp, позволяющий выполнять регулярные выраже-
выражения над строками. С помощью этого объекта легко вы-
выполнять поиск и замену, поскольку он оперирует ме-
методами именно этого характера. Данный объект еще
будет упоминаться в данной главе, однако подробное его
исследование можно отыскать только в главе 31.
Примеры манипуляций со строками
Придерживаясь традиционного подхода, можно разра-
разработать функцию stringReplace, имеющую три параметра:
• originalString — исходная строка, в которой будут
выполняться замены.
¦• flndText — строка, которую требуется заменить.
• replaceText — строка, которая будет вставляться в
originalString.
Функция использует эту информация для выполне-
выполнения замены. Как показано в листинге 10.2, для поиска
параметра flndText используется метод indexOf(), а ме-
метод substring() удаляет строки, стоящие до и после па-
параметра flndText. Функция объединяет preString,
replaceText, postString и присваивает результат перемен-
переменной originalString.
Основные объекты языка
Глава 10
Листинг 10.2. Создание функции, выполняющей поиск и замену в строках.
<html>
<head>
<title>JavaScript Unleashed</ title>
<script language="JavaScriptl .1" type="text/javascript">
function stringReplace(originalString, findText, replaceText) {
var pos = 0;
var len = findText. length;
pos = originalString.indexOf (findText);
while (pos != -1) {
preString = originalString. substring @, pos) ;
poststring = originalString. substring (pos + len, originalString. length) ;
originalString = preString + replaceText + poststring;
pos = originalString. indexOf(findText) ;
J
return originalString;
</script>'
</head>
<body>
<script language="JavaScriptl .1" type="text/javascript">
/ / Объявление переменных
var origString = new String ( "Allen") ;
var findString = new String ("All") ;
var replaoeString = new String ( "Ell" ) ;
var resultstring = stringReplace (origString, findString, replacestring)
// Отображение результатов на странице
document.write ("The original string was: " + origString + "<br>");
document, write ("We searched for: " + findString + "<br>") ;
document, write ("We replaced it with: " + replacestring + "<hr size=' 1 ¦>"),¦
document.write ("The result was: " + resultstring);
II—>
</script>
</body>
</html>
Данная операция продолжается до тех пор, пока
findText встречается в строке. Если findText более не
найдена, пользователю возвращается новое значение
originalString.
При разработке этой же функции можно воспользо-
воспользоваться возможностями объекта-прототипа JavaScript 1.1
и добавить метод replace() в объектный тип String. Для
работы внутри объектной оболочки потребуется изме-
изменить структуру кода stringReplace(). Результат описан-
описанных действий показан в листинге 10.3.
Вовлечь в действие метод гер1асе() можно за счет
создания объекта String, установки его значения, а за-
затем вызова созданного метода для замены всех вхожде-
вхождений определенной строки.
Форматирование строк
В JavaScript существует несколько способов форматиро-
форматирования строк. Многие из них являются эквивалентами
дескрипторов форматирования HTML. Это не только
гораздо проще постоянного объединения HTML-деск-
HTML-дескрипторов в строки, но также и способ применения
объектно-ориентированного подхода к разработке.
Другими словами, если есть строковый литерал "Ну
и денек выдался сегодня!", который необходимо отфор-
отформатировать, можно пойти по одному из путей. Можно
добавить дескрипторы форматирования HTML:
"<Ь>" + "Ну и денек выдался сегодня! " + "</Ь>"
Или воспользоваться методом bold() объекта String:
var myString = new String ("Ну и денек выдался
'••сегодня! ") ;
var results = myString.bold() ;
В конечном итоге, возвращается следующий HTML-
текст:
<Ь>Ну и денек выдался сегодня!</Ь>
^ПРИМЕЧАНИЕ
Щ
Учитывайте контекст, в котором используются мето-
методы форматирования. Их нельзя применять за предела-
пределами сценария JavaScript в качестве замены дескрипто-
дескрипторов форматирования HTML.
Базовое подмножество языка JavaScript
Часть I!
Листинг 10.3. Добавление метода replaceQ в объект String.
<html>
<head>
<title>JavaScript Unleashed</title>
¦<script language="JavaScriptl .1" type="text/javascript">
. // Определение нового метода для объекта String
String.prototype.replace = stringReplace;
function stringReplace (findText, replaceText) {
// Эту переменную необходимо добавить для унаследования вызываемого объекта
var originalstring = new String (this);
var pos = 0;
var len = f indText. length ;
pos = originalString.indexOf (findText) ;
while (pos != -1) {
preString = originalstring. substring @, pos) ¦
postString = originalstring. substring (pos + len, originalstring. length) ;
originalstring = preString + replaceText + postString;
pos = originalString.indexOf (findText) ;
\
return originalstring;
1
II—>
</script>
</head>
<body>
<script language="JavaScriptl.1" type="text/javascript">
<! —
// Объявление переменных
var origString = new String ("Allen" );
var findString = new String ("All") ;
var replaceString = new String("Ell") ;
// Заметили отличия?
var resultstring = origString. replace (findString, replaceString)
У/ Отображение результатов на странице
document.write ("The original string was: " + origString + "<br>") ;
document.write("We searched for: " + findString + "<br>");
document.write("We replaced it with: " + replaceString + "<hr size='l'>");
document.write("The result was: " + resultstring);
II—>
</script>
</body>
</html>
Для более подробного знакомства с базовыми мето-
методами форматирования JavaScript создадим пример стра-
страницы на JavaScript. Она обеспечит форматирование
определенной пользователем строки в соответствие с
доступными возможностями HTML. Реализация пре-
предусматривает использование HTML-формы.
Код предполагает создание метода showWindow(),
вызываемого в результате щелчка на кнопке Show. Ме-
Метод присваивает значение текстового поля формы стро-
строковой переменной txt.
Каждая из опций форматирования, представленная
флажком, принимает значение либо true, либо false.
Кроме того, имеется код, выясняющий, установлен ли
конкретный флажок. В конечном итоге, к переменной
txt применяется соответствующий метод форматирова-
форматирования.
Опции форматирования не являются взаимоисклю-
взаимоисключающими, хотя установка некоторых из них может при-
привести к отмене других. В результате появляется возмож-
возможность одновременного использования любого числа
методов. JavaScript остается только обработать каждый
из методов, последовательно добавляя тот или иной
HTML-дескриптор.
Определение цвета и размера шрифта не сводится к
простой логической операции. Напротив, выполняется
запрос требуемых параметров. Для упрощения выбора
Основные объекты языка
значений параметров форма содержит элементы управ-
управления типа списков.
В завершение всего, переменная txt при помощи
метода document.write() выводится в новое окно, кото-
которое тут же и создается. Полная строка записывается в
новое окно вместе со всеми дескрипторами форматиро-
форматирования, окружающими текст.
На рис. 10.2 показано окно со всеми опциями, а на
рис. 10.3 — результирующее окно для выбранных па-
параметров.
В листинге 10.4 приводится полный исходный код
рассмотренного примера.
String Object Formatting
String 1»-"° •""'"
Slyln: P Big П Efak. Г ВоИ Г feed & lakes Г Small Pi Stake Г Sub Г Sup
F»nc Color \ black ;*) Snc:'[5 jij
РИСУНОК 10.2. Страница выбора опций форматирования.
РИСУНОК 10.3. Результат форматирования строки.
НАПОМИНАНИЕ
Методы tollpperCasel) и toLowerCasel) работают в со-
соответствие с назначенным планом. Они используются
при сравнении текста без учета регистра. Например,
при сравнении введенного пользователем текста со
¦строковым литералом лучше перевести обе строки
либо к верхнему, либо к нижнему регистру.
Для создания объектов Link и Anchor можно вос-
воспользоваться методами link() и anchor() объекта String.
Данные методы существенно упрощают работу с точка-
точками привязки и ссылками в коде, минимизируя длинню-
длиннющие строки HTML-дескрипторов. Для иллюстрации
сказанного воспользуемся примером, аналогичным пре-
предыдущему примеру форматирования.
Метод, подобный showWindow()CanycKaeMbiil обра-
обработчиком событий onClick кнопки Show), обрабатыва-
обрабатывает выбранные пользователем опции, и обращается либо
к методу link(), либо к методу anchorQ переменной txt.
Листинг 10.4. Исходный код сценария форматирования строки.
<html>
<head>
<title>String Object Formatting</title>
<script language="JavaScriptl .1" type="text/javascript">
function showWindow( ) {
// Объявление переменных
var txt = document, f orml. stringField. value;
var clr = "
var sze = "";
// Проверка выбранных опций
if ( document. f orml. bigBox . checked) txt = txt.bigO;
if (document.forml .blinkBox.checked) txt = txt. blink ();
if (document, forml. boldBox . checked) txt = txt. bold {);
if (document, f orml . f ixedBox . checked) txt = txt . fixed () ;
if (document, f orml .italicsBox. checked) txt = txt. italics () ;
if (document, forml. smallBox. checked) txt = txt. small ();
if (document, f orml. strikeBox. checked) txt = txt. strike () ;
if (document, forml. subBox. checked) txt = txt.sub();
if (document, f orml. supBox. checked) txt = txt. sup () ;
.// Специальная проверка элементов управления типа списков
clr = document. forml. colorList. options [document .f orml. colorList. options, selectedlndex] .text;
txt = txt. fontcolor (clr) ;
sze = document.forml.sizeList.options[document, forml.sizeList.options.selectedlndex] .text;
txt = txt.fontsize(sze) ;
Базовое подмножество языка JavaScript
fil Часть II
// Открытие нового окна для отображения результатов
objWindow = window.open("", "" , "width=600,height=300") ;
objWindow.document.write(txt);
objWindow.document.close();
i
</script>
</head>
<body>
<h:L>
String Object Formatting
<hr>
<form method="POST" name="forml">
<p>
<strong>
String:
</strong>
<input type=text size=40 maxlength=256 name="stringField">
<strong>
Style-.
</strong>
<input type=checkbox name="bigBox" value="ON">
Big
<input type=checkbox name="blinkBox" value="ON">
Blink
<input type=checkbox name="boldBox" value="ON">
Bold
<input type=checkbox name="fixedBox" value="ON">
Fixed
<input type=checkbox name="italicsBox" value="ON">
Italics
<input type=checkbox name="smallBox" value="ON">
Small
<input type=checkbox name="strikeBox" value="ON">
Strike
<input type=checkbox name="subBox" value="ON">
Sub
<input type=checkbox name="supBox" value="ON">
Sup
<strong>
Font:
</strong>
Color:
<select name="colorList" size=l>
<option selected>black</option>
<option>green</option>
<option>red</option>-
</select>
Size:
<select name="sizeList" size=l>
<option selected>K/option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<opt ion>7</opt ion>
</select>
<input type="button" name="Show" value="Show" onClick="showWindow()
</form>
</body>
</html>
Основные объекты языки
На рис. 10.4 показана форма HTML, позволяющая
определять элементы гипертекстовой ссылки: текст,
наименованиепривязки/ссылкии1ШЬ/привязка, соот-
соответствующая подчеркнутому тексту.
String Object Hypertext Formatting
I « link Г Anchor
Jump To: ^hrtpjy/www • nw-e
РИСУНОК 10.4. Применение гипертекстового форматирования
к объекту String.
На рис. 10.5 изображено результирующее окно с уже
созданной гипертекстовой ссылкой.
1РИСУНОК 10.5. Создание объекта Link с использованием
метода link().
В листинге 10.5 находится полный исходный код
рассмотренного примера.
Работа со специальными символами
В любом языке программирования, рано или поздно,
придется столкнуться с определенными символами,
создающими определенные сложности при использова-
использовании их в строках. Для представления специальных сим-
символов в JavaScript применяется обратная косая черта
(\), за которой следует собственно символ либо его
код. В табл. 10.3 перечислены специальные символы
JavaScript.
Листинг 10.5. Исходный код примера страницы, форматирующей объект String при помощи дескриптора <а>.
<html>
<head>
<title>String Object Hypertext Formatting</title>
<script language="JavaScriptl.1" type="text/javascript">
<! —
function showWindow () (
var txt = document.forml.stringField.value
if (document.forml.hypertext[0].checked){
txt = txt.link(document.forml.jumptoField.value);
}else{
if (document, f orml .hypertext [1] . checked) {
txt = txt.anchor (document, forml. jumptoField. value) ;
// Создание нового окна для помещения в него результатов
objWindow = window.open("", '","width=600,height=300") ;
objWindow.document.write(txt);
objWindow.document.close();
1
II— >
</script>
</head>
<body>
String Object Hypertext Formatting
<hr>
<form method="POST" name-"forml">
Text:
Базовое подмножество языка JavaScript
Часть II
<input type=text size=20 maxlength=256 name="stringField">
<input type=radio name="hypertext" value="Link" checked>
Link:
<input type=radio name="hypertext" value="Anchor">
Anchor:
Jump To:
<input type=text size=20 maxlength=256 name="jumptoField">
</p>
<input type="button" name="Show" value="Show" onClick="showWindow(>">
</form>
</body>
</html>
Таблица 10.3 Специальные символы JavaScript
Символ Описание
¦
\n
V
\f
\ь
V
V
Табуляция
Новая строка
Возврат каретки
Перевод страницы
Обратная косая черта
Забой
Двойные кавычки
Одинарные кавычки
Например, если в строковом литерале необходимо
использовать обратную косую черту, поступите следу-
следующим образом:
var myString = new String ("Ищите свой файл в
¦¦•каталоге C:\\WINDOWS\\TEMP") ;
Подставив строку myString в метод document.write(),
на экране отобразится:
Ищите свой файл в каталоге С
НАПОМИНАНИЕ
В окне сообщений, отображаемом в результате вызова
alertl), символ \г обеспечивает возврат каретки.
Для исключительного удобства использования внут-
внутренних символов их можно присвоить переменным с
осмысленными именами. Если же частота их примене-
применения очень высока, можно извлечь определенные "кон-
"константы" из кодовой библиотеки JavaScript и использо-
использовать их снова и снова. В листинге 10.6 внутренние
символы рассматриваются как константы и присутству-
присутствуют в обращениях к методу document.write().
Листинг 10.6. Использование специальных символов.
<script type="text/javascript">
<!—
// Константы для представления внутренних
// символов
var TAB = "\t";
var CR = "\r" ,-
var LF = "\n";
var CRLF = "\r\n" ;
var FF = "\f";
var dquote = ¦ V ;
var SQUOTE = "\' ";
var BACKSLASH = "\\";
var BACKSPACE = "\b";
document. write("CTan6eul" + TAB + "Ст< " +
TAB + "СтолбецЗ")
II—>
</script>
Помимо внутренних символов JavaScript позволяет
работать с другими значениями, которые нельзя отне-
отнести к алфавитно-цифровым. Если требуется преобразо-
преобразовать подобное значение в ASCII-значение, стоит при-
прибегнуть к методу escape(), например:
escape("Нельзя не любить
wсимвол тильды <~)");
столь уважаемый
Возвращаемое значение выглядит так:
Нельзя%20не%2 0любить%20столь%20уважаемый%2 0
"-•символ%20тильды%28%7Е%29
Если требуется преобразовать ASCII- строку, воз-
возможно, строку, переданную сервером, воспользуйтесь
методом unescape():
unescape("Пишите%20мне%20по%20адресу%20зотеопе
"¦¦ @ anywhere .сот% 21");
Данный код возвращает строковое значение:
Пишите мне по адресу someone@anywhe:
Преобразование строк и чисел
JavaScript обеспечивает два встроенных метода для пре-
преобразования строк в числа: parseint() и parseFloat(). Обе
функции в качестве параметров принимают строки и
пытаются преобразовывать строковые данные в число-
числовые значения. parseintO преобразует строку в целочис-
целочисленное значение, a parseRoat() — в значение с плавающей
точкой. Например, приведенный ниже код возвращает
значение 123:
Основные объекты языка
var myString = new String (23.88888");
document.write(parselnt(myString));
Следующий код возвращает значение 1234.0012121:
var myString = new String(234.0012121") ;
document.write(parseFloat(myString));
Обе программы начинают преобразование с левой
стороны строки и продолжают его до тех пор, пока не
встретится нечто, не являющееся цифрой @—9), деся-
десятичной точкой (.) либо знаком плюса или минуса (+/-).
После столкновения с нецифровым символом оставша-
оставшаяся часть строки игнорируется. Приведенный ниже код
вернет значение 1234.01:
var myString = new String (234.01 — это общая
'-•сумма") ;
document.write(parseFloat(myString));
С другой стороны, следующий код возвращает зна-
значение NaN (Not a Number — не число), поскольку знак
доллара не является цифрой;
var myString = new String < "$1234.01 - это общая
w сумма") ;
document.write(parseFloat(myString));
При работе с текстовыми объектами без функций
преобразования не обойтись. Поскольку свойство value
объекта Text возвращает строку, эти данные придется
преобразовывать каждый раз, когда дело доходит до
необходимости трактовки текста, вводимого пользова-
пользователем, как цифрового значения.
Можно также преобразовывать численные значения
в строки. В версиях, предшествующих JavaScript 1.3,
соответствующие встроенные методы отсутствовали.
Однако упомянутое действие можно было выполнить,
основываясь на том, как JavaScript выполняет операцию
сложения (+). Если во время сложения элементов вы-
выражения JavaScript встречала строку, с этого момента все
выражение расценивалось как строка. Например,
.35+100 возвращает цифровое значение 135. С другой
стороны, 35+00" в результате дает строковое значе-
значение 5100".
ПРИМЕЧАНИЕ ." , , . - . '
При работе с объектом Number в среде, поддержи-
поддерживающей JavaScript 1.3+, для преобразования в стро-
строковые значения можно использовать метод toStringI).
Обратите внимание, что JavaScript выполняет опе-
операции сложения слева направо, поэтому перед преоб-
преобразованием выражения в строку можно сложить, ска-
скажем, два числа. Например, 10 + 20 + 0" вернет
строковое значение 040", поскольку пара 10 + 20 вы-
вычисляется до прибавления результата к строковому зна-
значению. А вот 0" +10 + 20 выдает в качестве резуль-
результата строковое значение 01020" из-за того, что левее
всех числовых значений находится строковый литерал.
Глава 10
Многие языки программирования требуют обяза-
обязательного преобразования числовых значений перед их
использованием в качестве строковых. Все что требует-
требуется предпринять — это либо поместить числовое значе-
значение в строковое выражение, либо добавить к нему пус-
пустую строку. Например, выражение 1300+ "" возвращает
строковое значение 300". Вместо того чтобы каждый
раз для преобразования добавлять пустую строку, мож-
можно записать простую функцию:
function numToString(number) (
number += " " ;
return number;
'_]
В листинге 10.7 находится сценарий, в котором ис-
используется приведенная выше функция. Первое окно
предупреждений выведет на экран в качестве типа
Number. После выполнения функции numToString() во
втором окне будет отображаться String.
Листинг 10.7. Преобразование Number в String.
<script type="text/javascript">
<!--
function numToString (number) {
number += "" ;
return number;
J
var number = 100;
alert(typeof number);
number = numToString (number) ;
alert(typeof number);
//-->
</script>
Объект RegExp
В предыдущем разделе упоминалось о возможности со-
создания функций, выполняющих вычисления и поиско-
поисковые операции. В JavaScript 1.2 появился базовый объект
RegExp, позволяющий выполнять регулярные выраже-
выражения над строками.
Поскольку глава 31 обеспечивает достаточно деталь-
нос рассмотрение данной темы, не имеет смысла углуб-
углубляться в нее сейчас. В табл. 10.4 сведены свойства и
методы объекта RegExp.
Объект Array
Массивы являются основой практически любого совре-
современного языка программирования, и JavaScript — тому
не исключение. Здесь имеется возможность создавать
массивы и работать с ними. Массив (array) — это кон-
контейнер, содержащий элементы данных. Каждый из эле-
элементов массива — отдельное значение, но все они су-
существуют как часть массива. Доступ к ним возможен
только через сам массив. В табл. 10.5 сведены все мето-
методы и свойства объекта Array.
Базовое подмножество языка JavaScript
Часть И
Таблица 10.4. Методы и свойства объекта RegExp.
Тип
Элемент
Описание
Метод
Свойство
compileO
ехес()
test()
iRegExp.$*
RegExp.$&
RegExp.&_
RegExp.&'
RegExp.$'
'RegExp.$+
RegExp.$1,$2,"$9
global
ignoreCase
input
lastindex
lastMatch
lastParen
leftContext
multiline
right Context
source
Компилирует регулярное выражение для ускорения его выполнения.
Выполняет поиск совпадений в строковом параметре.
Проверяет наличие совпадений в строковом параметре.
Представляет multiline.
Представляет last match.
Представляет input.
Представляет leftContext.
Представляет rightContext.
Представляет lastParen.
Представляет совпавшие подстроки.
Проверяет, какие возможные совпадения были найдены
Проверяет, игнорировался ли регистр во время поиска.
Строка, в которой осуществляется поиске помощью регулярного выражения.
Определяет индекс, с которого начинается поиск следующей строки.
Последние совпавшие символы.
Последняя совпавшая подстрока, взятая в круглые скобки.
Подстрока, предшествующая последнему совпадению.
Проверяет, должен ли выполняться поиск во множестве строк.
Подстрока, следующая за последним совпадением.
Шаблон строки.
Таблица 10.5 Методы и свойства объекта Array.
Тип
Элемент
Описание
Метод
Свойство
concat()
рор()
push()
reverse()
shift()
slice()
sort()
splice(>
toSource()
toStringO
unshift()
valueOf()
index
input
lengthi
prototype
Соединяет элементы существующего массива. Метод появился в JavaScript 1.2.
Соединяет все элементы массива в одну строку.
Удаляет последний элемент массива.
Добавляет элементы в конец массива.
Изменяет порядок следования элементов в массиве. Метод появился в JavaScript 1.2.
Удаляет элементы в начале массива. Метод появился в JavaScript 1.2.
Возвращает часть массива. Метод появился в JavaScript 1.2
Сортирует элементы в массиве.
Вставляет и удаляет элементы из массива. Метод появился в JavaScript 1.2.
Преобразует элементы в строку с квадратными скобками. Метод появился в JavaScript 1.3.
Преобразует элементы массива в строку.
Добавляет элементы в начало массива. Метод появился в JavaScript 1.2.
Возвращает массив элементов, отделенных запятыми.
Возвращает индекс совпадения в строке для массива, созданного в соответствие с
регулярным выражением. Появилось в JavaScript 1.2.
Для массива, созданного в соответствие с регулярным выражением свойство
возвращает исходную строку. Появилось в JavaScript 1.2.
Количество элементов в массиве.
.Позволяет добавлять свойства к экземплярам объекта Array. Свойство появилось в
JavaScript 1.1.
Основные объекты языка
Несмотря на то что в строго типизированных языках
все значения элементов массива должны иметь оди-
одинаковый тип, в JavaScript это необязательно. Массив
может содержать данные различных типов, точно так
же как объект имеет свойства разных видов.
¦ПРЕДУПРЕЖДЕНИЕ ^ Ц11Ш" , '^ ' - ' ^
В JavaScript массив не является родным объектом —
объект Array появился только в JavaScript 1.1. Для оп-
определения массива в JavaScript требовалось создавать
функцию. Заметьте, что он не будет обладать всей
функциональностью родного объекта Array.
function createArray(size) {
this, length = size;
for (var i = 1; i <= size; i-l—Ь) {
this[i] = null ;
return this;
I
Для определения или доступа к какому-либо эле-
элементу к переменной массива необходимо приписать
скобки и задать индексное значение. Например, для оп-
определения массива coffee необходимо сделать следую-
следующее:
coffee[0]
coffee[1]
coffee[2]
coffee[3]
coffee [4]
coffee[5]
coffee[6]
"Ethiopian Sidamo"
"Kenyan"
"Cafe Verona"
"Sumatra"
"Costa Rica"
'"Columbian"
"Bristan"
Если нужно использовать один из элементов масси-
массива внутри сценария, доступ к ним можно получить с
помошью переменной массива и значения, которое
представляет положение элемента внутри массива. Ото-
Отображение на экране строки
Мой любимый сорт кофе — Ethiopian Sidamo
осуществляет такая срока кода;
Document .write ("Мой любимый сорт кофе — " +
coffee [0] ) ;
Если читатель незнаком с массивами, то ближайший
эквивалент в JavaScript — это нумерованный список.
Пусть список состоит из 10 пунктов.
1. JavaScript
7. Java
3. Delphi
4. C++
5. Visual Basic
6. Oracle Power Objects
7. SmallTalk
Глава 10
8. PowerBuilder
9. Paradox
10. Access
Компоновка этой группы в массив JavaScript пока-
показана ниже. Особенность заключается в том, что масси-
массивы имеют нулевую базу, т.е. индекс первого элемента
равен 0:
devTools[0]
devTools[1]
devTools[2]
devTools[3]
devTools[4]
devTools[5]
devTools[6]
devTools[7]
devTools[8]
devTools[9]
"JavaScript"
"Java"
"Delphi"
"C++"
"Visual Basic"
"Oracle Power Objects''
"SmallTalk"
"PowerBuilder"
"Paradox"
"Access"
Экземпляр объекта Array создается при помощи опе-
оператора new и операторов, заполняющих массив элемен-
элементами данных. Например, для упоминаемого ранее мас-
массива coffee код должен выглядеть следующим образом:
¦¦ new Array () ;
"Ethiopian Sidamo"
"Kenyan";
"Cafe Verona" ;
"Sumatra";
"Costa Rica";
"Columbian";
"Bristan";
var coffee ==
coffee[0] = =
coffee[1] ==
coffee[21 = =
coffee[3] = =
coffee[4] = =
coffee [5] =»
coffee[6] = =
MjoBETi- '¦' •¦-¦¦:-",
Альтернативой определению объекта Array может
быть указание элементов данных как параметров зап-
запроса new. Следующая строка является функциональ-
функциональным эквивалентом предыдущего примера.
var coffee = new Array ("Ethiopian Sidamo",
"Kenyan", "Cafe Verona", "Sumatra",
"Costa Rica", "Columbian", "Bristan");
Обратите внимание, что размер массива явно не за-
задается; это не характерно для многих языков програм-
программирования. В JavaScript определение размера массива не
обязательно. Именно это свойство позволяет расширить
массив, добавляя новые элементы данных. С другой
стороны, если необходимо, размер массива можно за-
задать явно в new:
var coffee = new Array G>;
Изменение размеров массива также можно осуще-
осуществить путем определения элемента данных в позиции
п. Если п превышает существующее количество элемен-
элементов в массиве, размер массива увеличивается до п+1.
Посмотрите на следующий пример:
var javaDrinks = new Array () ;
javaDrinks[0] = "Regular coffee";
javaDrinks[1] = "Decaf coffee";
Базовое подмножество языка JavaScript
Часть II
javaDrinks[2] = "Cafe Mocha";
javaDrinks [ 3] = "Cafe au Lait";
javaDrinks[199J = "Cafe Latte" ;
Размер массива javaDrinks будет составлять 200,
даже притом, что определено только 5 элементов дан-
данных. При доступе к неопределенным элементам возвра-
возвращается значение null.
Выяснить размер массива поможет свойство length
объекта Array. Например, если необходимо пройти по
всем элементам объекта Array, можно воспользоваться
сценарием из листинга 10.8.
Листинг 10.8. Вывод на экран содержимого массива.
<script language="JavaScriptl .1"
-"text/j avas cript">
var coffee
coffee [0] =
coffee [1] =
coffee [2] =
coffee[3] =
coffee [4] =
coffee [5] =
coffee[6]
' new Array (> ;
"Ethiopian Sidamo"
"Kenyan";
"Cafii Verona" ;
"Sumatra";
"Costa Rica";
"Columbian";
"Bristan";
Coffees of the World:<p>") ;
for (var i = 0; i < coffee, length; i++) {
;.write(i + 1 + ". " + coffee[i] +
1
document, write(,</р>* ) ;
</script>
На рис. 10.6 показан результат.
. ?fe E<S vum'tsSmtM
.•U:\TEMPV7EK10 Lffi.hM
Coffees of the WmM:
J. ?thiopian Sidamo
2. Kenyan
3. Cafe Verona
4. Sumatra
5. Costarica.
6. Columbian
7. Bristatl
assets,...-:,, ¦¦*¦;.,.:¦;¦:-,:
ШшШВШшш
z izl
ПРЕДУПРЕЖДЕНИЕ
Свойство length объекта Array предназначено только
для чтения. Отсюда вывод — изменить размеры мас-
массива за счет присваивания нового знач< я свойству
length нельзя.
.
Объект Date
1РИСУНОК 10.6. Использование JavaScript для вывода на экран
списка сортов кофе.
С помощью объекта Date в JavaScript можно работать
со значениями даты и времени. Но перед тем как при-
приступить к работе с этим объектом, необходимо разоб-
разобраться в трех важных вещах:
В соответствие с соглашением UNIX, датой появле-
появления JavaScript считается 1 января 1970 Соответ-
Соответственно, с датами, предшествующими указанной, ра-
работать нельзя.
При создании объекта Date базой, на которой осно-
основывается отсчет времени внутри объекта, является
клиентская машина. Таким образом, на ней желатель-
желательно наличие работоспособных и точных часов. Учи-
Учитывайте это при написании JavaScript-сценариев,
чувствительных ко времени.
• JavaScript отслеживает значения даты и времени в
форме миллисекунд с момента даты основания A/1/
1970).
Важный набор методов, инкапсулированный внут-
внутри объекта Date, принимает и устанавливает значения
даты и преобразует их в различные формы. В табл. 10.6
показаны все методы и свойства объекта Date.
ПРИМЕЧАНИЕ
Как и все остальное в JavaScript, относительные зна-
значения даты также имеют нулевую базу. Нав« это
может вызвать определенные неудобства, поскольку
отсчет дней недели осуществляется от 0 до 6, а не
от 1 до 7, и месяцев от 0 до ' ' , а не от 1 до 12.
Используя в коде значения подобного рода, следует
принимать во внимание нулевую базу.
Однако, исключением из правил являются дни меся-
месяца, отсчитываемые от 1 до 31 и представляющие со-
собой абсолютные значения.
Создание объекта Date подобно созданию объектов
String или Array. В сценарии эти объекты можно созда-
создавать в любых количествах. Используя оператор new, оп-
определить объект Date можно так:
var dateVariable = new Date ([parameter.
Различные группы параметров, необходимые для
создания этих объектных экземпляров, перечислены в
табл. 10.7.
Основные объекты языка
Глава 10
Таблица 10.6. Методы и свойства объекта Date.
Тип
¦Элемент
Описание
Метод getDate()
getDayO
getFullYear()
getHours()
getMillisecondsO
getMinutesQ
getMonth()
¦getSeconds()
getTime()
getTimeZoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHoursQ
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
getYear()
parse()
setDate()
setFullYearf)
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTimeO
setUTCdatef)
setUTCFullYear()
setUTCHours()
setUTMillisecondsf)
setUTCMinutes()
setUTCMonth()
Возвращает день месяца (от 1 до 31).
Возвращает день недели (от 0 до 6).
Возвращает год в четырех символах по местному времени.
Метод появился в JavaScript 1.2.
Возвращает час суток (от 0 до 23).
Возвращает миллисекунды. Метод появился в JavaScript 1.2.
Возвращает минуты в пределах часа (от 0 до 59).
Возвращает месяцы года (от 0 до 11).
Возвращает секунды (от 0 до 59).
Возвращает количество миллисекунд, начиная с 1/1/1970 00:00:00.
Возвращает смещение часового пояса в минутах по отношению к GMT/UTC.
Возвращает день месяца. Метод появился в JavaScript 1.2.
Возвращает день недели, преобразованный к универсальному времени.
Метод появился в JavaScript 1.2.
Возвращает четырехзначное представление года, преобразованное к универсальному
времени. Метод появился в JavaScript 1.2,
Возвращает часы, преобразованные к универсальному времени.
Метод появился в JavaScript 1.2.
Возвращает миллисекунды, преобразованные к универсальному времени.
Метод появился в JavaScript 1.2.
'Возвращает минуты, преобразованные к универсальному времени.
Метод появился в JavaScript 1.2.
Возвращает месяц, преобразованный к универсальному времени.
Метод появился в JavaScript 1.2.
Возвращает секунды, преобразованные к универсальному времени.
Метод появился в JavaScript 1.2.
Возвращает номер года, начиная с 1900 г.
Преобразует строковые данные в миллисекунды.
Устанавливает день месяца (от 1 до 31).
Устанавливает год как четырехзначное число. Метод появился в JavaScript 1.2.
Устанавливает часы дня (от 0 до 23).
Устанавливает миллисекунды. Метод появился в JavaScript 1.2.
Устанавливает минуты в часе (от 0 до 59).
Устанавливает месяц в году (от 0 до 11).
Устанавливает секунды в минуте (от 0 до 59).
Устанавливает количество миллисекунд, начиная с 1/1/1970 00:00:00.
Устанавливает день месяца в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
Устанавливает год как четырехзначное число в соответствии с универсальным
временем. Метод появился в JavaScript 1.2.
Устанавливает час в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
Устанавливает миллисекунды в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
Устанавливает минуты в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
Устанавливает месяц в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
Базовое подмножество языка JavaScript
Тип
Часть II
Элемент
Описание
setUTCSecondsQ Устанавливает секунды в соответствии с универсальным временем.
Метод появился в JavaScript 1.2.
sefYearQ Устанавливает количество лет, начиная с 1900 г.
toGMTStringO Преобразует дату в строку в соответствии с мировым форматом.
toLocalString() Возвращает строку даты в формате локальной системы.
toSourceQ Возвращает источник-объект Date. Метод появился в JavaScript 1.3.
toString() Возвращает дату и время как строку в соответствии с местным временем.
ToUTCStringO Возвращает данные и время как строку в соответствии с мировым временем (UTC).
Метод появился в JavaScript 1.2.
UTC() Преобразует значения с разделителями-запятыми в миллисекунды даты по UTC,
valueOf() Возвращает эквивалент объекта Date в миллисекундах. Метод появился в JavaScript 1.1.
Свойство prototype Свойство, позволяющее добавлять методы и свойства к объекту Date.
Свойство появилось в JavaScript 1.1.
Таблица
Параметр
10.7.
Параметры, необходимые
Описание
ДЛЯ
создания
экземпляра
объекта
Date.
Пример
Отсутствие параметров
"месяцдд, гггг чч:мм:сс"
гг, мм, дд
irr, мм, дц, чч, мм, ее
Создает объект с текущими датой и временем.
Создает объект с указанными датой (дц — день, гггг — год)
и временем (чч — часы, мм — минуты, ее — секунды).
При этом все пропущенные значения считаются нулевыми.
Создает объект с указанными датой из набора
целочисленных значений (гг — год, мм — месяц, дц — день)
Созцает объект с указанными цатой и временем из набора
целочисленныхзначений(гг— гоц, мм — месяц, дц — цень,
чч — часы, мм — минуты, ее — секунцы). При этом все
пропущенные значения считаются нулевыми.
var today = new Date()
var someDate = new Date
("September 27, 2000";
var someDate =
new Date@0, 1, 0)
var someDate =
new Date@0, 7, 24, 6, 29, 50)
После создания объекта можно использовать все его
методы для получения или установки значения даты.
Например, для возврата текущей даты следует записать:
var today = new Date (> ;
result = today.getDate();
Для изменения месяца, определенного в объекте appt
типа Date потребуется записать:
var appt = new Date B000,10,20) ;
result = appt. setMonth G) ;
Раньше упоминалось, что значения даты с нулевой
базой осложняют процесс получения даты. Эту труд-
трудность несложно обойти, расширив методы объекта Date,
создав прототипы более приемлемых методов get.
Как известно, JavaScript позволяет расширять воз-
возможности встроенных объектов, тем самым позволяя
создавать прототипы новых методов или свойств. Все
объекты должны быть унаследованы от этого нового
прототипа. Добавьте в объект Date следующие новые
методы:
• getActualMonth() будет возвращать действительное
значение для месяца.
• getCalendarMonth() будет возвращать название меся-
месяца.
• getActualDay() будет возвращать текущее численное
значение дня недели.
• getCalendarDay() будет возвращать название дня не-
недели.
В листинге 10.9 приводятся определения для каждо-
каждого из прототипов перечисленных методов. Данный ли-
листинг послужит наглядным примером сохранения обще-
общеупотребительных функций во внешней библиотеке
JavaScript или в исходном файле, который можно заг-
загрузить при помощи атрибута src дескриптора <script>.
Листинг 10.9. Расширение объекта Date за счет
добавления в него новых методов.
<script type=" text/ javascript"
language="JavaScriptl.1">
Date . prototype. getActualMonth = getActualMonth;
Date.prototype.getActualDay = getActualDay;
Date.prototype.getCalendarDay = getCalendarDay;
Date.prototype.getCalendarMonth =
getCalendarMonth ,¦
Основные объекты языка
function getActualMonth() {
var n = this. getMonth () ;
n += 1;
return n ;
i
function getActualDay() {
var n = this.getDay ();
n += 1 ;
return n, ;
}
function getCalendarDay() (
var n « this.getDay () ;
var dow = new Array G) ;
dow[0] = "Sunday";
dow[lj = "Monday";
dow[2] = "Tuesday";
dow[3] = "Wednesday";
dow[4] = "Thursday";
dow[5] = "Friday";
dow[6] = "Saturday";
return dow[n];
j
function getCalendarMonth(> {
var n = this .getMonth();
var moy = new Array A2) ;
moy[0] = "January";
moy[l] = "February";
raoy[2] = "March";
moy[3] = "April";
moy[4] = "May";
moy[5] = "June";
moy[6] = "July";
moy[7] = "August";
moy[8] = "September";
moy[9] = "October";
moy[10] = "November";
moy[11] — "December";
return moy[n];
i
// Тестирование вновь созданных методов
var today = new Date () ;
document.write("<b>I hereby declare that on '
+ today.getCalendarDay() + " , the "
+ today. getDate () + " th day of
+ today . getCalendarMonth ()
¦+ "' in the year "
+ today.getFullYear () + " A.D. at the "
+ today.getHours()
+ "th hour of the day, absolutely nothing
wis happening.</b>") ;
II—>
</script>
Псслс объявления методов сценарий создает объект
Date и генерирует HTML-документ, используя комби-
комбинацию прототипных методов (см. рис. 10.7).
Поскольку JavaScript является приложением, работа-
работающим в среде World Wide Web, в нем определены мето-
методы, работающие с часовыми зонами. getTimezoneOffset()
возвращает размер различия в минутах между клиентс-
клиентским компьютером и GMT (Greenwich Mean Time -
время по Гринвичу). Например, я сейчас нахожусь в во-
Глава 10
сточной часовой зоне США. Если мне нужно вернуть
часовое смещение временной зоны, я запишу такой код:
var today = new Date() ;
offset = today.getTimezoneOffset() / 60;
if (offset = 5) (
alert("Вы находитесь в восточной временной
зоне");
hereby . laje that on Saturday, the 5th day of February in Uu year 2000 AJ>. at the 12Ui hQ»u- of the
day, ahsolutetjrnothingishappening-
РИСУНОК 10.7. Использованиеусовершенствованных
методов get.
Рисунок 10.8 показывает результат запуска сценария.
Можно выполнять вычисления со значениями дат,
определив таким образом количество дней до конца
следующего столетия. Даты, используемые в вычисле-
вычислениях, необходимо хранить в их собственном миллисе-
кундном формате, а затем выделять соответствующие
данные.
РИСУНОК 10.8. #cna/!b3oeaHHegetTimezoneOffset() для
определения временной зоны.
Объект Math
С целью эффективной организации математических вы-
вычислений JavaScript инкапсулирует большое число ма-
математических констант и процедур в единый объект
Math. Он в некоторой степени отличается от других
базовых объектов. Во-первых, можно выполнять базо-
базовые арифметические вычисления (сложение, вычитание,,
умножение, деление) за пределами объекта Math. До
тех пор пока не потребуются сложные математические
Базовое подмножество языка JavaScript
Часть II
функции, использование данного объекта будет чрезвы-
чрезвычайно редким.
Во-вторых, хотя и можно создавать экземпляры
объектов String, Array, Date при помощи new, все рав-
равно работа продолжается с базовым экземпляром Math.
Подобное качество позволяет расценивать этот объект
как созвучный navigator, который никогда не создается
"на лету". Именно поэтому на объект Math ссылаются
как на статический (static) объект.
Свойства объекта Math — ни что иное как последо-
последовательность общих математических констант. Свойства
и методы этого объекта сведены в табл. 10.8. Обратите
внимание на регистр в именах констант. Несмотря на
то что практически все имена свойств JavaScript запи-
записываются в нижнем или же в смешанных регистрах,
Таблица 10.8. Методы и свойства объекта Math.
имена рассматриваемых свойств записаны символами
верхнего регистра.
Объект Boolean
Значения логического типа являются неотъемлемой час-
частью любого языка программирования. Объект Boolean,
впервые появившийся в JavaScript 1.1, применяется для
преобразования значений, не относящихся к логическо-
логическому типу, в значения логического типа. В конечном итоге
с этим объектом можно работать как с обычным значе-
значением логического типа (true или false). Объект Boolean
можно создать, прибегнув к уже знакомому оператору
new:
var booIeanObjectName = new
Boolean(initialValue);
Tun
Элемент
Описание
Метод abs() Возвращает абсолютное значение.
acos() Возвращает значение арккосинуса для аргумента, выраженное в радианах.
asin() Возвращает значение арксинуса для аргумента, выраженное в радианах.
atan() Возвращает значение арктангенса для аргумента, выраженное в радианах.
atan2() Возвращает значение арктангенса для частного от деления аргументов, выраженное в
радианах.
ceil() Возвращает целое число, большее или равное переданному значению.
cos() Косинус для переданного значения.
ехр() Возвращает константу Эйлера для степени, переданной в качестве значения.
floor() Целое число, меньшее или равное переданному значению.
!од() Натуральный логарифм по основанию е.
тах() Максимальное число из двух переданных значений.
min() Минимальное число из двух переданных значений.
pow() Результат возведения первого переданного в качестве аргумента числа в степень второго.
Random() Возвращает случайное число между 0 и 1. Метод появился в JavaScript 1.1.
roundQ Возвращает значение, округленное до ближайшего целого.
sin() Возвращает синус переданного числа, выраженный в радианах.
sqrt() Квадратный корень переданного числа.
tan() Возвращает тангенс переданного числа, выраженный в радианах.
toSource() Копия объекта. Метод был добавлен в JavaScript 1.3.
toStringO Строковое представление объекта.
Свойство Е Константа Эйлера B.718281828459045).
LN2 Натуральный логарифм 2 @.6931471805599453).
LN10 Натуральный логарифм 10B.302585092994046).
LOG2E Логарифма Е по основанию -2 A.4426950408889633).
LOG10E Логарифм Е по основанию -10 @.4342944819032518).
PI Число Пи C.141592653589793)
SQRT1_2 Квадратный корень 0.5 @.7071067811865476)
SQRT2 Квадратный корень 2A.4142135623730951).
Основные объекты языка
Параметр initialValue определяет начальные установ-
установки объекта.Если параметр принимает значение false, О,
null или пустую строку (""), или вообще пропущен,
принимается значение по умолчанию, равное false. В
противном случае — true.
В табл. 10.9 приведены методы и свойства объекта
Boolean..
Объект Number
Объект Number, поддерживаемый в JavaScript 1.1 и сле-
следующих версиях, служит для хранения числовых зна-
значений наподобие того, как объект String предназначен
для хранения строковых значений. Однако в действи-
действительности он используется гораздо реже. Этот объект
применяется, если необходимо получить доступ к оп-
определенным значениям констант, таким как максималь-
максимально или минимально представимыс числа, плюс или
минус бесконечность или нечисловые значения (NaN).
Упомянутые значения реализованы в виде свойств
объекта Number. В табл. 10.10 приведены методы и свой-
свойства объекта Number.
Как и другие базовые объекты, экземпляры объекта
Number в сценарии создаются при помощи оператора
new со следующим синтаксисом:
var munberObjectName = new Number (initialValue) ;
Зачастую объекты Number создаются, когда к ним
требуется добавить новые свойства. Например, листинге
10.10 содержит сценарий, демонстрирующий особую
полезность объектов Number. Здесь уменьшается необ-
Таблица 10.9. Методы и свойства объекта Boolean.
Глава 10
ходимость выполнения множества преобразований
строк в числа.
Результат выполнения сценария показан на рис.
10.9.
t* if-* fiu Vftdw HH
1
:',>
~T| $J
The speed cKfferencptrtweeu Interstate Highway Speed Lunit ami City Speed Lenit is 30
РИСУНОК 10.9. Использование объекта Number.
Объект Function
Последний базовый объект, появившийся в JavaScript
1.1. — это Function. Он позволяет определить строку во
время выполнения и компилировать ее как функцию.
Рассмотрим синтаксис объявления объекта Function.
ямяОбъектаРипсЫоп = new Function {[аргумент1,
аргуыент2, ... аргументы], (гелоФункции) ;
Тип
Элемент
Описание
Метод Возвращает строковое представление простейшего значения Boolean, хранящегося в объекте.
Если в объекте содержится true, возвращается строка "true", а если false —то "false".
Свойство prototype Это свойство позволяет добавлять методы и свойства в объект Boolean.
Таблица 10.10. Методы и свойства объекта Number.
Тип
Элемент
Описание
Метод
toString()
valueOff)
Свойство MAX_VALUE
MIN_VALUE
NaN
POSITIVEJNFINITY
NEGATIVEJNFINITY
prototype
Возвращает строковое представление объекта Number. Метод появился в JavaScript 1.3.
Возвращает строковое представление заданного объекта Number.
Возвращает значение объекта Number как числовой тип данных.
Максимальное число A.797693148623157е+308).
Минимальное число Eе-324).
Специальное нечисловое значение (NaN).
Специальное значение бесконечности, возвращаемое в случае переполнения.
Специальное значение, представляющее отрицательную бесконечность; возвращается в
случае переполнения.
Позволяет добавлять новые свойства и методы к объекту Number.
Базовое подмножество языка JavaScript
Часть II
Листинг 10.10. Создание объекта Number вместо выполнения преобразования строк в числа.
<html>
<head>
<script language="JavaScriptl.1" type="text/javascript">
// Добавление свойства description в объект Number
Muniber.prototype, description = null;
// Значения ограничений скорости
slHighway = new Number F5) ;
slCity = new Number C5);
slSchoolZone = new Number B5);
// Добавление описаний в свойствах description
slHighway.description = "Interstate Highway Speed Limit";
slCity.description = "City Speed Limit";
slSchoolZone.description = "School Zone Speed Limit";
.// Вычитание num2 из numl и отображение результата вместе с
// описанием исходных значений,
function tellDifference(numl, num2) {
diff = numl - num2;
document.write("The speed difference between " + numl.description + " and " +
num2 .description + " is " + diff) ;
II—>
</script>'
</head>
<body>
<script language="JavaScriptl.1" type="text/javascript">
// Вызов функции
tellDifference(slHighway, slCity);
II—>
</script>
</body>
</hfanl>
Следует учесть, что несмотря на внешнее подобие
объекта Function и стандартной функции JavaScript (т.е.
function), все же они существенно отличаются друг от
друга. Имя объекта Function рассматривается как пере-
переменная, представляющая текущее значение функции,
определенной в строке new Function, в то время как имя
стандартной функции JavaScript переменной не являет-
является — это именно имя функции.
ПРИМЕЧАНИЕ :, ," .- Л",^ .Г'1* ¦*"*%¦:'¦
Трансляция объекта Function выполняется при каждом
его использовании. Неудивительно, что их выполнение
происходит гораздо медленнее по сравнению с нор-
нормальными функциями JavaScript.
Объект Function можно использовать как обработчик
событий. Рассмотрим пример;
window.onload = new Function("document.bgColor =
"aqua1");
Резюме
К базовым объектам языка следует относиться как к
важнейшим винтикам рабочего механизма JavaScript,
поскольку большая часть работы выполняется как раз
внутри их конструкций. Кроме того, не забывайте, что
именно базовые объекты стандартизируются в соответ-
соответствие со спецификацией ECMAScript.
Глава была посвящена методике использования ба-
базовых объектов языка и описанию особенностей из фун-
функционирования в различных версиях браузеров. В сле-
следующей главе будут рассматриваться примеры приме-
применения массивов и способы создания пользовательских
объектов.
Создание пользовательских
объектов JavaScript
В ЭТОЙ ГЛАВЕ
Создание объектов
Создание экземпляров объектов
Работа с экземплярами объектов
Создание составных объектов
Динамическое создание объектов
Расширение экземпляров объектов
Данная глава является логичным продолжением пре-
предыдущей. В главе 9 мы много говорили об основах
объектно-ориентированного программирования, а в гла-
главе 10 — о встроенных объектах языка JavaScript. Но
если на этом остановиться, возможности JavaScript мо-
могут показаться весьма скудными. Не следует упускать из
виду создание собственных пользовательских объектов.
Именно этой теме и посвящается данная глава.
Создание объектов
Пользовательские объекты JavaScript тесно связаны с
массивами. Массивы — средство структурирования дан-
данных в контейнере. Какими бы мощными не были бы
массивы, они не в состоянии удовлетворить все запро-
запросы разработчиков. Несмотря на то что массивы хранят
данные, они не могут хранить поведение.
Как обсуждалось в главе 9, объект содержит и дан-
данные, известные как свойства (properties), и поведение,
известное как методы (methods). На первый взгляд мо-
может показаться, что массив — почти то же самое, что и
объект со свойствами, однако есть один нюанс: массив
не хранит информацию о способе своей реакции на ме-
методы. Наша задача — создать объект, инкапсулирующий
элементы данных и обеспечивающий реакцию на вызов
методов.
Для создания объекта JavaScript необходим конст-
конструктор (constructor). Конструктор — это специальная
функция JavaScript, которая определяет вид объекта и
его поведение. Сам по себе конструктор не создает
объекты. Вместо этого он обеспечивает шаблон вида
реализованного объекта. (Создание экземпляра объекта
называется реализацией (instantiating) объекта.) Базовая
структура реализованного объекта выглядит так:
function object.{parameterI, parameter2,...\ {
this . proper tyl = parameter 1
this. property2 = parameter2
this. property 3 = parameters
this . proper ty 4 = parameter!
this.methodl = functionl
this .method2 = Iuiiclion2
Простота нестоящей структуры конструктора доста-
достаточно очевидна. Сначала потребуется присвоить имя
самому методу. Имя функции послужит именем объек-
объектного типа. Если объект создается с целью представле-
представления, скажем, счета-фактуры, назовите его invoice. Иног-
Иногда мне встречались программисты, которые в названиях
конструкторов использовали глагол; получалось что-то
наподобие createlnvoice. Подобная практика может при-
привести к снижению удобочитабельности кода, т.к. свой-
свойство объекта будет выглядеть как-то так:
myDate — createlnvoice.date;
Даже еще хуже, если среди методов объекта присут-
присутствует create(), код приобретет просто "шикарный" вид:
createlnvoice .created ;
А вот в случае применения существительных для
именования можно надеяться на гораздо более изящный
вид:
myDate = invoice.date;
И
invoice.create();
Следующий шаг заключается в добавлении парамет-
параметров в функцию для всех свойств объекта. Следуя тако-
такому подходу, при реализации объекта значения свойств
передаются в функцию в форме параметров.
Третьим шагом будет присвоение свойствам объек-
объектам значений входных параметров. Ключевое слово this
Базовое подмножество языка JavaScript
Часть II
очень удобно; оно используется для представления
объекта в момент определения свойств.
Четвертый шаг связан с определением методов, ко-
которыми будет обладать объектный тип. В то время как
свойствам присваиваются значения параметров конст-
конструктора, методы создаются в виде функций за предела-
пределами конструктора и присваиваются определениям мето-
метода объекта.
Предположим, что необходимо создать пользова-
тельскийобъект,применяемыйдляхраненияинформа-
ции о любимых книгах. В частности, хотелось, чтобы в
нем присутствовало название книги, имя автора (или
авторов), ISBN, предмет, которому посвящена книга, и
присвоенный ей внутренний рейтинг. Конструктор
можно определить следующим образом:
function book(title, author, ISBN, subject,
rating) I
this.title = title;
this.author = author;
this. ISBN = ISBN;
this.subject = subject;
this.rating = rating;
}
Кроме того, хотелось бы добавить метод show(),
который будет отображать на экране информацию об
объектах. Создадим функцию, размещенную за преде-
пределами конструктора:
function show () {
objwindow = window.open ("", "",
"width=600,height=300");
ob jwindow. document. write ("<htmlxbody>" > ;
objwindow.document.write("<hl>Object
^Description</hl>");
objwindow.document.write("<p>");
objwindow.document.write("Book Title: " +
this.title + "<br>");
objWindow.document.write("Author: " +
this.author + "<br>") ,-
objwindow.document.write("ISBN: " +
this.ISBN + "<br>") ,-
objwindow.document.write("Subject: " +
this.subject + "<br>");
Листинг 11.1. Определение объекта Book.
objwindow.document.write("Allen's Rating: "
this.rating + "<br>") ,-
objwindow. document.write ("</bodyX/html>") ;
objwindow.document.close () ;
Несмотря на то что этот код находится за предела-
пределами конструктора, можно рассмотреть его как часть опи-
описания объекта. Следовательно, в данном случае придется
прибегнуть к ключевому слову this.
Далее в конструктор добавляется новый вход для
метода:
function book(title, author, ISBN, subject,
rating) {
this.title = title;
this, author = author;
this.ISBN = ISBN;
this.subject = subject;
this.rating = rating;
this. show = show; // Новый метод отображения
»
Обратите внимание на две детали, относящиеся к
описанию метода show(). Во-первых, имя объектного
метода совпадает с соответствующей внешней функци-
функцией, чего быть не должно. Для большей читабельности
одни разработчики используют идентичные имена, а
другие — добавляют внешнюю функцию, содержащую
в своем имени еще и имя объекта, например, book_
show(). Во-вторых, в конструкторе записывается лишь
только имя внешней функции, без круглых скобок.
В ранних версиях Netcsape Navigator описание ме-
тодатребовалосьрасполагатьдоконструктора, посколь-
поскольку все ссылки выполнялись сверху вниз. В Navigator 3+
такого уже нет. Размещение метода show() относитель-
относительно метода конструктора в JavaScript роли не играет.
Упомянутый факт дает возможность улучшить чи-
читабельность кода, разместив описания методов непо-
непосредственно под конструктором. Крометого, стоитпо-
местить набор функций в комментарий, чтобы они вос-
воспринимались как целостная конструкция. В листинге
11.1 приводится полное описание объекта Book,
<script type="text/javascript">
<!--
function book(title, author, ISBN, subject, rating) (
this.title = title;
this.author = author;
this. ISBN = ISBN,-
this.subject = subject;
this.rating = rating;
this. show = show;
}
function show (У {
objwindow = window. open ("", "", "width=600,height=300");
objwindow. document .write {„<htmlXbody >") ;
objwindow.document.write("<hl>Object Description</hl>");
objwindow.document.write("<p>");
objwindow.document.write("Book Title: " + this.title + "<br>");
Создание пользовательских объектов JavaScript
Глава 11
objWindow.document.write ("Author: " + this, author + "<br>") ;
objWindow.document.write("ISBNr " + this.ISBN + "<br>");
objWindow.document.write("Subject; " + this.subject + "<br>");
objWindow.document.write("Allen's Rating: " + this.rating + "<br>");
objWindow. document.write ("</bodyX/html>") ;
objWindow.document.close();
II—>
</script>
Создание экземпляров
Для задействования объекта, объявленного в конст-
конструкторе book() необходимо создать его экземпляр. Для
этих целей используется оператор new, синтаксис кото-
которого выглядит так:
окземллярОбъекта = new объектный
Тип(параметр!, лараметр2, параметрЗ, ...)
При помощи new объект Book создается следующим
образом:
dbBook = new book("Cost of Discipleship",
"Dietrich Bonhoeffer", -57521-118-1", "Grace",
5)
Теперь на это объект можно ссылаться из любого
места кода через переменную (IBook. Экземпляр будет
храниться в памяти, пока страница загружена в браузе-
браузере. После перехода на следующую страницу или закры-
закрытия браузера, экземпляр объекта исчезает. Присваивая
значения свойствам объекта, не следует забывать об этом
факте. Если требуется обеспечить постоянный объект,
его обработка должна быть переложена на сторону сер-
сервера.
ПРИМЕЧАНИЕ """ ™Г' '" "" '*" Г**" ¦***"' '':f'[ *" '^'
Постоянство, или устойчивость (persistence), - это
весьма распространенное слово в предметной облас-
области, связанной с объектами. В двух словах, это озна-
означает способность создавать экземпляры объектов и
сохранять состояние объектов так, что при следую-
следующем доступе к объекту он восстанавливается в сохра-
сохраненном состоянии.
Клиентская часть JavaScript не обеспечивает свойства
постоянства для объектов.
В листинге 11.2 приведен код, реализующий созда-
создание экземпляров объекта Book и вызывающий метод
show(). На рис. 11.1 показан результат загрузки данной
страницы в браузер.
Листинг 112. Использование объектного конструктора Book.
<html>
¦<head>
<title>Using the book object</title>
<script type""text/javascript">
function book(title, author,
this.title = title;
this.author = author;
this. ISBN = ISBN;
this, subject = subject;
this.rating = rating;
this . show = show ;
ISBN, subject, rating)
function show() {
objWindow = window. open ("", "", "width=600 ,height=300") ;
objWindow. document. write < "<htmlxbody>)";
objWindow.document.write ("<hl>Object Description</hl>") ;
objWindow.document. write ("<p>" J.-
objWindow. document, write ("Book Title: " + this.title + "<br>");
objWindow. document, write ("Author: " + this, author + "<br>") ;
objWindow. document, write ("ISBN: " + this . ISBN + "<br>") ;
objWindow. document.write ("Subject: " + this.subject + "<br>");
objWindow. document.write ("Allen's Rating: „ + this.rating + "<br>");
objWindow.document.write ("</body X/html>") ,-
objWindow.document.close () ,•
]¦
</script>
</head>
<body>
Базовое подмножество языка JavaScript
Часть II
<script type="text/javascript">
<! —
// Определение объекта Book
dbBook = new book ("Cost of Discipleship"
dbBook.show();
II—>
</script>
</bocly>
</html>
"'Dietrich Bonhoeffer", -57521-118-1", "Grace", 5) ,-
Object Description
Book. Title: Cost of Discipleship
Author: Dl
ISBN; 1-57521-118-1
abject: Grace
Rich's Rating: 5
¦<body>
<hl>Book Objects</hl>
<form name="forml">
<P>
Select a book :
РИСУНОК 11.1. Информация из объектаНооквыводится в новое
окно
Работа с экземплярами объектов
Работу с экземпляром объекта можно продолжать
сразу же после его создания — присваивать ему значе-
значения или обращаться к любому из его методов. Кроме
того, можно связать объекты с элементами пользова-
пользовательского интерфейса.
Например, требуется создать форму, которая бы
позволяла изменять рейтинг книг и выводить на экран
информацию для каждого созданного объекта Book.
Объект Book можно определить так, как было показа-
показано ранее, и создать пять его экземпляров:
dbBook = new book(' sst of Discipleship",
"Dietrich Bonhoeffer",
1-1", "Grace", 5)
fkBook = new book ("The Once and Future King",
"Т.Н. White", -57521-112-1",
"Camelot", 5)
olBook = new book ("On Liberty", "John Stuart Mill",
-53221-118-1", "Political Philosophy", 4) ;
iaBook = new book("Icarus Agenda",
"Robert Ludlum", -53221-118-1",
"Politcal Thriller", 2}
cnBook = new took("Chronicles of Narnia",
"C.S. Lewis", -53231-128-1",
"Children's Fiction", 5)
В самой форме следует использовать объект select с
элементами <option>, определенными по одному для
каждой книги, а также по одному на каждый показатель
рейтинга (интервал от 1 до 5). Добавьте еще две кнопки
- одну для установки рейтинга, а другую — для вывода
на экран информационной формы по конкретной кни-
книге. Код для реализации формы приводится ниже. Ре-
Результат загрузки кода в браузер показан на рис. 11.2:
<select name="bookList" size=l>
<option value="dbBook">Cost of
Discipleship</option>
<option value="fkBook">The Once and
•Future King</option>
<option value="olBook">On Liberty
</option>
<option value="iaBook">Icarus Agenda
</option>
<option value="cnBook">Chronicles of
Narnia</option>
</select>
Assign a rating:
<select name="rating" size=l>
<option>K/option>
<option>2</option>
<opt ion>3</opt ion>
<option>4</option>
<option>5</option>
</select>
Click to assign:
<input type="button" name="Assign"
value="Assign" onClick="assignRating()
Click to show:
<input type="button" name="Show"
value="Show" onClick="showBook()"
</form>
</body>
Сердце данного примера — это обработчик событий
для кнопок Assign и Show. Метод assignRating() присва-
присваивает книге выбранное значение рейтинга:
function assignRating {) {
selectedBook =
document.forml.bookList. options[document, forml.
^•bookList. selectedlndexJ . value;
Создание пользовательских объектов JavaScript
selectedBook = eval(selectedBook);
selectedBook.rating =
document.forml.rating.options[document.forml.
*• rating, selectedlndex] .text;
Book Objects
Setetabod-
Assign a rating:
ra
Clbktoasslg-i:
РИСУНОК 11.2 Форма i
i Book.
Посмотрев внимательнее на код, несложно заметить,
что метод получает значение выбранной опции bookList
и присваивает его переменной selectedBook. Для полу-
получения этого значения используется свойство options
Листинг 11.3. Исходный код для примера showBook().
Глава 11
объекта bookList вместе с его же свойством selectedlndex.
Сейчас имя объекта Book содержится в переменной
selectedBook, однако JavaScript воспринимает его как
строковое значение, а вовсе не как ссылку на экземп-
экземпляр объекта. Поэтому для преобразования переменной
в объектную ссылку используется метод eval().
В последней строке метода свойству rating перемен-
переменной selectedBook присваивается значение вновь выбран-
выбранного рейтинга, содержащееся в объекте ratingSelect.
ПРИМЕЧАНИЕ
Для проверки типа переменной во время выполнения
метода можно использовать оператор typeof. Напри-
Например, следующий код отображает окно сообщений, вы-
выводящее тип переменной selectedBook:
alert(typeof selectedBook);
Метод showBook() использует ту же технологию для
вызова метода объекта show():
function showBook(> {
selectedBook = document.forml.bookList.
"->options [document, forml.bookList.selectedlndex].value;
selectedBook = eval(selectedBook);
selectedBook.show() ;
Листинг 11.3 содержит полный исходный код дан-
данного примера.
<html>
<head>
<^1Ые>Использование объекта Book</title>
<script type="text/javascript">
subject, rating)
function book(title, author, ISBN,
this.title = title;
this.author = author;
this. ISBN = ISBN;
this.subject = subject;
this.rating = rating;
this.show = show;
I
function show ( ) {,
objWindow = window . open ("", "", "width=600 ,height=300") ;
objWindow. document, write ( "<htmlxbody;)";
objWindow. document, write ("<hl>Object Description</hl>") ;
objWindow. document .write("<p>") ;
1 + this.title + "<br>");
1 + this.author + "<br>");
objWindow. document, write ("ISBN: " + this . ISBN + "<br>") ;
' + this.subject + "<br>");
objWindow.document, write ("Allen's Rating: ' + this, rating + "<br>"),
objWindow. document.write ("</body X/html>") ;
ob jwindow document. close( ) ;
function assignRating() {
selectedBook = document, forml .bookList.options [document.forml.bookList. selectedlndex] .value;
selectedBook = eval(selectedBook);
selectedBook. rating = document, forml. rating, options [document.forml .rating, selectedlndex] . text;
Базовое подмножествоязыка JavaScript
Часть II
function showBook() {
seleetedBook = document.forml.bookList.options[document.forml.bookList.selectedlndex].value;
selectedBook = eval (seleetedBook) ;
seleetedBook.show ();
I
// Вьпожить во время загрузки
dbBook = new book("Cost of Discipleship", "Dietrich
.fkBook = new book("The Once and Future King", "Т.Н..
olBook = new book("On Liberty", "John Stuart Mill",
iaBook = new book ("Icarus Agenda", "Robert Ludlum",
Bonhoeffer", -57521-118-1", "Grace", 5}
White", -57521-112-1", "Camelot", 5) ;
-53221-118-1", "Political Philosophy",
-53221-118-1", "Political Thriller", 3)
cnBook 1= new book("Chronicles of Narnia" , "C.S. Lewis", -53231-128-1", "Children1s Fiction", 5) ,
</script>
</head>
<body>
<hl>Book Objects</hl>
<?orm name=" forml">
<P>
Select a book:
select name="bookList" size=l>
<option value="dbBook">Cost of Discipleship</option>
<option value="fkBook">The Once and Future King</option>
<option
<option
<option
elect>
value="olBook">On Liberty</option>
value="iaBook">Icarus Agenda</option>
value="cnBook">Chronicles of Narnia</option>
Assign a rating:
<select name="rating" size=l>
<opt ion>l</opt ion>
<option>2</option>
<option>3</option>
<opt ion>4</opt ion>
<option>5</option>
</select>
Click to assign :
<input type="button" name="Assign" value="Assign" onClick="assignKating()
Click to show:
<input type="button" name="Show" value="Show" onClick="showBook()
</form>
</body>
</html>
Создание составных объектов
Объекты, с которыми мы имели дело до этого момен-
момента, относятся к категории простых объектов. Они обла-
обладают одним уровнем свойств и методов. Следующий
пример, посвященный созданию объекта buttonSet, с
одной стороны более быстр, а с другой — более сложен
в восприятии. Разрабатываемый объект должен позво-
позволять "на лету" добавлять кнопки в соответствующий
массив, помещать buttonSet в любой объект Document
и по заданным условиям отображать отдельные кноп-
кнопки. Конструктор объекта buttonSet показан в листинге
11.4.
Создание пользовательских объектов JavaScript
Глава 11
Листинг 11.4. Конструктор объекта buttonSet.
<soript type="text/javascript">
<<
function buttonSet (name) {
this, name = name;
this, length = 0;
this.addBtn = addBtn;
this.print = print;
// Указать, куда Б объект поместить дополнительные элементы.
// Любое выполненное изменение отразите в this.print().
this.index = 4;
return this ;
,// Метод print() объекта buttonSet
function print(dObj) {
var spacelnt;
for (var i = 5; this. index >= i; i++) {
if(eval(this[i].condition)) {
dob j .writeln('<a href=" '+this [i] .url+' "Ximg src='" + this [i] .file+'" alt=" '+this[i] .alt +
111 width=4" height=6" border=0X/a>') ;
// Если требуется, добавляем пробелы
spacelnt = 0 + this[i].spacer;
if(navigator.appName = "Microsoft Internet Explorer") {
spacelnt = spacelnt + 3 ;
i
if (spacelnt != 0) {
dobj.write('<img src="images/space.gif" width='
+ spacelnt + 'height=46 border=0>');
</script>
Помимо прочих, JavaScript поддерживает составные
объекты, свойства которых сами могут быть объектами.
Составные объекты дают возможность более логично
структурировать код. Это гораздо лучше, нежели пы-
пытаться втиснуть все данные в одноуровневый объект.
Предположим, что требуется отслеживать информа-
информацию о сотрудниках, их текущих проектах и клиентах.
Очевидно, что адрес клиента не должен быть частью
описания объекта сотрудника. В этом смысле суще-
существенную помошь в структуризации данных вокруг трех
отдельных, однако связанных сущностей — сотрудник,
проект, клиент — окажут составные объекты JavaScript.
В конструкторе employee определите основные свой-
свойства (имя, телефон, адрес электронной почты) и метод
showSummarylnfoQ. Для представления связанной с
Проектом информации потребуется определить свойство
project в объекте employee. Определение выполняется
таким же путем, как и для обычного свойства, за исклю-
исключением того, что параметр project является ссылкой на
другой объект, а не на строковое значение:
function employee(FirstName, LastName,
HomePhone, Ext, EmailAddress, project) (
this.FirstName = FirstName;
this. LastName = LastName;
this.HomePhone = HomePhone;
this.Ext = Ext;
this.EmailAddress = EmailAddress;
this.Project = project;
this . showSummarylnf о = summarylnf о;
i
Совершенно аналогично определите объект project,
установив объект client в качестве свойства:
function project(ProjectName, client, DevTool) {
this.ProjectName = ProjectName;
this.Client = client;
this.DevTool = DevTool;
"j
function client(ClientName, Address, City,
State, Zip) {
this.ClientName = ClientName;
this. Addre s s = Addre s s;
this.City = City;
this.State = State;
this. Zip = Zip;
}
Создаваемый сейчас метод showSummaryInfo() де-
демонстрирует способ ссылки на эти вложенные объекты.
Функциональность этого метода связана с отображения
нового окна для представления краткой информации о
сотруднике — список всех свойств объекта employee и
других объектов внутри него.
Базовое подмножество языка JavaScript
Часть II
function summaryInfo() {
objwindow = window.open("", "", "width=600,height=400");
ob jwindow. document. write ("<htmlxbody>");
objwindow.document.write("<hl>Employee Summary Information Sheet </hl>");
objwindow.document.write("<h2>" + this.FirstName + " " + this.LastName + "</h2>");
objwindow. document.write ('<<pXemXSstrong>Contact Information </strong></emX/p>") ;
objwindow.document.write("<p>Home Phone: " + this.HomePhone + "</p>");
objwindow.document.write("<p>Ext. : " + this.Ext + "</p>");
objWindow.document.write("<p>Email: " + this.EmailAddress + "</p>");
objwindow. document .write ("<pXemXstrong>Pro ject Information </strongX/emX/p>") ;
objwindow.document.write ("<p>Current Project: " + this .project.ProjectName + "</p>");
objwindow.document.write("<p>Client: " +¦ this.Project.Client.ClientName + "</p>") ;
objwindow. document.write("<p>Client: " + this.Project.Client.Address + "</p>");
objwindow.document.write("<p>Client: " + this. Project. Client. City + ", " +
this. Pro ject. Client. State + " " + this.Project.Client.zip + "</p>">;
objwindow.document.write("<p>Developmnt Tool Used: " + this.Project.DevTool + "</p>");
objwindow.document.write("</bodyX/html>") ;
objwindow.document.close();
Ссьшка на дочерний объект выполняется в соответ-
соответствие с точечной нотацией. Таким образом, на адрес кли-
клиента можно сослаться через this.Project.CIient.Address.
Точечная нотация позволяет легко и просто отследить
код с момента определения пути для используемых
методов и свойств, поскольку предполагает указание
пути к тому или иному методу либо свойству. Совер-
Совершенно несложно добраться до родительских объектов
(имена которых находятся слева перед первой точкой),
проходя через множество дочерних до тех пор, пока не
встретится искомый метод или свойство.
Как только определены конструкторы для каждого
из объектных типов, приступайте к созданию экземп-
экземпляров employee, project и client.
CoastTech = new client("Coastal Techonology",
00 Beacon Hill", "Boston", "MA", 1220") ;
Coastal = new project("CoastalOl", CoastTech,
11 JavaScript") ;
Allen = new employee("Allen", "Wyke", 17/555-
'212", 00", "allen@anywhere.com", "Coastal");
Параметр project в определении объекта сотрудни-
сотрудника и параметр client в определении объекта проекта -
далеко не строки; они — суть имена вновь созданных
объектов. Обязательно примите во внимание порядок
создания объектов. Поскольку объект Allen использует
объект проекта Coastal в качестве параметра, создание
экземпляра Coastal должно происходить в первую оче-
очередь, иначе возникнет ошибка. По тем же соображени-
соображениям, сначала потребуется создать экземпляр CoastTech
объекта client и только затем заняться созданием про-
проекта Coastal.
После создания экземпляров объектов обратитесь к
Allen.showSummaryInfo() для отображения окна, пока-
показанного на рис. 11.3.
В листинге 11.5 показан исходный код для этого
примера.
Employee Summary Information Sheet
Thelma Turner
Contact Information ¦
Home Phore: 556-2364J02
Ext: 100
Email; thelma@ibjrner.com
Project Information
Current Project; CoastalOl - :
Client Coastal Techonology
Address: lOOBeacon Hill
City, State, Zip: Boston, MA 01220
Development Tool Used: JavaScript
РИСУНОК 11.3. Страница с краткой информацией о сотруднике.
Листинг 11.5. Пример использования объектов employee, client и project.
<html>
¦<head>
<title>Using the book object</title>
<script type="text/javascript">-
function employee (FirstName, LastName, HomePhone,
this.FirstName = FirstName;
Ext, EmailAddress, project) {
Создание пользовательских объектов JavaScript
Глава 11
this, LastName = LastName;
this. Home Phone = HomePhone;
this. Ext == Ext;
this.EmailAddress = EmailAddress;
this.Project = project;
this.showSummarylnfо = summarylnfо;
function summarylnfо() {
objWindow = window.open("", "", "width=600,height=400"> ;
objWindow. document. write ("<htmlxbody>") ;
ObjWindow.document.write("<hl>Employee Summary Information Sheet</hl>");
objWindow.document.write("<h2>" + this.FirstName + " " + this.LastName + "</h2>");
objWindow.document.write ("<pXemXSstrong>Contact Information</strongX/emX/p>") ;
objWindow.document.write("<p>Home Phone: " + this,HomePhone + "</p>");
objWindow.document.write("<p>Ext.: " + this,Ext + "</p>");
objWindow.document.write("<p>Email: " + this.EmailAddress + "</p>") ,•
objWindow. document, write ("<pXemXstrong>ProjectInformation</strongX/emX/p>") ;
objWindow.document.write("<p>Current Project: ' + this.project.ProjectName + "</p>");
objWindow.document.write ("<p>Client: " + this.Project.Client.ClientName + "</p>");
objWindow.document.write("<p>Clientr " + this.Project.Client.Address + "</p>");
ob jWindow. document, write ("<p>Client: "¦ + this.Project.Client.City + ", " +
this.Project.Client.State + " " + this.Project.Client.zip + "</p>") ;
objWindow.document.write("<p>Development Tool Used: " + this.Project.DevTool + "</p>");
objWindow.document.write ("</bodyX/html>") ;
objWindow.document.close() ;
function project (ProjectName, client,
this. ProjectName = ProjectName;
this.Client = client;
this. DevTool = DevTool ;
DevTool) (
City, State, Zip) {
function client(ClientName, Address,
this . ClientName = ClientName;
this.Address = Address;
this. City = City;
this.State - State;
this. Zip = Zip;
j
II—>
</script>
</head>
<body>
<script type="text/javascript">
CoastTech = new client ("Coastal Techonology" , 00 Beacon Hill", "Boston", "MA", 1220");
Coastal = new project ("CoastalOl", CoastTech, "JavaScript") ;
Allen = new employee ("Allen", "Wyke", 17/555-1212", 00", "allen@anywhere.com", "Coastal"),
Allen. showSummarylnf о (У;
//—>
</script>
</body>
</html>
Динамическое создание объектов
Возможность создания объектов непосредственно в коде
существенно расширяет возможности разработчика. Во
всех рассмотренных ранее примерах объекты создава-
создавались посредством оператора new во время загрузки окна.
А какие же действия потребуется предпринять для со-
создания объектов во время выполнения? Объектно-ори-
Объектно-ориентированные среды программирования позволяют со-
создавать экземпляры "на лету".
JavaScript позволяет создавать объекты "на лету",
¦однако все же с рядом определенных ограничений.
Сначала планировалось создать обобщенную функцию,
которая бы создавала экземпляры при каждом ее вызо-
вызове. Если замысел увенчается успехом, исчезнет необхо-
необходимость в использовании операторов new, и объекты
Базовое подмножество языка JavaScript
Часть II
можно будет создавать на основе информации, введен-
введенной пользователем. Идея метода выглядит приблизи-
приблизительно так:
function addEmployee(ObjectName,FirstName,
LastName) {
ObjectName = new employee(FirstName, LastName);
)
В идеальном случае метод должен был создавать
экземпляр объекта и присваивать ему имя на основе
значения параметра ObjectName. К сожалению, попыт-
попытка успехом не увенчалась. JavaScript не позволяет име-
имени экземпляра объекта быть переменным. Вместо этого
в качестве имени объекта используется ObjectName. На-
Например, если Frank определен как объектная ссылка, то
следующее выражение будет полностью корректным:
function addFrank(FirstName, LastName) (
Frank = new employee(FirstName, LastName);
)
Несмотря на невозможность динамического имено-
именования реализованных объектов, объект можно создать
как элемент массива-контейнера. Это означает, что мож-
можно предусмотреть массив employeeList, который будет
хранить все созданные объекты employee. Таким обра-
образом, можно изменить метод addEmployee(), использовав
вместо него что-то наподобие:
function addEmployeeObject(FirstName, LastName,
HomePhone, Ext, EmailAddress) {
Листинг 11.6. Динамическое создание объектов.
empList[i] = new employee (FirstName
LastName, HomePhone, Ext, «mailAddress);
.Используя приведенный выше метод, можно созда-
создавать экземпляры объектов, базируясь на вводе пользо-
пользователя и динамическом создании объекта за счет вызо-
вызова addEmployeeObject(). Например, при помощи формы,
представленной на рис. 11.4, пользователь может вво-
вводить основную информацию о сотрудниках. После щел-
щелчка на кнопке Add создается новый экземпляр объекта. В
листинге 11.6 показан исходный код для данной формы.
Dynamic Object Creator
РИСУНОК i 1А Динамическое создание объектов.
<html>
<head>
<title>Intranet Employee Database</title>
<script type="text/javascript">
< ! —
// Глобальные переменные
var i = 0;
// Создание массива
var empList = new Array () ;
.// Конструктор объекта сотрудника
function employee (FirstName, LastName, HomePhone, Ext, EmailAddress) (
this.FirstName = FirstName;
this. LastName = LastName;
this.HomePhone = HomePhone;
this.Ext = Ext;
this. EmailAddress = EmailAddress;
this . show = show;
function show ( > {
alert (this. FirstName + "/n" + this. LastName + "/n" + this.HomePhone + "/n" +
this. Ext + "/n" + this. EmailAddress) ;
function addEmployeeObject (FirstName, LastName, HomePhone, Ext, EmailAddress) {
empList[i] =» new employee (FirstName, LastName, HomePhone, Ext, EmailAddress);
function insertRec >rd() {
FirstName = document.forml.FirstName.value;
Создание пользовательских объектов JavaScript
Глава 11
LastName = document.forml.LastName.value;
HomePhone = document. forml. HomePhone. value;
Ext = document, forml.Ext.value;
EmailAddress = document.forml.EmailAddress.value;
addEmployeeObject(FirstName, LastName, HomePhone, Ext, EmailAddress) ;
)
function showAll() {
objWindow = window. open ("", "", "width=600,height=300");
objWindow. document. write ("<htmlxbody>" );
objWindow.document.write("<hl>Object Description</hl>");
objWindow.document.write("<p>");
for (var q=l; q<empList. length; q++) {
objWindow.document.write("<strong>" + empList[q].FirstName + " " +
empList[q] .LastName + "</strongX/p>") ;
objWindow.document.write("<p>" + empList[q] .HomePhone + "</p>") ;
objWindow.document.write("<p>" + empList[q].Ext + "</p>");
ob jWindow. document, write ("<p>" + empList[q] .EmailAddress + "</p>");
objWindow. document. write ("</bodyX/html>") ;
objWindow.document. close ()
.11—>
</script>
</head>
<body>
<hl>Dyanamic Object Creator</hl>
<p>Enter employee information in the form below and click the Add button.
Press the Show All button to view a list of all employees you have
entered.</p>
<form name="forml">
<pre>
First Name:
<input type=text size=20 maxlength=256 name="FirstName">
</pre>
<pre>
Last Name:
¦<input type=text size=20 maxlength=256 name="LastName">
</pre>
<pre>
Home Phone:
<input type=text size=20 maxlength=256 name="HomePhone">
</pre>
<pre>
Ext. :
<input type=text size=20 maxlength=256 name="Ext">
</pre>
. <pre>
Emai 1 Addr e s s:
<input type=text size=20 maxlength=256 name="EmailAddress">
</pre>
<pre>
<input type="button" name="Add" value="Add" onClick="insertRecord()">
<input type="button" name="ShowAll" value="Show All"
onClick="showAll()">
</'pre>
</form>
</body>
</html>
Кнопка Show All (Показать всех) позволяет просмот- ПРИМЕЧАНИЕ .,,-._ ¦ ¦ , ;. "¦ ': ' »"
реть все объекты, созданные в течение сеанса. На рис. Объекты типа массивов не поддерживались Netscape
11.5 показан список объектов employee, экземпляры ко- Navigator вплоть до его версии 3.0. Учтите это при со-
ТОрЫХ уже были созданы. здании сценариев для версии 2.0.
6 I-IS8
Базовое подмножество языка JavaScript
Часть II
Object Description
Tom Smith
555-1221
129
tom@rnv.com
Tim Smith
555-1222
1»
tim@mv.cwn
Leon Openhlemer
111-1112
132
1eon@my.com
s
:;
i:
j.
Л in ¦••¦ -
РИСУНОК 11.5. Список созданных динамически объектов.
Расширение экземпляров объектов
Раз уж JavaScript является слабо типизированным язы-
языком, он весьма гибок в плане описания объектов. Оп-
Определение экземпляра любого объекта можно расши-
расширить, объявив новое свойство и присвоив ему значение.
В качестве примера добавим в экземпляр cnBook объекта
Book из предыдущей главы свойство Series. Экземпляр
cnBook создается следующим образом:
cnBook = new book("Chronicles of Narnia",
'-Lewis", -53231-128-1", "Children's Fiction",
5) ;
Где-то в сценарии поместите код добавления свой-
свойства Series:
cnBook.Series
"True"
Подобная технология применима только к экземп-
экземплярам объектов, но не к объектному типу. С другой
стороны, браузеры, поддерживающие как минимум
JavaScript 1.1. позволяют расширять созданные объек-
объекты с использованием объектных прототипов, синтаксис
которых выглядит так:
Объектный прототип позволяет добавлять свойства
и методы к каждому экземпляру объектного типа. Если
бы требовалось к каждому объекту Book добавить но-
новое свойство recommended со значением true, следовало
бы воспользоваться кодом, показанным ниже:
book.prototype.recommended = True;
Протестировать все можно, вызвав alert(cnBook.
recommended). Результат тестирования показан на рис.
11.6.
РИСУНОК 11.6. Вывод на экран значения свойства с
использованием alert().
Резюме
JavaScript поддерживает возможность создания пользо-
пользовательских объектов в клиентских сценариях, что делает
язык более гибким и позволяет структурировать код в
соответствие с объектно-ориентированной методологи-
методологией.
В главе были рассмотрены различные аспекты созда-
создания и реализации объектных типов. Читатели почерп-
почерпнули информацию о том, как можно расширить функ-
функциональность обычных объектов за счет создания
составных объектов, т.е. того, что носит название
"объектов внутри других объектов". Составные объекты
используются для инкапсуляции данных, простираю-
простирающихся на большое количество уровней. По аналогично-
аналогичному же принципу строятся реляционные базы данных с
отношениями "один-ко-многим". В добавок ко всему,
читатели узнали о расширении экземпляров объектов с
использованием прототипов объектов.
объектныйТип.prototype.имяСвойства;
Серверная часть JavaScript
В ЭТОЙ ГЛАВЕ
Использование архитектуры клиент/сервер
Разработка серверных приложений JavaScript
Базовые серверные объекты
Несмотря на то что JavaScript играет ключевую роль
именно со стороны клиента, зачастую этот язык про-
программирования используется при создании серверных
приложений (с помощью Netscape Server-Side JavaScript,
SSJS). SSJS, как и его эквивалент для клиентской сто-
стороны, представляет собой набор объектов, функций и
методов, расширяющих стандарт ECMAScript. Примени-
Применительно к разработке Web-приложений, он использует-
используется в качестве серверного языка сценариев, заменяюще-
заменяющего CGI и другие технологии.
ЁПРИМЕЧАНИЕ ^
Оригинальное название серверной части JavaScript выг-
выглядит как LiveWire. Начиная с Netscape Enterprise Server
3, LiveWire был погружен в сервер, после чего пере-
перестал существовать в виде отдельного продукта. LiveWire
на данный момент реализует функциональность подклю-
подключения к базам данных.
ПРИМЕЧАНИЕ
SSJS работает только на Netscape-серверах, поэтому в
настоящий момент нельзя использовать с другими Web-
серверами. Компания Microsoft поддерживает JScript в
собственном сервере Active Server Pages (ASP), одна-
однако эти расширения серверного языка отличаются от SSJS.
И вообще, не стоит забывать, что Java Server Pages (JSP)
— это совершенно другая технология.
Прежде чем углубиться в SSJS, необходимо разоб-
разобраться, как создавать приложения типа сервер/клиент.
SSJS вместе с используемым для управления этими при-
приложениями менеджером приложений (Application
Manager) в клиент-серверной модели представляют сер-
сервер. Клиентом является браузер или приложение, куда
отправляется информация. Изучение технологии кли-
клиент/сервер существенно повысит уровень ваших знаний.
Использование архитектуры клиент/
сервер
Клиент и сервер представляют собой различные сущно-
сущности, независимые друг от друга до тех пор, пока клиен-
клиенту не понадобится информация от сервера. Концепция
клиент/сервер усовершенствовалась до такой степени,
что вышла за пределы сервера, служившего просто хос-
хостом для HTML-страниц. Серверная часть Web-прило-
Web-приложения может быть истинным сервером, поддерживаю-
поддерживающим обработку приложения и хранение баз данных.
Хранение обычных статических документов кануло в
лету.
Web-приложения с клиент-серверной
архитектурой
Разработка Web-приложений типа клиент/сервер отли-
отличается от традиционного процесса разработки в рамках
архитектуры клиент/сервер. Так сложилось, что сервер
рассматривается в качестве разновидности сервера баз
данных, используемого для хранения и обработки зап-
запросов данных от клиента. В клиент-серверной техноло-
технологии для Web сервер не обязательно должен быть базой
данных, это просто Web-сервер, используемый для об-
обработки, администрирования и выполнения вычислений
в HTML-документах. Все еще существует возможность
разделения функциональности между клиентом и сер-
сервером, тем не менее, обработка централизована на сер-
сервере.
Двухуровневая структура приложений
Разрабатываемое приложение необходимо разбить на
две четко определенных части. Это как раз и есть дву-
Базовое подмножество языка JavaScript
Часть II
хуровневая структура для архитектуры типа клиент/сер-
клиент/сервер. Первая часть представляет собой пользовательский
интерфейс (UI), или внешний интерфейс, который
обеспечивает связь пользователя с приложением. Вто-
Вторая часть — сервер, где проходит основной процесс
выполнения. Благодаря наличию клиентской части
JavaScript, выполнение можно разделить между клиен-
клиентом и сервером в соответствии с требованиями прило-
приложения.
В обычной среде было бы разумнее перенести как
можно большую часть обработки на клиентскую часть,
поскольку необходимо располагать определенной сте-
степенью управления конфигурацией и настройкой машин
пользователей. Такое разделение может сделать сам раз-
разработчик, по своему усмотрению, в зависимости от воз-
возможностей клиентской стороны, загрузки сервера и се-
сетевого трафика.
Сервер — это обрабатывающий механизм приложе-
приложений. Он управляет и хранит большое количество дан-
данных, выполняет интенсивные и крупномасштабные вы-
вычисления, а также системную обработку.
Возможность изоляции двух частей системы, обес-
обеспечивающая их независимость друг от друга, внесли
существенную долю в развитие широкомасштабных
систем баз данных. Упомянутая возможность привносит
дополнительную гибкость в процесс разработки при-
приложений.
N-уровневая структура приложений
Л^-уровневая методология применяется с целью преодо-
преодоления ограничений двухуровневой структуры. УУ-уров-
невая архитектура предусматривает разбиение пользо-
пользовательского интерфейса, обработки и хранения данных
на отдельные уровни, еще больше разделяя рабочий
поток. Клиент отвечает за пользовательский интерфейс
и несложную обработку, а сервер — за хранение дан-
данных. При этом существенная обработка и вычисления
(или бизнес-правила) перемещаются на средний уровень.
Такие возможности позволяют вносить изменения в
бизнес-правила, не оказывая влияния на пользователь-
пользовательский интерфейс и базы данных.
По сравнению с обычной средой приложений, в сре-
среде Web-разработки клиентский компьютер (и Web-бра-
Web-браузер, и рабочая станция) управляется в гораздо меньшей
степени. Очень сложно оценить, как проходят процессы
на клиентской части. Более разумно запускать процес-
процессы на серверной части, потому как необходимо конт-
контролировать среду, обеспечивая тем самым предсказуе-
предсказуемые результаты.
С другой стороны, обычные приложения типа кли-
клиент/сервер сталкиваются с некоторыми проблемами,
незнакомыми для клиент-серверных Web-приложений.
В обычных приложениях баз данных типа клиент/сер-
клиент/сервер при изменении клиентского модуля повторное рас-
распределение целого приложения не требуется, посколь-
поскольку клиентом является Web-страница и модификации
распространяются автоматически при ее следующей заг-
загрузке.
Браузер инициирует транзакцию путем отправки
серверу запросов на выполнение некоторых операций,
на получение информации из баз данных, на определен-
определенные вычисления, на запуск процессов либо на выпол-
выполнение функций SSJS. Прежде чем продолжать, клиент
должен дождаться ответа от сервера. Процессы сервер-
серверной части обеспечивают хранение кода в едином цен-
централизованном сервере. Это позволяет более быстро
выполнять требуемые модификации и увеличивает ско-
скорость прохождения процессов, поскольку все они вы-
выполняются на сервере.
Как не попасть в западню
С использованием JavaScript связан ряд вопросов каса-
касаемо архитектуры типа клиент/сервер. В зависимости от
предпочтений, обработка в JavaScript может распреде-
распределяться между клиентом и сервером. Скорость обработ-
обработки со стороны клиента зависит от клиентской среды,
памяти, быстродействия и других внутренних факто-
факторов, в то время как на сервере скорость зависит от тра-
трафика в Internet и запущенных процессов на сервере. В
этой связи неплохой идеей будет разделение обработ-
обработки между различными элементами с акцентированием
внимания на сервере, как на более известной и предска-
предсказуемой сущности.
»примечание! . " v; ;!;
Размышляя над дизайном архитектуры на ранних стади-
стадиях разработки Web-приложений, можно создавать бо-
более устойчивые приложения, что ускорит выполнение
процессов.
Передача информации между клиентом и
сервером
Связь клиента с сервером в Web-среде — очень важный
вопрос, которому стоит уделить особое внимание. В
отличие от клиент-серверной среды в обычных сетях,
Web-среда не обеспечивает постоянной связи с серве-
сервером, устанавливая вместо этого взаимодействие через
протоколы HTTP с использованием TCP/IP.
От клиента к серверу
Самый важный обмен информацией между клиентом
(браузером) и сервером — это клиентские запросы. Сама
природа HTTP требует, чтобы браузер клиента отправ-
отправлял на сервер запросы на любую необходимую инфор-
информацию. Сервер не может самостоятельно инициировать
переход или подключение к HTTP-документу.
Серверная часть JavaScript
Формат HTTP-запроса к серверу может быть базо-
базовым запросом HTML-страницы или запросом, включа-
включающим информацию содержимого либо данные, кото-
которые должны быть обработаны или отправлены на
сервер. К тому же, часть информации, содержащаяся в
запросе (называемая "телом"), включает в себя данные
(содержимое) функций или полей HTML-документа, с
которыми будет работать сервер.
HTTP-запросе содержит три основных группы ин-
информации:
¦ • Строка запроса (GET, HEAD, POST), URL и версия
HTTP.
Пары имя/значение для таких полей, как accept,
refer, if-modifled, user-agent, content-type, content-
length.
• Содержимое — информация (данные), отправленная
на сервер для обработки.
От сервера клиенту
После отправки клиентом на сервер запроса определен-
определенной информации, сервер, в свою очередь, отправляет
клиенту сообщение, содержащее запрашиваемую инфор-
информацию. HTTP-ответы обладают тем же форматом, од-
однако в конце содержат возвращаемый HTML-документ
(ответ).
HTTP-ответ содержит три основных группы инфор-
информации:
¦• Строка ответа
• Заголовки ответа
¦• Данные ответа
Серверная строка ответа имеет синтаксис версии
HTTP, код состояния (код возврата из трех цифр) и
строку ответа текста (не используемую браузером, но
участвующую в интерпретации документа). Все сказан-
сказанное выглядит следующим образом:
НТТР/1.1 200 ОК
Server: Netscape-Enterprise/3.5.1G
Date: Wed, 19 Apr 2000 17:13:33 GMT
Content-type: text/html
Connection: close
Строка ответа предоставляет браузеру начальную
информацию о том, что можно ожидать далее, если
пройти ответ до самого конца. Версия HTTP сообщает
о том, как начать интерпретацию документальной час-
части ответа, а код состояния — что можно ожидать пос-
после возврата. Например, код состояния ответа, равный
200, означает "ОК" (то бишь, "все будет хорошо").
Iпримечание ., '..; ,.^, :а,>„,-, . ¦'¦¦{}'
Существует великое множество кодов ответа (наподо-
(наподобие 200, 302, 404), которые имеют отношение к состо-
состоянию и возвращаемому содержимомудокумента.
Глава 12
Данные ответа, или "тело", — это последняя часть
HTTP-ответа. Они хранятся в формате, определенном
content-type. Значение этих данных зависит от кода со-
состояния, возвращаемого в заголовке ответа. Как прави-
правило, данные ответа имеют форму HTML-документа, ко-
который и будет отображаться в браузере клиента.
Управление сеансами
Одно из преимуществ Web и технологии разработки
Web-приложений в то же время является и существен-
существенным препятствием для приложений, требующих взаи-
взаимодействия клиента и сервера. Поскольку сервер опе-
оперирует в среде, не поддерживающей концепцию
состояний, выполнение происходит гораздо быстрее,
однако при этом сервер должен полностью полагаться
на клиента в том плане, что клиент сам должен напо-
напоминать, кто он есть и когда он производит запрос. Эво-
Эволюция HTML от статических страниц к интерактивным
приложениям повлияла на среды, не обладающие состо-
состоянием, заставив искать способы осуществления поддер-
поддержки состояния.
Поскольку клиент не связан постоянно с Web-сер-
Web-сервером, возникает немаловажная проблема: как сообщить
Web-серверу, кто является клиентом при его повторном
подключении к серверу и отправке запроса. Если бы
подключение Web-приложений к серверу было бы по-
постоянным, то разработка Web-приложений была бы
столь же простой, как и разработка приложений типа
клиент/сервер.
Существует несколько методов управления сеанса-
сеансами, среди которых — использование клиентских cookie-
наборов, кодирование URL и IP-адреса на сервере. Пер-
Первых две технологии предполагают полную поддержку
состояния со стороны клиента и определенную помощь
со стороны сервера. В случае технологии, связанной с
IP-адресами, поддержку информации осуществляет сер-
сервер, а клиент лишь оказывает в этом помощь.
Cookie-наборы
Cookie-наборы обеспечивают механизм сохранения кли-
клиентской информации на Web-сервере, предусматрива-
предусматривающий идентификацию. Эта информация может быть
использована в будущих подключениях к серверу.
Cookie-наборы — это методология поддержки состоя-
состояния клиентов. Сервер сохраняет информацию о клиен-
клиенте на клиентской части, а затем клиент отправляет со-
сохраненную информацию обратно на сервер вместе с
каждым HTTP-запросом.
Cookie-наборы хранятся в текстовом файле на кли-
клиентском дисковом устройстве. Сервер, как средство от-
отслеживания состояний клиентов, может помещать ин-
информацию в cookie-набор столько раз, сколько это
позволяет браузер. Различные браузеры по-разному рабо-
работают с cookie-наборами. Некоторые (скажем, Navigator)
Базовое подмножество языка JavaScript
Часть II
имеют только один файл cookie, в который все сервера
записывают информацию, помечая его разделы специ-
специальными именами URL по мере сохранения и обновле-
обновления. Другие браузеры, такие как Internet Explorer, сохра-
сохраняют информацию в различных файлах каталога cookie.
^ПРЕДУПРЕЖДЕНИЕ : '¦''¦:- ^ V '$.¦
Размер файла cookie ограничен. Передаваться клиенту
и сохраняться на его стороне может только определен-
определенный объем информации. Сей факт ограничивает коли-
количество информации, которую может сохранять каждый
сервер, и число Web-серверов, сохраняющих информа-
информацию на клиентском компьютере.
Всегда существует вероятность ошибочного удале-
удаления файла cookie (это всего лишь текстовый файл). В
этом случае сервер потеряет информацию о состоянии,
поэтому клиенту для стабилизации своих отношений с
сервером придется все начать сначала.
Поскольку cookie-информация хранится на клиен-
клиентской части, то серверные элементы повлиять на нее не
могут. Это позволяет клиенту выполнить повторную от-
отправку запроса, даже если первый раз на сервере возни-
возникали какие-то проблемы. Другое преимущество cookies-
наборов заключается в том, что сервер не обязан
хранить информацию о клиенте; после первоначально-
первоначального запроса информации сервер вообще может "забыть"
о клиенте.
Cookie-наборы приводят к увеличению трафика,
поскольку с каждым запросом сервер должен отправлять
и получать дополнительную информацию. Cookie-ин-
Cookie-информация передается в соответствие с методологией пар
имя/значение, используя для этого протокол передачи
cookie-информации.
Кодирование URL
Кодирование клиентского URL для поддержки инфор-
информации о состоянии взаимодействия клиент-сервер пре-
предусматривает отправку пары имя/значение (name/value)
или уникальных ключевых полей информации как ча-
части строки URL в клиентском HTTP-запрос. Подобный
способ сохранения информации о состоянии выгоден
для серверов так же как и cookie-наборы, поскольку в
данном случае серверы не должны сохранять какую-
либо информацию.
V.ПРИМЕЧАНИЕ ''"*? - ' J:
Использование данного процесса для поддержки клиен-
клиентского состояния требует, чтобы построение URL было
динамическим каждый раз, когда генерируется запрос,
Разумеется, размеры URL при этом существенно воз-
возрастают.
Использование метода кодирования клиентских
URL обеспечивает значительную гибкость, если суще-
существует потребность в поддержке состояния. В отличие
от cookie-наборов, кодирование URL не зависит от кон-
конкретного браузера. Поскольку разработчик не ведает,
какой конкретно браузер получает доступ к серверу, то
это, пожалуй, наилучший способ поддержки состояния.
IP-адреса на сервере
Третий способ поддержки состояния — сохранение IP-
адреса и информации о состоянии на сервере. Это оз-
означает, что сервер должен иметь доступ к базам данных
или к совместно используемой памяти, где будет сохра-
сохраняться информация. Хранение информации о сос-
состоянии основано на IP-адресах клиента. Информация
используется и хранится только совершенно определен-
определенным сервером.
Из-за множества недостатков, такой способ поддер-
поддержки состояния используется только в определенных
случаях:
Должно быть известно, что клиенты обладают посто-
постоянными IP-адресами
Приложение поддерживает только один сервер
Практика динамического распределения IP-адресов
для машин, которые выполняют Web-браузеры, делает
невозможным внедрение данного способа хранения со-
состояния. Кроме того, невозможна также и поддержка
множества Web-серверов.
Разработка серверных приложений
JavaScript
После того как все особенности серверной части языка
JavaScript рассмотрены, можно приступить к исследо-
исследованию процесса разработки приложений в этой среде с
использованием SSJS. На рис. 12.1 показаны все дета-
детали упомянутого процесса.
Создание исходных файлов
Первый шаг к построению серверного приложения
JavaScript связан созданием исходных файлов, которые
бывают двух видов:
Исходные HTML-документы. Эти документы могут
быть статическими либо страницами с кодами
JavaScript. Их расширения — .htm или .html.
• Библиотечные файлы JavaScript. Их расширение -
js. Эти файлы служат в качестве библиотек функций
JavaScript. Использовать HTML-дескрипторы внут-
внутри них не требуется.
Серверная часть JavaScript
Создание
исходных HTML-
и JS-файлов
Компиляция е
приложение
.WEB
РИСУНОК 12.1. Процесс
разработки серверных
приложений JavaScript.
Установка в виде
серверного расшк-
рения LiveWIre
Server Extension
Запуск приложения
из LiveWire
Application Manager
Рассмотренные файлы необходимы, поскольку, в
отличие от клиентской части JavaScript, до помещения
на Web-сервер SSJS следует откомпилировать в байтко-
ды. Упомянутая необходимость предварительной ком-
компиляции рассматривается с одной стороны как досто-
достоинство, а с другой — как недостаток использования
JavaScript на серверной части. Достоинство заключает-
заключается в том, что именно по причине предварительной
компиляции операция выполнение существенно уско-
ускоряется. Однако, одновременно, это же и недостаток, по-
поскольку большая часть того, что создается в SSJS, дол-
должно быть обязательно Wcb-приложениями, а не
обычными страницами (как раз страницы и требуются
большинству разработчиков).
HTM L-документы
Зачастую разработчики практикуют внедрение кода
JavaScript в HTML-документы. Однако внедрение сер-
серверной части JavaScript в HTML-файл может существен-
существенно изменить результат. Существуют два пути внедрения
JavaScript в HTML-документы.
ПерБый путь заключается в применении дескрипто-
дескрипторов <server>n </server>. В любом случае, использова-
использование этих дескрипторов напоминает дескрипторы
<script> и </script>, применяемые на клиентской час-
части JavaScript. Например, требуется сгенерировать стро-
строку, которая отображает ID (идентификатор) лица, ра-
ранее переданный через форму. Для этого можно
прибегнуть к дескриптору <server>:
Глава 12
<serveг>
if (client, custid = null) {
write("Вы не имеете идентификатора");
:) else {
write ("Ваш идентификатор — " +
client.custid);
)
</server>
Второй путь встраивания кода не предусматривает
использование дескриптора <server>, поскольку код
находится внутри другого HTML-дескриптора. Если не-
необходимо поместить выражение JavaScript внутрь
HTML-дескриптора, код окружается обратными кавыч-
кавычками (\Q). Эти кавычки весьма полезны при работе с
объектами Link, Anchor и Form. Например, генерирова-
генерирование HTML-кода с созданной "на лету" ссылкой, кото-
которая включает заранее введенный пользователем Web-
адрес, достигается при помощи такого кода:
<AHREF=\ ' client .WebAddress\ ' >Доиашыяя
*¦ страница</А>
При внедрении серверного JavaScript-кода в HTML-
документ, пользователь видит только результат выпол-
выполнения кода, но не сам код. Именно в этом и заключа-
заключается различие между серверной и клиентской частями
JavaScript, которое можно заметить только во время
просмотра исходного файла в любом Web-браузере.
Листинг 12.1 содержит исходный код HTML с вне-
внедренным кодом JavaScript. Во время выполнения при-
приложения (см. листинг 12.2) это именно то, что будет
лицезреть клиент при просмотре исходного кода в Web-
браузере. (Результат отображения показан на рис. 12.2.)
Несколько позже в главе будет рассматриваться объект
Client. Сейчас достаточно будет отнестись к выражени-
выражениям как к свойствам недавно созданного и определенно-
определенного объекта.
Листинг 12.1. Внедренный серверный сценарий.
<html>
<head>
<title>Feedback</title>
</head>
<body>
"Superiffic" Feedback Confirmation
Dear <server>client. firstName</server>,
Thank you for submitting feedback about
our product. If you have asked us to
contact you, we will be using the
following information:
<blockquote>
<strong>
E-mail: <server>client.email</server>
</strongXbr>
Базовое подмножество языка JavaScript
Часть II
<strong>Telephone: <server>client.phone
</server>
</strongXbr>
<strong>FAX: <server>client.fax</server>
</strong>
</blockquote>
<P>
If any of this information is incorrect,
please go back to the feedback form and
¦change it, We thank you for taking the
time to help us be a "superiffic" company.
Sincerely,
Rupert Mydryl
<br>
Manager, Customer Services
</body>
</html>
Листинг 12.2. Результирующий документ,
передаваемый клиенту.
<html>
<head>
<title>Feedback</title>
</head>
<body>
"Superiffic" Feedback Confirmation
Dear Charles :
Thank you for submitting feedback about
our product. If you have asked us to
contact you, we will be using the
following information:
<blockquote>
<strong>
E-mail: chappy@smiles.com
</strongXbr>
•<strong>
Telephone: 808-555-1212
</strongXbr>
<strong>
FAX: 808-555-5050
</strong>
</blockquote>
<P>
If any of this information is incorrect,
please go back to the feedback form and
change it. We thank you for taking the
time to help us be a "superiffic" company.
Sincerely,
Rupert Mydryl
<br>
Manager, Customer
Services
</body>
</html>
Ж ^
'Superiffic" Feedback
Pear Charles.
"Piank you for flibmiteiefeftaback ab.-,ut out рто4и
informaticn-
E- m a il: Л ар py@imfl« i .r inn
telephone: 308-555-1212
FAX: 808^55-5050
IFany ofЙи an'on ц incorrect, please go back
to help щ Ъ« a "jupniffic" Company.
M^nagrr, СиЛмйег Services
'- .2 A l -.3
d^.:-\
Confirmation
t IfTouhave askedus to contact ynu. wwin be i «if the Mowing
о the feedback Form and change it We thank you for tskmelhc time
РИСУНОК 12.2. HTML-документ в браузере.
Библиотечные файлы JavaScript
В любой серьезной среде разработки необходимо где-то
размещать общие функции, которые можно вызывать из
различных исходных файлов. Так же как и клиентская
часть, серверная версия JavaScript позволяет размещать
код JavaScript во внешних файлах, имеющих расшире-
расширения .js.
Внутри библиотечного файла JavaScript должны на-
находиться функции, но не HTML. Ссылки на эти функ-
функции можно производить внутри HTML-файла. После
компиляции SSJS-приложения компьютер разрешает
все вызовы внешних функций путем просмотра js-фай-
лов, включенных в приложение.
Подготовка приложения
В отличии от клиентской части, процесс разработки
серверной части требует компиляции исходных файлов
в файлы приложений .web. По этой причине большин-
большинство разработок SSJS — это Web-приложения. Далее
поговорим о том, как создавать приложения и запускать
их в Netscape Enterprise Server (NES).
Активизация серверной части JavaScript
Для того чтобы пользователи смогли получить доступ
к приложению, потребуется активизировать серверную
часть в экземпляре Enterprise Server. Для этого необхо-
необходимо получить доступ к Enterprise Administration Server
и выбрать серверный экземпляр, в котором и будет вы-
выполняться активизация SSJS. Как только появится
Серверная часть JavaScript
Server Manager для данного экземпляра, выберите вклад-
вкладку Programs и щелкните на элементе меню Server Side
JavaScript. Все что потребуется предпринять на этой
странице (см. рис. 12.3) — так это выбрать соответству-
соответствующий переключатель для активации SSJS и решить,
требуется ли запрашивать пароль администратора при
доступе к Server-Side JavaScript Application Manager
(весьма неплохая идея). Не забудьте сохранить и при-
применить произведенные изменения.
После перезапуска экземпляра Enterprise Server, как
того требует Administration Server, доступ к Application
Manager (см. рис. 12.4) можно получить с использова-
использованием показанного ниже URL. www.yourinstance.com необ-
необходимо заменить на соответствующее имя сервера:
http:/1www.yourinstance.com/appmgr
Итак, среда Server-Side JavaScript уже запущена,
можно подготовить и запустить свое приложение.
РИСУНОК 12.3. Активизация Server-Side JavaScript в Netscape
Enterprise Server 4.
Web F
Default Page: home htmt
InirJalPage; start hinit
Built-in UiudiniuiL
DatmhateColraecriMU: 0
Mainieninre: г1кы cookit
Sranu: _1 ¦: i..-
им
isd
Глава 12
Компиляция приложений
После создания исходных файлов для приложения, их
необходимо откомпилировать. Компилятор, входящий
в состав NES, создает из HTML-документа и библио-
библиотечных файлов JavaScript файл .web, содержащий пос-
последовательность байткодов.
Для компиляции приложения потребуется перейти
в командную строку и запустить программу компиля-
компилятора JavaScript Application Compiler (jsac). B NES 4.01
этот исполняемый модуль расположен в подкаталоге
bin\https\bin. Вот варианты запуска компилятора:
jsac [-cdv] [-1 ходоваяТаблица] [-а версияЯзыка]
-о двоичныНФайл [-i] исходныйФайл1 [-i]
исходныйФайл2...
jsac [-cdv] [-а версияЯзыка] -О двоичныйФайл -f
файлВключения
jsac [-cdv] [-а версияЯзыка] -О двоичныйФайл -р
каталог ~/ файлВключения -г файлРетстрацииОшибок
Рассмотрим допустимые опции, передаваемые в ко-
командной строке:
-а Версия языка JavaScript, например .2".
-с Выполнять только проверку синтаксиса без гене-
генерации файла двоичныйФайл.
-d Активизировать режим отладки.
-f Включение файла, заданного именем файлВклю-
файлВключения.
-h Вывести справочную информацию по опциям ко-
командной строки компилятора.
-i Определить имя исходного файла (исходный-
файл).
-1 Имя набора символов (например, iso-8859-1или
x-sjis).
-о Определить имя создаваемого файла .web как дво-
двоичныйФайл.
-р Текущий путь при обработке файлов.
-г Перенаправить вывод сообщений об ошибках в
указанный файл (файлРегистрацииОшибок).
-V Компилировать с расширенными сообщениями.
Например, следующее командная строка компили-
компилирует (с расширенным выводом) приложение SSJS в
файл policy.web, используя три исходных HTML-фай-
HTML-файла (index.htm, toc.htm, polpage.htm) и два библиотечных
файла JavaScript (jsroutines.js и jsdates.js):
jsac -v -о policy.web index.htm toc.htm
polpage.htm jsroutines.js jsdates.js
СОВЕТ
РИСУНОК 12.4. Менеджер приложений Server-Side JavaScript.
После активизации Server-Side JavaScript на Web-серве-
Web-сервере, можно осуществлятьудаленную компиляцию прило-
приложений, выполнив доступ к программе jsacRemofe, посту-
Базовое подмножество языка JavaScript
Часть II
пающей вместе с Application Manager. Просто введите
URL в свой экземпляр Enterprise Server и воспользуйтесь
/jsacremote в качестве пути для доступа к приложению.
Инсталляция приложений
Для инсталляции приложения на сервере с использова-
использованием Server-Side JavaScript Application Manager, щелк-
щелкните на вкладке Add Application. После выбора этой
вкладки в правом фрейме окна отобразится HTML-фор-
HTML-форма, которую потребуется заполнить (см. рис. 12.5).
РИСУНОК Xl Добавление приложения.
Заполните форму, основываясь на следующей ин-
информации:
¦• Name (Имя). Введите имя приложения. Оно необхо-
необходимо для доступа к приложению после его инстал-
инсталляции. Например, если имя приложения — fireball,
a URL сервера — www.junebug.com, доступ к нему
можно получить так:
http://www.junebug.com/fireball
ПРЦДУПРЕЖДЕНИЕ
Убедитесь, что приложению не присваивается имя, со-
совпадающее с именем существующего каталога на сер-
сервере. Если совпадение имеет место, клиент не сможет
получить доступ к этому каталогу сервера.
• Web File Path (Путь к .web-файлу). Введите полный
путь и имя файла Web-приложения.
• Default Page (Страница по умолчанию). Введите имя
HTML-файла, который будет служить страницей по
умолчанию для приложения. Страница по умолча-
умолчанию отображается, когда клиент, получивший дос-
доступ к приложению, не определяет файл в запросе.
• Initial Page (Начальная страница). Введите имя
HTML-файла, который будет служить начальной
страницей, когда клиент получает доступ к прило-
приложению. Эта информация необязательна.
• Built-in Maximum Database Connections (Максималь-
(Максимальное число встроенных соединений баз данных). Вве-
Введите максимальное количество одновременных со-
соединений, которые допускаются сервером баз
данных, выполняющимся под управлением операци-
операционной системы NY Server.
• External Libraries (Внешние библиотеки). Если при-
приложение использует внешние библиотеки (например,
библиотеки динамической компоновки, или DLL),
введите здесь полный путь доступа к ним.
• Client Object Maintenance (Поддержка объекта
Client). Это поле определяет режим поддержки по-
постоянства объекта Client. Допустимые 1арианты
включают: client-cookie, client-url, server-ip, server-
cookie и server-url.
По заполнении информации о приложс ши, щелк-
щелкните на кнопке ОК в нижней части страницы.
Application Manager проверит введенные значения на
предмет наличия ошибок и затем выполнит инсталля-
инсталляцию приложения на сервере.
После инсталляции потребуется вернуться на вклад-
вкладку Applications и убедиться, что ваше приложение в
списке присутствует. Запустите приложение, щелкнув
на Run. Доступ к приложению производится путем вво-
ввода адреса URL, где находится Enterprise Server, и сле-
следующего за этим URL имени приложения, отделенно-
отделенного наклон чертой вправо. Рассмотрим пример вызова
приложения туАрр:
http ://www.mysi te.com/туApp
ПРИМЕЧАНИЕ
После внесения определенных изменений в входные
тексты приложения и его повторной компиляции, при
помощи Application Manager перезапустите приложение,
чтобы изменения возымели действие.
. ,.. ., „., ...
Исправление ошибок
Теперь, когда запуск произведен, следует получить до-
доступ к приложению, дабы убедиться, что все работает
предсказуемым образом. Если это действительно так,
можно разрешать доступ к приложению и другим
пользователям. Если же возникают какие-то проблемы,
потребуется запустить отладчик приложений и выяс-
выяснить, в чем же дело.
Общая отладка
При работе с клиентской и серверной частями JavaScript,
можно прийти в некоторое замешательство, поскольку
Серверная часть JavaScript
¦НУ
по идее отлаживать необходимо как серверную, так j4
клиентскую часть. Внутри Application Manager суще-
существует отладчик, доступ к которому можно получить
путем выбора приложения из списка и щелчка на кноп-
кнопке Debug. В результате открывается новое окно браузе-
браузера с фреймом (или окном) трассировки, как показано
на рис. 12.6. Окно трассировки отображает текущие
объекты и их свойства. Также можно прибегнуть к ус-
услугам встроенной функции debug(), действующей по-
подобно функции write(), для вывода в окно трассировки
результатов вычисления JavaScript-выражения.
; ¦
F.,m..h|-J
Ф-42? 0 0 1- Ш
T-jitiel jiniJHrt ub|t.l 1
bdul inrver tbject Я
hqit="faL«aLtL'L ^j
: ; = ¦
¦¦¦¦¦¦¦¦¦¦
¦ 1
& щ
РИСУНОК 12.6. Отладчик Server-Side JavaScript Application
Manager.
Ошибки, связанные с базами данных
Большинство методов, используемых для взаимодей-
взаимодействия с базами данных, возвращают код состояния. Код
состояния представляет собой целое число от 0 до 27.
Код 0 уведомляет о ТОМ, что команда выполнена успеш-
успешно, в то время как другие значения, перечисленные в
табл. 12.1, указывают на ошибки, возникающие на сер-
сервере.
Объект базы данных имеет четыре отладочных ме-
метода, которые возвращают код ошибки и соответствую-
соответствующее сообщение от сервера баз данных. Значения того,
Глава 12
что возвращается, зависит от сервера баз данных. В табл.
12.2—12.5 перечислены возвращаемые значения для че-
четырех поддерживаемых SSJS баз данных SQL.
Таблица 1 I. Коды состояния баз данных.
Код Описание
состояния
О
1
2
3
4
5
6
7
8
9
10
И
12
13
14
15
16
17
я
19
20
21
22
23
24
25
26
27
Ошибок нет.
Недостаточно памяти.
Объект не инициализирован.
Ошибка преобразования типов.
Незарегистрированная база данных.
Ошибка, выданная сервером.
Сообщение отсервера.
Ошибка от библиотеки поставщика.
Потеря связи.
Операция считывания завершена.
Неправильное использование объекта.
Столбец не существует.
Неправильное размещение внутри объекта
(ошибка выхода за границы).
Неподдерживаемая возможность.
Нулевая ссылка.
Объект базы данных не найден.
Отсутствует необходимая информация.
Объект не поддерживает множественное
чтение.
Объект не поддерживает удаление.
Объект не поддерживает вставку.
Объект не поддерживает обновление.
Объект не поддерживает обновление.
Объект не может поддерживать индексы.
Объект не может быть удален.
Неправильное подключение.
Объектнеподдерживаетпривилегии.
Объект не поддерживает курсоры.
Открытие невозможно.
Таблица 12.2. Библиотека ошибок производителя Informix (код состояния 7).
Метод
Что возвращает
majorErrorMessageO
minorErrorMessage()
imajorErrorCode()
minorErrorCodeO
Vendor Library Error: errorMsg (Ошибка библиотеки производителя: errorMsg) {errorMsg — это
текст от Informix).
ISAM Error: errorMsg (Ошибка ISAM: errorMsg) {errorMsg— текст кода ошибки ISAM от Informix
либо пустая строка (""), если ошибки ISAM нет).
Кодошибки Informix.
Код ошибки ISAM либо нуль, если ошибки нет.
Базовое подмножество языка JavaScript
Часть II
Таблица 12.3. Ошибки сервера Oracle (код состояния 5).
Метод
Что возвращает
majorErrorMessage()
minorErrorMessageO
imajorErrorCode()
iminorErrorCode()
Server Error: errorMsg (Ошибка сервера: errorMsg) (errorMsg — трансляция кода возврата Oracle).
Имя сервера Oracle.
Возвращает код, переданный Oracle Call-level Interface (OCI).
Код ошибки операционной системы, переданный OCI.
Таблица 12.4. Библиотека ошибок производителя Sybase (код состояния 7).
Метод'
Что возвращает
majorErrorMessage()
minorErrorMessageO
imajorErrorCodeQ
minorErrorCode()
Vendor Library Error: errorMsg (Ошибка библиотеки производителя: errorMsg) (errorMsg—это
текстошибки, полученный от DB-Library).
Текст ошибки операционной системы (в соответствие со спецификацией библиотеки DB-
Library).
Номер ошибки DB-Library.
Степень серьезности ошибки (в соответствие со спецификацией библиотеки DB-Library).
Таблица 12.5. Ошибки сервера Sybase (код состояния 5).
Метод
Что возвращает
majorErrorMessage()
minorErrorMessage()
majorErrorCodeO
minorErrorCodeO
Server Error: errorMsg (Ошибка сервера: errorMsg) (errorMsg — текст, возращенный сервером
SQL). Если степень серьезности ошибки и номер сообщения равны 0, возвращается только
текст сообщения.
Имя сервера SQL.
Номер сообщения сервера SQL.
Уровень серьезности (в соответствие со спецификацией сервера SQL).
Базовые серверные объекты JavaScript
Теперь, когда имеется представление о работе модели
клиент/сервер в пространстве Internet и особенностях
функционирования серверной части JavaScript, можно
перейти к рассмотрению объектов, доступных при по-
построении приложений (рис. 12.7). Основная цель сер-
серверных объектов заключается в управлении постоянны-
постоянными данными. Внутри Web-среды, не поддерживающей
концепцию состояний, эти объекты могут постоянно
хранить различные типы данных для разных запросов
одного и того же клиента, для запросов множества кли-
клиентов и даже для различных приложениях SSJS.
Объект Server
Объект Server используется для управления глобальны-
глобальными данными о самом сервере. Этот объект всегда при-
присутствует на сервере SSJS и создается при его запуске.
Он разрушается при завершении сервера. Встроенные
методы и свойства объекта Server перечислены в табл.
12.6.
РИСУНОК 12.7. Структура базовых серверных объектов
JavaScript.
Серверная часть JavaScript
Глава 12
Таблица 12.6. Встроенные методы и свойства объекта Server.
Тип
Элемент
Метод
Свойство
lock()
unlockO
host
ihostname
jsVersion
iport
protocol
Описание
Блокирует код во время выполнения манипуляций сданными с одним потоком.
Освобождение ранее заблокированного кода.
Строка, определяющая имясервера, субдомена и домена\Л/еЬ-сервера.
Полное имя сервера (включая порт); то же самое, что и объединение свойств host и
port.
Серверная версия JavaScript и платформа.
Номер порта используемого сервером.
Используемый Internet-протокол, присутствующий в адресе Ш1_до первого двоеточия.
Для того чтобы глубже понять работу методов lock()
и unlock(), изучите следующий раздел, посвященный
объекту Project. Методы этого объекта действуют совер-
совершенно аналогично.
Объект Project
Объект Project разработан с целью поддержки инфор-
информации о приложениях на клиентской части и обеспе-
обеспечения постоянства до тех пор, пока приложение на сер-
сервере не будет закрыто. Данный объект не содержит
свойств, но только два метода, описанные в табл. 12.7.
Таблица 12.7. Встроенные методы объекта
Project.
Метод
Описание
lock() Блокирует код во время выполнения
манипуляций сданными, к которым
подключен только один поток.
unlock() Освобождает ранее заблокированный код.
Благодаря многопользовательской природе Web, к
приложению SSJS могут одновременно получить дос-
доступ сотни и тысячи пользователей. В результате, впол-
вполне вероятна ситуация, когда большое число пользова-
пользователей одновременно пытаются выполнить чтение или
запись в объект Project. SSJS обеспечивает скрытое бло-
блокирование на весь период чтения и записи значения
свойства.
Начиная с Netscape Enterprise Server 4.01, для объек-
объектов Project и Server скрытое блокирование не реализу-
реализуется, как это имело место в предыдущих версиях.
Иногда требуется явная блокировка. Примером мо-
может послужить установка начального значения для уве-
увеличивающегося номера, скажем, накладной, которое
хранится в свойстве. Для это необходимо прочитать
старое значение, прибавить к нему какую-то величину
и присвоить новое значение свойству.
Скрытая блокировка в данном случае не срабатыва-
срабатывает, однако, для достижения требуемой цели можно при-
прибегнуть к услугам метода lock() объекта Project. Метод
lock() обеспечивает явную блокировку объекта вплоть
до вызова метода unlock(). Например, для установки
нового номера накладной можно использовать такой код:
proj ect.lock() ;
project.invoiceNum += 1;
project.unlock();
Если в этот момент доступ к объекту Project пыта-
пытается получить другой клиент, ему придется ожидать
завершения текущего процесса.
; примечание ';:,„;г-"** ! ,
SSJS гарантирует отсутствие внутри экземпляра Project
взаимной блокировки (или коллизии), когда два объекта
блокируют базу данных. Это достигается автоматичес-
автоматическим освобождением всех блокировок после отработки
клиентского запроса.
Объект Client
Как было показано, объекты Request существуют толь-
только в определенные моменты времени. Поскольку взаи-
взаимодействие клиента с серверным приложением предпо-
предполагает наличие более одного запроса, для поддержки
состояния в течение серии запросов используется
объект Client. Новые экземпляры объекта Client созда-
создаются каждый раз, когда новый клиент получает доступ
к приложению. Подобно Project, объект Client не име-
имеет свойств, но лишь только два метода, краткое описа-
описание которых приводится в табл. 12.8.
Таблица 12.8. Встроенные методы объекта Client.
Метод
Описание
destroy() Метод явно разрушает объект и все
свойства, поддерживаемые объектом.
expiration() Метод позволяет изменять 10-минутное по
умолчанию истечение времени действия
объектов Client на другой промежуток
времени.
Базовое подмножество языка JavaScript
Часть II
Объект Client разработан таким образом, чтобы са-
саморазрушаться по прошествии определенного проме-
промежутка времени. Основная причина заключается в том,
что требуется поддерживать состояние в клиентских
запросах, однако совершенно невозможно определить,
какой запрос является последним. Поскольку никто не
желает оставлять в памяти множество неиспользованных
объектов Client, необходимо автоматически разрушать
объект по истечению определенного промежутка време-
времени. Время жизни объекта по умолчанию — 10 минут.
Это значение можно изменить при помощи метода
expiration().
Например, для увеличения периода времени до 20
минут потребуется записать следующий код:
client.expirationA200);
Для изменения упомянутого времени метод expiration()
должен вызываться на каждой странице приложения.
Страницы, не имеющие обращения к expiration(), будут
использовать значение времени по умолчанию.
Объект Request
Листинг 12.3. Регистрационнаяформа.
<html>
<head>
<title>PeriicTpaitfta</title>
</head>
<body>
<hl>Registration</hl>¦
<hr>
<form action="/ssjs/objects" method="POST">
Please provide the following contact
information:
Экземпляр этого объекта создается каждый раз, когда
сервер получает новый запрос. Объект Request содержит
данные текущего запроса клиента. Он обладает множе-
множеством свойств, перечисленных в табл. 12.9.
Как упоминалось в табл. 12.9, объект Request также
имеет определенные свойства для каждого элемента
ввода переданной HTML-формы — formkey. Например,
пользователь передает форму, описание которой приво-
приводится в листинге 12.3.
Когда на основе отправленной формы создается объект
Request, с ним ассоциируются следующие свойства:
request.FullName
request.Title
request.Organization
request.Email
Таблица 12.9. Встроенные свойства объекта Request.
<em>Name</em>
<input type="text" size=5"
maxlength=5 6" name="FullName "Xbr>
<em>Title</em>
<input type="text" size=5"
maxlength=56" name="Title"Xbr>
<emX3rganization</em>
<inpilt type="text" size=S" maxlength=56"
name="Organization" Xbr>
<em>E-mail</em>
<inpilt type="text" size=5"
maxlength=56" name="Email"Xbr>
<p>
<inpilt type="submit" value="Submit">
i type=lireset" value="Reset">
</form>
</body>
</html>
Единственный элемент формы, который обрабаты-
обрабатывается специальным образом, — это объект Select с
возможностью выбора множества значений (в <select>
параметр multiple находится в установленном состо-
состоянии). В данной ситуации имеет смысл воспользова-
воспользоваться встроенными функциями getOptionValue() и
getOptionVa!ueCount(), организовав проход по множе-
множеству выбранных значений объекта Select. Функция
getOptionValue() определяется следующим образом:
getOptionValue (name, index) :
Свойство
Описание
agent
auth_type
authuser
formKey
imageX
imageY
ip
method
protocol
query
Информация о клиентском программном обеспечении (т.е. название и версия).
Тип авторизации; соответствует переменной AUTH_TYPE среды CGI.
Имя локального HTTP-пользователя браузера, если активизирована авторизация доступа HTTP.
Соответствует переменной REMOTEJJSER среды CGI.
Представляет любой ключ формы, отправленный браузером.
Горизонтальная координата курсора мыши над картой изображения.
Вертикальная координата курсора мыши над картой изображения.
.IP-адрес клиента.
Метод HTTP (обычно GET или POST).
Уровень HTTP-протокола клиента.
Содержит информацию, передаваемую в URL после знака ?. Соответствует переменной
QUERY_STRING среды CGI.
Серверная часть JavaScript
Параметр пате — это имя объекта Select, а параметр
index — индекс массива вариантов. Обратите внимание
на список вариантов в объекте Select, определенных в
листинге 12.4 и показанных на рис. 12.8. После пере-
передачи формы на сервер, запрашивается код из листинга
12.5. При помощи знакомого цикла for можно пройтись
по всем выбранным элементам. На рис. 12.9 показана
результирующая HTML-форма, динамически сгенери-
сгенерированная обращениями к write().
Листинг 12.4. Форма для отбора песен.
<html>
<head>
< title> Song- Picker < /title>
</head>
<body>
<h2>Pick Your Favorite Songs From the List:
</h2>
<form action="topsongs.htm" method="post"
name="songSelect">
<select name="songs" size=0" multiple>
<option>1979 (Smashing Pumpkins) </option>
<option>Breakfast at Tiffany's (Deep
"-•Blue Something) </option>
<option>Don't Cry (Seal)</option>
<option>Flood (Jars of Clay) </option>
</select>
<input type="submit" value="Submit">
</form>
</body>
</html>
Pick Your Favorite Songs From the List:
1979 (Smashing Pumpkins)
3reakfa-;l at Tiffany's (Deep Blue Something)
lonl Cry (Seal)
Float) (Jars of Clay)
¦ ¦ ¦
РИСУНОК 12.8. Список с возможностью множественного выбора
перед передачей формы.
Листинг 12.5. Код со стороны сервера для
обработки списка выбранных песен.
<html>
<head>
<title>Results Page</title>
</head>
<body>
Глава 12
<server>
write ("<h2>The songs selected included:</h2>") ,
write("<ul>");
var size = getOptionValueCount("songs");
for (var i = O; i < size; i++) {
write("<li>" + getOptionValue("songs" , i)
write("</ul>");
</server>
</body>
</html>
it *
if
The songs selected included:
• Breakfast at Tiffany's (Deep Blue Something)
¦• Flood (Jais ofCIay)
РИСУНОК 12.9.Динамически сгенерированный документ.
Объект Lock
Данный объект используется для обеспечения блокиро-
блокировок других объектов. Как упоминалось ранее, этот про-
процесс обеспечивает защиту доступа к данным со стороны
определенных экземпляров в случае, когда предполага-
предполагается только единственный поток операций. Наглядный
пример тому — счетчик. К е 111 услугам прибегают, ска-
скажем, тогда, когда необходимо посчитать количество
клиентов или запросов, пришедших за фиксированный
промежуток времени. У объекта есть три метода и един-
единственное свойство, перечисленные в табл. 12.10.
Объект File
Вплоть до сего момента рассматривались только своего
рода "автоматические" объекты. Под "автоматическими"
объектами подразумеваются только такие, к созданию
которых в среде SSJS приводит запуск самого сервера,
получение запросов, поддержка проектов и of
блокировок. Первый объект, выходящий за пределы
очерченной области, — это объект File.
Базовое подмножество языке JavaScript
Часть II
Объект File позволяет считывать и записывать дан-
данные в файл, хранящийся в файловой системе сервера.
Команды для чтения и записи в файл относятся к стан-
стандартным функциям большинства языков программиро-
программирования. Если доводилось использовать другие языки про-
программирования, особых неудобств испытывать не
придется. Данный объект имеет всего одно свойство и
несколько методов, краткое описание которых приво-
приводится в табл. 12.11.
Новые экземпляры объекта File создаются при помо-
помощи оператора new. Рассмотрим один пример:
var fileObject = new File("path");
Поскольку объект File имеет дело с файловой сис-
системой сервера, параметр path должен содержать полный
путь к файлу, но не URL. После создания экземпляра
объекта, его потребуется открыть для подготовки либо
к считыванию, либо к записи, вызвав метод ореп(). В
этот метод передается параметр mode, который может
принимать одно из значений, перечисленных в табл. 12.12.
Возможно, вы обратили внимание на необязатель-
необязательный параметр Ъ, используемый для открытия файлов в
двоичном режиме только в среде операционной системы
Windows. После завершения работы с открытым файлом
потребуется вызвать метод close() для его закрытия.
Icobet" . >.", *^v\ "'¦¦¦' d" ' "• " .-
Несмотря на то что объект File не имеет методов lock|)
и unlock!), возможности блокировки оказываются дос-
доступными через объекты Project и Server.
Листинг 12.6 демонстрирует один из способов ис-
использования файлов. Приведенный код предназначен
для регистрации пользователей, передавших форму. При
каждой передаче формы серверный сценарий открыва-
открывает файл contlog.txt и записывает в него содержимое всех
полей, используя запятые в качестве разделителей.
Таблица 12.10. Встроенные методы и свойства объекта Lock.
Тип
Метод
Описание
Метод
Свойство
isValidO
ilock()
unlockO
prototype
Проверяет допустимость конструкции объекта Lock.
Блокирует код на период выполнения манипуляций с данными, которые должны
осуществляться в эксклюзивном режиме.
Освобождает ранее заблокированный код.
Позволяет добавлять новые методы и свойства в объект Lock.
Таблица 12.11. Свойства и методы объекта File.
Тип
Элемент
Описание
Преобразует число, представленное в одном байте, в строку.
Очищает состояние ошибки для файла.
Закрывает файл.
Определяет, находится ли указатель в конце файла.
Возвращает текущее состояние ошибки.
Определяет, существует ли определенный файл.
Записывает в файл содержимое внутреннего буфера.
Вьиает длину файла.
Выдает текущую позицию указателя в файле.
Открывает файл для доступа.
Считывает данные из файла в строку.
Считывает заданное количество байтов и возвращает их значение.
Считывает текущую строку файла в строковую переменную.
Устанавливает текущую позицию в файле.
Преобразует первый число, находящееся в строке, в значение, представленное байтом.
Записывает данные в файл.
Записывает один байт данных в файл.
Записывает данные в файл с добавлением кода возврата каретки.
Позволяет добавлять методы и свойства в объект File.
Метод
Свойство
byteToStringO
clearError()
close()
eof()
error()
exists()
flush()
getLength()
getPositionQ
open()
read()
readByte()
readln()
setPosition()
stringToByte()
write ()
writeByte()
writelnf)
prototype
Таблица
Mode
12.
12. Параметры
Описание
метода ореп() для
объекта
File.
Серверная
часть JavaScript шрм
Глава 12 ЦЦ
а[Ь] Открывает существующий файл для добавления нового текста. Если файл не существует, он создается.
а+[Ь] Открывает существующий файл для чтения и записи. Если файл не существует, возвращается false.
Указатель устанавливается в конец файла.
r[b] Открывает существующий файл для чтения. Если файл не существует, возвращается false.
r+[b] Открывает существующий файл для чтения и записи. Если файл не существует, возвращается false.
Указатель устанавливается в начало файла.
w[b] Открывает новый файл для записи. Если файл уже существует, происходит его перезапись.
w+[b] Открывает новый файл для чтения и записи. Если файл уже существует, происходит его перезапись.
Листинг 12.6. Работа с файлами через объект File.
<html>
<head>
< ti Ъ1е>Регистрация< / ti tle>
</head>
<body>
<server>
if (request. FullName != null) (
cLog = new File ("d:/netscape/suitespot/server4/logs/contlog.txt") ;
project.lock(У ;
if (cLog.open("a") = true) {
cLog.write (request. FullName + ",");
cLog. write (request.Title + ",");
cLog. write (request.Organization + ",");
cLog.write (request.Email + ",");
cLog.close();
project.unlock ();
)
</server>
<hl>Registration</hl>
<hr>
<form aetion="/ssjs/objects" method="POST">
<P>
Please provide the following contact information:
<em>Name</em>
<input type=text size=35 maxlength=256 name="FullName"Xbr>
<em>Ti tle</em>
<input type=text size=35 maxlength=256 name="Title"Xbr>
<em>Organiz ati on< / em>
<input type=text size=35 maxlength=256 name="Organization"Xbr>
<em>E-mail</em>
<input type=text size=25 maxlength=2S6 name="Email"Xbr>
<P>
<input type=submit value="Submit">
<input type=reset value="Reset">
</form>
</body>
</html>
ОбъеКТ SendMail бы пользователям возможности по отправке почтовых
сообщений. Методы и свойства SendMail перечислены
Еще один весьма полезный объект SendMail позволяет в табл. 12.13.
отправлять сообщения через почтовый сервер. Как и Подобно объекту File, SendMail создается с исполъ-
Предг! слагалось, при помощи этого объекта можно со- зованием оператора new:
ЗДавать страницы приложения, которые предоставляли . ..
r r r r var myMessage = new SendMail () ;
Базовое подмножество языка JavaScript
Часть II
Таблица 12.13. Методы и свойства объекта SendMail.
Тип
Элемент'
Описание
Метод errorCodeQ Возвращает целочисленное представление кода ошибки, возникшей во время отправки
сообщения.
errorMessage() Возвращает строку, связанную с кодом ошибки, возникшей во время отправки
сообщения.
send{) Отправляет электронную почту.
Свойство Вес Разделенный запятыми список адресатов, получаемых скрытую точную копию
сообщения.
Body Основной текст сообщения.
Сс Разделенный запятыми список адресатов, явно получаемых точную копию сообщения.
Errorsto Имя пользователя, которому будут адресоваться сообщения об ошибках при отгравке.
Значение по умолчанию совпадает со значением свойства From.
From Обязательное имя отправителя сообщения,
¦Organization Название компании-отправителя или любая информация о ней.
prototype Позволяет создавать новые свойства и методы для объекта SendMail.
Replyto Имя пользователя, используемое вместо свойства From в качестве адреса, куда будет
отправляться ответное сообщение.
Smtpserver Имя хоста или IP-адрес SMTP.
Subject Предмет сообщения.
То Список получателей сообщения, разделенный запятыми
Объекты баз данных
Одно из преимуществ серверной части JavaScript заклю-
заключается в возможности взаимодействия с базами данных.
Как упоминалось ранее, LiveWire вызывает SSJS, для
чего, собственно, последний и используется. В настоя-
настоящий момент LiveWire относится к функциональным
средствам доступа к базам данных в среде SSJS. Чуть
ниже будут рассматриваться базовые объекты, обеспе-
обеспечивающие упомянутый доступ.
Объект Database
Объект Database инкапсулирует всю функциональность
взаимодействия с реляционными базами данных. У дан-
данного объекта определено всего лишь одно свойство, в то'
Таблица 12.14. Методы и свойства объекта Database.
время как большинство действий реализуется через ме-
методы. Таблица 12.14 содержит краткие описания всех
методов. Если до этого приходилось работать с базами
данных в других языках программирования, несложно
заметить, что JavaScript обладает практически всеми
средствами взаимодействия с базами данных.
Объект DbPool
Объект DbPool, появившийся в Netscape Enterprise
Server 3, очень напоминает объект Database с тем лишь
отличием, что этот объект представляет целиком весь
пул подключений к базе данных. После создания тако-
такого пула, из него можно вытаскивать необходимые со-
соединения. В табл. 12.15 представлены методы и свой-
свойство данного объекта.
Тип
Элемент
Описание
Метод beginTransaction()
commitTransactionO
connect()
connected()
¦cursorQ.
disconnect)
executeO
majorErrorCodeO
Начинает транзакцию SQL.
Выполняет текущую транзакцию SQL.
Подключает приложение кзаданной базе данных.
Возвращает true, если связь между приложением и базой данных установлена.
Создает объект Cursor для заданной SQL-оператора SELECT,
Разрывает связь с базой данных.
Выполняет заданный оператор SQL. Используется для операторов SQL, которые не
возвращают курсор.
Главный код ошибки, возвращаемый сервером баз данных или ODBC.
Серверная часть JavaScript
Тип
Глава 12
Элемент
Описание
Свойство
majorErrorMessage()
minorErrorCode()
iminorErrorMessage()
rollbackTransaction()
SQLTableO
stored Proc()
stored ProcArgs()
toStringf)
prototype
Сообщение, соответствующее главному коду ошибки, возвращаемое сервером баз
данных или ODBC.
Вторичный код ошибки, возвращаемый библиотекой поставщика.
Сообщение, соответствующее вторичному коду ошибки, возвращаемое библиотекой
поставщика.
Выполняет откат текущей транзакции SQL.
Генерирует HTML-таблицу для вывода на экран результатов запроса SELECT.
Создает объект Stproc и запускает выбранную хранимую процедуру.
Создает прототип хранимой процедуры DB2, ODBC или Sybase.
Возвращает строку, представляющую заданный объект.
Позволяет добавлять методы и свойства к экземплярам объектов Database.
Таблица 12.15. Методы и свойства объекта DbPool.
Тип
Элемент
Описание
Метод
Свойстзо
connectf)
connectedQ
connection ()
DbPoolO
disconnect)
imajorErrorCode()
majorErrorMessage()
iminorErrorCodeO
minorErrorMessage()
storedProcArgsQ
toString()
prototype
Подключает пул приложения к заданной базе данных.
Возвращает true, если пул подключен к базе данных.
Захватывает доступное соединение из пула.
Создает пул соединений с базами данных.
Закрывает все соединения с базами данных в пуле.
Главный код ошибки, возвращаемый сервером баз данных или ODBC.
Сообщение, соответствующее главному коду ошибки, возвращаемое сервером баз
данных или ODBC.
Вторичный код ошибки, возвращаемый библиотекой поставщика.
Сообщение, соответствующее вторичному коду ошибки, возвращаемое библиотекой
поставщика.
Создает прототип хранимой процедуры DB2, ODBC или Sybase.
Возвращает строку, представляющую заданный объект.
Позволяет добавлять методы и свойства к экземплярам объектов DbPool.
Объект Connection
Объект Connection появился в Netscape Enterprise Server
.3 и представляет собой связь, взятую из резерва связей
с базами данных. Создается этот объект с помощью
вызова метода DbPool.connection (). В таблице 12.16
представлены методы и свойство данного объекта.
Объект Cursor
Данный объект создается за счет вызова методов
Connection.cursor() или database.cursor(). Поскольку
запрос к базе данных требует вернуть курсор, этот
объект содержит ссылку на строки, возвращаемые в ре-
результате выполнения запроса. В таблицу 12.17 сведены
методы и свойства этого объекта.
Таблица 12.16. Методы и свойство объекта Connection.
Тип
Элемент
Описание
Метод beginTransactionQ
eommitTransactionO
connectedQ
cursor()
execute()
imajorErrorCodeO
Начинает транзакцию SQL.
Выполняет текущую транзакцию SQL.
Возвращает true, если связь между приложением и базой данных установлена.
Создает объект Cursor для заданной SQL-оператора SELECT.
Выполняет заданный оператор SQL. Используется для операторов SQL, которые не
возвращают курсор.
Главный код ошибки, возвращаемый сервером баз данных или ODBC.
Базовое подмножество языка JavaScript
Тип
Часть II
Элемент
Описание
Свойство
majorErrorMessage()
iminorErrorCode()
minorErrorMessageO
release {)
rollbackTransaction()
SQLTableO
storedProc()
toStringO
prototype
Сообщение, соответствующее главному коду ошибки, возвращаемое сервером баз
данных или ODBC.
Вторичный код ошибки, возвращаемый библиотекой поставщика.
Сообщение, соответствующее вторичному коду ошибки, возвращаемое библиотекой
поставщика.
Освобождает соединение, возвращая его в пул.
Выполняет откат текущей транзакции SQL.
Генерирует HTML-таблицу для вывода на экран результатов запроса SELECT.
Создает объект Stproc и запускает выбранную хранимую процедуру.
Возвращает строку, представляющую заданный объект.
Позволяет добавлять методы и свойства к экземплярам объектов Database.
Таблица 12.17. Методы и свойства объекта Cursor.
Тип
Элемент
Описание
Метод close() Закрывает курсор и освобождает занимаемую им память.
columnNameO Принимает проиндексированную позицию столбца и возвращает соответствующее имя
столбца.
columns() Возвращает количество столбцов в рамках курсора.
deleteRowQ' Удаляет текущую строкутаблицы.
insertRow() Вставляет новую строку в таблицу.
next() Перемещает экземпляр объекта Cursor из текущей строки на следующую.
lupdateRowO Обновляет текущую строкууказанной таблицы.
Свойство columnName Представляет имена столбцов, возвращаемых курсором.
prototype Позволяет добавлять методы и свойства к экземплярам объекта Cursor.
Объект Resultset
Данный объект (результирующий набор) создается пос-
после вызова метода Stproc.resultSet(). В нем сохраняются
результаты выполнения хранимой процедуры. В случае
выполнения процедур в базах данных DB2, Oracle,
Sybase и ODBC объект Resultset возвращается для каж-
каждого оператора SELECT. В сервере Infomix будет воз-
возвращаться только один объект Resultset. В табл. 12.18
перечислены методы и свойства данного объекта.
Объект Stproc
Объект Stproc создается в результате вызова методов
Connection.storedProc() или database.storedProc() и вы-
Таблица 12.18. Методы и свойство объекта Resultset.
полняет хранимую процедуру в базе данных, к которой
получен доступ. Убедитесь, что вызов метода close()
производится по завершении выполнения процедуры. В
табл. 12.19 перечислены методы и свойства объекта.
Объект BLOB
Последний базовый объект, достойный рассмотрения,
обеспечивает поддержку работы с Binary Large Objects
(большие двоичные объекты, BLOB) в базе данных.
Объект не обладает свойствами, лишь только двумя
методами (см. табл. 12.20).
Тип
Элемент
Описание
Закрывает результирующий набор и освобождает занимаемую им память.
Принимает проиндексированную позицию столбца и возвращает соответствующее имя
столбца.
Возвращает количество столбцов в результирующем наборе.
Перемещает экземпляр объекта Resultset из текущей строки на следующую.
Позволяет добавлять методы и свойства к экземплярам объекта Resultset.
Метод
Свойство
close;)
columnName()
columnsQ
next()
prototype
Таблица
Тип
12.19. Методы
Элемент
и свойства объекта Stproc.
Описание
Серверная
часть javascript WWTfM
Глава 12 ЕШ
Метод closeQ Закрывает экземпляр хранимой процедуры, освобождая занимаемую им память.
outParamCountQ Возвращает количество выходных параметров процедуры.
outParameters() Возвращает значение определенного выходного параметра.
resu!tSet() Создает новый объект Resultset.
returnValue() Ввдает значение возврата хранимой процедуры.
Свойство prototype Позволяет добавлять методы и свойства к экземплярам объекта Stproc.
Таблица 12.20. Методы объекта BLOB.
Метод
Описание
ЫоЫтадеО Извлекает из базы данных и отображает экземпляр данных типа BLOB.
blobLinkQ Извлекает из базы данных и отображает HTML-ссылку, которая адресуется на экземпляр данных типа BLOB.
Резюме
Перед тем как приступить к созданию Internet-прило-
Internet-приложений, следует разобраться в их архитектуре. Предва-
Предварительный доступ к серверу окажет существенную по-
помощь в выборе метода разработки приложений типа
клиент/сервер. Функциональность JavaScript вместе с
механизмом баз данных позволяет перевести приложе-
приложения на новый качественный уровень.
Отдавая предпочтение клиентской или серверной
обработке, следует принять во внимание быстродействие
и функциональность приложений JavaScript. He забы-
забывайте, что двух- и л-уровневая модели обладают как
достоинствами, так и недостатками, и присущими им
степенью сложности и сопровождения.
Данная глава продемонстрировала, что в JavaScript
важна не только клиентская, но и серверная часть. С
использованием Netscape Server-Side JavaScript этот'
язык сценариев можно применить даже для создания
целых Web-приложений.
Использование DOM
ЧАСТЬ
В ЭТОЙ ЧАСТИ
13. Основы объектной модели документец
(DOM)
14. Управление событиями!
15. Объект Window
16. Объект Document
17. Объекты Form
18. Объекты Frame
19. Другие DOM-объекты
Основы объектной модели
документа (DOM)
В ЭТОЙ ГЛАВЕ
Понятие объектной модели документа
Навигация по таблице
Управление документами
Навигация по документу
В этой главе приводятся начальные понятия, каса-
касающиеся объектной модели документа (Document Object
Model — DOM) и ее назначения, характеристик, объек-
объектов и некоторых важных методов и свойств. Конечно,
здесь рассматриваются только основные принципы,
например, навигация по документам, а также их визу-
визуализация в виде деревьев DOM. В данной главе будут
показаны важные методы DOM, которые работают не-
непосредственно с деревьями, хотя более детальные по-
пояснения будут даны в главе 19, где DOM-модель рассмат-
рассматривается с точки зрения JavaScript.
Понятие объектной модели документа
Ключевые успехи Web помогают решить давно стоящие
проблемы. Например, Java обеспечивает путь разработ-
разработки независимых от платформы прикладных Web-прило-
Web-приложений с помощью аплетов, тогда как DOM-модель по-
постепенно решает другую довольно старую (хотя и не
столь важную) проблему создания JavaScript-сценариев
и программ на Java, переносимых в контексте Web-бра-
Web-браузеров. Это достигается за счет использования стандар-
стандартных прикладныхпрограммныхинтерфейсов (application
programming interfaces — API), которые входят в язык
определения интерфейсов (Interface Definition Language
— IDL), созданный Рруппой управления объектами
(Object Management Group — OMG), и поэтому могут
использоваться любым IDL-совместимым языком. Кол-
Коллективный DOM API можно считать методом стандар-
стандартизации объектов в браузерах при распространении
HTML- и XML-документов. Web-браузеры становятся
DOM-совместимыми, причем этот процесс идет быстры-
быстрыми темпами.
О DOM-модели, фактически, можно сказать немно-
немногое. Она просто определяет логическую и стандартизи-
стандартизированную структуру документа. Это дает возможность
формировать, редактировать и просматривать элементы
и содержимое в HTML- или XML-документах. Струк-
Структура DOM — это всего лишь объектная иерархия, сопо-
сопоставимая с иерархией в JavaScript или любом другом
основанном на объектах языке. Различие в том, что
DOM-модель имеет полезный API, который является
нейтральным языком и определяет стандартный набор
интерфейсов. Это не означает, что все прикладные про-
программы DOM будут основаны на одних и тех же объек-
объектах; они должны определять собственные интерфейсы и
объекты. Это возможно осуществить путем настройки
приложения так, чтобы оно, например, стало DOM-со-
DOM-совместимым.
У?ЕСУРС ' • .<-Ч .. ; , ,-,,,-, ,- . _,0. ,;
По адресу www.w3.org/TR/i999/CR-DOM-Level-2-
19991210 находится "W3C Document Object Model
(DOM) Level 2 Specification". Более ранняя специфи-
спецификация уровня Level 1 также находится на этом сайте.
Информация, содержащаяся в спецификации, не пе-
передается непосредственно в JavaScript или другой
ЕСМА-совместимый язык создания сценариев. Прило-
Приложение Е спецификации показывает привязку к соот-
соответствующему ECMAScript языку. В Web появилось
большое количество учебников по DOM и множество
сопроводительных статей и документов.
От DHTML к DOM
Приведение Web-страниц к объектной модели имеет
много стадий, но самая существенная из них — DHTML,
который сом по себе является довольно незначащим по
сравнению с D0M. Это потому, что D0M — стандарти-
стандартизированная объектная модель, которую Web-разработчи-
Web-разработчики ждали очень долго. Например, если Web-разработчик
должен будет модифицировать или настраивать Web-
Использование DOM
Часть III
страницу с помощью объектной модели DHTML, ему
в качестве руководства потребуется значительный объем
информации. Причина этому — огромное число HTML-
дескрипторов, свойств, методов и событий. DHTML дей-
действительно не больше, чем средства, позволяющие из-
изменять и управлять объектами с помощью атрибутов id
и name. Это далеко от стандартизации и упрощения
DOM, которая инкапсулирует целый документ в объек-
объектную модель, представляя его в виде иерархии или де-
дерева. Узлы дерева представляют собой HTML-деск-
HTML-дескрипторы и текстовые сегменты, которые они могут
содержать. Полный HTML-документ хранится в этом
дереве, а все объекты и их отношения отображаются как
дочерние и родительские элементы, а также элементы
одного уровня. В отличие от DHTML, управлять и вно-
вносить изменения в DOM-дерево документов весьма не-
несложно. Для изменений текстовых элементов, например,
просто изменяют значения узла дерева с помощью свой-
свойства nodeValue. Кроме того, существует возможность
создавать, удалять и перемещать узлы в дереве DOM-
документа. (Методы, которые позволяют это делать,
описываются позже, в табл. 13.2.)
Навигация по таблице
Для того чтобы лучше понять структуру дерева, рассмот-
рассмотрим структуру DOM-дерева простой таблицы (см. рис.
Таблица 13.1. Выражения для навигации.
13.1). Здесь показаны свойства childNodes, flrstChild,
lastChild, nextSibling и previousSibling. Используем их,
чтобы понять структуру дерева и научиться перемещать-
перемещаться к любой его части.
В DOM-дереве таблицы <table> будет находиться в
корне дерева. Из этого следует, что можно двигаться в
любой пункт дерева, определяя соответствующий узел.
Двигаясь вниз по дереву, достигнуть различных его частей
можно с помощью выражений, показанных в табл. 13.1.
Управление документами
Рассмотрим некоторые основные методы DOM, кото-
которые позволяют исполнять часто встречающиеся задачи.
В своем API DOM определяет методы, которые долж-
должны создавать, удалять, вставлять, перемещать, менять
местами и заменять узлы или объекты. Эти методы и их
аргументы, описания и возвращаемые значения, или
исходящие параметры, кратко описаны в табл. 13.2. Фак-
Фактически, все это довольно очевидно; метод removeNode()
удаляет поддерево, встроенное в указанный узил, если
deep равно true. Если же deep — false, удаляется только
указанный узел, а его дочерние объекты возвращаются
текущему родительскому элементу предыдущего уровня.
Другой метод, зависящий от логического параметра, —
cloneNode(). Когда параметр равен true, копируется под-
поддерево, а когда он — false, копируется только узел.
Перемещение
Выражение
Ко второй строке таблицы.
К первой ячейке второй строки.
К содержимому второй ячейки
в первой строке.
К корню второй строки.
К каждой из ячеек и затем
возврат в корень.
К каждой из ячеек.
tablel\lode.firstChild.childNodes[1]
tableNode.firstChild.childNodes[1].childNodes[0]
tableNode.firstChild.firstChild.childNodes[1].firstChild
Tr2Node.parentNode.parentNode
или
Tr2Node. previousSibling.parentNode.parentNode
или
Tr2Node.previousSibling.previousSibling.parentNode.parentNode
tableNode.firstChild.firstChild.firstChild.firstChild.parentNode.parentNode.
parentNode.parentNode
tableNode.firstChi!d.firstChild.childNodes[1].firstChild.parentNode.parentNode.
parentN ode. parentN ode
tableNode.firstChild.childNodes[1].firstChild.firstChild. parentNode.parentNode.
parentN ode. parentN ode
tableNode.firstChild.childNodes[1].childNodes[1].firstChild.parentNode.parentNode.
parentNode. parentNode
tableNode.firstChild .firstChild .firstChild. firstChild
tableNode.firstChild.firstChild.childNodes[1].firstChild
tableNode.firstChild.childNodes[1].firstChild.firstChild tableNode.
firstChild.childNodes[1].childNodes[1].firstChild
Основы объектной модели документа (DOM) Ш9Я
Глава 13
РИСУНОК 13.1. Простая структура
DOM-дерева таблицы.
|childNodes[1] II Or lastChild I I chlldNodeejO] I [chlldNoites|11 § QrtasLChiW I
Таблица 13.2. Методы DOM для управления документами.
Синтаксис метода DOM
Аргумент или
параметр
Описание
AppendChild fatherObj.appendChild(childObj) Объект
ApplyElement childObj.applyElement(fatherObj) Объект
ClearAttributes clearedObj.clearAttributes() He имеет
CloneNode newObj =existingObj. cloneNode(deep) Логический
CreateElement newObj = document. HTML-
createElement("Tag") дескриптор
CreateTextNode newObj = document. Строка
createTextNode(string)
HasChildNodes hasChildrenFlag = testedObj. He имеет
hasChildNodesQ
InsertBefore parentObj.insertBefore(childObj, brotherbbj) Объект
MergeAttributes targetObj.mergeAttributes(sourceObj) Объект
RemoveNode deletedObj.removeNode(deep) He имеет
ReplaceNode oldObj.replaceNode(newObj) Объект
SwapNode firstObj.swapNode(secondObj) Объект
Добавляет дочерний объект (childObj) к
родительскому объекту (fatherObj).
Направляет элемент объекта к другому объекту
(fatherObj).
Удаляет все атрибуты и значения объекта
(clearedObj).
Копирует существующий объект для создания
нового (newObj).
Создает узел (newObj) для нового дескриптора.
Создает новый текстовый узел (newObj).
Определяет, имеет ли объект дочерние элементы.
Вставляет объект (childObj) как дочерний элемент
для (parentObj).
Объединяет все атрибуты (sourceObj) в
(targetObj).
Удаляет поддерево объекта, если deep равно
true, и только узел, если deep — false.
Заменяет узел (oldObj) новым (newObj).
Меняет местами один узел с другим.
Объектная модель и атрибуты
иерархиями, показывая все их связующие ссылки. Но
соглашение DOM не требует представления документов
Структура DOM-документа может, фактически, ВКЛЮ- в виде деревьев, а также не требует наличия определен-
чать множество деревьев, являющихся объектными НЫХ отношений между объектами. Однако, каждый до-
Использование DOM
Часть III
кумент должен иметь узел типа документа, корневой
узел элемента, служащий корнем дерева документа, а
также комментарии или инструкции по обработке. Пред-
Представление в виде дерева, или структурная модель, имеет
информационные элементы, к которым обращаются,
используя методы перемещения по дереву. DOM также
твердо придерживается структурного изоморфизма, в ко-
котором различные DOM-совместимые реализации при
создании представления одного и того же документа
приводят к идентичной структурной модели. Узлы, об-
обсуждавшиеся выше, имеют различные атрибуты, многие
из которых перечислены в табл. 13.3.
ПРИМЕЧАНИЕ . ,з а. ".¦ '" ';'*.¦ ... Й
Изменение префикса атрибута, который принимает
значение по умолчанию, не создает новый атрибут с
этим значением по умолчанию и первоначальным пре-
префиксом, если namespaceURI и localName не менялись.
Таблица 13.3. Часто используемые атрибуты DOM.
Навигация по документу
Рассмотрев, как управлять простой таблицей, вполне
естественно перейти к тому, как делать то же самое с до-
документом. Листинг 13.1 показывает DOM-структуру, ко-
которая содержит заголовок документа, текстовый блок и
четыре параграфа:
Листинг 13.1. Простой документ.
<HTML>
<HEAD>
<TITLE> DOM document tree </TITLE>
</HEM»
<BODY ID=[dbl]bodyNode[dbl]XP ID = "Nodel">A
first paragraph</P>
The main document
<P ID = [dbl]Node2[dbl]>
<P ID = [dbl]Node3[dbl]X/P>
<P ID = [dbl]Node4[dbl]X/P>
</BODY>
</HTML>
Атрибут
Чтение/запись
Описание
Атрибуты типа NamedNodeMap Только для чтения
childNodes типа NodeList
firstChild типа Node
lastChild типа Node
localName типа DOMString
Только для чтения
Только для чтения
Только для чтения
Только для чтения
namespaceURI типа DOMString Только для чтения
nextSibling типа Node
Только для чтения
nodeName типа DOMString Только для чтения
nodeType типа unsigned short Только для чтения
ownerDocument типа Document Только для чтения
parentNode типа Node
Префикс типа DOMString
previousSibling типа Node
Только для чтения
Только для чтения
NamedNodeMap содержит атрибуты узла.
NodeList содержит все дочерние элементы узла.
Первый дочерний элемент узла; если узел не существует,
возвращается Null.
Последний дочерний элемент узла; если узел не существует, то
возвращается Null.
Возвращает локальную часть составного имени данного узла.
Когда используется с узлами, созданными с помощью метода
DOM первого уровня, включая createElement, то возвращает
значение Null.
Содержит данное значение namespaceURI. Это — всегда Null
для узлов всех типов, кроме ElementNode или Attribute Node.
Это Null для узлов, созданных методом DOM первого уроаня,
включая createElement из интерфейса Document.
Следующий узел в последовательности; когда следующего узла
не существует, возвращается Null.
Имя узла.
Код, содержащий определенный тип объекта.
Объект Document, который принадлежит узлу; этот объект
Document используется для создания новых узлов.
Родительский элемент узла. Это — не Attr, Document,
Document Fragment, Entity или Notation.
ParentNode будет равен Null, если узел недавно создан и
только должен стать частью дерева, либо если он удален из
дерева.
Префикс пространства имен узла; возвращается пустой
указатель, если ничего не определено. Установка этого атрибута
заменяет атрибут nodeName, который содержит составное имя
tagName и атрибуты имен интерфейсов Attr и Element.
Следующий из предыдущих узлов; когда такой узел не
существует, возвращается Null.
Основы объектной модели документа (DOM)
Дескриптор <body> находится на верхнем уровне
дерева и имеет пять дочерних элементов: четыре деск-
дескриптора <Р> и одиночный текстовый блок. DOM-дере-
DOM-дерево документа имеет узлы для дескрипторов и текстовых
Таблица 13.4. Навигация по документу.
Глава 13
блоков. Можно управлять деревом из узлов, которые
имеют атрибуты ID. Используя свойства DOM, можно
перемещаться к любому пункту в документе (см. табл.
13.4).
Перемещение
Выражение
К первому дочернему элементу.
Ко второму дочернему элементу.
К четвертому или последнему дочернему элементу.
Ко второму дочернему элементу корня (текстового
узла) от узла 1.
IK третьему дочернему элементу корня от узла 1.
К последнему дочернему элементу корня.
К дочерним элементам четвертого дочернего элемента.
Ко второму дескриптору <Р> от третьего <Р>.
К дочернему элементу дескриптора <body>.
К дескриптору корня <body> от дескриптора <Р>.
К дочернему элементу <body> и возврат к <body>.
bodyNode.firstChild или bodyNode.childNodes[0]
bodyNode.childNodes[1]
bodyNode.childNodes[4] или bodyNode.lastChild
Nodei.nextSibling
Nodei .nextSibling.nextSibling
Nodei .nextSibling.nextSibling. nextSibling
Nodei .nextSibling.nextSibling. nextSibling.childNodes[0]
Node3.previousSibling. previous
Sibling. previousSibling.cnildNodes[0]
bodyNode.firstChild.firstChild
Nodei .parentNode
body Node.firstChild.firstChild. parentNode. parentNode
Резюме
В главе рассматривались основные принципы DOM, a
также базовая объектная модель, применимая к стандар-
стандартным объектам простых Web-страниц. Были показаны
методы навигации и способы перемещения между узла-
узлами, определяющими документы. Кроме того, рассматри-
рассматривались свойства, их изменения и использование для
получения информации с помощью модели дерева. При-
Приводилась терминология DOM, например, узлы с имена-
именами типа firstChild, lastChild, nextSibling и previousSibling.
С этой основной информацией теперь можно подроб-
подробно остановиться на приложении DOM в контексте
JavaScript. В главе 19 DOM исследуется более подроб-
подробно.
Управление событиями
в этой главе
Понятие событий и обработчиков событий
Обработчики событий JavaScript
Обработка ошибок (опЕгтог)
Прерывание загрузки изображения (onAbort)
Замена обработчиков событий
Программная генерация событий
События таймера
Если в последние несколько лет вы много занима-
занимались программированием, скорее всего, вы использова-
использовали язык программирования, управляемый событиями.
Процедурные программы из прошлого диктовали, какие
задачи пользователю ИСПОЛНЯТЬ в любой заданный мо-
момент времени. Однако, графические оконные среды
сегодня имеют совершенно другую парадигму и требу-
требуют, чтобы прикладные программы, в первую очередь,
отвечали на инициированные пользователями события.
Памятуя об основанном на объектах характере
JavaScript (см. главу 9) можно ожидать, что JavaScript
является прежде всего управляемым событиями языком.
Эта глава рассматривает JavaScript-события и способы
ответа на них, т.е. создание на сайте интерактивных сце-
сценариев.
Понятие событий и обработчиков
событий
Многие из кодов JavaScript отвечают на события, выпол-
выполненные пользователем или программным обеспечением
браузера. Эта управляемая событиями среда позволяет
разработчику сосредотачиваться только на событиях,
которые затрагивают его приложение; то, что браузер
исполняет между событиями — дело браузера, а не раз-
разработчика. Кроме того, разработчику не нужно интере-
интересоваться всеми событиями, выполненными пользовате-
пользователем — лишь только теми, которые требуют ответа.
Каждое JavaScript событие имеет соответствующий
обработчик событий (event handler), который предназна-
предназначен для автоматического ответа на происходящее собы-
событие. При работе с событием к нему не добавляют код и
не изменяют его непосредственно, а, скорее, управляют
обработчиком события, которому данное событие соот-
соответствует.
Обработчики событий JavaScript
Разработчикам HTML-страниц известно, что каждый
элемент в форме имеет дескриптор и связанный с ним
атрибут. Например, ввод текста определяется следующим
способом:
<input type=text size=30 maxlength=30
name="LastName">
JavaScript реализует обработчики событий, встраивая
их в качестве атрибутов HTML-дескрипторов. Напри-
Например, предположим, что необходимо выполнять создан-
созданный метод каждый раз, когда значение объекта Text
изменяется. Для этого придется присвоить метод (с име-
именем, например, checkField()) обработчику событий
onChange объекта Text:
<input type=text size=30 maxlength=256
name="LastName" onChange="checkFieldC this ) ">
В кавычках можно записывать непосредственно
JavaScript-код или же вызов отдельной функции. Хотя
предыдущий пример вызывает функцию checkFieldQ,
следующий код также допустим:
<input type=text size=30 maxlength=256
паю-1 Las tName "
onChange= "if ( confirm( 'Are you certain
'^•you wish to change this value?'))
{ alert('Changed' )}" >
При использовании встроенного кода можно разме-
размещать сразу несколько строк в пределах назначения об-
обработчика событий, применяя точку с запятой для от-
отделения друг от друга операторов JavaScript. Однако,
множество строк программы следует применять с ос-
осторожностью. Намного проще работать с кодом, вы-
выделенным в функцию, а не с находящимся непосред-
Управление событиями
ственно внутри обработчика событий. Например, если
весь код физически расположить в одном месте, из-
изменения делать в нем окажется намного удобнее.
Далее в главе исследуются самые распространенные
события, поддерживаемые как Microsoft Internet Explorer,
так и Netscape Navigator. Особое внимание уделяется
наиболее часто используемым событиям. Для этого бе-
берется типичная HTML-форма (см. рис. 14.1) и добавля-
добавляется код в ее обработчики событий. Форма, которая бу-
будет использоваться на первых порах — обобщенная
форма заказа для некоторой виртуальной компании.
Щелчок на объекте (onClick)
Одна из наиболее общих целей JavaScript — расширение
HTML-формы и достижение таким способом большей
степени взаимодействия с пользователем. Если это так,
возможно, единственное наиболее частое событие, с
которым будет работать большинство разработчиков, —
это событие click. Событие click вызывается, когда
пользователь щелкает на каком-либо объекте, предназ-
предназначенном для нажатия.
Для большинства компьютерных сред событие click
вызывается только после того, как заданная по умолча-
умолчанию кнопка мыши нажата и отпущена. Пользователь,
который будет держать кнопку мыши и не отпустит ее
на объекте, событие click объекта не вызовет.
Когда событие click происходит, обработчик событий
onClick для нажатого объекта выполняет одну (или боль-
больше) JavaScript-команд либо вызывает определенную
функцию. Например, посмотрим на кнопку "View Hat"
на рис. 14.1. Предположим, что необходимо добавить
код, который при нажатии этой кнопки отобразит еще
одно окно браузера с изображением шляпы.
В HTML объект Button определяется следующим
образом:
<input type=button name="ViewHat" value="View Hat"
onClick="displayHat() ">
Legeiitt of Kakatn Hat Order Form
Jfyerti/ouldlikefflWt inforamnaihthe I.^f faaowb^foreft.
Ц lll«'to!eeii<teBl«<lp««muf*.tUs«aJofK»kai^atbeEorraJ»rltis.pt.iHcld
Custoirer Information!
Lu
С
M i
С .HVW!
L. ¦
Глава 14
В разделе <bead> HTML-файла записывается метод
(lisplayHat(), который будет вызываться при вызове об-
обработчика событий кнопки onClick:
<head>
<script language="JavaScript">
<! —
//Обработчик событий onclick
function displayHat() {
hatWindow = window.openf'http://
'-•www.myhat.com" , "view MyHafc" , "toolbar=0,
width=20O,height=40O,resizable=0") ;
)
</script>
< /head>
Когда пользователь нажимает кнопку, обработчик
событий использует метод ореп() объекта Window для
вывода на дисплей окна, содержащего изображение
шляпы (см. рис. 14.2).
Обработчик событий OnClick существует не только
для кнопок; его можно использовать для ответа на вклю-
включение флажков, выбор переключателей и щелчка на
объектах Link. Из-за характера этих элементов управле-
управления настройка их события click встречается редко. Флаж-
Флажки и переключатели часто используются для ввода дан-
данных и вычисляются после выполнения на них щелчка.
Что касается объекта Link, то он используется прежде
всею как ссылка на расположение, указанное в его свой-
свойстве href, и в добавлении кода часто нет необходимос-
необходимости, если только не нужно менять его заданное по умол-
умолчанию поведение.
|
: View lisri
; ¦ ¦¦¦ j
¦ io«..iv: 1
...i i
rta
Eftn
>Ji
-;.¦
- ¦ j_ ui1 ¦ '- i
Hat Order Form
of ti\t Legend cflltiBiii Ait tci'-лг ¦¦: Jem
¦
j. ркмс oft* Uk f-Ji
dfS|
'РИСУНОК 14.2. С помощью метода ореп() отображается
второе окно.
ПРИМЕЧАНИЕ
РИСУНОК 14.1. Например HTML-формы.
Для флажков, ссылок, переключателей, а также для
кнопок "Reset" и "Submit" можно возвращать значе-
значение false от обработчика событий onClick, чтобы от-
отменить вызванное действие. Например, если нужно
подтвердить, действительно ли выставлен флажок, в
Использование DOM
Часть III
его обработчик событий onClick добавляется следую-
следующий код:
<input type="checkbox" name="checkboxl"
value="DeluxeRoom"
pnClick="return confirm('Deluxe rooms are very
'-•expensive. Are you sure?') ">Deluxe Room
Поскольку вид Web-страницы также важен, для от-
ответа на события click вместо кнопок лучше использовать
изображения. Хотя изображение не способно фактичес-
фактически ответить на любое событие, можно имитировать со-
событие click с помощью объекта link. Продемонстриру-
Продемонстрируем это, используя изображение вместо кнопки "View Hat"
для вызова метода disp!ayHat() из предыдущего приме-
примера. Для этого определим соответствующий объект Link:
<href в "JavaScript :displayHat () ">
<img sro = "minihat.gif" align=bottam border=Q
width=89 height=75>
Вместо добавления кода в обработчик события
onClick ссылки, здесь используется JavaScript в качестве
протокола для свойства href. Использование JavaScript:
JavaScriptExpressioitKSiK значение свойства href застав-
заставляет браузер выполнить выражение JavaScript вместо
перехода к определенной ссылке.
Отправка формы (onSubmit)
Как обсуждалось в главе 1, одно из преимуществ исполь-
использования JavaScript в HTML-формах — возможность вы-
выполнения проверки правильности данных на стороне
клиента вместо перекладывания этой задачи на и без
того перегруженный сервер. Проверку правильности
можно выполнять для каждого поля в отдельности или
для всех полей сразу. В зависимости от контекста ис-
используется один или оба метода.
Для проверки правильности данных во всех полях
сразу, равно как и для других задач, главное значение
имеет событие submit. Это событие генерируется как раз
перед отправкой HTML-формы. Добавление кода в об-
обработчик событий onSubmit объекта Form дает возмож-
возможность совершить проверку, а затем разрешить продолже-
продолжение или блокировать его, уведомив об этом пользователя.
Событие submit произойдет, если от обработчика
событий onSubmit не возвращается значение false. Лю-
. бое другое значение (true или еще что-нибудь) приве-
приведет к генерации этого события. Например, предполо-
предположим, что перед отправкой формы на сервер необходимо
отобразить простое сообщение для пользователя с
просьбой подтвердить заполнение формы заказа шляпы
Kakata. Форма в HTML определяется следующим обра-
образом:
<form action="process.cgi" method="POST"
onSubmit="return confirmOrder () ">
Метод confirmOrderQ, используемый в обработчике
событий onSubmit формы, объявляется в разделе <head>
файла:
//обработчик событий onSubmit
function confirmOrder() {
return confirm ('Are you certain you wish to
border the Kakata hat?') ;
)'
При включении метода confirmOrder() он отобража-
отображает диалоговое окно Confirm с кнопками "ОК" и "Cancel".
Если пользователь нажимает на "ОК", диалоговое окно
закрывается и в обработчик событий onSubmit возвра-
возвращается значение true. Если пользователь нажимает на
'"Cancel", возвращается false. Оператор return в обработ-
обработчике событий onSubmit исследует входящее значение и
определяет, нужно ли продолжать обработку формы.
Оператор return в назначении обработчика событий не-
необходим для корректной работы кода. Присваивание
обработчику событий onSubmit = "confirmOrder()" запус-
запускает обработку формы независимо от возвращенного из
диалогового окна значения.
Обработчик событий onSubmit — то же самое, что
и обработчик событий onClick объекта Submit. Оба они
— события, которые можно использовать, чтобы захва-
захватить форму прежде, чем она будет обработана. Как по-
показано на рис. 14.3, обработчик событий onClick объекта
Submit был вызван до вызова обработчика onSubmit
формы.
Form
OnClick
No
Yes
Return
OnSubmit
No yes
Return
ACTION
РИСУНОК 14.3. Установление последовательности событий
для отправки формы.
Обработчик событий onSubmit — идеальное место
для размещения проверки правильности данных формы
до ее отправки на сервер.
Сброс формы (onReset)
Может понадобится вызвать событие и при сбросе фор-
формы, а не только при отправке. Обработчик событий
onReset вызывает код JavaScript, когда происходит собы-
Управление событиями
Глава 14
тие reset. Так же, как onSubmit, onReset — обработчик
событий объекта Form.
Для демонстрации этого снова рассмотрим форму
заказа шляпы Kakata, упомянутую в прошлом разделе.
После добавления нового обработчика событий к опре-
определению объекта Form код будет выглядеть так:
<form action="process.cgi" method="POST"
onSubmit="return confirmOrder<)"
onReset="return confirmReset () ">
Мегод confirmReset(), используемый в обработчике
событий onReset формы, объявляется в разделе <head>
файла:
//обработчик событий onReset
function confirmReset () {
return confirm ('Are you certain you wish to
¦"¦clear the order form? ' ) ;
1
примечание'':<*"У?'Ц>>-;;~~ -v^ ; :.^ ¦ yj-^-
Обработчик событий onReset поддерживается в JavaScript
t.t и более поздних версиях.
Изменение данных (onChange)
Как упоминалось в связи с событием submit, если при-
прикладные программы JavaScript имеют дело с данными,
обычно возникает необходимость в предварительной
обработке данных, введенных пользователем, во избежа-
избежание проблем проверки допустимости при отправке дан-
данных серверу. В то время как submit служит для провер-
проверки сразу всех полей формы, событие change обычно
наиболее важно для проверки допустимости на уровне
каждого поля формы. Событие change происходит, ког-
когда изменяется значение объектов поля и когда само поле
выходит из фокуса.
Для решения такого рода задачи используется обра-
обработчик событий onChange для выполнения JavaScript-
кода либо вызова функции для обработки события.
Предположим, что необходимо добавить базовую под-
подпрограмму проверки допустимости данных в форму вво-
ввода данных для заказа шляпы Kakata. Скажем, требуется
гарантия того, что содержимое поля "State" записано
буквами верхнего регистра. Объект Text определяется
следующим образом:
<input type=text size=3 maxlength=2 name="State"
onChange="convertToUppercase{this)">
M етод convertToUppercase() преобразовывает значе-
значение поля "State" к верхнему регистру, используя метод
toUpperCase() строки:
function convertToUppercase (fieldObject) (
fieldObject.value = fieldObject.value.toUpperCase{)
Получение фокуса (onFocus)
Событие focus вызывается, когда объект поля получает
фокус, т.е. когда пользователь переходит к объекту с
использованием клавиши "Tab" или с помощью щелчка
мыши на объекте, либо когда вызывается метод focus()
объекта. В каждый момент времени фокус может иметь
только один объект.
ПРИМЕЧАНИЕ ''^^"¦" _ _
JavaScript 1.1 и последующие версии расширяют воз-
возможности onFocus, включая его в качестве обработ-
обработчика событий для объектов Window, Frame и Frameset.
Для каждого из этих объектов обработчик событий
onFocus определяет действие, которое должно выпол-
выполниться при переходе фокуса.
Обработчик событий OnFocus должен размещаться
внутри дескрипторов <body> объектов Window,
Frame или Frameset.
Обработчик событий onFocus в этих объекта может
отвечать за переключение действия. Например, он мо-
может расширять стандартное поведение объектов Text в
форме. При переходе к объекту Text курсор появляется
по умолчанию. Однако, во многих средах (например, в
Windows), если поле уже имеет значение, то при уста-
установке фокуса на объект содержимое поля выделяется.
Для получения такого поведения (см. листинг 14.1) по-
потребуется добавить обработчики событий onFocus каж-
каждому из объектов Text и Textarea:
Листинг 141. Использование события onFocus для
полей формы.
<pre> First Name: <input
type=text
size=20
maxlength=20
name="FirstName"
onFocus="selectContents(this)">
Last Name: < input
type=text
size=20
maxlength=20
name="LastName"
onFocus="selectContents(this) ">
Title: <input
type=text
size=30
maxlength=25 6
name="Title"
onFocus="selectContents(this)">
Company: < input
type=text
size=30
maxlength=256
name="Company"
onFocus="selectContents(this) ">
Street Address: <input
type=text
size=30
maxlength=2 56
Использование DOM
Часть III
name="StreetAddr"
onFocus="selectContents(this)">
City: <input
type=text
size=30
raaxlength= 256
name="City"
onFocus="selectContents(this) ">
State: <input
type=text
size=3
maxlength=2
name="State"
onFocus="selectContents(this)"
onChange="convertToUppercase(this)">
Zip Code: <input
type=text
size=30
maxlength=10
name="Z ipCode"
onFocus="selectContents(this) ">
Telephone: <input
type=text,
size=12
maxlength=12
name="Phone"
onFocus="selectContents(this)">
FAX: <input
type=text
size=12
maxlength=12
name="FAX"
onFocus="selectContents(this)">
E-mail: <input
type=text
size=30
maxlength=25 6
name="Email"
onFocus="selectContents(this) ">
DM.: <input
type=text
size=30
raaxlength=256
name="URL"
onFocus="selectContents (this) "x/pre>
<textarea name="worthyBox" rows=3 cols=49
onFocus="selectContents(this)">
</textarea>
Хотя можно написать отдельные обработчики собы-
событий для каждого из полей, это будет нерациональным
подходом, если только процессы не оказываются совер-
совершенно разными. Вместо этого в методе seIectContents()
пользуются преимуществом ключевого слова this для
ссылки на вызывающий объект. Приведенная ниже фун-
функция тогда будет использоваться в качестве глобальной
для всех объектов:
function selectContents (fieldObject) (
FieldObject.select() ;
)
Когда один из объектов Text или Textarea вызывает
метод selectContentsQ, метод использует параметр
fieldObject как ссылку на вызывающий объект. Затем
метод select() осуществляет выбор информации в обла-
области ввода указанного объекта.
Выход из фокуса (onBlur)
Событие blur (противоположность события focus) вызы-
вызывается, когда объект теряет фокус.
«ПРИМЕЧАНИЕ ~" iW^f^t s
Как и с обработчиком событий onFocus, JavaScript 1.1
и последующие версии расширяют возможности
onBlur, включая его в качестве обработчика событий
для объектов Window, Frame и Frameset. Для каж-
каждого из этих объектов обработчик событий onBlur
определяет действие, которое должно выполниться,
когда окно теряет фокус.
Обработчик событий OnBlur должен помещаться в
дескриптор <body> объектов Window, Frame или
Frameset.
Например, предположим, что для формы ввода дан-
данных нужна гарантия, что пользователь не оставил пус-
пустым объект EmailText. Такую проверку можно добавить
в обработчик событий onBlur данного объекта. Посколь-
Поскольку она воздействует на одно поле формы, можно доба-
добавить JavaScript-код только к определению объекта Text:
<input type=text size=30 maxlength=256 ijame="Email"
onFocus="selectContents(this)" onBlur="if
(this, value = ¦'){
alert ('You must enter
^something. ') ;this.focus();)">
Если пользователь попытается убрать фокус из
объекта без ввода текста в данное поле, сигнальное ди-
диалоговое окно уведомит о недопустимости. Следующая
команда возвращает фокус к объекту EmailText. Без этой
команды курсор перешел бы к следующему полю.
Несложно заметить, что onChange и onBlur — очень
похожие обработчики событий. Возникает вопрос о том,
когда нужно использовать один, а когда другой. OnChange
больше подходит для проверки или анализа содержимого
объекта и обладает преимуществом в том, что не вызы-
вызывается при изменении значения пользователем. С дру-
другой стороны, для обязательных полей лучше использо-
использовать onBlur.
Важно понять правильный порядок следования об-
обработчиков событий onChange, onBlur и onFocus. Как
показано на рис. 14.4, onFocus происходит при входе в
поле. При выходе из него вызывается onChange, затем
onBlur и, наконец, обработчик onFocus следующего
входного объекта. Имейте в виду, что код, который до-
добавляется (например, в обработчик событий onChange),
может воздействовать на обработчик событий onBlur того
же самого объекта. Другими словами, использовать эти
три события следует с особой осторожностью.
Управление событиями
First Name
First Name
onFocus
onChange
\/
onBlur L
onFocus
РИСУНОК 14.4. Порядок следования событий от одного
объекта Text до другого объекта Text.
Выделение текста (onSelect)
Следующее JavaScript событие — событие select, кото-
которое происходит, когда пользователь выделяет текст в
объекте Text или Textarea. Обработчик событий onSelect
этих объектов выполняет JavaScript-код или вызывает
указанную функцию.
Независимо от способа реализации, возможности
события select довольно ограничены, и большинству
разработчиков оно вообще может не понадобиться.
.Перемещение мыши по объектам
(onMouseOver и onMouseOut)
Опытный пользователь Web, вероятнее всего, будет ожи-
ожидать, что перемещение мыши по тексту ссылок отобра-
отобразит место назначения ссылки (обычно URL-адрес). Од-
Однако, несмотря на то, что опытные пользователи хотят
видеть URL-адрес, начинающие пользователи предпоч-
предпочли бы вместо этого увидеть нечто менее прозаическое.
Это особенно актуально в intranet-средах, где URL-ад-
URL-адрес обычно значительно менее понятен. Захват событий
Листинг 14.2. Исходный код для Register.htm.
Глава 14
mouseOver и mouseOut позволяет изменять в строке со-
состояния текст по умолчанию.
^ПРИМЕЧАНИЕ s «f» ¦ Vv!^^*»}',----^ ¦;' ¦ .:,. ,%g
Обработчики событий onMouseOver и onMouseOut
также поддерживаются объектом Area в JavaScript 1.1
И последующих версиях.
Событие mouseOver генерируется, когда пользователь
помещает курсор мыши поверх объекта Link или Area.
Как и следовало ожидать, onMouseOut ведет себя таким
же образом, за исключением того, что событие проис-
происходит, когда курсор уводится из Link или Area. Обработ-
Обработчики событий onMouseOver и onMouseOut этих объек-
объектов могут затем изменять заданное по умолчанию
поведение браузера. Если необходимо установить свой-
свойства status и defaultStatus окна, следует возвратить в об-
обработчик событий значение true.
Например, предположим, что требуется отобразить
следующий текст в строке состояния, когда для ссылки
на шляпу Kakata генерируется событие mouseOver:
Click here to get the whole story about the
Legend of Kakata .
Для отображения данного текста добавьте в дескрип-
дескриптор Link обработчик событий onMouseOver:
<а href="http://www.kakata.com" name="linker"
onMouseOver="returnupdateStatusBar ( ) "
>Legend of Kakata
Метод updateStatusBar() определяется таким обра-
образом:
// обработчик событий onMouseOver
function updateStatusBar {) {
window, status = 'Click here to get the whole
^* story about the Legend of Kakata' ;
return true
II
Все рассмотренные в главе примеры содержатся в
файле Register.htm. Листинг 14.2 дает полный исходный
код для этих примеров.
<html>
<head>
<title>Kakata Hat Registration</title>
<script languages"JavaScript">
var noticeWindow
//Обработчик событий onclick,
function displayHat() {
hatwindow=window. open f "http: / , . /kakata/viewhat. htm" ,
"ViewHat" /"toolbar=0,width=200,height=400,resizable=0")
//Обработчик собыгш on Submit
7 1-158
Использование DOM
Часть III
function conf irmOrder ( )
return confirm ('Are you certain you wish to order the Kakata hat?');
1
//Обработчик событий onChange
function convertToUppercase ( f ieldObject) {
fieldObject.value =f ieldObject.value,toUpperCase <);
]
./ / Обработчик событий onFocus
function selectContents(f ieldObject) {
fieldObject.select() ;
1
/ / обработчик событий onMouseOver
function updateStatusBar () {
window, status = 'Click here to get the whole story about the Legend of Kakata1
return true
}
// обработчик событий onMouseOut
.function updateStatusBarOut() {
window, status = ' ' ,-
return true
]
// Обработчик событий onSelect
function accessText () {
alert ( ' Success" ) ;
1
// —>
</script>
</head>
<body baekground="lt_rock.gif">
<hlxfont color="#008000">Legend of Kakata Hat Order FornK/fontX/hl>
<hr>
<p>If you would like more information on the
<ahref="http: //www, acadians.com/javascript/kakata/kakata.htm"
name="linker"
onMouseOver="return updateStatusBar() "
onMouseOut="return updateStatusBarOut () ">Legend of Kakata </a>, please
fill out the following form. </p>
<form method="POST">
¦<p>If you would like to see a detailed picture of the Legend of Kakata
Hat before ordering, please click the following button: <input
type=button name="ViewHat" value="View Hat" onClick=displayHat () X/p>
</form>
<hr>
<?orm action="JavaScript: alert(' order' ) "
method="POST"
name="MainForm"
onSubmit="return confirmOrder () ">
<h2Xfont color="#008000">Customer Information</fontx/h2>
<pre> First Name: <input
type=text
size=20
maxlength=20
name="FirstName"
onFocus="selectContents(this)">
Last Name: <input
type=text
size=20
maxlength=20
name="LastName"
onFocus="selectContents(this)">
Title: <input
type=text
size=30
Управление событиями
Company: <input
Street Address: <input
City; <input
State : <input
maxlength=30
name="Title"
onFocus="selectContents(this)">
type=text
size=30
maxlength=30
name="Company"
onFocus="selectContents(this)">
type=text
size=30
maxlength=30
naroe="StreetAddr"
onFocus="selectContents (this)">
type=text
.size=30
maxlength=30
name="City"
onFocus="selectContents (this) ">
type=text
size=3
maxlength=2
name="State"
onFocus="selectContents(this)"
onChange="convertToUppercase (this)">
Zip Code: <input
Telephone: <input
FAX: <input
Email : <input
size=30
URL : < input
type=text
size=30
maxlength=10
name="ZipCode"
onFocus="selectContents(this)">
type=text
maxlength=12
name=" Phone"
onFocus="selectContents (this) ">
type=text
size=12
maxlength=12
name="FAX"
onFocus="selectContents (this) ">
maxlength=50
name="Email"
onFocus="selectContents(this)">
type=text
size=30
maxlengtbOl О
<hr>
onFocus="selectContents (this) "X/pre>
Глава 14
<pXstrong>Are you Squot; Kakata worthySquot;? Please use the space below to
enter a thorough reason for your order .</strongX/p>
<blockquote>
<pXtextarea
riame= "worthy Box "
rows=3
¦cols=49
onFocus="selectContents(this)">
</textareaX/blockquoteX/p>
Использовонш DOM
Часть III
<h2Xfont color="#008000">Form Submission</f ontX/h2>
<pXen»Please click the Order button to order your free Legend of Kakata hat.
You will receive email confirmation of your order in 24 hours.</emX/p>
<pXinput
type=submit
value="Order"
onClick="confirmOrder('Submit object')">
<input
type=reset
value="Clear Fonn"
onClick="alert('Clearing! ')"X/p>
<p>snbsp;</p>
<P>
</form>
href="JavaScript:displayHat()">
<img src="ball.gif" align=bottom border=0 width=16 height=16>
</body>
</html>
СОВЕТ
При захвате множества событий mouseOver и mouse
в объекте Area обработчик событий onMouseOut
вызывается при уходе из этой области, затем при вхо-
входе в следующую область вызывается on MouseOver.
Загрузка документа (onLoad)
1ачальнос открытие окна или фрейма может оказаться
важным моментом времени для выполнения определен-
определенного JavaScript-кода. Событие load позволяет использо^
вать этот момент, добавляя обработчик событий onLoad
к дескриптору <body> в случае однофреймового окна
или к дескриптору <frameset> в случае мультифреймо-
вого окна. Событие load выполняется, когда браузер за-
завершает загрузку окна или всех фреймов мультифрей-
мового окна. Объект Window — единственный объект,
который может работать с этим событием.
В качестве примера рассмотрим ситуацию, когда
нужно гарантировать, что все пользователи intranet-сети
некоторой компании используют требуемую версию
Netscape Navigator. Для этого можно определить брау-
браузер, применяемый обработчиком событий onLoad и за-
затем уведомить пользователя, правильная ли у него вер-
версия программы. В дескриптор <body> документа
добавляют обработчик событий onLoad:
<body i
Затем в дескрипторе <head> документа определяет-
определяется метод checkBrowser():
//обработчик событий onLoad
function checkBrowser() {
if 'Netscape') ss
(navigator.appVersion = '4.0 (Win95; I)')> {
noticeWindow = window. open ("" , "NoticeWindow'1,
"toolbar=0,width=300,height=100,resizable=0");
noticeWindow. document, write <"<headXtitle>Upgrade
l-(Notice</titleX/head>") ;
int.write ("<ce
*"*Web Browser needs to be updated. Pleas<
e your supervisor before noon.
^</bX/bigX/center>"))
Сразу после загрузки документа выполняется JavaScript-
метод. На рис. 14.5 показан вид окна Upgrade Notice для
версий, не прошедших испытания.
РИСУНОК 14.5. Окно UpgradeNotice открыто с помощью
обработчика событий onLoad.
ПРИМЕЧАНИЕ
У объекта Image также есть обработчик событий
onLoad. Это событие вызывав' ся, когда браузер вы-
выводит на дисплей изображение. Обратите внимание,
что данное событие происходит не в процессе загруз-
Управление событиями
Глава 14
ки изображения клиенту, а в течение вывода на дисп-
дисплей этого изображения.
Выход из документа (onUnload)
Событие unload (противоположное событию load) вы-
вызывается непосредственно перед выходом пользователя из
документа. Как и в случае с onLoad, обработчик событий
¦onUnload можно добавлять в дескриптор <body> в случае
однофреймового окна или в дескриптор <frameset> в слу-
случае мультифреймового окна. Если есть мулътифреймовое
окно и множество обработчиков событий onUnload для
фреймов, то обработчик событий мультифреймового
окна всегда выполняется в последнюю очередь.
Приведем пример использования обработчика собы-
событий onUnload для очистки среды браузера перед перехо-
переходом к следующей странице. Например, предположим,
что требуется закрыть окно View Hat при уходе со стра-
страницы заказа шляпы Kakata. Можно добавить onUnload
к дескриптору <body> следующим образом:
<body onLoad="checkBrowser()" onUnload="clean()">
Затем определяется метод clean():
// обработчик событий onUnload
function clean () {
Листинг 14.3. Исходный код для LoadUnload.htm.
noticeWindow.close();
:i
noticeWindow — глобальная переменная, которая
объявляется в дескрипторе <head> документа и ссыла-
ссылается на окно Upgrade Notice, отображенное с помощью
обработчика onLoad. Окно Upgrade Notice закрывается,
когда пользователь покидает текущую страницу.
Листинг 14.3 показывает полный исходный код для
onLoad и onUnload.
Обработка ошибок (onError)
Объекты окна и изображения имеют обработчик собы-
событий onError, который позволяет отслеживать ошибки,
возникающие в процессе загрузки документа или изоб-
изображения. Отслеженная ошибка будет либо синтаксичес-
синтаксической ошибкой JavaScript, либо ошибкой времени выпол-
выполнения программы, но не ошибкой браузера (типа
сообщения сервера о том, что страница не существует).
Глава 33 дает полное представление об отслеживании
ошибок с помощью onError.
Обработчик событий onError поддерживается в
JavaScript 1.1 и последующих версиях.
<html>
<head>
<title>Load/Unload Example</title>
<scrlpt language="JavaScript">
var noticeWindow
//Обработчик событий onLoad
function checkBrowser (> {
if t (navigator. appName = 'Netscape1) SS (navigator. appVersion = '4.0 (Win95; I)')) {
noticeWindow = window . open <"", "NoticeWindow", "toolbar=0,width=300,height=100,resizable=0"> ;
noticeWindow.document.write { "<HEADXTITLE>OpgradeNotice</TITbEX/HEMD>" ) ;
noticeWindow. document, write ("<CENTERXBIGXB>Your Web Browser needs to be updated. Please
your supervisor before noon.
^</BX/BIGX/CENTER>)' )
// Обработчик событий onUnload
function clean {) {
if ( noticeWindow != null ) { noticeWindow. close () };
I
// ~>
</script>
</head>
<body cnLoad="checkBrowser()" onUnload="clean(>">
<font color="#008000">
<centerXbigXb>Intranet Home Page</bX/bigX/center>
< /body>
</html>
Использование DOM
Часть III
Я
Прерывание загрузки изображения
(onAbort)
В зависимости от размеров HTML-изображения, загруз-
загрузка его может занимать много времени. В результате
пользователи могут потерять терпение и остановить заг-
загрузку изображения до ее завершения. Например, пользо-
пользователь может прервать процесс загрузки, щелкнув на
ссылке на другую страницу или нажав кнопку "Stop" в
меню браузера.
Объект Image и обработчик событий onAbort поддер-
поддерживаются в JavaScript 1.1 и последующих версиях.
Однако, если пользователь будет работать с частич-
частично недогруженным HTML-файлом, может не произой-
произойти что-то из задуманного разработчиком, и, вероятно,
возникнут некоторые нарушения выполнения кодов для
изображений сценария. Обработчик событий onAbort
позволяет реагировать на прерывание загрузки изобра-
изображения и вызывает в качестве ответа JavaScript-функцию.
Например, предположим, необходимо предупредить
пользователя о том, что HTML-документ не был загру-
загружен полностью. Тогда к дескриптору <img> добавляют
следующий обработчик событий:
<img name="mapworld" SRC="global.gif'"
onAbort="alert('You have not downloaded the
"¦¦entire document. ') ">
Замена обработчиков событий
В JavaScript 1.1 и последующих версиях можно заменять
обработчик события, назначенный в определении
HTML-дескриптора. Например, в приведенном ниже
листинге функция optionA() назначена в определении
<input> в качестве обработчика события для объекта
buttonl. Однако, второй сценарий вычисляет перемен-
переменную choice. Если значение choice не равно "А", то, как
видно из листинга 14.4, код заменяет назначенный об-
обработчик событий на функцию optionBQ.
Листинг 14.4 Пример замены обработчиков событий.
<script language="JavaScript">
var choice = "A";
function optionA() {
I
function optionB() {
</script>
<body>
<form name="forml">
<input type="button" name="buttonl"
onClick="optionA()">
</form>
<script language="JavaScript">
if (choice != "A") {
document.forml.buttonl.onclick=optionB
</script>
</body>
Обратите внимание, что обработчики событий — это
ссылки на функции, поэтому при определении в коде не
нужно добавлять к ним круглые скобки. Если бы код был
определен так, как показано ниже, функция optionB()
была бы вызвана, но не назначена в качестве обработ-
обработчика событий:
document.forml.buttonl.onclick=optionB ()
Программная генерация событий
До сих пор в данной главе обсуждался ответ на события,
сгенерированные пользователем (например, событие
click) или системой (например, событие onllnload). В
большинстве случаев код проектируется так, чтобы от-
отвечать на эти события, как только они происходят. Од-
Однако, разработчики JavaScript не должны рассчитывать
только на внешние факторы, генерирующие события. В
действительности, можно вызывать возникновение не-
некоторых из этих событий внутри кода.
Например, можно смоделировать событие click для
объекта Button, вызывая его метод click(). Хотя это вер-
верно для объекта Button, но, например, для объекта Link
(у которого имеется обработчик событий onClick) метод
click() не существует.
События таймера
Множество управляемых событиями сред программиро-
программирования используют событие таймера, которое является
событием, вызываемым каждый раз по прошествии за-
заданного интервала времени. Хотя JavaScript не предла-
предлагает событие типа таймера, для тех же целей можно ис-
использовать метод setlnterval объекта Window.
' ' ~~'
ПРИМЕЧАНИЕ
Метод setlnterval поддерживается в JavaScript 1.2 и
последующих версиях.
Метод setlnterval многократно вызывает функцию
или вычисляет выражение каждый раз по истечении
указанного интервала времени (в миллисекундах). Этот
метод будет выполняться, пока окно не закроется или
пока не будет вызван метод clearlnterval.
Управление событиями
Например, в листинге 14.5 метод setlnterval выпол-
выполняется, когда документ открывается и начинает вызы-
вызывать функцию dailyTaskO каждые 10000 миллисекунд.
Функция dailyTaskO ПРИ каждом вызове проверяет
время, и в 8:30 утра начинает выполняться код в опе-
операторе if, предназначенный для подачи сигнала пользо-
пользователю и очистки интервала. Как только вызывается
метод clearlnterval, выполнение setlnterval останавлива-
останавливается.
Листинг 14.5. Исходный код для Timer12.htm.
<head>
<script language="JavaScript">
function dailyTaskO {
var tdy = new Date () ;
if ((tdy.getHoursO = 8) &&
(tdy.getMinutesO = 30)) {
alert('Good morning sunshine! ')
clearlnterval(timerlD)
\
II—>
timerlD = setlnterval ('dailyTask()', 10000)
</script>
</head>
При использовании JavaScript 1.1 или более ранней
версии можно выполнять подобный процесс (хоть и не
таким прямым способом) с помощью методов setTimeout()
и clearTimeout().
Обычно метод setTimeoiit() используется для вычис-
вычисления выражения по прошествии определенного проме-
промежутка времени. Это вычисление — одноразовый процесс,
который не повторяется бесчисленное количество раз.
Однако, поскольку в JavaScript есть возможность произ-
производить рекурсивные вызовы функции, рекурсию можно
использовать для создания события таймера де-факто.
Предположим, что каждое утро в 8:30 необходимо
выполнить задачу, описанную немного выше. Для этого
нужно иметь таймер, вычисляющий время; когда это
время достигнуто, процесс запускается. Метод dailyTaskO
определяется так:
function dailyTaskO {
var tdy = new Date () ;
if ((tdy.getHoursO = 8) &&
(tdy.getMinutesO =30)) {
performProcess()}
timerlD = setTimeout("dailyTask()",10000)
Метод создает объект Date, содержащий текущее
время, с помощью getHours() и getMinutes(). Если они
вычисляют 8:30 утра, вызывается метод performProcess().
Глава 14
Следующая строка — основа процесса таймера — ис-
использует метод seffimeoutO для рекурсивного вызова ме-
метода dailyTaskO каждые 10000 миллисекунд.
Этот пример демонстрирует определенные трюки в
отношении таймера, и лучше быть поосторожнее с
подобной реализацией процесса в реальных задачах.
Осуществление такого непрерывного процесса выпол-
выполнения цикла е браузере может привести, в конце
концов, к нехватке ресурсов.
Для запуска таймера при загрузке документа потре-
потребуется добавить обработчик событий onLoad в дескрип-
дескриптор <body> HTML-документа:
<body onLoad ="dailyTask()">
Листинг 14.6 содержит полный исходный код приме-
примера.
Листинг 14.6. Исходный код для Timer11.htm.
<head>
<script language="JavaScript">
< ! —
function performProcess() {
alert ('Good morning sunshine! ') ;
)
function dailyTaskO {
var tdy = new Date (> ;
if ((tdy.getHoursO = 8) &&
i (tdy.getMinutesO = 30)) {
perf ormProcess () }
timerlD =
setTimeout("dailyTask()",10000)
}
II—>
</script>
</head>
<body onLoad="dailyTaskО">
</body>
Резюме
Учитывая управляемый событиями характер JavaScript,
можно утверждать, что твердое понимание встроенных
событий — ключ к максимальному увеличению его мощ-
мощности. В главе рассматривались события и связанные с
ними обработчики событий. Особое внимание уделялось
событиям, наиболее полезным для разработчиков, а так-
также определенным примерам их использования. Эти ба-
базовые знания понадобятся в следующих главах, в которых
будут детально рассматриваться встроенные JavaScript-
события.
Объект Window
В ЭТОЙ ГЛАВЕ
Объект Window
Открытие и закрытие окон
Навигация между окнами
Отображение окон сообщений
Работа с сообщениями строки состояния
Объекты браузера Navigator — это объекты самого
высокого уровня в иерархии JavaScript-объектов. Эти
объекты не имеют дело с HTML; они имеют дело преж-
прежде всего с браузером, например, с открытием новых окон
браузера, перемещением по списку посещений или по-
получением имени хоста из текущего URL. В этой главе
подробно рассматривается объект Window (который, как
было сказано, находится на вершине объектной иерар-
иерархии), а также упоминается группа других объектов, хотя
детальное объяснение им будет дано в следующих гла-
главах. Эта группа включает в себя объект Frame, который
будет обсуждаться в главе 18. Кроме того, рассматрива-
рассматриваются объекты Location, History и объект Navigator уров-
уровня приложения.
Объект Window
Объект Window верхнего уровня, который является ро-
родителем других дочерних объектов, присутствует на каж-
каждой Web-странице, и, безусловно, в одном JavaScript-
приложении их можно иметь несколько. Основные
Таблица 15.1. Основные методы объекта Window.
методы объекта Window реализуют вполне очевидные
функциональные возможности (см. табл. 15.1):
Как было показано в главе 9, Window — объект вер-
верхнего уровня в иерархии объектов JavaScript. В отличие
от других объектов, которые могут присутствовать или
отсутствовать в среде выполнения, объект Window все-
всегда присутствует — либо в мультифреймовом окне, либо
в одиночном. Однако, отличие объекта Window от дру-
других заключается в том, что его часто можно просто иг-
игнорировать. Вот две причины этого.
Первая причина: при работе в среде одиночного
фрейма можно игнорировать явную ссылку на объект
Window. JavaScript выводит ссылку в текущее окно. На-
Например, следующие два кода эквивалентны и выдают
¦один и тот же результат:
myTitle
myTitle
window.document.title
document.title
Вторая причина: в силу особой структуры языка
JavaScript, некоторые методы системного уровня (напри-
(например, всплывающие окна сообщений или установка тай-
таймера) присвоены объекту Window.
Метод
Описание
Open и Close Открытые и закрытие окна браузера; есть возможность определять размер окна, его содержимое, а
также наличие кнопочной панели, поля адреса и других атрибутов.
Alert Появление окна сигнального диалога с соответствующим сообщением.
Confirm Появление окна диалога подтверждения с кнопками "ОК" и "Cancel".
Prompt Появление окна диалога подсказки с полем текстового ввода.
Blur и Focus Удаление или установка фокуса на окно.
ScrollTo Прокрутка содержимого окна до определенной точки.
Setlnterval Установка временного интервала между функциональным вызовом и вычислением выражения.
SetTimeout Установка однократного временного интервала до функционального вызова или вычисления выражения.
Объект Window
Однако, для вызова этих методов нет необходимос-
необходимости использовать ссылку непосредственно на окно; такая
ссылка будет неявной.
Работа с объектами Window — сложная часть про-
программирования на JavaScript из-за способов, по которым
пользователи применяют окна браузера. Хотя большин-
большинство пользователей обычно имеют дело только с одним
окном, иногда бывает полезно открыть сразу два и боль-
больше окон. Так можно сравнивать страницы различных
сайтов, вводить информацию в форму, используя дан-
данные с другой Web-страницы, а также проводить поиск
элементов списка одной страницы, просматривая ссыл-
ссылки с помощью еще одного экземпляра браузера.
Термин окно браузера часто сокращается до просто-
окна, хотя нужно быть внимательнее и не путать разные
копии браузера с фреймами, которые также называют
окнами (подокнами окна браузера). Окно браузера так-
также называют верхним (top) окном, потому что фреймы —
это подокна браузера. Браузеры, поддерживающие
JavaScript, позволяют программно открывать и закры-
закрывать окна браузера, а также перемещаться по этим ок-
окнам. Сайт с отдельными окнами сможет обеспечить
сразу несколько версий содержимого, увеличив тем са-
самым доступ к информации и возможностям и предло-
предложить новые пути более полного взаимодействия с сай-
сайтом.
''¦^ПРИМЕЧАНИЕ "' ''! " 1Р^1Щ*3??,
В JavaScript 1.2 в Window было добавлено несколько
новых методов: atob, back, btoa, captureEvents,
clearlnterval, crypto.random, crypto.signText,
disableExternalCapture, enableExternalCapture, find,
forward, handleEvent, home, moveBy, moveTo,
releaseEvents, resizeBy, resizeTo, routeEvent, scrollBy,
scrollTo, setHotKeys, setlnterval, setResizable и
setZOptions.
Кроме того, добавилось несколько новых свойств:
crypto, innerHeight, innerWidth, locationbar, menubar,
offscreenBuffering, outerHeight, outerWidfh,
pageXOffset, pageYOffset, personalbar, screenX,
screenY, scrollbars, statusbar и toolbar.
Для JavaScript 1.2 требуется Navigator 4.0-4.05, в то
время как для JavaScript 1.3 — Navigator 4.06-4.5.
Во многих случаях для одновременного просмотра
страниц удобнее использовать фреймы (см. главу 18).
Однако, у пользователей есть возможность изменять
размеры и положение множества отдельных окон брау-
браузера. Пользователи могут также сворачивать и разворачи-
разворачивать окно, при необходимости перемещать окно поверх
или вниз всех окон и сохранять все инструментальные
средства и другие особенности (строку меню, поле ад-
адреса, строку состояния, закладки и т.д.) в каждом эк-
экземпляре браузера.
Глава 15
Многие пользователи считают отвлекающим и раздра-
раздражающим неожиданное открытие новых окон браузе-
браузера, в особенности, если они потом должны сами зак-
закрывать их. Уведомьте посетителя о том, что данное
действие откроет новое окно — например, с помо-
помощью короткого примечания рядом со ссылкой. В сле-
следующем примере Spike — это ссылка, которая откры-
открывает новое окно:
See a picture of my dog spike, (new window)
Открытие и закрытие окон
f ПРИМЕЧАНИЕ * "'¦'
Пользователь в любой момент может открыть новое
окно, выбрав File, New Browser (или что-то подобное).
Однако, сослаться на такое окно из JavaScript не уда-
удастся.
При помощи JavaScript можно открывать и закрывать
окна браузера. Разработчик может создать новое окно с
определенным документом, загружающимся в него при
выполнении некоторых условий. Можно также указать,,
например, размер нового окна и параметры, доступные
в окне, а также присвоить окну имя (для ссылок на него).
Хотя открытие окна подобно созданию нового объекта
Window, в данном случае конструктор new не использу-
используется. Вместо этого применяется следующий синтаксис:
WindowVar = window, open (URL, windowName,
[ , windowFeatures])
Параметры метода ореп():
URL. URL целевого окна. Этот параметр не обяза-
обязателен. Если URL — пустая строка (""), браузер от-
открывает пустое окно, позволяя использовать метод
write() для создания динамического HTML.
windowName. Имя объекта Window. Имя также не обя-
обязательно; однако для обращения к окну с помощью
ссылок или форм имя необходимо. Можно присво-
присвоить имя позже, через свойство window.name.
• windowFeatures. Список атрибутов отображения для
окна браузера.
Если окно открылось, метод ореп() возвращает мет-
метку объекту Window. Если окно почему-либо не было
открыто, данный метод возвращает значение Null.
^ПРИМЕЧАНИЕМ
Два имени, относящихся кокну, функционально — не
одно и то же. Рассмотрим следующий код:
myWindow=window.open ("" , "newWindow") ;
myWindow — переменная объекта, который открыл
newWindow. newWindow — имя нового окна. На
свойства нового окна можно ссылаться с помощью!
переменной myWindow. Ссылки и формы могут об-
Использование DOM
Часть III
ращаться к новому окну с использованием его имени
new Window.
Ссылки на окна
При работе с одиночными и множественными фрейма-
фреймами в JavaScript-приложениях, возможно, потребуется
использовать и другие способы ссылок на окна. JavaScript
обеспечивает четыре вида ссылок на окна, и каждый из
них реализуется как свойство объекта Window. Более
подробная информация относительно ссылок на окна и
фреймы будет дана в главе 18.
Отдельные окна браузера не имеют иерархической
структуры; однако, окно, содержащее код, который
открывает другое окно, часто называется родительс-
родительским окном. Соответственно, новое окно называется до-
дочерним. Любое новое окно можно присвоить перемен-
переменной из других окон так, чтобы другие окна могли
ссылаться на нее и ее свойства. Для ссылки на свойство
в новом окне используйте windowName.property.
Рассмотрим следующий код;
newWindow = window.open О;
newWindow. location.href = "http://www.mcp.com/","
Хотя этот фрагмент — не самый эффективный спо-
способ записи кода, он демонстрирует способ ссылки на
свойство дочернего окна. Новое окно открывается и
получает имя (в данном случае, newWindow). Затем
устанавливается location.href нового окна.
Текущее окно
В главе 9 обсуждалось использование окон для ссылок
на текущее окно. Однако, не было упомянуто, что объект
Window содержит свойство под названием window, кото-
которое может использоваться как инструмент ссылки на
самого себя. Кроме того, свойство self объекта Window —-
еще одно средство сделать окно текущим или активным.
Например, следующие две строки кода — функциональ-
функционально идентичны:
window, defaultstatus = "Welcome to the Goat
^Farm Home Page"
self. defaultStatus = "Welcome to the Goat Farm
'•Home Page"
Поскольку window и self— синонимы текущего окна,
может показаться странным, что оба они включены в
язык JavaScript. Как показано в предыдущем примере,
это объясняется необходимостью увеличения гибкости,
т.е., по желанию, возможно использовать либо window,
либо self.
Однако, насколько полезными могут быть window и
self, настолько же они могут стать запутанными, если
подойти к этому логически. В конце концов, свойство
объекта, которое используется как эквивалентный тер-
термин для самого объекта, довольно необычно. Следова-
Следовательно, window и self будет удобнее считать зарезерви-
зарезервированными словами для объекта Window, а не его свой-
свойствами.
Поскольку window и self— свойства объекта Window,
нельзя использовать и window, и self в одном и том же
контексте. Например, следующий код не будет работать:
window.self.document.write("<hl>Test.</hl>")
Наконец, в мультифреймовых средах window и self
всегда относятся к окну, в котором выполняется JavaScript-
код.
В некоторых объектно-ориентированных или основан-
основанных на объектах языках self может относиться к ак-
активному объекту, независимо от его типа. В JavaScript
self относится только к активным объектам Window
или Frame — и ни к чему больше.
Определение содержимого окна
Параметр URL определяет, какое содержимое появится
в новом окне. Если задается какое-то значение, браузер
пытается найти и отобразить указанный документ:
NewWindow = window.open("http://
www.acadians.com", "AcadiaPage", LO:WRONG)
С другой стороны, можно отобразить пустую стра-
страницу, указав в качестве параметра URL пустую строку
(""). Используйте эту методику при необходимости ди-
динамического создания HTML-страницы с использова-
использованием JavaScript:
newWindow = window.open(""r "DynamicPage" "")
newWindow. document. wri te ("<Hl>Document created
fusing JavaScript.</Hl>")
newWindow.document.close()
В главе 16 подробно рассматривается использование
метода write() объекта Document для создания динами-
динамического HTML.
Определение атрибутов окна
Параметр windowFeatures необходим при отображении
окна, т.к. с его помощью настраивается внешний вид
открытого окна. Параметр windowFeatures не обязателен;
если он не используется, отобразится окно с такими же
атрибутами, как у текущего окна. Таблица 15.2 содержит
список атрибутов внешнего вида окна.
ПРИМЕЧАНИЕ """ *""
Атрибуты alwaysRaised и z-lock, добавленные в
JavaScript 1 .2, работают только на платформах
Windows и Macintosh.
Таблица
Атрибут
15.2
. Атрибуты метода ореп() для отображения
Описание
окна.
иьъект Window PSai
Глава 15 ЁШ
width Ширина клиентской области Navigator в пикселах. См. innerWidth, который появился в JavaScript 1.2.
height Высота клиентской области Navigator в пикселах. См. innerHeight, который появился в JavaScript 1.2.
dependent Если значение равно yes, создает дочернее окно из текущего окна; в Windows дочернее окно в панели
задач не появляется. Дочернее окно закрывается одновременно со своим родительским окном.
Появился в JavaScript 1.2.
toolbar Отображает/скрывает инструментальную панель браузера.
menubar Отображает/скрывает меню браузера.
scrollbars Отображает/скрывает горизонтальную и вертикальную полосы прокрутки браузера.
innerWidth Определяет ширину области содержания окна. Окна размером меньше, чем 100x100 пикселов, требуют
подписанного сценария. Атрибут появился в JavaScript 1.2. Заменяет width, который также может
использоваться для совместимости сверху вниз.
innerHeight Определяет высоту области содержания окна. Окна размером меньше, чем 100x100 пикселов, требуют
подписанного сценария. Атрибут представлен JavaScript 1.2. Заменяет height, который также может
использоваться для совместимости сверху вниз.
resizable Разрешает/запрещает изменение размеров окна браузера.
screenX Определяет расстояние от левой стороны экрана до нового окна. Окно может быть помещено за
пределами экрана с помощью атрибута в подписанных сценариях. Появился в JavaScript 1.2.
screenY Определяет расстояние от вершины экрана до нового окна. Окно может быть помещено за пределами
экрана с помощью этого атрибута в подписанных сценариях. Появился в JavaScript 1.2.
status Отображает/скрывает строку состояния браузера,
location Отображает/скрывает окно URL-адреса.
directo'ies Если значение равно yes, отображает вторичную инструментальную панель (Netscape) с кнопками
наподобие "What's New" и "What's Cool".
copyhistory Копирует список посещений текущего окна в новое окно.
outerWidth Ширина окна Navigator в пикселах (JavaScript 1.2).
outerHeight Высота окна в пикселах (JavaScript 1.2).
left Расстояние в пикселах от левой стороны экрана (JavaScript 1.2).
top Расстояние в пикселах от верха экрана (JavaScript 1.2).
alwaysLowered Создает окно браузера, которое всегда помещается ниже других окон, независимо от того, является ли
оно активным (появился в JavaScript 1.2). Безопасная возможность, требующая подписанного сценария.
alwaysRaised Если значение равно yes, создает окно браузера, которое помещается выше других окон, независимо
оттого, является ли оно активным. Появился в JavaScript 1.2. Безопасная возможность, требующая
подписанного сценария.
z-lock Создает новое окно браузера, которое не всплывает поверх других окон при помещении в фокус
(JavaScript 1.2).
Атрибуты height и width Определяют размеры окна в.
пикселах и совместимы сверху вниз с JavaScript 1.0 и 1.1,
хотя предпочтительнее использовать вместо них соответ-
соответствующие ключевые слова — innerWidth и innerHeight.
Остальные атрибуты устанавливаются с помощью логи-
логических значений: значение true — 1, yes или атрибут
alone; значение false — 0, по или отсутствие атрибута
вообще. Например, если необходимо отобразить новое
окно только с инструментальной панелью и меню, ис-
используют следующий синтаксис:
NewWindow = window.open (LO:WRONG, "myWindow",
"toolbar=l, menubar=l")
Следующий синтаксис также допустим:
NewWindow = window, open ("", "myWindow",
"toolbar=yes, menubar=yes")
NewWindow = window.open (" " ,
"myWindow", "toolbar, menubar")
Таким образом, можно просто не учитывать те ат-
атрибуты, которые не определены. Эти атрибуты имеют
значения false.
.ПРИМЕЧАНИЕ '_"'"' ' " ¦ .Ъ: ' '
Атрибуты outerWidth, outerHeight, left и top, добавлен-
добавленные в JavaScript 1.2, обеспечивают абсолютное пози-
Использование DOM
Часть III
ционирование окон браузера на рабочем столе.
InnerWidth и innerHeight обеспечивают контроль над
точными размерами окон браузера, хотя при исполь-
использовании JavaScript 1.0 или 1.1 вместо них необходи-
необходимо применять ключевые слова width и height.
, совет -, , «., „. ,,.Л>ь ,.„,„
Ошибка в некоторых версиях браузера Netscape Navigator
не позволяет использовать метод window.ореп() для
¦отображения документов. Для обхода этой ошибки
нужно повторить команду открытия окна:
myWindow = window, open ("new.html" , "newwindow") ;
myWindow = window.open("new.html", "newwindow");
При таком повторении newWindow и его документ ото-
отобразится во всех версиях браузеров Netscape Navigator.
^
Примечание Ci;
В дополнение к методу window.openl), для открытия
нового окна можно также применять атрибут ссылки
TARGET = "_blank" или даже целевой атрибут со
значением любого имени (окна или фрейма), не ис-
используемого в данный момент. Ссылка <HREF =
"foo.html" TARGET = "bar">foo</A> открывает
окно браузера, именует заголовок окна и загружает
в окно документ foo.html, пока одно из текущих окон
или фреймов не получит имя bar (имена окон и фрей-
фреймов зависят от регистра).
Кроме того, ссылка TARGET = "_blank" создает не-
непоименованное окно, которое в дальнейшем тяжело
поддается модификациям. С помощью _blank ссыл-
ссылка (та же самая ссылка или другая) просто создает
еще одно новое окно вместо обновления открытого
ранее.
^
Закрытие окон
Для закрытия окна используют метод close() объекта
Window. Если требуется закрыть текущее окно, вызов
метода будет выглядеть просто как window.close(). В от-
отличие от других методов объекта Window, таких как
alert() или SetTimer(), метод close() должен всегда сопро-
сопровождаться объектной ссылкой. Если метод closeO ис-
использовать без объектной ссылки, может закрыться те-'
, кущий документ, а не окно, в зависимости от контекста
вызова метода. Причина в том, что объект Document
также имеет метод close(). Таблица 15.3 содержит не-
некоторые типичные коды сценария, в которых можно
применять метод close().
©ПРИМЕЧАНИЕ , „*
Более поздние версии Netscape не допускают, чтобы
метод window.closel) закрывал окна, которые были
созданы не JavaScript. Эта мера защиты не позволя-
позволяет шутникам вставлять нежелательный код в гостевые
книги и т.п. Данная мера не затрагивает любое закон-
законное использование метода window.closet).
Функция или обработчик событий с window.close()
закрывают окно, содержащее их:
<PORM>
<INPOT* TYPE="BUTTON" VRLUE="Close Window"
onClick="top.close 0">
</FORM>
Для обработчика событий типа onClick необходимо
определять имя окна, например, window, parent, top,
self либо имя установленной переменной, например,
myWindow, как в window.closel) или в myWindow.closel).
Простое использование closet] в обработчике собы-
событий подразумевает document, closel).
Можно закрывать окно с помощью ссылки на то же
самое окно, из которого данное окно было открыто,
используя переменную, установленную равной новому
окну:
myWindow = window.open("new.html", "newwindow");
<FORM>
<INPOT TYPE="BUTTON" VftLUE="Close Window"
onClick="myWindow. close {)" >
</FORM>
1ПРИМЕЧАНИЕ
-w,
newWindow.closel); работать не будет. Имя newWindow
можно использовать в предыдущем примере для иден-
идентификации окна (свойство window.name) и для адре-
адресации окна в ссылках и формах. Однако, нельзя ис-
использовать newWindow для ссылки на новое окно и его>
свойства.
Таблица 15.3. Метод closeQ и открывающие окна.
Close 0/Opener
Описание
window.opener.close()
document.write("<br>opener property is " +
window.opener.name)
top.opener.closeQ
window.opener.docurnent.bgColor='bisque'
window.opener=null >
Закрывает окно, из которого было открыто текущее окно.
Определяет имя окна, из которого было открыто текущее окно.
Закрывает главное окно браузера.
Изменяет цвет фона окна, определенного свойством opener.
Устанавливает значение свойства opener равным Null, предотвращая
закрытие открывающего окна.
Объект Windm
Глава 15
При использовании метода window.closel) хорошо было
бы обеспечить кнопку или ссылку для пользователей,
чтобы они могли закрыть новое окно по завершении
работы с ним. (Некоторые пользователи, в особенно-
особенности новички, могут не знать, как закрыть окно, или
могут по ошибке выйти из браузера вместо закрытия
окна.) Можно использовать условный оператор для со-
создания закрывающей кнопки или ссылки, если доку-
документ загружен в названном явно окне (новое окно):
<SCRIPT IANUAGE="JavaScript">
<! —
.//newWindow is the name given the new window
if(top.name == "newWindow" {
document.write) '<A HREF="javascript:
+
' this window to return to previous window.") ;
} // Для наглядности угловые скобки не
// представляются своими ходами:
// unescape("%3C"), unescape("%ЗЕ").
//Однако в реальных кодах » о потребуется
//делать, чтобы они не воспринимались как
//дескрипторы комментария в старых браузерах.
</SCRIPT>
Форма на рис. [5.1 демонстрирует различные аспек-
аспекты открытия и закрытия окон. Заполняя форму, можно
по желанию определить просмотр нового окна.
Листинг 15.1. OpenWindow.htm.
Window Open Example
Р/еязо select motoitowingtlbptayoptions «ntf tftwt click If» Open Wlmtowtortton.
WggisJyou like an easting page or one treated on the ty?
" &tsnng Page |
r Dynamic Раве
Window Attributes:
Г Tbolbec Г Iftnubtr
Г Status. Г Location
Г cu^tun fite
Vldch: I Height: f
Г Directories Г Сор/- Hif4.DC.;'
— iininrviiBiirti шгшатшей
В первом поле определяют параметр URL — исполь-
используя существующий URL или создавая страницу "на
лету". Второе поле позволяет определять каждый из до-
доступных атрибутов окна. По умолчанию все поля не
заполнены. Можно заполнить требуемые из них. За счет
заполнения полей "Custom Size" можно определить раз-
размеры нового окна.
При нажатии кнопки "Open Window" всплывает но-
новое окно, показанное на рис. 15.2.
Листинг 15.1 содержит исходный код этого примера.
<html>
<head>
<title>Window Open</title>
<SCRIPT IANGUAGE="JavaScript">
<< —
var newWindow
.// Открыть окно на основе атрибутов, определенные пользователем
function openWindow() {
// Построение списка параметров windowFeatures
var winAtts = '
if {document.winOptions.toolbarOption.checked) {
winAtts += "toolbar=l," }
i f (document.winOptions.menubarOption.checked) {
winAtts += " ienubar=l," )
if (document.winOptions.scrollbarsOption.checked) {
winAtts += "scrollbars=l," )
if (document.winOptions.resizableOption.checked) {
winAtts += "resizable=l," )
if (document.winOptions.statusOption.checked) {
winAtts += "status=l," }
if (document.winOptions.locationOption. checked) {
winAtts += "location=l," }
if (document.winOptions.directoriesOption.checked) (
winAtts += "directories=l," )
if (document.winOptions.copyHistoryOption.checked) (
winAtts += "copyhistory=l," )
if (document. winOptions. customSizeOption. checked) (
winAtts += "height=" + document.winOptions .heightBox. value
winAtts += "width=" + document. winOptions. widthBox. value +
I
winAtts = winAtts. substring @, winAtts . length-2)
// Определить URL и отобразип окно
Использование DOM
ЧастьШ
if (document.winOptions.pageType[l] .checked) {
var urlVar = ""
urlVar = document. winOptions . urlBox. value
newWindovf = window, open (urlVar, "newWindow" ,winAtts) )
else {
newWindow = window, open (""/'newWindow" ,winAtts)
newWindow. document, write ("<Hl>WindowOpen Test</HlXp>")
// Закрыть OKRO
function closeWindow ( ) {
newWindow. close ( >
I
// ~>
</SCRIPT>
</head>
<body background=" . ./lt_rock.gif">
<hlxfont color="#008040">Window Open Example</fontX/hl>
<pXiXb>Please select the following display options and then click
the Open Window button. </iX/BX/p>
<form name="winOptions" method="POST">
<p>Would you like an existing page or one created on the fly?</p>
<input
type=radio
checked
name="pageType"
value="existing">Existing Page
¦< input
type=text
size=30
maxlength=25 6
name= " urlBox " x/p>
< input
type=radio
name="pageType"
value="dynamic">Dynamic Page</p>
<hr>
<p>Window Attributes :</p>
<preXinput
type=checkbox
name—"toolbarOption"
value="ON"
>Toolbar <input
type=checkbox
name=t'menubarOption"
value="ON">Menubar <input
type=checkbox
name="scrollbarsOption"
value="ON">Scrollbars <input
type—checkbox
name="resizableOption"
value="ON">Resizable</pre>
<preXinput
type=checkbox
name="statusOption"
value="ON">Status <input
type=checkbox
name="locationOption"
value="ON">Location <input
type=checkbox naine= " directoriesOption "
value="ON">Directories <input
type=checkbox name="copyHistoryOption"
value="ON">Copy History</pre>
<preXinput
type=checkbox
name="customSizeOption"
value="ON">Custom Size</pre>
Объект Window
Глава 15
<pre>Width: < input
type=text
size=5
maxlength=5
name="widthBox"> Height: <input
type=text
size=5
maxlength=5
name="heightBox">
type="button"
name= " OpenButton"
value="Open Window"
onClick="openWindow(> "> <input
type="button"
nane="CloseButton"
value="Close Window"
onClick="doseWindow(> "X/pre>
</form>
<p>finbsp;</p>
</body>
</html>
<input
Window
Open Test
f j
Ш
xample
(У options and Шел eltcKthe Open Windowbutton.
?ne created on the*
Window Attributes:
Г Toolbar Г mm
T Bta Г (.dsi
IP" Custom 5k;
¦ -
РИСУНОК 15.2. Отображение нового окна.
Навигация между окнами
Возможно, что в течение одного сеанса пользователь от-
откроет большое количество окон; однако, в каждый мо-
момент вргме! ; только одно окно из них может быть ак-
активным, т.е. быть в фокусе. Наличие фокуса означает,
что окно может непосредственно получать вводимые
данные и отвечать на ввод пользователя. Кроме того,
окно в фокусе — обычно самое верхнее окно на дисп-
дисплее, т.е. окно в активном режиме накладывается на дру-
другие окна. (В UNIX и X Window окно в фокусе бывает и
на заднем плане.)
Пользователь может передвигаться между окнами с
помощью мыши. Обычно щелчок на окне переводит на
это окно фокус. В некоторых версиях UNIX для пере-
перевода окна в фокус достаточно перемещения курсора
мыши поверх окна; напротив, вывод курсора за преде-
пределы окна выводит и фокус (или деактивирует) из окна.
Перекладывание действий на пользователя — не
единственный путь, а иногда — и не лучший путь пе-
передачи окну фокуса. JavaScript и HTML обеспечива-
обеспечивают несколько методов для установки и удаления фокуса
автоматически — с использованием кода. Эти автома-
автоматические установки и удаления фокуса позволяют пе-
перемещаться по окнам с минимальным участием пользо-
пользователя или вообще без оного. Вместо генерации сооб-
сообщения для пользователя, приглашающего щелкнуть на
окне, код может автоматически передавать фокус окну.
Это не означает, что пользователь не будет управлять
сеансом, однако он получит помощь, подобную автопи-
автопилоту.
Хотя многим сайтам не нужны многократные окна,
сайтам, которые в них нуждаются, может оказаться
удобно программно управлять этими окнами. JavaScript
предоставляет хорошие средства управления окнами с
помощью открывающих и закрывающих методов, опи-
описанных выше, и с помощью методов установки и уда-
удаления фокуса из окна. Все эти методы управления ок-
окнами объединяются в программную систему навигации
по окнам.
В JavaScript простое определение объекта окна или
его документа, или даже изменение свойства в окне, не
переводит окно в фокус. Переводить окно в фокус мож-
можно двумя способами:
Косвенно, устанавливая в фокус один из объектов в
окне.
Непосредственно, устанавливая фокус на само окно.
Косвенная установка фокуса
Окно, открытое с помощью переменной п indow и
содержащее документ с формой myF< и элементом
ввода mylnpul может получить фокус через окно, из
которого оно было открыто, с помощью такого кода:
Использование DOM
Часть III
myWindow.document.myForm.mylnput.focus();
Элемент ввода, mylnput, получает фокус, и в резуль-
результате myWindow, который содержит mylnput, также по-
получает фокус.
Новое окно может передавать фокус окну, которое
открыло его, с помощью своего свойства opener:
window.opener.focus();
ПРИМЕЧАНИЙ -¦— '~--' -
Свойство opener поддерживается в JavaScript 1.1 и
следующих версиях.
Для перевода фокуса из нового окна на окно, из ко-
которого оно было открыто, в ранних версиях JavaScript-
браузеров для нового окна требовалась переменная для
ссылки на открывающее окно:
myWindow = window.open("new.html", "newWindow");
myWindow. oldWindow = top;
Новое окно может ссылаться на старое окно и кос-
косвенно передавать ему фокус:
oldWindow.Document.myForm.mylnput.focus() ;
Прямая установка фокуса
Окно может получить фокус непосредственно при ис-
использовании метода window.focus(). Если окно ссылает-
ссылается на другое окно с помощью переменной типа myWindow,
оно передает фокус другому окну:
myWindow.focus();
Новое окно может передавать фокус окну, которое
открыло его, с помощью свойства opener:
window.opener.focus();
Вызов функции в окне может передавать фокус окну,
если функция содержит window.focus():
function focusDemo(){
top.focus;
.... остальная часть функции
I ,
Методы window.focusl) и window.blur|), как и свой-
свойство opener, поддерживаются только в JavaScript 1.1
и следующих версиях. Для обеспечения согласования
с ранними версиями браузера необходимо использо-
использовать косвенную методику установки фокуса.
Удаление фокуса
Деактивизация окна (удаление из него фокуса) выпол-
выполняется путем передачи фокуса другому окну. Посколь-
Поскольку в каждый момент времени только одно окно может
иметь фокус, передача фокуса окну непосредственно или
косвенно деактивизирует другие окна.
С помощью метода window.blur() из окна можно не-
непосредственно удалить фокус без передачи фокуса дру-
другому окну. Для window.blurQ можно использовать лю-
любое из средств, применяемых с window.focus().
'ПРИМЕЧАНИЕ ¦'",_.
Согласно документации Netscape, щелчок на ссылке
в окне передает этому окну фокус:
<А. HREF="some.html" TARGET="myWindow">My Window</A>
Щелчок на ссылке загрузит документ some.html в окно
myWindow и передаст фокус myWindow. Если myWindow
не существует, будет открыто новое окно, после чего
в него загрузится some.html и новое окно получит
фокус.
Эта методика работает не во всех версиях браузеров.
Иногда, если окно уже открыто, оно может и не по-
получить фокус.
Отображение окон сообщений
Диалоговые окна — традиционно важная часть при-
прикладной программной среды. Пользователям Windows
известно, что диалоговые окна присутствуют как в дан-
данном, так и в других графических пользовательских ин-
интерфейсах. JavaScript может отображать стандартные
диалоговые окна для уведомлений пользователя или
получения информации перед продолжением работы.
Однако, из-за немодального характера Web использовать
диалоговые окна не рекомендуется. Обычно лучше свя-
связываться с пользователем другим способом.
Модальные диалоговые окна достаточно обычны в при-
прикладных программах Windows. Если вы пришли из мира
Windows 4GL, убедитесь, что вы подкорректировали
свое мнение относительно их использования.
Язык JavaScript не так строго понимает это замеча-
замечание, добавляя префикс к отображаемым сообщениям.
Для сигнальных сообщений, перед сообщением появ-
появляется "JavaScript Alert". Для диалоговых окон подтвер-
подтверждения — "JavaScript Confirm", а в диалоговых окнах
подсказки появляется "JavaScript Prompt". В результате
пользователь может легко определить источник появив-
появившегося диалогового окна.
1|ПРИМЕЧАНИЕ
Помимо возможности обеспечения самого сообщения,
не существует возможности настраивать просмотр
окон сообщений JavaScript. Заголовок и пиктограммы
— всегда одни и те же.
Простое уведомление
Для передачи пользователю информации используется
метод alert() объекта WindowQ. Сигнальное диалоговое
Объект Window
окно отображает сообщение с одной кнопкой "ОК.", зак-
закрывающей данное окно. Это модальное диалоговое
окно, поэтому пользователь будет вынужден закрыть его
перед продолжением работы в браузере (даже в муль-
•ифреймовых документах). При закрытии диалогового
окна никакие значения не возвращаются. Его синтаксис
таков:
[window. ] alert {.message)
Можно отображать информацию относительно теку-
текущего окна в сигнальном сообщении с помощью кода,
показанного в листинге 15.2.
Листинг 15.2 DisplavWindowlnfo.htm.
<нтщ>
<HEAD NAME = "WindowPane">
<SCRIFT LANGUAGE = " JavaScript">
function displayWindowInfo() {
var winlnfo = '
winlnfo = "Number of frames: ' +
window.length + "\r"
winlnfo += "Window object name: +
window.window + "\r"
winlnfo += "Window parent name: ' +
window. parent + "\r"
winlnfo += "URL: " + window. location
alert(winlnfo)
1
</SCRIPT>
</HEAD>
<BODY>
<FORM>
<INPUT
„\r"
</INPOT>
</FORM>
</BODY>
Type="button"
Value="Display Window Information"
OnClick="displayWindowInfo()"
На рис. 15.3 показано сигнальное диалоговое окно,
которое отображается при нажатии кнопки.
Параметр message метода alert() — обычно строка,
хотя это не обязательное требование. Поскольку JavaScript
не является строго типизированным языком, можно
отображать информацию других типов данных без пре-
преобразования данных в строку. В качестве параметра
можно использовать даже объект, как показано в лис-
листинге 15.3. На рис. 15.4 представлен результат.
Листинг 15.3. DisplayWindowObjectlnfo.htm.
<HTML>
<HEAD>
<SCRIPT LANGUAGE = "JavaScript">
function Application(Title, ProgramName,
Path, Vendor) {
this.Title = Title
this. ProgramName = ProgramName
Глава 15
this.Path = Path
this.Vendor = Vendor
)
function displayApp () {
alert(Application)
</SCRIPT>
</HEAD>
<BODY>
<H1X/H1>
<FORM>
<INPUT
Type="button"
Value="Display Obj ect Definition"
OnClick="displayApp()"
</INPUT>
</FOPM>
</BODY>
РИСУНОК 15.3. Сигнальное диалоговое окно.
РИСУНОК 15.4 Определение объекта, отображенное в
сигнальном диалоговом окне.
Использование DOM
Часть
Yes/No-подтверждение
В дополнение к простому отображению информации в
диалоговом окне, можно задавать пользователю вопрос,
используя метод confirm() объекта Window. Диалоговое
окно подтверждения отображает кнопки "ОК" и "Cancel",
причем каждая из них возвращает значение. "ОК" воз-
возвращает true, a "Cancel" — false. Как подразумевается в
имени метода, обычно используют диалоговые окна под-
подтверждения, чтобы пользователь подтвердил действие,
которое собирается совершить. Синтаксис в данном слу-
случае выглядит так:
returnValue
[window.]confirm(message)
Обычное диалоговое окно подтверждения должно
предлагать пользователю подтвердить отправку формы
либо сообщения по электронной почте. Листинг 15.4
показывает, как можно использовать метод confirm() для
возврата значения onSubmit обработчику событий фор-
формы. Если пользователь щелкает на "ОК", форма отправ-
отправляется по указанному адресу. Если же щелчок выполня-
выполняется на кнопке "Cancel", событие не генерируется.
Листинг 15.4. JavaScriptChronicles.htm.
<html>
<head>
LeMJntitled Normal Page</title>
<SCRIPT LANGUAGE="JavaScript">
if irmAction ( 5 {
return < о you really want
subscription?")
</SCRIPT>
</head>
<body>
t Chronicles — Free Subscription
Form</emX/h2>
<form
action="mailto:subscribe@jschronicles.com"
method="POST"
name="SubscribeForm"
onSubmit="return confirmAction()">
other magazines do you currently
subscribe to?
<prexinput type=
>PC Week
<input 1
value= 4 >DBMS
< input type=
value=" SKU07 " >Wired
<input type
>Yahoo
< input type
value="SKU02">InfoWorld
< input 1
>Databased Advisor
< input type=ch
value="SKO08">Web Publisher
<input type=checkbox name="Cl-SKUll"
value="SKUll">Internet Advisor
<input type=checkbox name="Cl-SKU03"
value="SKU03">PC Magazine
<input type=checkbox name="Cl-SKU06"
value="SKU06">Delphi Informant
<input type=checkbox name=
value="Cl-SKU09">Web Informant
<input type=checkbox name="Cl-SKO12"
value="SKO12">JavaWorld
</pre>
</li>
<li>Please enter the reason you would like to
subscribe to
<em> JavaScript Chronicles : </emXbr>
<br>
<textarea
name="Comments"
rows=6
cols=46>
</textareaX/li>
</oL>
<p>
<input
type=submit
name="Submit"
value="Submit" >
</form>
</body>
</html>
На рис. 15.5 показано окно подтверждения, которое
отображается при нажатии кнопки "Submit".
Г Ybjibcj
Г liLtSUoiMd
Г ОАЕ-.Ьгчг 1 J.difi.ini-
Г ГСеЬ P-ftiJ^s^pi
Г JavnCct id Г:-""""- L' " ' "**""""¦ "
ж
Si
бЕгйгй1.":.77-тк •"-¦¦ ¦-- .¦-¦:¦¦—- г
1
^Ш
РИСУНОК 15.5. Диалоговое окно подтверждения возвращает
ответ пользователя.
Пользовательский ввод
Третье диалоговое окно, которое можно использовать
для получения пользовательского ввода, вызывается с
помощью метода Prompt() объекта Window. Воспользуй-
Воспользуйтесь диалоговым окном подсказки, когда требуется по-
получить значение от пользователя. Это диалоговое окно
Объект Window
состоит из сообщения, поля пользовательского ввода и
кнопок "ОК" и "Cancel". Метод Prompt() имеет следу-
следующий синтаксис:
returnValue = [window.]prompt(message,
defaul tReply)
Как видно из этого примера, в дополнение к указа-
указанию сообщения диалогового окна необходимо опреде-
определить параметр defaultReply. Это значение будет заданным
по умолчанию текстом, вставляемым в поле пользова-
пользовательского ввода окна. Данный параметр нужно опреде-
определять даже в том случае, когда он не имеет никакого зна-
значения по умолчанию.
— ... ¦ .
ПРИМЕЧАНИЕ
Будьте уверены, что для диалогового окна подсказки
определен заданный по умолчанию ответ. Если не
добавлять этот параметр, JavaScript поместит в поле
ввода Undefined, которое может запутать пользова-
пользователей. Если значений по умолчанию нет, используйте
для этого параметра пустую строку {'
Если пользователь щелкает на "ОК", метод Prompt()
возвращает значение строки, введенное пользователем.
Если пользователь ничего не ввел, возвращается пустая
строка (""). Однако, если он щелкнет на "Cancel", воз-
возвращается значение Null.
ПРЕДУПРЕЖДЕНИЕ
•Не считайте, что пользователь будет всегда нажимать
на "ОК" в диалоговом окне подсказки. Всякий раз при
использовании метода Prompt!) необходимо гаранти-
гарантировать, что непустое значение возвращается раньше
чем оно будет использовано в вычислениях. В таком
случае, если пользователь нажмет на "Cancel", про-
программа будет работать со значением строки "null",
а не с тем, что было фактически введено пользова-
пользователем в поле текстового ввода.
Листинг 15.5 показывает пример использования окна
подсказки. Пользователю предлагают ввести текст в поле
(см. рис. 15.6). Этот текст затем используется в новом
окне, как показано на рис. 15.7.
Листинг 15.5. UserTexthtm.
<HTML>
<H?AD>
<SCRI?T LANGUAGE = " JavaScript">
function showBoxO {
userText = prompt ("Enter the text i
your " + "pe: i browser
' own browser text")
if (userText null) {
userWindow — window.open("",
"userTextWindow", "toolbar=0")
userWindow.document.write("<hl>" +
userText + "</hl>") }
)
</SCRIPT>
<BODY>
Глава 15
<FORM>
<INPUT
Type="button"
Value="Create Your Own HTML Page"
OnClick="showBox()"
</INPOT>
</FOKM>
</BODY>
Возвращаемое значение — это всегда строка. Если
нужно обрабатывать его как другое значение, сначала его
необходимо преобразовать. Например, если требуется
вычислить общую стоимость на основе определяемой
пользователем процентной ставки, можно получить ее
значение с помощью метода Prompt(), как показано на
рис. 15.8. Затем перед вычислением полной стоимости
следует преобразовать это значение в вещественное чис-
число при помощи метода parseEloat(). Листинг 15.6 пока-
показывает код этого примера.
Hl4..ll .jM.j.1...
РИСУНОК 15.6. Диалоговое окно подсказки.
Листинг 15.6. Calc.htm.
<HTML>
<HEAD>
<SCRIPT LANGUAGE = "JavaS<
function get {
percent = p lat is the current
-rate?", "8.5")
if (percent != null) {
e = p I * 20000
) }
</SCRIPT>
<BODY>
<FORM>
<INPUT
Type="button"
:ulate Total Price"
OnClick="getPercentageRate()"
</INPUT>
</FOEM>
</BODY>
Использование DOM
Часть III
My own browser text
РИСУНОК 15.7 Новое окно отображает содержимое,
введенное пользователем.
РИСУНОК 15.8 Полъзовательскийввод.
Работа с сообщениями строки
состояния
Строка состояния браузера может оказаться важным
средством взаимодействия с пользователем. Здесь
можно задействовать два свойства объекта Window,,
defaultStatus и status, для управления отображенным
текстом.
Вообще говоря, использовать строку состояния мож-
можно двумя способами. Первый способ — отображать за-
заданное по умолчанию сообщение в строке состояния.
Пользователь видит это сообщение, не выполняя ника-
никаких действий. Заданное по умолчанию сообщение отобра-
отображается через свойство defauItStatus. Свойство defauItStatus
может быть установлено в любое время — то ли после
загрузки окна, то ли после его открытия.
Второй способ — отображать временное сообщение
поверх заданного по умолчанию текста. Фактически, это
сообщение обычно появляется, когда пользователь про-
продуцирует событие, например, перемещая мышь. Это со-
сообщение можно устанавливать с помощью свойства
status.
Рисунок 15.9 иллюстрирует использование свойств
defauItStatus и status.
http://www.acadians.com
в/ga URL ряде.
p
РИСУНОК 15.9. Установка свойств defauItStatus и status.
Код для этой страницы показывает три действия для
изменений сообщения в строке состояния. Сначала при-
приведенный ниже набор кодов устанавливает заданное ш>
умолчанию сообщение при открытии окна:
window.defauItStatus =
*->URL page. "
"Welcome to the large
Во-вторых, когда пользователь переходит на ссыл-
ссылку "Go", ее обработчик событий onMouseOver вызыва-
вызывает следующую функцию:
function changeStatus (> {
window, status = "Click me to go to the
^¦Acadia Software home page."
1
В-третьих, чтобы изменить текст заданного по умол-
умолчанию сообщения состояния, пользователь может выб-
выбрать одно из сообщений объекта Select. Когда вызыва-
вызывается обработчик событий onClick кнопки "Change", он
вызовет следующую функцию:
function changeDefaultStatus () {
window.defauItStatus =
window.document.statusForm.messageList.
options [window.document. statusForm.
wmessageList.selectedlndexj.
text
I
Листинг 15.7 содержит полный исходный код этоп>
примера.
Объект Window
Глава15
РбЗЮМб многое — как в мультифреЙМОВЫХ окнах, так и в оди-
одиночных. Объекты Frame, Location и History являются
В этой главе детально исследовался верхний уровень свойствами объекта Window и обеспечивают средства
иерархии JavaScript-объектов. Рассмотренные объекты для работы с соответствующими экземплярами браузе-
работают скорее с различными аспектами окна браузе- ра. В этой главе также обсуждалось применение JavaScript
pa, нежели с HTML-дескрипторами. Как объект верх- для ссылок на объекты и свойства в других фреймах и
Него уровня в иерархии, объект Window отвечает за окнах браузера.
Листинг 15.7. Status.htm.
<html>
<head>
<title>Status Bar</title>
<SCRIPT LANGUAGE=" JavaScript" >
window, defaultstatus = "Welcome to the large URL page."
function changeStatus {) {
window, status = "Click me to go to the Acadia Software home page."
}
function changeDef aultStatus ( ) {
window, defaultstatus = window, document. statusForm.messageList.
lb*options [window.document. statusForm.messageList. selectedlndex] . text
}
II—>
</SCRIPT>
</head>
<body>
<p>b#160;</p>
<p>fi#160;</p>
<p align=center>
<font color="#008040">
<font size=7>
<strong>http: //www. acadians. com</strongx/fontx/fbntx/p>
¦<p align=center>
<a href ="http://www.acadians. com" onMouseOver="changeStatus ();return true">Go. . .</aX/p>
<form name="statusPorm" method="POST">
<pXbr>
<br>
<br>
<br>
<p align=center>
<font size=l>To change the default status bar message, select
a message from the list below and click the Change button. </fontX/p>
<p align=centerXselect
name="messageList"
size=l>
<option selected>Welcome to the large URL page , </option>
<option>En route to Acadia Software</option>
<option>This page intentionally left (nearly) blank. </option>
<option>An exciting example of changing status bar text. </option>
</select>
<input
type=button
name="Change"
value="Change "
onClick=" changeDef aultStatus () "X/p>
</form>
</body>
</html>
Объект Document
В ЭТОЙ ГЛАВЕ
Объект Document
Объект Link
О бъектAnchor
Объект Image
В главе 9 был проведен краткий обзор JavaScript-
объектов каждого объектного уровня, начиная с перво-
первого. В той же главе кратко рассматривались объекты
Document, Link, Anchor и Image, но не были детально
описаны их работа и применение. Поскольку эти объек-
объекты предоставляют существенные функциональные воз-
возможности с точки зрения Web-разработчика, стоит по-
посвятить им отдельную главу.
Глава продолжает начатое обсуждение обзором этих
объектов, часто называемых объектами документов. Дан-
Данный набор объектов включает в себя ключевой клиент-
клиентский объект Document и три его "дочерних" объекта:
Link, Anchor и Image.
Объект Document
Объект Window является объектом самого высокого
уровня для клиентских JavaScript-объектов. В этой роли
он служит в качестве контейнера, но фактически может
содержать не все подряд. Содержимое Web-документа
оставлено для объекта Document. Объект Document иг-
играет роль JavaScript-эквивалента HTML-документа и
используется в качестве метода доступа к своим дочер-
дочерним объектам.
В этой роли объект Document является контейнером
для всех HTML-объектов, которые соотносятся с деск-
дескрипторами <body> и <head>. Объект Document получает
значение свойства title из дескриптора <title> (располо-
(расположенного в разделе <head >) и несколько связанных с
цветом свойств из раздела <body>, который приведен
здесь:
<body
,[baekground= "bacfcyroundlmage"]
[bgcolor=" backgroundColor" ]
[ text="foregroundColor"]
l[ link=" unfollowedLinkColor"]
[alink="activatedLinkColor"]
[vlink=" followedLinkColor"]
[onload="mefchodName"]
|[onunload="methodName"] >
</body>
ПРИМЕЧАНИЕ "
Хотя события onLoad и onUnload могут быть захваче-
захвачены обработчиками событий on Load и onUnload внутри
дескриптора<Ых!у>, они являются событиями объек-
объекта Window, а не объекта" Document.
Объект Document — решающий во время работы с
JavaScript и HTML, поскольку все действие происходит
на Web-странице в пределах документа. Таким образом,
придется ссылаться на объект Document при ссылке на
один из объектов внутри него. Например, при обраще-
обращении к объекту Form с именем invoiceForm в ссылке по-
потребуется указать document:
document. invoiceForm. submit () ;
Если этого не сделать, JavaScript не сможет помес-
поместить объект на страницу.
Программное создание HTML-документов
Как видно из этой книги, JavaScript можно использо-
использовать для ответа на события, сгенерированные на стати-
статических Web-страницах. Можно также использовать его
и для визуальной генерации HTML-страниц. Фактичес-
Фактически, каждый из методов объекта Document используется
для запрограммированных изменений документов:
• ореп(["/яшге2у/>е"])открывает поток для write() и
writeln(). Его параметром может быть один из при-
приведенных ниже типов MIME (text/html — по умол-
умолчанию):
text/html
Объект Document
text/plain
image/gif
image/jpeg
image/x-bitmap
plugin (любой подключаемый mime-тип Netscape)
• write (JavaScriptExpressionKamicbmaeT выражение
JavaScript в документ.
• write\n(JavaScriptExpression)i:&KKC записывает выра-
выражение JavaScript в документ, но добавляет после вы-
выражения символ новой строки.
• close() закрывает поток, открытый с помощью мето-
метода ореп().
В то время как методы ореп() и close() открывают
или закрывают сгенерированный документ, методы
tvrite() и writeln() обеспечивают содержимое документа.
В качестве параметра можно использовать любое допу-
допустимое выражение JavaScript, включая литерал, перемен-
переменную или целое число. Например, каждый приведенный
ниже пример — вполне допустимое использование write():
var loc = "Ashford, Kent"
The castle is located in" + loc)
document.write("I stayed in the Robert
*• Courtney s room.")
Г would like" + 70 + "copies of
"¦•that report.")
Имейте в виду, что необходимо записывать HTML-
код, а не простой текст. Можно использовать HTML-
дескрипторы так же, как если бы документ готовился в
HTML-редакторе:
document.write ('<h3>Return to the <a I-
p</a> home page .</h3Xp>' ) ;
На рис. 16.1 показан результат.
РИСУНОК 16.1. Генерация ссылки с помощью JavaScript.
Одно ключевое ограничение, которое следует иметь
в виду при использовании write() или wri связано
с тем, что нельзя изменять содержимое текущего доку-
Глава 16
мента без полной перегрузки окна. Следующие разде-
разделы описывают три допустимых метода, с ПОМОЩЬЮ ко-
которых можно визуально создавать HTML-документы.
Разработка документа в текущем окне
Новый документ можно создавать в текущем окне при
его загрузке. Этот код обычно размещают внутри деск-
дескрипторов <script>, либо в разделе <head>, либо отдель-
отдельно, если это возможно. Например, если требуется оп-
определить браузер и скорректировать текст в соответствие
с его типом, можно прибегнуть к сценарию, показан-
показанному в листинге 16.1.
Листинг 16.1. Генерация разного текста на Web-
странице в зависимости от типа браузера.
<script type="text/javascript">
<!--
var browser = navigator.appName;
document. open <) ,-
if(browser == "Netscape"){
document.write("<h2>Welcome <a hre?=
:om'> Navigator</a>
"-•user .</h2>") ;
)else if(browse г == "Microsoft Internet
'"Explorer") {
"<h2>Welcome <a href=
> 'http://www .micrc Dft.com1> Internet
1->Explorer</a>user .</h2>") ;
)else{
5nt.write("<h2>Welcome. But what
r are you i
)
jnt. write ("We are glad you came to our
Web -«site. Do you know how") ;
' we knew your browser type?")
document, close ();
II
</script>
На рис. показан результат в Navigator 4, а на
рис. 16.3 — в Internet Explorer 5.
f> ?.* Vie* Qo Vnic
I
2} Ou
WelcomeNavigatoruser.
We are glad you саше to our Web site. Do you how we knew your brc 'ser type?
РИСУНОК 16.2 Настроенная страница в браузере Navigator.
Использование DOM
Welcome Internet Explorer user.
We are glad you come to our Web site. Don't you wish jva new how we knew your birr
type?
РИСУНОК 16.3. Настроенная страница в браузере Internet
Explorer.
Создание документа в фрейме
Возможна также генерация нового документа в другом
фрейме мультифреймового окна. Этот метод подобен
приведенному ранее, но здесь необходимо ссылаться на
нужный документ, используя точечную нотацию. На-
Например, для ссылки на первый фрейм мультифреймо-
мультифреймового окна используется следующий код:
parent.frames[0].Document.write("test");
Листинг 16.8, который будет приведен ниже в гла-
главе, демонстрирует пример программной установки до-
документа в фрейме.
Создание документа в отдельном окне
Третья методика визуального создания документов свя-
связана с открытием нового окна и записью в него созда-
создаваемого документа. Если необходимо привести в отдель-
отдельном окне список установленных в браузере Navigator
подключаемых модулей, применяется код, показанный
в листинге 16.2.
Рисунок 16.4 демонстрирует результаты работы сце-
сценария в браузере Navigator.
Листинг 16.2. Отображение списка подключаемых
модулей Navigator.
<html>
<head>
<script type=
function showWindow (){
var len = navigator.plugins.length;
newWin = window.open("", ' ,
"height=400,width=500");
newWin.document.write("<h2>Plug-In Info :
for (var i = 0; i < len; i++) {
newWin.document.write ("<li>'r +
navigator.plugins[i].description +
newWin. document. close ()
II—>
</script>
</head>
<body>
<fonn>
<input type="button" value="Show Plug-In
** Information"
</form>
</body>
</html>
y
HPMPatfl NetscapePhig-m
Netscape'- ¦ -:t" Plug-in
Тата Plug-in 12.2 for Netscape Navigatorrath Я
JavaFlug ш 1 2.2forNelscape NavigatorwithJTK'IK 1.;' 2(DLLHelper)
Ha 1 a2forbTetscape!TavigatorwitfcJE RE 1.1 2 (DLLHelper)
Netscape
Plug- ink'r Acrobat
Sound Playerfor Netscape -iQator.v. 1.1
QuickTime » f« Win32». 1.1.1
NPAVF2. *n ph^n DLL
D-bull РЦ-п
РИСУНОК 16.4. Генерация нового документа в отдельном окне.
Изменение цвета документа
Установки цветов документов по умолчанию определе-
определены в конфигурации пользовательского браузера, одна-
однако HTML обеспечивает возможность изменения этих
установок, а в JavaScript можно сделать это программ-
программно. Объект Document имеет пять свойств, которые пред-
представляют цвета различных атрибутов в документе -
aLinkCoIor, bgColor, fgColor, LinkColor и vLinkCoIor.
Описание этих свойств сведено в табл. 16.1.
Эти свойства выражаются либо в виде строковых
литералов, либо в виде шестнадцатиричных RGB-зна-
RGB-значений. Например, если требуется назначить для фона
документа цвет "chartreuse", используют литерал стро-
строки chartreuse:
document.bgColor = "chartreuse";
Можно также использовать эквивалентное шестнад-
шестнадцатиричное RGB-значение:
document.bgColor = fffOO";
Объект Document
Глава 16
Таблица 16. I Цветовые свойства объекта Document.
Свойство
HTML-атрибут <body> Описание
ahnkColor
bgColor
fgColor
linkColor
vlinkColor
ПРИМВШИЕ
alink
bgcolor
text
link
vlink
Цвет активной ссылки (после того, как кнопка мыши нажата, и до того, как
она отпущена).
'Цвет фона документа.
Цвет символов (текста) документа.
Цвет непосещенных ссылок.
Цвет посещенных ссылок.
Список числовых значений цветов в JavaScript находится
в табл. 5.8 в главе 5. Эта таблица содержит списки чис-
числовых значений цветов как в виде строковых литера-
литералов, так и в виде шестнадцатиричных RGB-значений.
Шестнадцатиричный RGB-триплет — это комбина-
комбинация трех шестнадцатиричных значений, соответствую-
соответствующих красному, зеленому и синему составляющим цвета.
За счет объединения значения формируют шестнадца-
шестнадцатиричный RGB-триплет. Число должно принимать
один из двух зависящих от регистра видов: rrggbb или
#rrggbb.
При использовании изменений цвета в атрибуте
Document необходимо соблюдать те же самые принци-
принципы, как и при изменении текста. Изменения можно де-
делать только тогда, когда страница установлена, напри-
например, в Document.write(). но не на странице, которая уже
"отрисована" в окне браузера.
Для объяснения способа установки цветов рассмот-
рассмотрим пример, показанный на рис. 16.5. Нижний фрейм
содержит список выбора со всеми цветами и группой
переключателей, связанных с опциями цвета атрибута
Document. Можно выбрать используемые цвет и свой-
свойство, а затем нажать на кнопку "Apply". JavaScript пере-
перегружает верхний фрейм с учетом проделанных установок.
Листинг 16.3 содержит исходный код HTML для
документа frameset. Листинг 16.4 показывает код для
основной части текста, а листинг 16.5 код для ниж-
нижнего фрейма, который исполняет данный процесс. Ког-
Когда пользователь нажимает на кнопку "Apply", метод
refreshMain() присваивает значение, зависящее от выб-
выбранной в данный момент опции списка выбора, пере-
переменной newColor. Затем с использованием точечной
нотации выполняется ссылка на документ в верхнем
фрейме (parent.main.Document) и перезагрузка верхне-
верхнего фрейма на основе write() и color.
Листинг 16.3. Источник для установки фреймов в
Document.
<hfanl>
<head>
<title>Color Example</title>
</head>
<frameset rows=S%,25%">
<frame src=63Xl6_L04 .html" name="main'
marginwidth="l" marginheight="l">
<frame src=63X16_L05.html" name="colorDef"
marginwidth="l" marginheight="l">
</frameset>
</html>
Листинг 16.4. Код основной части текста примера.
<html>
<head>
<title>Main Body</title>
</head>
<body>
<h2>
<em>
JavaScript Unleashed
</an>
</h2>
<P>
Here is some sample text
Here is a sample link:
<a href="http: //home. netscape. com">Netscape
'РИСУНОК 16.5.Динамическое изменение цветов фрейма.
</body>
</html>
, Использование DOM
Часть III
Листинг 16.5. Код JavaScript-сценария и выбора
цветов.
<html>
<head>
<title>Color Definition</title>
<SCRIPT IANGOAGE=" JavaScript" >
<! —
var graf = ' <body> ' ;
graf += '<h2Xem>JavaScript Unleashed</em>
graf += '<p>Kere is some sample text</p>' ;
graf += '<p>Here is a sample link:
<a href="http://home.netscape.com">
Netscape</aX/p>' ;
graf += • </body> '
function refreshMain () {
var newColor =
document . f orml. colorList. options {document,
forml.colorList.selectedlndex],text
var selProp = null
with (parent.main. documentV {
open ( ) ;
write (graf) ;
if(document.forml.type[0].checked){
bgColor = newColor
}else{
if (document.forml.type [1] .checked) {
f gColor = newColor ;
)else{
if (document.forml. type 12]. checked) {
alinkColor = newColor;
}else{
if (document.forml. type [3]. checked) {
linkColor ss newColor;
}else if (document.forml. type {4} .
checked) {
vlinkColor = newColor;
1
closed
>
II—>
</script>
</bead>
<body bgcolor="tomato">
<form name="forml">-
<P>
Select Color:
<select name="colorList" size="l">
<option>black</option>
<option>blue</option>
<opt ion>brown</opt ion>
<option>cyan</option>
<option>gold</option>
<option>gray</option>
<option>green</option>
<option>indigo</option>
<option>lavender</option>
<option>lime</option>
<option>maroon</option>
<option>navy</option>
<option>olive</option>
<option>orange</option>
<option>pink</option>
<option>purple</option>
<option>red</option>
<option>royalblue</option>
<opt ion>silver</opt ion>
<opt ion>slategray</opt ion>
<option>tan</option>
<option>teal</option>
<option>turquoise</option>
<option>violet</option>
<option>white</option>
<option>yellow</option>
</select>
<br>
<input type="radio" name="type" value=
"bgColor" checked>Background </input>
<input type="radio" name="type"
value="fgColor">Foreground</input>
<input type="radio" name="type" value=
"alinkColor">Activated Link </input>
<input type="radio" name="type" value=
"linkColor">Unvisted Link </input>
<input type="radio" name="type" value=
"vlinkColor">Visited Link </input>
<br>
<input type="button" name="Apply"
value="Apply" onclick="refreshMain() "
</form>
</body>
</html>
Хотя это и не универсальный пример, им можно вос-
воспользоваться для разработки намного более гибких сце-
сценариев визуального изменения цветов.
5СОВЕГ *¦-¦¦ "},, ¦ ¦'¦.. '¦ V,,"' ¦: ¦''''-' '' ¦¦ -:;\ "¦
За более общими примерами использования цветов в
документах стоит обратиться к hldaho Color Center на
сайте htfp:/ /www.hidaho.com/colorcenter/.
Объект Link
Возможно, миром правит любовь, однако WWW-миром
правят ссылки. HTML-ссылки — основные элементы
любого документа сети, позволяющие переходить на
другие Web-страницы с помощью простого щелчка. Рас-
Расположение документа несущественно; он может нахо-
находиться на том же самом сервере либо за тысячи кило-
километров от него. Все, что требуется обеспечить — это
допустимость данного URL. JavaScript-эквивалент ги-
гипертекстовой ссылки — объект Link, который опреде-
определяется в HTML-синтаксисе так:
[name="objectName" I
[ targe t="windowName"J
[onclick="jnefchodWaine"]
toimouseover=" methodWame" ] >
HnkText
Объект Document
СОВЕТ
Дополнительная информация по событиям объекта Link
находится в главе 14.
: ¦ - . . - .
Объект link имеет несколько свойств, аналогичных
параметрам для объекта Location. Они включают в себя
hash, host, hostname, href, pathname, port, protocol и
search. В главе 9 можно найти дополнительную инфор-
информацию по этим свойствам.
Ссылки на объекты Link
Объекты Link не имеют свойства name, поэтому невозмож-
невозможно отдельно сослаться на определенный объект Link.
Единственный способ — сослаться на объект Link в коде
JavaScript-сценария, используя массив dociiment.links.
Массив document.links — это совокупность всех ссылок
в пределах текущего документа. Порядок массива соот-
соответствует порядку расположения ссылок в исходном
файле. Ниже будет представлен пример, который де-
демонстрирует способ использования массива document.links
для обращения к отдельному объекту Link.
Предположим, что требуется извлечь адреса URL из
каждой ссылки на странице и перечислить их на дру-
другой странице. Используя три фрейма, можно выбрать
нижний фрейм в качестве "свободного" окна, которое
будет использоваться для просмотра, верхний фрейм
будет содержать кнопку, инициирующую процесс, а
средний фрейм — создавать список URL. Рисунок 16.6
показывает три фрейма в окне Internet Explorer после вы-
выполнения всего процесса.
Л>П 1Ь 7»ie JavaScript 1мцазд«
4) Fundamental* oftht, JavaScript language
5) Control Structures and Looping
6) Opuru.irr
PaW 1П: JuvaSatol OIiImh
3) Fundamentals °f Object- Oiientatioir
9) Handling
10) JavaScript Built-in Objert Modal
вяиаш
РИСУНОК 16.6. Получение информации об URLc помощью
массива ссылок.
Листинг 16.6 содержит код установки фреймов, ли-
листинг 16.7 показывает код для нижнего фрейма, кото-
который содержит все строки текста, а листинг 16.8 дает ис-
исходный JavaScript-код для верхнего фрейма, в котором
обрабатывается данный пример. При щелчке на кнопке
"Extract Link Information" вызывается метод getLink!nfo().
Глава 16
Этот метод обращается к массиву ссылок нижнего фрей-
фрейма (с именем bFrame) и устанавливает переменную len
равной его длине. При записи в средний фрейм метод
последовательно проходит через каждый элемент в мас-
массиве ссылок и отыскивает значение свойства href.
Листинг 16.6. Исходный код установки фреймов.
<html>
<head>
<title>New Frameset</title>
</head>
<frameset rows="80,*,185">
<frame src=63Xl6_L08 .html" name="tFrame"
marginwidth=" marginheight=">
<frame src="about:blank" name="mPrame"
marginwidth=" marginheight=">
<frame src=63Xl6_L07.html" name="bFrame"
marginwidth=" marginheight=">
</frameset>
</html>
Листинг 16.7. Исходный код нижнего фрейма.
<html>
<head>
<title>Links</title>
</head>
<body>
<h2>Launching Pad</h2>
<table width="80%">
<tr>
<td width=5%">
<em>
¦<strong>
Software
</strong>
</em>
</td>
<td width=5V>
<em>
<strong>
Magazines
</strong>
</em>
</td>
<td width=5%">
<em>
<strong>
Search
</strong>
</em>
</td>
<td width=5%">
<em>
<strong>
JavaScript
</strong>
</em>
</td>
</tr>
<tr>
<td width=5%">
<a href=
"http://www.borland.com">Borland</a>
</td>
<td width=5%">
Использование DOM
Часть III
<а href="http://www.informant.eom">Web
Informant</a>
</td>
<td width=5%">
<a href="http://www.excite.com">Excite
</aX/td>
<td width=5%">
<a href=
"http://www.gamelan.com">Gamelan</a>
</td>
</tr>
<tr>
<td width=5%">
<a href=
"http://www.microsoft.com">Microsoft
</aX/td>
<td width=5%">
<a href=
"http://www.javaworld.com">JavaWorld
</aX/td>
<td width=5%">
<a href="http://www.yahoo.com">Yahoo
</aX/td>
<td width=5%">
<a href="http://www.c2.org/-andreww/
^javascript "> JavaScript Index</a>
</td>
</tr>
<tr>
<td width=5%">
<a href=
"http://home.netscape.com">Netscape
</aX/td>
<td width=5%">
<ahref ="http: //www.pcweek.com">PCWeek
</aX/td>
<td width=B%">
<a href=
"http://www.altavitsa.digital.com">
Alta Vista</a>
</td>
<td width=S%">
<a href="http://www.intercom.net/user/
wmecha/Java/index. html" >JavaScrip t
Res. Center</a>
</td>
</tr>
<tr>
<td width=S%">
flnbsp;
</td>
<td width=5%">
<a href=
"http://www.infoworld.com">InfoWorld
</aX/td>
<td width=5%">
<a href="http://home.netscape.com/
yiescapes/search/search4 .html">
Netscape Search Page</a>
</td>
<td width=5%">
<a href="http://home.netscape.com/misc/
'¦'developer/conference/proceedings ">
Netscape Conference</a>
</td>
</tr>
</table>
</body>
</html>
Листинг 16.8. Исходный код верхнего фрейма.
<html>
<head>
<base target="iniddle">
<script type="text/javascript">
function getLinklnfoO {
var len =
parent.tFrame.document.links.length;
with (parent. tnFrame. document) (
open();
write ("<h3>The " + len + " Links of
*-*The Top Frame Include: </h3Xp>") ;
for (var i = 0; i < len; i++) {
write((i +1) + ". » +
parent.tFrame.document.links[i].href +
I
close ()
</script>
</head>
<body bgcolor="red">
<form>
<div align="center">
<input type="button" name="Extract"
value="Extract Link Information"
onclick="getLinkInfo{)">
</form>
</body>
</html>
Выполнение JavaScript-кода для ссылок
Используя javascript в качестве элемента протокола href
ссылки, можно выполнять выражение JavaScript вмес-
вместо обычного действия ссылки (вместо перехода на но-
новую Web-страницу или отправки сообщения по почте).
Однако, выполняемый код должен быть самодостаточ-
самодостаточным. Нельзя ссылаться на другой объект вне его кон-
контекста, например, на другое окно.
Ссылку можно использовать для определения типа
пользовательского браузера, как показано в следующем
коде:
<а href = " javascrxpt:if (navigator.appName ! =
"¦•'Netscape') { alert ('You should not have
¦-»clicked this link! • > ) else (
"*alert ("Thanks for clicking.')} ">
All Netscape users, click me</a>
В качестве второго примера приведем оглавление
первого издания этой книги в HTML-документе со
ссылками на каждую ее часть. Для атрибута href этих
ссылок описание каждой части помещается в окно сиг-
сигнального сообщения. Листинг 16.9 показывает HTML-
код для данного примера, а рис. 16.7 — результат пос-
после щелчка на ссылке "Part Ш".
Объект Document
Глава 16
Листинг 16.9. Создание оглавления со ссылками document.alertQ.
<html>
<head>
<title>JavaScript Unleashed Table of Contents</title>
</head>
<body>
<a href =" javascript: alert I ' In this first section, you will get a complete introduction to
^* JavaScript . Chapter 1 takes a unique look at JavaScript, focusing on how and where it fits
w into the Web application development framework- You will also see how it relates to other Web
*•» technologies both on the client- and server-side. Next, in Chapter 2, you will learn about
wthe relationship between JavaScript and Hypertext Markup Language (HTML) and how the browser
^interprets your code at runtime. Chapter 3 looks at the software tools you need to develop in
**JavaScript. ' ) ">
<h3>Part I: Getting Started with JavaScript</h3>
<h4>
1) JavaScript and the World Wide Web <br>
2) How JavaScript and HTML Work Together <br>
3) Assembling Your JavaScript Toolkit
</h4>
¦<a hre?=" javascript : alert ( 'The second part presents a thorough look at the JavaScript language.
wIn Chapters 4-7, you will learn about language basics, control structures, operators, and,
¦¦«functions. ¦ ) ">
<h3>Part II: The JavaScript Language</h3>
</a>
<h4>
4) Fundamentals of the JavaScript Language<br>
5) Control Structures and Looping <br>
6) Operators<br>
7) Functions
</h4>
<a href=" javascript : alert ( "Part three dives into the heart of JavaScript -- objects. After an
^introduction to object-oriented concepts in Chapter 8, Chapter 9 looks at how you can handle
*-*user and system events. Chapter 10 then looks at the built-in JavaScript hierarchy and introduces
^you to each of the Navigator and Built-in language objects ¦ Chapters 11-14 continue where the
'-'previous chapter left off by exploring in-depth each of the built-in JavaScript objects.
'•Chapter 15 rounds out the discussion on objects, focusing on how you can create your own. It
¦"¦includes many innovative ideas related to custom object development within JavaScript. ' ) ">
<h3>Part III: JavaScript Objects</h3>
</a>
<h4>
3) Fundamentals of Object-Orientation <br>
9) Handling Events <br>
10) JavaScript Built-in Object Model <br>
11) Navigator Objects <br>
12) Document Objects <br>
13) Form Objects <br>
14) Built-in Language Objects <br>
15) Creating Custom JavaScript Objects
<h4>
¦<a href=" javascript: alert { 'The next section builds upon everything you learned up to that point
wto look at specific areas of interest to the JavaScript developer. Chapter 16 explores how you
^can enhance HTML forms with JavaScript, such as providing client-side data validation. Both
^Chapters 17-18 really focus on frames and how you can use JavaScript in multi-frame windows.
'¦•I have found frame management to be perhaps the most common use of JavaScript on the Web.
^•Chapter 19 looks at yet another key topic, cookies and other techniques for handling and
¦^maintaining state in the stateless environment of the Web.')">
<h3>Part IV: JavaScript Programming</h3>
</a>
<h4>
16) Enhancing Forms with JavaScript <br>
17) Working with Frames and Windows<br>
18) Scripting Outlines and Table of Contents <br>
19) Cookies Samp; State Maintenance
</h4>
<a href=" javascript : alert ( "While Parts I-IV focused on client-side JavaScript, this section
^focuses on its server-side counterpart. Within Netscape LiveWire and other products such as
Использование DOM
Часть III
«Borland IntraBuilderr you can use JavaScript as a server-side scripting language - In doing so,
w you are freed from wr i t ing CGI s cr ipt s and deal ing wi th such language s as PERL - Chap t e r 2 0
'^ looks at server-side JavaScript, focusing on LiveWire and IntraBuilder. Chapter 21 takes look
«at the issue of how to architect client/server applications on the Web- Covered are many of
wthe issues you will encounter as you plan such an application. ' ) ">
<h3>Part V: JavaScript on the Server</h3>
</a>
<h4>
20) Server-Based JavaScript <br>
21) Partitioning Client and Server Applications
</h4>
<a href=" javascript: alert ( ' Part VI explores five advanced subj ects, many of which are emerging
«as key topics as JavaScript matures - Chapter 22 dives into Error Handling and Debugging
«JavaScript applications. Chapters 23-24 cover the hot topic of integrating JavaScript with
«Netscape Plug-Ins and ActiveX controls. Chapter 2 5 looks at integrating JavaScript with VRML
«and multimedia data. Chapter 2 6 closes the section by looking at a more conceptual topic-*
«JavaScript security- The chapter not only looks at the key issues surrounding this subj ect,
«but provides some helpful advice as you consider using JavaScript for your Web site. ' ) ">
<h3>Part VI: Advanced JavaScript</h3>
<h4>
22) Error Handling and Debugging in JavaScript <br>
23) Working with Netscape Plug-ins <br>
24) ActiveX Scripting with JavaScript ^эг>
25) VRML and Multimedia <br>
26) JavaScript and Web Security
</h4>
<a href=" javascript: alert ( ' JavaScript is an important tool to glue HTML and Java applets.
«In this section, we will look at Java from a JavaScript perspective in Chapter 27 and see
'«how similar or different the language is for JavaScripters . Chapter 2 8 provides a good
'«introduction on how to build a Java applet, while Chapter 29 is where the rubber meets the
«road when it focuses on integrating Java and JavaScript - ' ) ">
<h3>Part VII: Java and JavaScript</h3>
<h4>
27) Java from a JavaScripter Perspective <br>
28) Building Java Applets<br>
29) Integrating JavaScript with Java
</h4>
<a href =" javascript: alert ? 'Many corporations will use the Web as a way to get at their data.
«As a result, how JavaScript can access data will be an increasingly important topic as the
«technology matures. In this section, we will look at how you can work with data both on the
«client-side and server-side- Chapter 30 introduces the notion of maintaining lookup tables
«on the client side to lessen the need to access the server- Chapter 31 then gets into how
«you can use JavaScript to access server-side data- LiveWire and IntraBuilder will again be
«used in this context. ') ">
<h3>Part VIII: JavaScript Database Applications</h3>
<h4>
30) Using Client-Side Tables in JavaScript <br>
31) Working with Server-Side Database Objects
</h4>
<a href=" javascript : alert { 'The final section provides some extra information that will assist
'«you as you read the book. Appendixes A-B provide basic references on the JavaScript and HTML
«respectively- Appendix С looks at how VBScript and JavaScript compare- Appendix D lists
«JavaScript resources that are available online . ' ) ">
<h3>Part IX: Appendixes-;/h3>
</a>
<h4>
A) JavaScript Language Summary <br>
B) Fundamentals of HTML <br>
¦C) Comparing JavaScript with Microsof tS#14 6 ;s VBScript <br>
D) JavaScript Resources on the Internet
<h4>
</body>
</html>
Объект Document
Глава 16
Vftl I ! I: lite JavaScript I.№g!i3&(
4) Fundamental* of the JnvaXeript Language
5) Control 5 tucIum and Looping
6) Operator*
7) Rind
Part ГО: «Jmva,Scrfo< О1>|*пе
I 8) Fundamentals of Object-Orientation
| 9) Handling Events
10) Ja*»SrnPt Built-in Object Model
РИСУНОК 16.7. Щелчок на ссылке отображает окно
сигнального сообщения.
Объект Anchor
Наиболее часто объект Link используется для перехода
на другую Web-страницу или другое место в текущем
документе. В пределах текущего документа ссылка ука-
указывает на место в тексте, которое называется якорем
(anchor). В HTML-синтаксисе он определяется так:
<а [href=IocationOrDRL]
name="objectWame"
[target="windowName" ]>
anchorText
Можно сказать, что объект Anchor — поистине гость
для JavaScript. С помощью якорей в JavaScript можно
сделать немногое. Сам по себе объект Anchor не имеет
никаких свойств, методов или событий. Единственный
способ его применения в JavaScript — с помощью мас-
массива anchors объекта Document. Массив document.anchoi
используется для определения количества якорей в
документе и выполнения необходимых итераций по
ним.
Объект Image
ПРИМЕЧАНИЕ
Объект Image поддерживается в JavaScript 1.1 и сле-
следующих версиях. Его не поддерживают JavaScript 1.0
и JScript 1.O.
Тем, кто провел достаточно много времени в Web,
должно быть, понятно, насколько важна для Web гра-
графика. Едва ли существуют страницы, вообще не имею-
имеющие графических элементов. Объект Image, новый в
Navigator 3, представляет HTML-изображение, которое
определяется в следующем формате:
<img
[name="objectWame" ]
src="Location"
[lowsrc="Location" ]
[height="Pixels"|"VaIue"%J
[width="Pixels"I"Value"%]
[hspace="Pixeis"]
[wspace="Pixe!s"]
[border="Pixels"]
[align="left"|"right" I "top"|
"absmiddle"|"absbottom"|
"texttop"|"middle"|"baseline"|
"bottom"]
[ismap]
[usemap=" Location#MapName"\
[onabort="methodName"}
[onerror="methodName"]
[onload="me thodName"] >
СОВЕТ
Дополнительная информация
Image находится в главе 14.
о событиях объекта
Например, для вывода изображения dot.gif в HTML-
коде необходимо воспользоваться следующим синтак-
синтаксисом:
<img src="dot.gif" height=0i
Экземпляр объекта Image создается с помощью ко-
команды new:
CompanyLogo = new
CompanyLogo.sro =
Image();
"logo.gif";
Размеры графического элемента можно передавать
как параметры в конструктор Image(). Например, если
требуется отобразить логотип размером 200x300 пиксе-
пикселов, используется код:
CompanyLogo = new Image B00,300);
CompanyLogo.sre = "logo.gif";
Присваивая значение свойству sre, можно изменять
отображаемый графический элемент. Однако, при этом
в область и: тя загрузится новый URL или гра-
графический элемент.
Поскольку изображение определяется только с по-
помощью дескриптора <img>, создаваемый объект Image
обладает достаточно ограниченными возможностями.
Его можно использовать для получения изображения до
того, как оно станет фактически необходимо для пока-
показа на дисплее. Поскольку изображение в этом случае
хранится в памяти, при перегрузке документа оно бу-
будет намного быстрее отображаться. Наиболее общий
пример — анимационная последовательность изображе-
изображений, которые получаются с использованием объекта
Image и позже отображаются из памяти.
Использование DOM
Часть III
f СОВЕТ ,,.,,;. v • ¦ . т ^
В главах 20 и 21 можно найти дополнительную инфор-
информацию по способам применения объектов Image.
Резюме
Объекты документа, рассмотренные в этой главе, явля-
являются JavaScript-эквивалентами ряда базовых HTML-эле-
HTML-элементов. К таким объектам относятся Document, Link,
Anchor и Image. Хотя JavaScript используется для рас-
расширения или получения информации из этих объектов,
многие JavaScript-взаимодействия обычно исходят из
работы с формами. Поэтому в следующей главе объек-
объекты Form рассматриваются более детально.
Объекты Form
В ЭТОЙ ГЛАВЕ
Объект Form
Объект Text
Объекты Button: Submit, Reset и Button
Объект Checkbox
Объект Radio
Объект Select
Объект Password
Объект Hidden
Одним из ключевых достижений в развитии Web
было появление HTML-форм в мире статических стра-
страниц. За счет форм Web фактически может обеспечить
нечто большее, нежели однонаправленный режим свя-
связи. Формы предоставляют средства, с помощью которых
любой пользователь на любой машине сможет передать
данные на сервер для обработки.
Благодаря JavaScript, HTML-формы получают гораз-
гораздо более широкие возможности. Теперь можно не толь-
только предварительно обрабатывать данные формы до от-
отправки их пользователю, но также использовать формы
в приложении, которое полностью находится на сторо-
стороне клиента. В главе рассматривается объект Form и мно-
множество объектов, которые он может содержать, включая
объекты Text, Button, Radio и Select. Цель этой главы -•
предоставить вкратце всю информацию, касающуюся
форм, и в то же время дать несколько действительно
полезных советов.
Кроме того, можно воспользоваться примерами этой
главы в качестве шаблонов, что поможет сэкономить
время при разработке сайтов. Для копирования шаблона
нужно просто посмотреть на листинги и на их общую
структуру, и затем подкорректировать код под собствен-
собственные потребности. Все больше и больше разработчиков
следуют этому рецепту, а данная глава предоставляет
изрядное число подходящих шаблонов.
^примечание „Щ1
Объекты Form, обсуждаемые в этой главе, могут су-
существовать только в пределах формы, но не вне ее.
Объект Form
Одна из основных целей JavaScript — обеспечить сред-
средства для взаимодействия с пользователем на стороне
клиента. В большинстве случаев это взаимодействие с
о !. 158
пользователем происходит с помощью HTML-формы.
Таким образом, JavaScript-объект Form — важный
объект в объектной модели JavaScript. С самим объек-
объектом Form не многое можно сделать. Выражаясь кратко,
объект Form — это контейнер, содержащий введенные
пользователем данные.
В HTML объект Form определяется так:
<FORM
[NAME=" ?orwName" ]
[ACTION="serverVRL" ]
i[ENCTYPE=" encodingType"]
[METHOD=GET | TOST]
[TARGE T="windowNaine" ]
[onSubmit=" methocfflame" ] >
</FORM>
Для определения формы используют стандартные
условные обозначения HTML:
< FORM NAME = "Forml" ACTION=
"http://www.acadians.com/js/script,jfm"
METHOD=GET >
<!— Здесь должны следовать объекты формы —>
</FORM>
^ПРИМЕЧАНИЕ-: Щ^Х м;_>-,,
Дополнительная информация по использованию форм
в JavaScript находится в главе 29.
Отправка формы на сервер
До JavaScript единственное реальное назначение HTML-
формы состояло в отправке на сервер элементов данных,
собранных на стороне клиента. Поскольку на стороне
клиента не было достаточно возможностей для обработ-
обработки данных, они посылались серверу, который затем
реагировал на полученную информацию. JavaScript по-
позволяет теперь передавать обработку данных HTML-
Использование ЮМ
Часть III
формам, хотя это не устраняет потребность отправки
формы на сервер.
Можно отправлять форму, используя один из двух
процессов. Во-первых, можно вызвать метод submit()
объекта Form, а во-вторых — нажать на кнопку "Submit",
которая автоматически отправит соответствующую ей
форму.
^ПРИМЕЧАНИЕ?
В главе 14 приводится дополнительная информация по
реализации с помощью JavaScript проверки допустимо-
допустимости данных перед отправкой формы на сервер.
Многие из свойств объекта Form работают с допол-
дополнительной информацией, которую форма отправляет на
сервер. Эти свойства перечислены ниже:
• action (то же, что и параметр ACTION=). Свойство
action определяет URL сервера, куда отправляется
форма.
forml.action = "http://www.aoadians.com/js/
** surv. cgi "
Это обычно программа CGi, приложение LiveWire
или файл IntraBuilder JFM.
• enctype (то же, что и параметр ENCTYPE=). Свой-
Свойство enctype определяет MIME-кодирование формы.
Значение по умолчанию — appIication/x-www-Form-
urlencoded:
if (forml. enctype ==
^urlencoded") {
alert("Encoding
"application/x-www-form-
type is normal.") )
¦• method (то же, что и параметр METHOD=). Свой-
Свойство method определяет, каким образом форма от-
отправляется серверу. Наиболее часто применяется
значение GET, однако можно использовать также и
Листинг 17.1. formSubmithtm.
POST. Этот параметр основан на процессе со сто-
стороны сервера, поэтому при проектировании HTML-
форм необходимо учитывать требования программы
сервера. Следующий код показывает пример исполь-
использования параметра method.
var methodType
methodType = forml.method
alert ("The method type for this form is: " +
methodType)
• target (то же, что и параметр TARGET=). Свойство
target определяет целевое окно, которому сервер дол-
должен послать ответную информацию. Если свойство
target не определено, сервер отображает результаты
в окне, отправившем форму. Если используется
мультифреймовое окно, свойство target определяет-
определяется для фрейма с помощью параметра NAME деск-
дескриптора <FRAME>. Можно также использовать
одно из следующих зарезервированных имен окон:
_top, _parent, _self или Jbhink- Но не забывайте, что
это спецификация HTML, а не JavaScript. Нельзя
указывать JavaScript-имя объекта Window, такое как
parent.resultsWindow. Следующий код демонстрирует
пример использования этого свойства:
if (document.forml.newWindowCheckBox.checked) (
document.forml.target = "resultsForm" )
else {
document.forml.target = "_self" )
HTML-форма, показанная в листинге 17.1, исполь-
использует для отправки формы комбинацию HTML-дескрип-
HTML-дескрипторов и JavaScript-кода. Обратите внимание, что свой-
свойство action объекта Form получает новое значение в
течение события onSubmit объекта Form, если пользо-
пользователь установил флажок в "Rush Order". Программная
установка свойства action отменяет его значение по
умолчанию.
<html>
<head>
<title>For More Information</title>
<SCRIPT LANGUAGE="JavaScript">
function checkType() {
if (document.forml.rush.checked) {
document.forml.action = "http://www.acadians.com/js/rush.cgi"
}
</SCRIPT>
</head>
<body>
<hl>Order Form</hl>
<hr>
<form name="forml" action="http://www.acadians.com/js/order.cgi"
method="POST" onSubmit="cheekType()">
<p>Please provide the following contact information:</p>
<blockquote>
<preXem> First name </emXinput type=text size=25 maxlength=256
name="Contact_FirstName">
<em> Last name </emXinput type=text size=25 maxlength=256
Объекты Form
Глава 17
name="Contact_LastName">
<em> Title </emXinput type=text size=35 maxlength=256
name="Contact_Title">
<em> Organization </emXinput type=text size=35 maxlength=256
name="Contact_Organization">
<em> Work Phone </emXinput type=text size=25 maxlength=25
name="Contacfc_WorkPhone">
<em> FAX </emXinput type=text size=25 maxlength=25
name="Contact_FAX">
<em> E-mail </emXinput type=text size=25 maxlength=256
name="Contact_Email">
<em> URL </emXinput type=text size=25 maxlength=25
name="Contact_URL">
</pre>
</blockquote>
<p>Please provide the following ordering information:</p>
<blockquote>
<preXstrongXJTY DESCRIPTION
</strongXinput type=text size=6 maxlength=6
name="Ordering_OrderQty0">
<input type=text size=45 maxlength=256 name="Ordering_OrderDescO">
<input type=text size=6 maxlength=6 name="Ordering_OrderQtyl">
<input type=text size=45 maxlength=256 name="Ordering_OrderDescl">
<input type=text size=6 maxlength=6 name=rdering_0rderQty2">
<input type=text size=45 maxlength=256 name=rdering_0rderDesc2">
<input type=text size=6 maxlength=6 name=rdering_0rderQty3">
<input type=text size=45 maxlength=256 name=rdering_OrderDesc3">
<input type=text size=6 maxlength=6 name=rdering_0rderQty4">
<input type=text size=45 maxlength=256 name="Ordering_OrderDesc4">
<em> </emXstrong>BILLING</strong>
<em>Purchase order # </emXinput type=text size=25 maxlength=256
names"Ordering_PONumber">
<em> Account name </emXinput type=text size=25 maxlength=256
name="Ordering_POAccount">
<em> </emXstrong>SHIPPING</strong>
<em> Street address </em><input type=text size=35 maxlength=256
name="Ordering_StreetAddress">
<em> Address (cont.) </emXinput type=text size=35 maxlength=256.
name=rdering_Address2">
<em> City </emXinput type=text size=35 maxlength=256
name="Ordering_City">
<em> State/Province </emXinput type=text size=35 maxlength=256
name="Ordering_State">
<em> Zip/Postal code </em><input type=text size=12 maxlength=12
name="Ordering_ZipCode">
<em> Country </emXinput type=text size=25 maxlength=256
name="Ordering_Counfcry">
</pre>
<preXinput type=checkbox name="rush" value="ON">Rush Order!</pre>
</blookquote>
<pXinput type=submit value="Submit Form"> <input type=reset
value="Reset Form">
</form>
</body>
</html>
Для получения дополнительной информации об обра-
обработчике событий onSubmit обратитесь в главу 14.
Проверка элементов в Form
Form действует как контейнерный объект для всех дру-
других объектов формы. Поскольку эти типы объектов (на-
(например, объекты Text или Button) нужны для взаимо-
взаимодействия с пользователем, можно относиться к ним как
к объектам пользовательского интерфейса (Ш-объектам).
Объект Form имеет свойство elements, которое приме-
применяется для ссылки на элемент формы или перебора всех
элементов в форме для специфических задач. Порядок
массива полностью основан на порядке следования эле-
элементов HTML-формы в исходном файле. Первый пере-
Использование DOM
Часть III
численный элемент — elements[0], второй — elements[l]
и т.д.
Можно ссылаться на каждый элемент Form с помо-
помощью имени либо его индекса в массиве элементов. На-
Например, если объект Text с именем LastName является
первым элементом в форме, на него можно ссылаться с
помощью следующего кода:
custLastName = Forml.elements [0].value
Кроме того, допускается также и такой код:
custLastName = Forml.LastName.value
Свойство elements применяют для работы с каждым
объектом формы. Предположим, необходимо удостове-
удостовериться, что каждое поле в форме не является пустым.
Используя свойство elements, можно создать цикл for
для выполнения итераций по каждому элементу мас-
Листинг 17.2.formElements.htm.
сива и проверки значений. Этот код показан в лис-
листинге 17.2.
Обратите внимание, что следующие процедуры про-
проверки достоверности формы не проверяют правиль-
правильность ввода значения года. Для получения дополнитель-
дополнительной информации относительно полезных методов
проверки правильности обратитесь в главу 29.
Несложно заметить, что метод checkFields() для оп-
определения количества итераций в цикле for использует
свойство elements.length. Далее, поскольку массив
elements включает в себя все объекты формы, в том чис-
числе и два объекта Button, операция typeof используется
для определения типа элемента перед проверкой его зна-
значения. На рис. 17.1 показано сигнальное окно сообщения,
которое появляется в случае нахождения пустого поля.
<html>
<head>
<title>Online Registration</title>
<SCRIPT LANGUAGE="JavaScript">
<\ —
function checkFields (> {.
var num = document.forml.elements.length
var validFlag = true
for (var i=0; Knum; i++) {
if ((document.forml.elements[i] .value = null I I.
document.forml.elements[i].value = "") S&
(typeof document.forml.elements[i] != 'submit' I I
typeof document.forml.elements[i] != 'reset'))
I]
validFlag = false
alert ("The " + document, forml. elements [1] . name +
" field Is blank. Please enter a value.")
break }
1
return validFlag
</SCRIPT>
</head>
<body>
<form name="forml" method="POST" onSubmit="return checkFields()">
<h2>Online Registration</h2>
<p>Osername:<br>
<input type=text size=25 maxlength=256 name="Username"Xbr>
Category of Interest :<br>
<input type=text size=25 maxlength=256 name="Category"Xbr>
Starting Year:<strongxbr>
</strong><input type=text size=25 maxlength = 256 name="StartYear"xbr>
Email address :<strong><br>
</strong><input type=text size=25 maxlength=2S6 name="EmailAddress"X/p>
<h2xinput type=submit value="Register"> <input type=reset value="Clear"X/h2>
</form>
<p>snbsp;</h5>
</body>
</html>
Объекты Form
[РИСУНОК 17.1. Проверка значений полей в форме.
Объект Text
Для большинства задач объект Text — это элемент, ко-
который наиболее часто используется для хранения дан-
данных, вводимых пользователем. Объект Text используется
для захвата однострочной произвольной информации.
Для многострочной информации применяется объект
Textarea, обсуждаемый в разделе "Объект Textarea". Как
и другие объекты Form, объект Text реализует "объект-
"объектную" версию HTML-дескриптора и имеет следующий
синтаксис:
<INPUT
TYPE="text"
[NAME="objectName" ]
[VALUE=" value"]
[SIZE=size]
[MAXLENGTH=size]
Листинг 17.3. textDefaultValueWrite.htm.
Глава 17
f onBlur= "method/tame"]
t onChange= " me thodName "]
[ onFocus="me thodName "]
[onSelect="aie thodName"] >
Например, чтобы определить объект Text для пос-
последнего имени, используют следующее:
<INPUT TYPE="text" NAME=LastName SIZE=20
MAXLENGTH=25>
ПРИМЕЧАНИЕ
Для получения дополнительной информации о событи-
событиях объекта Text, таких как onBlur, onChange, onFocus
и onSelect, обращайтесь в главу 14.
Присваивание объекту Text значения по
умолчанию
Иногда требуется присвоить объекту Text значение по
умолчанию. Если HTML-документ создается визуально,
это можно сделать, определяя параметр VALUE= деск-
дескриптора <INPUTtype=text>. Предположим, что требу-
требуется автоматически проверить тип объекта Navigator и
ввести эти данные в форму. Код из листинга 17.3 гене-
генерирует форму, показанную на рис. 17.2. Обратите вни-
внимание, что поле "Browser" заполняется автоматически,
когда сценарий проверяет свойство appName объекта
Navigator.
Второй способ присваивать значение по умолчанию
объекту Text связан с установкой его свойства value.
Например, можно создать ту же самую форму, исполь-
используя код, показанный в листинге 17.4. В этом примере
значение полю "Browser" присваивается в обработчике
событий onLoad.
"Username"Xbr>'
<SCRIPT LANGUAGE="JavaScript">
var browserVar = navigator . appName
document.write ( '<body>')
document, write < '<form name="forml" method="POST">' )
document.write ( '<h2>OnlineRegistration</h2>' )
document .write( ' <p>Username <br>' )
document.write ( '<input type=text size=25 maxlength=256 name=
document.write( 'Browserused:<br>' >
document.write( '<input type=text size=25 maxlength=2 5 6 name="Browser" value=
' "Xbr>' >
Email address:<strong> <br>'>
document.write ( '</strongXinput type=text size=25 maxlength=256 ' )
document .write ( ' name="EmailA<idressl1X/p>)r
document, write ( '<h2Xinput type=submit value="Register"> ')
document.write ( '<input type=reset value="Clear"x/h2>' )
document.write ( '</form>'>
document.write ( '</body>')
document.write ( '</html>')
browserVar ч
document.write (
// —>
</SCRIPT>
Использование DOM
Часть III
Online Registration
usemare
Emai
РИСУНОК 17.2. Установка значения no умолчанию.
Это может показаться странным, но свойство
default Value в этом примере не используется. Хотя мож-
можно присваивать значение свойству default Value, форма
при этом не изменяется. Поэтому следует использовать
свойство value (см. листинг 17.4).
Листинг 17.4. textDefaultValue.htm.
<html>
<head>
<title>Online Registration</title>
<SCRIPT IANGUAGE="JavaScript">
<! —
function findBrowser() {
document.forml.Browser.value =
navigator.appName
</SCRIPT>
< /h.ead>
<body onLoad="findBrowser()" >
•<form name="forml" method="POST">
<h2>Online Registration</h2>
<p>Username:<br>
<input type=text size = 25 maxlength=2S6
name="Username"><br>
Browser used: <br>
<input type=text size=25 maxlength=256
name="Browser"Xbr>
Email address :<strong> <br>
</strongXinput type=text size=25 maxlength=256
name="EmailAddress"X/p>
<h2Xinput type=submit value="Register"> <input
type=reset value="Clear"X/h2>
</fonn>
</body>
</html>
СОВЕТ
Свойство defauItValue полезно для получения значения
по умолчанию объекта Text, но не для установки упо-
упомянутого значения.
Выделение текста в фокусе
По умолчанию при вводе объекта Text позицией ввода
является курсор. Если поле в данный момент содержит
текст и требуется печатать поверх него, придется выде-
выделить текст, удалить его и ввести новое значение. Мож-
Можно сделать это по-другому, используя метод select()
объекта Text. Листинг 17.5 показывает HTML-форму с
четырьмя объектами Text, каждый из который вызыва-
вызывает this.selectO в момент прихода события onFocus. В ре-
результате, когда пользователь вводит текст в любое из
полей формы, он автоматически выделяется. Рисунок
17.3 демонстрирует результат.
Листинг 17.5. textSelecthtm.
<html>
<head>
<title>Online Regis tration</title>
</head>
<body>
<form name="?orml" method="POST">
<h2>Online Registration</h2>
<p>Username:<br>
<input type=text size=25 maxlength=256
name="Use rname"
onFocus="this.select()"><br>
Browser used:<br>
<input type=text size=25 maxlength=25
name="Browser"
onFocus="this . select () "Xbr>
Email address :<strong> <br>
</strongXinput type=text size=25 maxlength=256
name="EmailAddress"
onFocus="this. select() "x/p>
<h2xinput type=submit value="Register > <input
type=reset value="Clear"X/h2>
</form>
</body>
</html>
РИСУНОК 17.3. Текст подсвечивается автоматически.
Объекты Form
Захват данных с помощью объекта
Textarea
Все другие объекты Form предназначены для захвата
данных ограниченного размера (менее 256 символов).
Объект Textarea обеспечивает средства для захвата ин-
информации, недоступной для простых текстовых полей,
переключателей или списков выбора. Можно использо-
использовать объект Textarea для ввода данных произвольной
формы, занимающих несколько строк. Ввод ограничен
отображением текста ASCII, однако допускается базо-
базовое форматирование (например, параграфов). Объект
Textarea определяется с помощью стандартного синтак-
синтаксиса HTML:
<TEXTAREA
NAME=" objectName"
ROWS="numRows"
COLS="numCols"
[WRAP="off|virtual|physical"]
[onBlur="me thodName"]
[onChange="methodNaine"]
[onFocus="jnetiodName"]
[onSelect="methodName" ]>
displayText
</TEXTAREA>
Например, при использовании Textarea для передачи
по сети комментариев объект определяется следующим
образом:
rows=12 cols=78>
На рис. 17.4 показана результирующая форма.
<textarea name="Comments
</text are a >
Comments
EnteryourcommerAs Inlhespace provided telow:
1 *тя «vased to яее that you did run » itor? on "Нои со Develop J«v*
.pplets ш 20 Bibugm". 1 did bat think It could be done, buc ynu proved
n: WEong. Aitec readlna tbe article, I aat down and wrote w/ lirst Java
.pplHE -- nciniilc» wish №^L dncithPH BMdttttrttT -- It 317ЛГ it ¦nlnntf-л.
Cb>rlei се* 3V
РИСУНОК 17.4. Объект Textarea.
ПРИМЕЧАНИЕ
Дополнительная информация о событиях Textarea (та-
(таких ка< onBlur, onChange, onFocus и onSelect) может
быть найдена в главе 14.
. : .- : :;- ....... ... ..... ,.., ,,.....,.
Глава 17
'Перенос текста в объекте Textarea
По умолчанию в объекте Textarea текст не переносит-
переносится. Пользователь должен вручную обозначать новую
строку (с помощью клавиши "ENTER"). Однако, учи-
учитывая, что такая работа вряд ли вызовет энтузиазм, вы-
выполняется установка опции переноса текста с помощью
параметра WRAP= HTML-дескриптора <TEXTAREA>.
Помимо off (опции по умолчанию), существуют еще две
дополнительных опции:
virtual. Если параметр WRAP= установлен в virtual,
строки переносятся на экране на границе области
объекта Textarea, однако новая строка определяет-
определяется только через нажатие клавиши "ENTER".
physical. Если параметрWRAP= установлен в physical,
строки переносятся на экране, а при отправке дан-
данных на сервер в конце каждой экранной строки ус-
устанавливается символ возврата каретки.
Объекты Button: Submit, Reset и Button
Ввиду того что графические среды в течение прошлого
десятилетия стали доминирующими, кнопка представ-
представляет собой, возможно, наиболее распространенный из
всех компонентов пользовательского интерфейса. В
HTML существует три типа кнопок, которые можно
использовать в формах: Button, Submit и Reset. Как ви-
видите, два из них являются специализированными фор-
формами универсального объекта Button. С помощью обыч-
обычного HTML-синтаксиса кнопка определяется так:
< INPUT
TYPE = "button I submit I reset"
[ЖМЕ = " objectName" ]
[VALUE = "labelText"]
|[CnCliok = " methodtiame" ] >
Эти три типа кнопок предназначены для различных
целей:
Кнопка Submit отправляет форму, в которой она со-
содержится, на сервер, основываясь на параметрах
формы. Для такого действия не нужен JavaScript-
код, поскольку все поведение встроено непосред-
непосредственно в объект.
Кнопка Reset сбрасывает значения полей в теку-
текущей форме, восстанавливая ранее установленные
значения по умолчанию. Как и для кнопки Submit,
JavaScript-код здесь не используется.
Объект Button — это универсальный объект без
предварительно определенного встроенного поведе-
поведения. При работе с этим объектом необходимо добав-
добавлять к кнопке обработчик событий onClick.
Использование DOM
Часть III
При недостаточном знакомстве с HTML может воз-
возникнуть вопрос о целесообразности существования кно-
кнопок Submit и Reset, т.к. объект Button можно использо-
использовать для выполнения тех же самых задач. Они возникли
до появления JavaScript, когда нельзя было использо-
использовать универсальную кнопку, потому что не существо-
существовало соответствующих способов. Кроме того, несмотря
на то, что не все браузеры поддерживают JavaScript (a,
значит, и объект Button), все современные браузеры
поддерживают кнопки Submit и Reset. Преследуя цели
совместимости, обычно лучше всего использовать кноп-
кнопки Submit и Reset, если поддержка JavaScript не являет-
является требованием для доступа к данной странице. При на-
наличии таких требований выбор кнопок роли не играет.
Для получения дополнительной информации о событии
onClick для объектов типа Button стоит обратиться в
главу 14.
Листинг 17.6 демонстрирует пример использования
всех трех кнопок. Как и следовало ожидать, кнопки
Submit и Reset используются для отправки и очистки
формы, хотя их параметры VALUE= были изменены
для отображения более дружественных к пользователю
формулировок. Объект Button используется для выво-
вывода на экран справочного окна, которое подсказывает
пользователю, как заполнять регистрационную форму.
Вдобавок, в справочном окне (которое было сгене-
сгенерировано методом showHelpQ) объект Button определя-
определяется с помощью метода writeQ документа. Обратите вни-
внимание на две вещи, связанные с этой кнопкой.
Во-первых, для центрирования кнопки на странице ис-
используется дескриптор <DIVALIGN=>. Во вторых, для
увеличения ширины кнопки добавлено несколько про-
пробелов до и после ОК в параметре VALUE=. На рис. 17.5
показана форма, сгенерированная в HTML.
Листинг 17.6. buttons.htm.
<html>
<head>
<titleX>nline Registration</title>
<SCRIFT LANGOAGE="JavaScript">
function showHelpO {
helpWin = window.open("", "Help", "height=200,width=400")
helpWin. document.write ("<bodyXh2>Help on Registration</h2>")
helpWin. document, write(. Please enter your product information into the fields. <p>")
helpWin.document.write(. Press the Register button to submit your form.<p>")
helpWin.document.write(. Press the Clear button to clear the form and start again.<p>")
helpWin.document.write("<p>")
helpWin. document. write ("<f ormXDIV ALIGN =' CENTER' >" >
helpWin.document.write("<input type=button value=' OK 'onClick='window.closed '>")
helpWin. document. write ("</DIVX/f ormX/body>")
i
</SCRIPT>
</head>
<body>
<hl>Online Registration</hl>
<form method="POST">
<p>Please provide the following product information: </p>
<blockquote>
<preXem> Product name </emXinput type=text size=25 maxlength=256
name="ProductName">
<em> Model </emXinput type=text size=25 maxlength=256
name="Product_Model">
<em> Version number </emXinput type=text size=25 maxlength=256
name="Product_VersionNumber">
<em>Operating system </emxinput type=text size=25 maxlength=2 5 6
name="Product_OperatingSystem">
<em> Serial number </emXinput type=text size=25 maxlength=2S6
name="Product_SerialNumber">
</pre>
</blockquote>
<pXinput type=submit value="Register"> <input type=reset value="Clear">
<input type=button -walue="Help" onClick="showHelp () "X/p>
</form>
</body
Объекты Form
Online Regi!
Rease provide BierallcrMn
Pruauet п-bw
VucaXca audit!
»j»«i"T en:**
(Пи! nw**f
Help on Registration
¦nteryour product information into the nelds.
2 Press the Register buttnWo submit yOur form
3. Pee: г trie Clear button to dear (tie form and start agari.
ay
- Jig
РИСУНОК 17.5. В этом приложении используются кнопки
Button (OK), Reset (Clear) u Submit (Register).
ПРИМЕЧАНИЕ
Для увеличения эффективности при применении
JavaScript 1.4 не следует определять имя функции,
если используются массивы аргументов. В JavaScript
1.4 массив аргументов является не свойством объек-
объектов Function, но переменной. Считайте, что функция,
связывающая строки, как показано выше, имеет един-
единственный аргумент, который содержит символы, раз-
разделяющие составные элементы.
function ConcatenateUnleashed (separator) {
result="" // инициализация списка
for (var i=l; Karguments.length; i++> {
result += arguments [i] + separator
}
return result
]
Функция просто создает списки, которые соответству-
соответствуют передаваемым аргументами:
// Возвращает "Ford; GM; Chrysler,-"
ConcatenateUnleashed ("; " , "Ford" "GM" "Chrysler")
O6beicrCheckbox
Объект Checkbox — это тот же объект Form, но пред-
предназначенный прежде всего для обозначения логических
данных (true или false). Он действует как переключа-
переключатель, который может быть включен или выключен поль-
пользователем либо JavaScript-кодом. Для определения
Checkbox используют следующий HTML-синтаксис:
<INPUT
TYPE="checkbox"
[ NAME= " obj ec tName "]
[VALUE="value" ]
[CHECKED]
[onClick="methodName" ]>
laisplayText]
Например, приведенный ниже код для флажка по-
позволяет указывать, владеют ли пользователи иностран-
иностранными языками:
Глава 17
<input type=checkbox name="language">I speak
multiple languages.
Следующее соглашение для пользовательского ин-
интерфейса связано с тем, что Checkbox не должен вызы-
вызывать выполнение какого-либо действия (как это делают
объекты Button). В результате его обработчик событий
onClick, вероятно, будет применяться не столь широко.
Исключением из этого правила является изменение со-
состояния других объектов формы.
ПРИМЕЧАНИЕ
Дополнительная информация о событии onClick объекта
Checkbox находится в главе 14.
¦ ¦ ¦ ¦..
Определение заполнения объекта Checkbox
Возможно, наиболее важным свойством объекта Checkbox
является свойство checked. Это свойство проверяется
для определения, выставил ли пользователь флажок. Для
проверки объекта Checkbox использовать свойство value
нельзя и причины будут поясняться далее.
ПРЕДОСТЁРЕИШЧИЕ
Свойство value может поначалу вводить в заблужде-
заблуждение. В отличие от некоторых сред, здесь свойство
value статическое и в ответ на изменение состояния
Checkbox не изменяется. Поэтому не проверяйте
свойство value для определения факта выставления
флажка.
. - - .
Для иллюстрации воспользуемся примером, приве-
приведенным ранее при обсуждении объекта Text в этой гла-
главе. В одном из примеров с помощью метода select()
объекта Text при повторном вызове автоматически вы-
выделялось содержимое объекта Text. Предположим, что
для пользователей требуется создать опцию выделения/
невыделения текста. Для этого можно использовать фла-
флажок.
Листинг 17.7 содержит соответствующий код, а на
рис. 17.6 показана результирующая форма.
Листинг 17.7. checkboxSelect.htm.
<html>
<head>
<title>Online Registration</title>
<SCRIPT LANGOAGE="JavaScript">
function selectText (currentobject) (.
if (document. f orml. selectBox. checked) {
currentobject.select(}
:i
</SCRIPT>
</head>
<body>
<form name="forml" method="POST">
<h2>Onllne Reglstratlon</h2>
Использование DOM
Часть III
<p>Username:<br>
<input type=text size=25 maxlength=256
name="Username"
onFocus="selectText (this) "Xbr>
Browser used:<br>
¦<input. type=text size=25 maxlength=25G
name="Browser"
onFocus="seleotText(this)"><br>
Email address :<strong> <br>
</strongXinput type=text size=25 maxlength=256
name="EmailAddress"
onFocus="selectText (this) "X/p>
<h2xinput type=submit value="Register"> <input
type=reset value="Clear"X/h2>
<pXinput type=checkbox
name="selectBox">Activate field selection.
</form>
</body>
</html>
Online Registration
Uiurname
P Adfcate Леи selection
РИСУНОК 17.6. Использование флажка.
ПРИМЕЧАНИЕ
Пример, показанный в листинге 17.7, демонстрирует
порядок вычисления отмеченного свойства. Однако,
необходимо учитывать, что этот код не обязательно
работает так, как ожидается. Как только выставлен
флажок, текст будет выделяется от текущего пункта,
независимо от того, снимет ли пользователь флажок.
Так происходит потому, что при вызове метода select!)
для объекта Text состояние выделения текста будет ос-
оставаться в силе, пока страница не перезагрузится.
Стоит заметить также, что при перегрузке страницы
командой инструментальной панели "Reload" в Netscape
Navigator содержимое формы сохраняется. В то же
время, при использовании метода reload!) в Netscape
Navigator 3.0 текущие значения в форме сбрасывают-
Объект Radio
Объект Radio используется для предоставления пользо-
пользователям возможностей выбора одиночной опции из
группы параметров. Если выбирается одна опция в пре-
пределах набора, другие в тот же момент выбраны быть не
могут. Щелчок на переключателе снимает выделение с
любого другого выбранного ранее переключателя.
Объект Radio отличается от других изученных ранее
объектов Form. Заметим, что другие объекты Form име-
имеют взаимно-однозначное соответствие HTML-дескрип-
HTML-дескриптору, тогда как объекту Radio в пределах исходного
HTML-кода соответствует целый набор элементов
<INPUT type="radio">. Каждый элемент объекта Radio
определяется таким образом:
<INPUT
TYPE="radio"
[NAME="grroupWanie" ]
[VALUE="value"]
[CHECKED]
IonClick="methodWame" ] >
idisplayTextl
Элементы здесь не группируются таким способом,
как это делается с элементами в объекте Select (кото-
(который обсуждается ниже в главе). Способ их группиров-
группировки основан на параметре NAME= переключателя. Каж-
Каждый элемент в объекте Radio должен использовать в
этом параметре одно и то же значение. Например, сле-
следующий набор переключателей работает с одним объек-
объектом Radio — weekdays:
<INPUT TYPE="radio" NAME="weekdays"
VALUE="Monday">Monday
¦CINPUT TYPE="radio" NAME="weekdays"
VALUE="Tuesday">Tuesday
<INPUT TYPE="radio" NAME="weekdays"
VALUE="Wednesday">Wednesday
<INPOT TYPE="radio" NAME="weekdays"
VALUE="Thursday">Thursday
<INPUT TYPE="radio" NAME="weekdays"
VALUE="Friday">Friday
<INPUT TYPE="radio" NAME="weekdays"
VALUE="Saturday">Saturday
<INPUT TYPE="radio" NAME="weekdays"
VALUE="Sunday">Sunday
ПРИМЕЧАНИЕ
За дополнительной информацией о событии опСНскдля
объекта Radio обращайтесь в главу 14.
Определение значения выбранного
переключателя
Одной из наиболее распространенных задач, которые
должны решаться при использовании объекта Radio,,
является проблема получения значения выбранного в
данный момент переключателя. Для этого потребуется
определить, какой из переключателей выбран и затем
вернуть его значение. Вместо написания оригинально-
оригинального кода каждый раз, проще воспользоваться универсаль-
универсальной функцией, называемой getRadioVa!ue(), которая
может возвращать значение объекта Radio, передаваемо-
передаваемого в метод в качестве параметра.
Объект Form
Рассмотрим код, показанный в листинге 17.8. Объект
SongsRadio содержит список из трех песен. Объект
Button "Show Selected" отображает выбранный в данный
момент объект, вызывая метод getRadioValue() с пере-
передачей объекта Songs в качестве параметра функции.
Метод GetRadioValue() выполняет цикл for, предназна-
предназначенный для проверки, какой из переключателей выбран.
Для определения количества итераций используется
свойство length объекта Radio. Когда цикл for сталки-
сталкивается с выбранным значением, он присваивает пере-
переменной значение переключателя, прерывает выполне-
выполнение цикла, а затем возвращает значение в обработчик
событий Button.
Листинг
17.8.
radio.htm.
<html>
<head>
<script language = " JavaScript" >
function getRadioValue(radioObject)
var value = null
for (var i=0; i<radioObject. length;
{
if <radioObject[i].checked) {
value = radioObjectfi] .value
break }
}
return value
}
</script>
</head>
<body>
<?orm name="forml">
<pxinput type=radio name=" songs*1
value=" Liquid" >Liquid</p>
<pxinput type=radio name=" songs"
value="Flood">Flood</p>
<pxinput type=radio name="songs" value="World' s
Apart" >World' s Apart</p>
<input type=button value="Show Selected"
onClick="alert (getRadioValuefthis. form, songs) ) ">
< / f orm>
</body>
</html>
На рис. 17.7 показан результат нажатия кнопки
"Show Selected".
ПРИМЕЧАНИЕ
Листинги 17.12 и 17.17, приведенные ниже в главе,
демонстрируют способ автоматической проверки пе-
переключателя.
.... .... ....
Объект Select
Объект Select — один из наиболее полезных и гибких
объектов Form. Его можно использовать в тех же слу-
случаях, что и объект Radio. Объект Select нуждается в
меньшем количестве реального пространства по сравне-
сравнению с объектом Radio, которому необходимо простран-
Глава17
ство под каждый переключатель. Базовый синтаксис
HTML для объекта Select выглядит так:
<SELECT
[NAME="objectName"]
[SIZE="numberVisible"]
[MULTIPLE]
[onBlur="methodNanie"]
:[onChange="jnet.hodName"]
[onFocus="jne thodName"]>
<OPTION VALUE="optionValue"
[ SELECTED ]>dispIayText</OPTION>
[<OPTION VALUE=" optionValue">d±splayText
</OPTION>]
</SELECT>
-"»»• sMUM
¦ i
Г Liquid
tfVrtirkb Apart
РИСУНОК 17.7. Определение значения объекта Radio.
Благодаря своей гибкости, объект Select может при-
принимать три различных формы: список выбора, прокру-
прокручиваемый список и прокручиваемый список с мульти-
выбором.
ПРИМЕЧАНИЕ
Дополнительная информация о событиях объекта Select
может быть найдена в главе 14.
Создание списка выбора
Список выбора — это выпадающий список опций, в
котором пользователь может выбрать только одну оп-
опцию. Список выбора обычно отображает одно значение
на экране (см. рис. 17.8), но при нажатии на стрелку
список расширяется и отображает все элементы выбора
(см. рис. 17.9). В отличие от комбинированных списков
Windows, вводить значение в список выбора не допус-
допускается; можно только выбирать элемент из существую-
существующего массива элементов.
Список выбора, показанный на рис. 17.8 и 17.9, мож-
можно определить так:
<select NAME="songs" SIZE=1>
<option VALUE="Liquid">Liquid</option>
Использование DOM
Часть III
<option VALOE="World's Apart">World" s Apart
</option>
<option VALUE="Ironic">Ironic</option>
-Coption VALUE=979">1979</option>
<option VALUE="Wonderwall">Wonderwall</option>
<option VALUE="Standing Outside a Broken Phone
wBooth">Standing Outside a Broken Phone
Booth</option>
РИСУНОК 17.8. Список выбора в начальном состоянии.
РИСУНОК 17.9. Список выбора вразвернутом состоянии.
Ключ к определению списка выбора заключается в
присвоении параметру SIZE значения 1 (либо вообще
никакого значения). Это даст гарантию того, что спи-
список будет отображать только одну строку.
Создание прокручиваемого списка
Второй формой объекта Select является прокручивае-
прокручиваемый список, во многих средах называемый окном спис-
списка. Он отображает указанное число элементов одновре-
одновременно в формате списка, вместо того чтобы прятать все
элементы кроме одного, как это делает выпадающий
список. Прокручиваемый список включает полосу про-
прокрутки, при этом пользователь может прокручивать спи-
список элементов вверх или вниз, чтобы просматривать и
те элементы, которые не уместились в окне.
¦ Для создания прокручиваемого списка единственное
изменение в HTML-определении <select> необходимо
проделать в параметре SIZE=. Если его значение боль-
больше 1, объект Select преобразуется в прокручиваемый
список. Например, если изменить параметр SIZE= оп-
определенного ранее объекта Songs с 1 на 5, список при-
примет новый вид, показанный на рис. 17.10. Как и спи-
список выбора, прокручиваемый список позволяет выбирать
только одно значение.
Создание прокручиваемого списка с
мультивыбором
Последняя форма, в которой может быть представлен
объект Select, — это прокручиваемый список с мульти-
мультивыбором. Он выглядит так же, как обычный прокручива-
прокручиваемый список, но ведет себя по-другому. Из этой формы
объекта Select можно выбирать один и более элементов.
Решение задачи выбора множества элементов шсит от
среды. В большинстве случаев можно либо перемешать
мышь с нажатой кнопкой поверх требуемых элементов,
либо удерживать в нажатом состоянии к шу Shift
или Ctrl во время щелчков на элементах списка.
РИСУНОК 17.10. Прокручиваемый список.
Для определения прокручиваемого списка с мульти-
мультивыбором необходимо в определение объекта Select до-
добавить параметр MULTIPLE:
<select NMJE=" songs" SIZE=5 MOLTIPLE>
<option VALUE="Liquid">Liquid</option
<option VALUE="World' s Apart">World'» Apart
</option>
<option VALUE="Ironic">Ironic</option>
<option VALUE=979">1979</option>
<option VALOE="Wonderwall">Wonderwall</option>
Объекты Form
<option VALUE="Standing Outside a Broken Phone
"¦¦Booth" >
.Standing Outside a Broken Phone Booth</option>
Определение значения или текста
выбранной опции
В списке выбора или прокручиваемом списке можно
определять значение выбранной опции с помощью ком-
комбинации свойств options и selectedlndex объекта Select.
Например, если требуется определить песню, которая
была выбрана в приведенном выше примере объекта
Songs, используют следующий код:
favorite = document.forml.songs.options
I [document.forml.songs.selectedlndex].value
Свойство options — это массив, содержащий каждую
опцию, определенную внутри объекта Select. Исполь-
Используя это свойство, можно обращаться к свойствам каж-
каждой опции. С помощью свойства Selectedlndex возвра-
возвращается индекс выбранной опции. Когда options и
Selectedlndex используются в комбинации, возвращает-
возвращается значение выбранной в данный момент опции.
С учетом требований точечной нотации JavaScript,
выбранное в данный момент значение может включать
длинные строки текста программы. Этого можно избежать
с помощью универсального метода getSelectValue(). Ли-
Листинг 17.9 показывает способ применения такого мето-
метода. Как видно из листинга, объект Select переходит к
параметру метода getSeIectValue(), как только пользо-
пользователь нажимает на кнопку "Show Current". Переменная
SelectObject обрабатывается как переменная объектно-
объектного типа и принимает значение выбранной в данный
момент опции. Это значение переходит в обработчик
событий объекта Button и отображается в сигнальном
окне сообщения.
Листинг 17.9. select.htm.
<html>
<head>
<script language = "JavaScript">
function getSelectValue(selectObject) {
return selectObject.
options[selectObject.selectedlndex].
value
</script>
</head>
<body>
<form name="forml">
Songs: <select NAME="songs" SIZE=1>
<option VALUE="Liquid">Liquid</option>
<option VALUE="World's Apart">World's Apart
</option>
<option VALUE="Ironic">Ironic</option>
<option VALUE=979">1979</option>
<option VALUE="Wonderwall">Wonderwall</option>
<option VALUE="Standing Outside a Broken Phone
Глава 17
Standing Outside a Broken Phone Booth</option>
</SELECTXp>
<input type=button value="Show Current"
onClick="alert(getSelectValue(this.form.songs))">
</form>
</body>
</html>
Одно важное различие между объектами Select и
Radio связано с тем, что объект Select, в дополнение к
свойству value, имеет свойство text. Если определяемое
значение аналогично тому, которое отображается для
пользователя (как в листинге 17.9), то можно вместо
свойства value возвращать значение text выбранного в
данный момент объекта. Предположим, что объект
Select был определен так:
<select NAME="songs" SIZE=1>
<option>Liquid</option>
<option>World's Apart</option>
<option>Ironic</option>
¦<option>197 9</option>
<option>Wonderwall</option>
<option>Standing Outside a Broken Phone Booth
</option>
Тогда для возврата названия песни вместо свойства
value можно воспользоваться свойством text:
function getSelectValue(selectObject) {
return selectObject.options[selectObject.
selectedlndex].text
Определение значений в прокручиваемых
списках с мультивыбором
В списках, где в каждый момент времени может быть
выбрана только один вариант, свойство selectedlndex
работает эффективно и возвращает необходимую ин-
информацию из выбранной опции. Однако, в прокручи-
прокручиваемом списке с мультивыбором selectedlndex возвраща-
возвращает только первую выделенную опцию, а не все сразу.
При использовании списка с мультивыбором необхо-
необходимо применять свойство selected массива опций для
определения состояния каждой опции в списке. Ли-
Листинг 17.10 демонстрирует пример этого в методе
showSelection(). Цикл for выполняет итерации по каж-
каждой опции объекта Select и проверяет, равно ли свой-
свойство selected значению true. Если да, то значение свой-
свойства text элемента добавляется в переменную списка.
Результат отображается во втором окне, показанном на
рис. 17.11.
Листинг 17.10. selectMultiple.htm.
<html>
<head>
<script language =
"JavaScript">
function showSelection(objectName)
Использование DOM
Часть III
var list =
for (var i=0; i<objectName. length;
if (objectName. options [i] .
^selected) {
list +=
objectName.options[i].text + "<p>"
selWindow = window. open ( " " ,
"Selections", "height=200,width=400")
selWindow.document.write("<h2>You
^•picked the following songs :
</h2XpXp>")
selWindow.document.write(list)
</script>
</head>
<body>
<form name="forml">
Pick Youx Favorite Songs From the List:<p>
<select NAME="songs" SIZE=5 MULTIPLE>
<option>Fortress Around Your Heart</option>
<option>Breakf ast at Tiffany' s</option>
<option>Flood</option>
<option>The Chess Game<
<option>Liquid</option>
<option>World's Apart</option>
<option>Ironic</option>
<option>1979</option>
<option>Wonderwall</option>
<option>Standing Outside a Broken Phone Booth
</option>
</SELECTXp>
<input type=button value="Show Selection"
onClick="showSelection(this.form.songs)">
</form>
</body>
</html>
<body>
<form name="forml">
Favorite Band: <input type=text name="
size=20 onBlur="quickSelect () "Xp>
Songs: <select NAME="songs" SIZE=1>
<option VALUE="Liquid">Liquid</option>
<option VALUE="World's Apart">WorId's Apart
</option>
<option VALOE="Ironic">Ironi c</option>
<option VALUE=979">1979</option>
<option VALUE="Wonderwall">Wonderwall</option>
<option VALUE="Standing Outside a Broken Phone
*»Booth">
Standing Outside a Broken Phone Booth</option>
</SELECTXp>
<input type=button value="Show Current"
onClick="quickSelect()">
</form>
</body>
</html>
- IWtt'fcail^W.h ,1-1 l^-F.J... f"iiv " "
Выбор опции с помощью JavaScript
Можно программно выбирать опцию, устанавливая
свойство selected массива параметров объекта Select.
Предположим, что имеется поле "Favorite Band" и спи-
список песен. Пусть значение поля "Favorite Band" — Oasis,
и требуется расположить песню, исполняемую этой
группой, в поле "Songs". В листинге 17.11 показан код
этого примера.
Листинг 17.11. selectSelected.htm.
<html>
<head>
<script language = "JavaScript">
function quickSelect() {
var bnd = с
bnd = bnd.toUpperCase()
if (bnd = "OASIS") {
document.forml.songs[4].selected = "
</script>
</head>
P ИСУ Н О К17.11. Отображение множественного выбора.
Объект Password
Как можно понять по его имени, объект Password пре-
преследует одну цель: захватывать значения пароля, вве-
введенного пользователем. Объект Password аналогичен
объекту Text, но отображает любой символ, напечатан-
напечатанный пользователем в поле, в виде звездочки (*). Этот
объект определяется в синтаксисе HTML следующим
образом:
<INPUT
TYPE= "pas sword"
[NAME=" objectName"]
[VALUE="defaultPassword"J
[SIZE=integer] >
Ниже приведен пример:
<INPUT TYPE="password" NAME="passwordField"
SIZE=15>
JavaScript не предоставляет большой степени управ-
управления объектом Password. Например, нет возможности
Объекты Form
получать значение текста, введенного пользователем;
можно только получить заданный по умолчанию текст,
который был определен в параметре VALUE= дескрип-
дескриптора <INPUT type=Password>. Одна из причин, почему
JavaScript не может получить доступ к объекту Password,
связана с тем, что JavaScript-код в настоящее время
встраивается в HTML-документ так, чтобы пользователь
мог обращаться к нему. Когда язык JavaScript будет
разработан до конца, вероятно, появится большая сте-
степень управления этим объектом.
Объект Hidden
Как можно понять по его имени, объект Hidden неви-
невидим для пользователя. Объект Hidden — это поле скры-
скрытого текста, использующееся для хранения значений,
которые не требуется представлять пользователю в
обычных текстовых полях. Затем можно передавать эту
информацию на сервер для обработки. Объект Hidden
в HTML определяется с помощью следующего синтак-
синтаксиса:
TYPE="hidden"
MAME="objectName"
[VALUE= "value" ] >
Листинг 17.12. hidden.htm.
Глава 17
Ниже приведен пример:
<INPUT TYPE="hidden" NAME="hiddenFieldl">
В HTML-мире скрытые поля играли важную роль в
получении определенной информации со стороны
пользователя, которая затем использовалась сервером. С
появлением JavaScript, применение объекта Hidden в
комбинации с JavaScript становится менее эффектив-
эффективным. Причина связана с тем, что глобальные перемен-
переменные JavaScript служат тем же целям, что и объекты
Hidden, однако ими намного проще управлять.
Следующие два примера демонстрируют это. На рис.
17.12 показан набор переключателей, на которых мож-
можно совершать щелчки. Необходимо добавить код к кноп-
кнопке "Undo Last", чтобы пользователь мог отменять пос-
последний сделанный выбор. Использовать кнопку Reset
для этого нельзя, т.к. она или сбросит все переключа-
переключатели, или вернет значение по умолчанию. Вместо этого
для выполнения упомянутой задачи придется добавить
JavaScript-код. Код, приведенный в листингах 17.12 и
17.13, демонстрирует решение такой задачи. Листинг
17.12 использует для этого набор скрытых полей, в то
время как листинг 17.13 выполняет данную задачу с по-
помощью глобальных переменных. Заметим, что оба эти
метода — вполне допустимы.
<html>
<head>
<title>Hidden Test</title>
¦< script language="JavaScript">
function postData(value) {
document.forml.holder2.value = document.forml.holder.value
document.forml.holder.value = value
function resetValue(> (
var len = document.forml.ctyList.length
;for (var i=0; i<len; i++) {
if (document.forml.ctyList[i].value =s
document.forml.ctyList[i].checked
break }
document.forml.holder2.value) {
"
</script>
</head>
<body>
<hl>I remember</hl>
<form name="forml" method="POST">
<pXinput type=radio name="ctyList" value="Argentina"
onClick="postData (this.value)">Argentina</p>
<pXinput type=radio name="ctyList" value=" Burkina Faso"
onClick="postData(this.value)">Burkina Faso</p>
<p><input type=radio name="ctyList" value="Pakistan"
onClick="postData(this.value)">Pakistan</p>
<p><input type=radio name="ctyList" value="Switzerland"
onClick="postData(this.value)">Switzerland</p>
<pXinput type=radio name=" ctyList" value="United Kingdom"
onClick="postData (this, value) "MJnited Kingdom</p>
<pXinput type=radio name="ctyList" value="United States of America"
Использование DOM
Часть III
onClick="postData(this.value>">United States of America</p>
<pXinput type=radio name="otyList" value="Zambia"
onClick="postData (this .value) ">Zaitibia</p>
<pxinput type=radio name="ctyList" value="Zimbabwe"
onClick="postData(this.value)">Zimbabwe</p>
<pxinput type=button name="UndoLast" value="Undo Last"
onClick="resetValue () "X/p>
<INPUT TYPE="hidden" NAME="bolder" value="'">
<INPUT TYPE="hiddenlr NAME="holder2" value="">
</form>
</body>
</html>
Листинг 17.13. hiddenVars.htm.
<html>
¦<head>
<title>Hidden Var Test</title>
<script language^"JavaScript">
var holder = ""
var holder2 = ""
function postData (value) {
holder2 = holder
holder = value
)
function resetValue() (
var len = document.forml.ctyList.length
for (var i=0; i<len; i++) {
if (document.forml.ctyList[i].value = holder2)
document.?orml.ctyList[i].checked = "
break )
</script>
</head>
<body>
<hl>I remember</hl>
<form name="forml" method="POST">
<pXinput type=radio name="ctyList" value="Argentina"
onClick="postData(this.value)">Argentina</p>
<pxinput type=radio name="ctyList" value="Burkina Faso"
onClick="postData(this.value)">Burkina Faso</p>
¦<pxinput type=radio name="ctyList" value="Pakistan"
onClick="postData(this.value)">Pakistan</p>
<pXinput type=radio name="ctyList" value="Switzerland"
onClick="postData(this.value)">Switzerland</p>
<pXinput type=radio name="ctyList" value="Onited Kingdom"
onClick="postData(this.value)">United Kingdom</p>
<pXinput type=radio name="ctyList" value="United States of America"
onClick="postData(this.value)">United States of America</p>
<p><input type=radio name="ctyList" value="Zambia"
onClick="postData(this.value)">Zambia</p>
<pxinput type=radio name="ctyList" value="Zimbabwe"
onClick="postData(this.value)">Zimbabwe</p>
<pXinput type=button name="UndoLast" value="Undo Last"
onClick="resetValue () "X/p>-
'</form>
</body>
</html>
В последнем примере всякий раз, когда пользователь нем holder, а текущее значение holder — в объект holder2.
щелкает на переключателе, метод postData() помещает Это значение затем используется, когда пользователь
текущее значение переключателя в объект Hidden с име- нажимает на кнопку "Undo Last", в результате чего вы-
выбирается соответствующий переключатель.
Объекты Form
I remember
РИСУНОК П.12. Сохранение последнего значения с помощью
объекта Hidden.
Глава 17
Во втором примере переменные holder и hol(ler2
определены глобально в начале сценария. Сценарий
использует эти переменные вместо ссылок на объекты
Hidden.
Резюме
Формы играют важную роль в JavaScript. Помимо того,
что появляется возможность классифицировать и обра-
обрабатывать данные до их отправки на сервер, HTML-фор-
HTML-формы можно также использовать для создания клиентских
приложений, использующих JavaScript. В этой главе
рассматривался объект Form и различные объекты, ко-
которые могут существовать внутри него. Кроме того, были
показаны способы отправки формы на сервер и методы
работы и проверки значений введенных данных до от-
отправки данных на сервер.
Объекты Frame
В ЭТОЙ ГЛАВЕ
Объект Frame
Объект Location
Объясг History
Объект Navigator
В этой главе обсуждается объект Frame и огромное
число его применений при создании Web-сайтов. Для
начала стоит рассмотреть создание одиночных и муль-
тифреймовых окон и связанные с ними методы, свой-
свойства и события. Затем можно перейти к распространен-
распространенным объектам, таким как объекты Navigator и History.
Их предшественник — это, конечно же, известный ре-
позитарий для регистрации пользовательских взаи-
взаимодействий и адресов посещенных страниц, который по-
позволяет получать информацию касательно текущего
браузера. Эта глава может показаться достаточно длин-
длинной, однако, следует помнить, что она и должна содер-
содержать большое количество необходимых разделов, посвя-
посвященных фреймам и окнам.
Объект Frame
Фреймы были введены еще в Netscape Navigator 2.0.
Фрейм (frame) — это подокно полного окна браузера; его
спецификации определяются разработчиком. Фреймы
очень быстро обрели популярность, поскольку они по-
позволяют одновременно в одном и том же окне отобра-
отображать сразу несколько документов.
Каждый фрейм может содержать отдельный документ
(HTML, текст, изображение и пр.), каждый фрейм име-
имеет свой адрес и полосу прокрутки. Как и в случае оди-
одиночных окон, фреймы можно вызывать и ссылаться на
них. Можно также загружать документы во фреймы без
воздействия на документы в других фреймах.
Фреймы обеспечивают средства просмотра и вза-
взаимодействия с сайтом, который не доступен другим
способом. Они позволяют постоянно отображать нави-
навигационное подокно, которое обеспечивает быстрый и
эффективный поиск требуемых страниц сайта. Можно>
одновременно отображать входные и выходные формы,
а также просматривать большое количество документов
одновременно. Можно выбирать для просмотра различ-
различные файлы изображений, используя меню. Для отобра-
отображения расширенного вида документа можно открывать
новое окно, которое будет закрываться, когда оно боль-
больше не нужно. Фреймы также обеспечивают возможность
слайдовой демонстрации. Использование и реализация
мультифреймового сайта ограничены только воображе-
воображением его автора.
Например, окно могло бы содержать несколько про-
прокручиваемых фреймов, которые указывают на некоторые
URL, которые, в свою очередь, могут указывать на фрей-
фреймы. Объекты Frame создаются с помощью дескрипторов
<FRAME> внутри дескрипторов <FRAMESET>, и они
будут, по сути, объектами Window, от которых и унасле-
унаследуют все методы и свойства. Для получения дополнитель-
дополнительной информации относительно этих методов, свойств и
¦общего поведения можно обратиться в главу 15.
; ПРЕДУПРЕЖДЕНИЕ, ^^¦^, . t . ; \ /X
Некоторые посетители сайтов считают фреймы и но-
новые окна в определенной степени отвлекающими. К
тому же, иногда при использовании фреймовой
структуры информация покидает область отображе-
отображения, особенно в случае маленького монитора. Авто-
Автору сайта необходимо удостовериться, что использо-
использование фреймов удобно для посетителей; желательно
также предусмотреть доступ к альтернативной не-
нефреймовой версии сайта.
JavaScript существенно расширяет возможности сай-
сайта с фреймами и многое добавляет в способы взаимодей-
взаимодействия сайта с пользователями. Можно программно от-
открывать и закрывать новые окна. Можно обновлять и
синхронизировать фреймы с помощью сценария без уча-
участия серверной программы. Карты изображений и ссыл-
ссылки могут быть динамическими, т.е. изменяющимися в
Объекты Frame
зависимости от различных конфигураций и применений
сайта. Документы в различных фреймах и окнах могут
взаимодействовать друг с другом и передавать друг дру-
другу информацию.
Сетевые ресурсы, касающиеся JavaScript и
фреймов, находятся на сайте Netscape по адресу
http: / / home.netscape.com /.
Реальная выгода фреймов заключается в возможно-
возможности обеспечивать постоянное навигационное меню сай-
сайта. Вместо прыжков с одной страницы на другую пользо-
пользователь может выбрать страницу из меню, и она появится
в другом (главном) фрейме. Оглавление может отобра-
отображаться в одном фрейме, а документы — в другом. Можно
разместить фрейм с кнопочной панелью с одной сторо-
стороны окна, и в этом фрейме пользователь будет нажимать
на кнопки, если ему потребуется загрузить часть сайта
в отображающий фрейм.
* совет -;;._ . . ; "ti. . :, ' .-ч -; ч,- - .;"
Использование фреймов имеет и некоторые недостат-
недостатки. Главный недостаток связан с уменьшением обла-
области отображения каждого документа. Пользователям
с небольшими мониторами, портативными или карман-
карманными компьютерами будет сложно в подробностях
рассмотреть некоторые документы в фреймах. Непло-
Неплохим выходом может оказаться создание наряду с фрей-
фреймовой также и нефреймовой версии сайта и предос-
предоставление всем пользователям возможности просмотра
выбранной версии (с помощью JavaScript это сделать
довольно-таки просто).
Объект Frame, по сути, аналогичен объекту Window,
и с ним работают подобными же методами. В случае
одиночного окна объект Window представляет собой
объект самого высокого уровня. В случае фреймов окно
самого высокого уровня считается родительским, а его
дочерние окна считаются объектами Frame.
Создание фреймов
Фреймы создаются с помощью дескрипторов <FRAMESET>
и определяются дескрипторами <FRAME>.
<HTML>
<HEAD>
<TITLE>Creating ?rames</TITLE>
</HEAD>
<FRAMESET COLS=0%,*,5%">
<FRAME SRC="docl.html" NftME="framel">
<FRAME SRC=" doc2.html" NAME="frame2">
<FRAME SRC="doc3.html" NAME="frame3">
</FRBMESET>
</HTML>
За счет добавления нескольких строк кода можно
легко создать окно с тремя фреймами:
<HTML>
Глава 18
<НЕМ»
<TiTLE>Window frames: Window One</TITLE>
</НЕМ»
<FRSMESET ROWS=5%,45%" COLS=0%,60%"
onLoad="alert('Windows have frames')">
<FRBME SRC="docl.htnil" NftME="framel">
<FRAME SRC="doc2,html" NftME="frame2">
<FRftME SRC="doc3.html" NMffi="frame3">
<FRaME SRC="doc4.html" NSME="frame4">
</FRftMESET>
</HTML>
(Выравнивание дескрипторов <FRAME> не является
необходимым, но часто делается с целью обеспече-
обеспечения лучшего вида программы и для демонстрации
мерархии фреймов в коде. Некоторые HTML-редак-
HTML-редакторы выравнивают дескрипторы автоматически, они
могут также окрашивать некоторые фрагменты кода
для лучшей читаемости.
Дескрипторы <FRAMESET>
Дескриптор <FRAMESET> имеет атрибут для описания
способа разделения окна на фреймы. Этим атрибутом
может быть COLS или ROWS (для столбцов или строк),
но не оба сразу. Разработчик определяет количество
строк или столбцов фреймов в окне и размеры каждого
фрейма. Для каждой строки или столбца может опреде-
определятся либо абсолютный размер в пикселах, либо отно-
относительный размер в процентах от окна, либо размер
вычисляется как остаток от окна после установки дру-
других фреймов. Следующая строка создает два фрейма в
виде столбцов, один размером 60% от окна, а другой —
в оставшейся части окна (указан с помощью "*", в дан-
данном случае этот размер составляет 40%):
<FRAMESET COLS=0%,*">
'Следующая строка кода создает снова два фрейма, но
без использования знака процента. Абсолютная шири-
ширина первого фрейма — 60 пикселов:
<FRRMESET COLS=0,*">
Как и прежде, второй фрейм создается в оставшейся
части окна.
Следующая строка создает четыре фрейма в виде
столбцов; три фрейма занимают по 30% ширины экра-
экрана каждый, а четвертый — оставшуюся часть:
<FRftMESET COLS=0%,30%,30%,*">
В данном случае можно заменить знак "*" на 0%".
Для последнего фрейма использовать "*" необязательно.
Однако, если размеры всех фреймов определяются че-
через проценты, в сумме они должны составлять 100%
ширины окна.
Следующая строка кода создает два фрейма в виде
строк, первый размером 70% высоты окна, а второй — 30%:
<FRAMESET ROWS=0%,30%">
Использование DOM
Часть III
Размеры фрейма можно задавать с помощью сочета-
сочетания абсолютных, относительных размеров и остатка, но
если полный размер всех фреймов не равен размеру
окна, результаты будут непредсказуемыми. Указание
размеров фреймов только с помощью символа "*" могло
¦бы показаться очевидным; однако, "*" можно использо-
использовать для каждого фрейма. Следующая строка создает три
равных фрейма, каждый размерами в треть высоты окна:
<FRAMESET ROWS="*,*,*">
Дескрипторы <FRAME>
Атрибуты дескриптора <FRAME> определяют доку-
документ, который будет загружаться в фрейм, имя фрей-
фрейма, границы фрейма, полосу прокрутки и опции изме-
изменения размеров. Все следующие атрибуты дескриптора
<FRAME> — необязательны:
Атрибут SRC — URL (относительный или абсолют-
абсолютный) документа, который будет загружаться во
фрейм. Документ может быть получен с того же сер-
сервера в виде фреймового файла или с другого серве-
сервера. Если атрибут SRC не используется, фрейм будет
пустым. Это пустое пространство можно заполнить
чем угодно, особенно, если для записи содержимого
в фрейм воспользоваться JavaScript.
Атрибут NAME, если определен, обеспечивает сред-
средства для ссылки на фрейм из другого фрейма, а так-
также из JavaScript. JavaScript может также ссылаться на
фрейм через массив frames, который рассматривает-
рассматривается далее в главе. Значение атрибута NAME должно
начинаться с алфавитно-цифрового символа.
Границы фрейма устанавливаются с помощью двух
атрибутов, MARGINWIDTH и MARGINHEIGHT:
Атрибут MARGINWIDTH управляет боковыми
границами фрейма. Этот атрибут может прини-
принимать значение в пикселах, начиная с единицы.
Максимальное значение ограничено только разме-
размером фрейма. (Невозможно установить границы
таким образом, чтобы не осталось места для ото-
отображения документа.)
Атрибут MARGINHEIGHT аналогичен
MARGINWIDTH за исключением того, что он
управляет верхней и нижней границами.
Если не указаны значения MARGINWIDTH и
MARGINHEIGHT, браузер выбирает для них
значения по умолчанию.
Атрибут SCROLLING определяет полосу прокрут-
прокрутки для фрейма. Значениями для SCROLLING мо-
могут быть YES, NO и AUTO. YES означает, что по-
полоса прокрутки всегда присутствует в фрейме. NO
означает, что полоса прокрутки не отображается.
AUTO отображает полосу прокрутки только, если
документ по размерам превышает фрейм. Значение
по умолчанию для SCROLLING — AUTO.
• NORESIZE запрещает пользователю изменять раз-
размеры фрейма. Для этого атрибута значение не ука-
указывается. По умолчанию, если этот атрибут не оп-
определен, весь фрейм получит изменяемые размеры.
Изменять размеры фреймов, которые имеют атрибут
NORESIZE, нельзя.
•^СОВЕТ . г
Если это возможно, лучше не определять этот атри-
атрибут, т.е. разрешить пользователю изменять размеры
фрейма.
¦Следующий фрагмент кода присваивает фрейму имя
framel, загружает документ, устанавливает боковые
границы в 5 пикселов, верхние и нижние границы в 10
пикселов, всегда отображает полосу прокрутки и не раз-
разрешает изменять размеры фрейма:
< FRMJE SRC = "docl.html" NAME = "framel"
MARGINWIDTH=S
MARGINHEIGHT=10 SCROLLING =YES NORESIZE>
Netscape и Microsoft предоставляют расширенные
возможности в браузерах последних версий. Посетите
web-сайты этих компаний, на которых находится более
подробная информация (соответственно http://
home.netscape.com/ и http://www.microsoft.com/).
При использовании фреймов дополнительно не-
необходимо рассмотреть обработку событий, отлаживая
JavaScript-код или подстраивая его под целевой браузер.
JavaScript-события, наиболее часто встречаемые как в
Microsoft Explorer, так и в Netscape Navigator, сведены
в табл. 18.1.
Размещение дескрипторов
Дескрипторы <FRAMESET> и <FRAME> обычно раз-
размещают в теле документа. Однако, в некоторых версиях
Netscape Navigator помещение их между дескрипторами
<BODY> и </BODY> не позволяет браузеру прочесть
дескрипторы <FRAMESET>. Поскольку дескрипторы
<BODY> необязательны, дескрипторы <FRAMESET>
размещают после раздела <HEAD> документа, а деск-
дескрипторы <BODY> опускают, как показано ниже:
<нтмь>
<НЕМ»
<TITLE>Frame Demo</TITLE>
</HEAD>
<FRAMESET COLS=0%,*">
<FRAME SRC="docl.html" KAME="framel">
<FRAME SRC="doc2.html" NAME="frame2">
</FRAMESET>
</HTML>
Таблица 18.1.
Объект
JavaScript-события и фреймы.
Событие
Описание
иьъекты trame EW3
Глава 18 ЁШ
Окно или фрейм
<BODY> <FRAMESET> <FRAME>
dragdrop
error
focus
load
Move
Resize
unload
Пользователь выбрал объект в окне.
Окно загружено с ошибкой.
Окно получило фокус.
Окно загружено.
Окно было перемещено.
Окно было изменено.
Пользователь покинул окно.
Этот код устанавливает фреймы и загружает соответ-
соответствующие документы. Фактически, можно сделать файл
меньше, поскольку дескрипторы <HTML>, <HEAD> и
<BODY> необязательны; файл может содержать только
дескрипторы <ТПЪЕ>, <FRAMESET>h <FRAME>, как
показано в следующем фрагменте. (Открывающий и
закрывающий дескрипторы <TITLE> — единственные
дескрипторы, которые по требованиям спецификации
HTML должны присутствовать в каждом HTML-доку-
HTML-документе.)
<TITLE>Frame Demo</TITLE>
<FRftMESET COLS=0%,*">
<FRRME SRC=" docl.html" NAME="framel">
<FRRME SRC="doc2.html" NAME="frame2">
</FRAMESET>
Дескриптор <NOFRAMES>
Многие авторы устанавливают также дескрипторы
<NOFRAMES> для отображения сообщений в браузе-
браузерах, не использующих фреймы:
<NOFRAMES>
код и текстовое содержимое для отображения в
¦браузерах, не поддерживающих фреймы
</NOFRRMES>
Содержимое может включать в себя как HTML-дес-
HTML-дескрипторы, так и текст. Поддерживающий фреймы
браузер игнорирует информацию между дескрипто-
дескрипторами <NOFRAMES> и </NOFRAMES>, тогда как
браузер, не поддерживающий фреймы, игнорирует
<FRAMESET>, <FRAME> и <NOFRAMES>, но ото-
отображает информацию, находящуюся между дескрипто-
дескрипторами <NOFRAMES>h </NOFRAMES>. Дескрипторы
<NOFRAMES> размещают внутри дескрипторов
<FRAMESET>:
<TITLE>Frame Demo</TITLE>
<FRAMESET COLS=0%,*">
<FRAME SRC="docl.html" NAME="framel">
<FRAME SRC=" doc2.html" NftME="frame2">
<NOFRAMES>-
код и текстовое содержимое дпя отображения в
браузерах, не поддерживающих фреймы
</NOFRAMES>
</FRAMESET>
Некоторые разработчики фактически дублируют глав-
главный документ сайта внутри дескрипторов <NOFRAMES>
для безфреймовой версии. Однако, обычно нет не-
необходимости использовать подобную методику, т.к.
с помощью JavaScript можно создавать фреймовую
версию сайта для тех же самых страниц, которые ото-
отображаются в браузерах, не поддерживающих фрей-
фреймы.
Интересно отметить, что дескрипторы <BODY> мож-
можно заключать в дескрипторы <NOFRAMES>, исполь-
используя атрибуты background, bgcolor, text и т.п. для без-
безфреймовой версии документа. Браузер, не
поддерживающий фреймы, игнорирует <FRAMESET>
и начинает выполнять раздел <BODY> с первого изве-
известного ему дескриптора (т.е. с дескриптора <BODY>)
внутри дескрипторов <NOFRAMES>. Поддерживаю-
Поддерживающий фреймы браузер инициализирует раздел <BODY>
в первом дескрипторе <FRAMESET> и игнорирует со-
содержимое дескриптора <NOFRAMES>. Конечно, под-
поддерживающий фреймы браузер загружает документы,
указанные дескрипторами <FRAME>, следовательно
дескрипторы <BODY> этих документов таким браузером
распознаются.
Вложенные фреймы
Можно создавать вложенные фреймы, в которых фрейм
будет разделен еще на несколько других фреймов. Су-
Существует два разных способа создания вложенных фрей-
фреймов, оба они обеспечивают похожие результаты. Одна-
Однако, возникает различие в иерархии фреймов и в способах
ссылок на вложенные фреймы.
Следующий код создает фреймы с мультифреймовой
структурой в одном родительском окне. На рис. 18.1
показаны фреймы, а на рис. 18.2 — структура (иерархия)
этих фреймов.
<FRMffiSET COLS=0%,*">
<FRftME SRC="docl.html"
NftME="framel">
Использование DOM
Часть III
<FRftMESET ROWS="*,20%">
<FRftME SRC="doc2.html"
NftME="?rame2">
<FRW4E SRC="doc3.html"
NAME="?raine3">
</FR»MESET>
</FRAMESET>
В коде для рис. 18.2 все три фрейма — дочерние фрей-
фреймы одного и того же верхнего окна. В коде, создающем
фреймы на рис. 18.4, только для фреймов framel и frame2
родительским окном является верхнее окно, a frame3 и
frame4 — это дочерние фреймы окна frame2. По этой
причине ссьшаться на данные фреймы необходимо по-
разному, и эти различия будут рассматриваться в следу-
следующих разделах.
РИСУНОК 18.1. Создание мулыпифреймовой структуры в
одномродителъском окне.
Top Window
\
'¦;¦'¦'¦: ¦¦¦ ¦ _
Parent is fia
: ;.<
в .
Г
framel frame2
РИСУНОК 18.2. Иерархия фреймов в одном родительском
окне.
Следующий код создает фреймы с мультифреймовой
структурой в двух окнах. (Фрейм тоже можно считать ок-
окном.) На рис. 18.3 показаны эти фреймы, а на рис. 18.4
— их иерархия.
<FRAMESET COLS=0%,*">
<FRAME SRC="docl.html" NAME=" framel ">
<FRAME SRC="frame2.html" NAME="frame2">
</FRAMESET>
Файл frame2.html содержит следующую дополни-
дополнительную информацию для установки фреймов:
<FRAMESET ROWS="*,20%">
<FRSME SRC="doo2.html"
NAME="frame3">
<FRAME SRC="doc3 . html"
!№ME="frame4">
</FRftMESET>
Эти два фрагмента кодов создают фреймы, которые
выглядят совершенно одинаково, как показано на рис.
18.1 и 18.3. Однако, структуры этих фреймов, как мож-
можно заметить из рис. 18.2 и 18.4, — полностью различны.
5»s
РИСУНОК 18.3. Создание фреймов с мулыпифреймовой
структурой в двух окнах.
TopWindow
Г
framel
I
frame 2
I
Г
frame3
I
frame4
РИСУНОК 18.4. Иерархия фреймов с мультифреймовой
структурой в двух окнах.
Добавление JavaScript-кода ко фреймам
Файлы с наборами фреймов и большинство файлов до-
документов, которые отображаются в фреймах — это
HTML-файлы. Таким образом, в них можно использо-
использовать JavaScript, как это делалось в других HTML-фай-
HTML-файлах. Единственное отличие связано с тем, что здесь
JavaScript ссылается и на свойства других документов,
находящихся в фреймах, а также использует определен-
определенные особенности ссылок на эти свойства.
На верхнее окно и его фреймы необходимо ссылать-
ссылаться с учетом их иерархических отношений. В ссылке на
окно могут быть указаны свойства Window, такие как
top, parent, window и self. Свойство top ссылается на
главное окно (окно браузера), a parent — на мульти
фреймовое окно, в котором содержится текущий фрейм.
Объекты Frame
Для фреймов, содержащихся в верхнем окне, parent и
top представляют собой одно и то же. Свойства self и
window ссылаются на текущий фрейм или окно,
Рассмотрим следующий код:
<FRAMESET COLS=0%,*">
<FRftME SRC="doel.htnil" HAME="framel">
<FRAMESET COLS=0%,*">
<FRAME SRC="frame2.html"
NSME="frame2">
<FRfiME SRC="doc3.html" NftME="frame3">
</FRAMESET>
Файл frame2.html содержит следующую дополнитель-
дополнительную информацию для установки фреймов в окне:
<FRAMESET ROWS="*,20%">
<FRM1E SRC="doc4.html" NAME="frame4">
<FRRME SRC="doc5.html" NSME="frame5">
</FRAMESET>
Родительским окном для frame 1, frame2 и frame3
является окно top, т.к. все эти фреймы содержатся в вер-
верхнем окне. Родительским окном для framc4 и frame5
будет frame2, поскольку эти два фрейма находятся в окне
frame2. Если необходимо сослаться на верхнее окно из
документа, содержащегося в frame4, используют свой-
свойство top; для ссылки на frame2 — свойство parent; и, на-
наконец, для ссылки на собственный фрейм данного до-
документа применяются свойства self или window.
На функции, переменные и другие свойства можно
ссылаться с помощью свойств Window:
<HTMt>
<Н?М»
<TITLE>Frame Demo</TITIiE>
<SCRIET LANGUAGE="JavaScript">
al = 2;
function addAl () {
a2 = al + 1;
return a2 ;
</SCRIPT>
</HEAD>
<BODY>
<FRbMESET COLS=0%,*">
<FRAME SRC="docl.html" NAME="framel">
<FRAMESET COLS=0%,*">
<FRAME SRC="frame2.html" NAME="frame2">
<FRAME SRC="doc3.html" NAME="frame3">-
</FRAMESET>
¦Файл frame2.html содержит следующую дополнитель-
дополнительную информацию для установки фреймов в окне:
<HTML>
<HEAD>
<TITLE>Frame Demo</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<! —
Ы = 2;
Глава 18
function addBl () {
Ь2 = Ы + 1;
return b2;
)¦
// —>
</SCRIPT>
</HEAD>
<BODY>
<FRAMESET ROWS="*,20%">
<FRftME SRC="doc4.html" NftME="frame4">
<FRBME SRC="doc5.html" NAME="frame5">
</FRAMESET>
Для ссьглок на переменную al и функцию addAl() из.
framel, framc2 или frame3 используют top.al или
parental, и, соответственно, top.addAl() либо parent.addAl().
Однако, для ссьглок из frame4 или frame5 можно исполь-
использовать только top.al и top.addAl, т.к. parent ссылается на
frame2. На переменную Ы и функцию addBl() из frame4
и frame5 можно ссылаться с помощью parent.bl и
parent.addBl().
Хочется надеяться, что все это не выглядит слиш-
слишком запутанно. Дополнительные способы ссьглок на раз-
различные фреймы и окна будут обсуждаться в разделе
"Ссылки на фреймы" далее в главе.
При работе с фреймовыми документами и JavaScript
необходимо соблюдать некоторые предосторожности.
Сценарий может выполняться ошибочно, если фрейм
содержит некорректный документ или даже вообще не
содержитдокумента.
Попытка сослаться на top.al из любого документа в
предыдущем примере приведет к ошибке, если документ
отсутствует во фрейме. Однако, JavaScript предлагает
средства для предотвращения таких ошибок; такие сред-
средства рассматриваются в следующем разделе.
Синхронизация фреймов
Как упоминалось ранее, при отсутствии правильных
документов или корректно загруженных фреймов могут
возникать ошибки и другие проблемы. Выполнение про-
программы остановится на половине пути, если программа
не сможет найти необходимую переменную. Кроме того,
проблема может возникнуть по причине неполной заг-
загрузки документа. Синхронизация фреймов гарантирует,,
что загрузка фреймов и документов будет завершена
прежде, чем в них возникнет необходимость, либо же
будут предприниматься альтернативные действия.
Проверка допустимости фреймов
Часто проблема возникает, когда страница содержит
JavaScript-код, который дает возможность просматри-
просматривать документы в фреймах или без них. Свойство
window.length обычно применяется для JavaScript- реше-
решения о просмотре документов в виде фреймов. Свойство
length хранит количество фреймов, содержащихся в окне.
Использование DOM
Часть III
Можно предусмотреть условный оператор, который ис-
исполняет какое-либо действие, если будут использоваться
фреймы:
if( top.length != О ){
document.write ("Frames are being used") ;
1
Обычно вместо window используют top или parent,
поскольку window подразумевает фрейм, содержащий
внутри безфреймовый код (если документ не является
файлом для установки других фреймов). Если окно или
фрейм содержат фреймы, значение их свойства length
будет больше нуля. Однако, если записать символ ">"
(для "больше"), то в старых браузерах он может быть
¦ошибочно интерпретирован как завершающий символ
HTML-комментария, поэтому предпочтительнее исполь-
использовать символы "!=" ("не равно").
Применение короткого цикла с оператором if помо-
поможет избежать ошибок, если документ, не находящийся
во фрейме, попытается сослаться на переменную из дру-
другого фрейма или мультифреймового окна. Если верхнее
мультифреймовое окно содержит переменную al, кото-
которая используется в операторе if в соответствие с создан-
созданным документом, ошибка возникнет при просмотре дан-
данного документа в автономном нефреймовом виде.
Однако, если свойство length, заранее проверенное в
условном выражении, равно false, то оператор if завер-
завершает работу, предотвращая возникновение ошибки из-
за попытки обращения к несуществующей переменной.
Первая часть следующего оператора, parent.length !=
О, равна false, когда фреймы не используются, так что
дальнейшее выполнение останавливается и ошибка не
возникает:
if( (parent.length != 0) && (top.al = X ) )
'Проверка правильности загрузки документов
Для синхронизации фреймов были разработаны различ-
различные методы, некоторые из них довольно просты, в то
время как другие — гораздо сложнее. Один из самых
простых методов использует JavaScript для проверки
наличия необходимого документа в данном фрейме пе-
перед продолжением выполнения остальной части кода.
Массив frames позволяет определять фрейм как элемент
массива. (В разделе "Ссылки на окна и фреймы" далее в
этой главе можно найти дополнительную информацию
относительно массива frames.) Рассмотрим следующую
строку кода:
if( (parent.length == 3) &&(parent.frames [1] .title
== "My Page") )
Оператор if проверяет правильность структуры
фрейма (в данном случае — наличие трех фреймов), а
также правильность документа во втором фрейме (на
который в данном случае ссылаются). Если структура
фрейма неправильна, вычисление условия останавлива-
останавливается, и никаких дальнейших действий не предпринима-
предпринимается либо же предпринимаются альтернативные дей-
действия. Если структура фрейма корректна, но неправилен
документ, сценарий не инициирует никаких действий
либо реализует альтернативные действия. Если никакие
дальнейшие действия не предпринимаются, программа
просто остается в текущей позиции, разрешая пользо-
пользователю продолжать выполнение других действий или
повторить неудавшееся действие. (Возможно, страница
не была до конца загружена, и следующая попытка заг-
загрузки окажется успешной.) Альтернативные действия
могут включать обеспечение сигнала для пользователя,
загрузку правильной страницы и продолжение работы
или же продолжение действия с пропуском шагов, тре-
требующих обращений к отсутствующему документу.
Предыдущий пример проверял простую фреймовую
структуру (три фрейма). Можно проверять корректность
и более сложных структур, используя массив frames раз-
различных окон в составном операторе if. Составной опе-
оператор if проверяет структуру сверху вниз, в противном
случае ссылка на отсутствующий фрейм вызовет ошиб-
ошибку. Рассмотрим следующую строку программы:
if (top. length==3)&S(top.frames [1] .length=2NS
(top.frames[l].frames[l]=3) . ..
Если часть фреймовой структуры не существует, опе-
оператор if останавливает работу в этой точке и сценарий
выполняет альтернативное действие либо не выполняет
никаких действий вообще.
В ходе проверки наличия правильного документа код
может проверять помимо заголовка и другие свойства,
например, location.href фрейма. Вместо проверки заго-
заголовка документа или другого свойства можно присваи-
присваивать общей переменной в каждом документе уникальное
имя или номер и затем проверять эту идентифицирую-
идентифицирующую документ переменную.
Регистрация документов
Простая проверка присутствия требуемого документа в
случае больших сайтов может стать слишком сложной,
в этом случае проверку полной зафузки документа мож-
можно не проводить. Другой выход из ситуации состоит в
том, чтобы сами документы уведомляли, загружены ли
они. Используя события onLoad() и <mUnload(), доку-
документы регистрируют свое присутствие в переменной
topWindow или в cookie-набора. Следующий код пока-
показывает, что нет необходимости использовать заголовок
для идентификации документа; можно использовать
другое свойство или идентифицирующую переменную:
<BODY onLoad="top. funRecord(document.title) "
onUnload="top.funRemove(document.title)">
Объекты Frame
Приведенный ниже пример демонстрирует простую
схему регистрации документа. Первый фрагмент кода
содержит файл для установки верхнего фреймового окна:
<SCRIPT LANGUAGE="JavaScript">
<! —
var a4 = ""; // переменная для регистрационной
// строки документа
function funRecord{ // добавить документ в
// регистрационную строку при загрузке
а4 += а;
function JunRemove{ // удалить документ из
// регистрационной строки при выгрузке
а4 = а4.substring{ 0,a4.index0f ) +
а4.substring<a4.indexOf+a.length,a4.length) ;
function funCheck{ // проверка, зарегистрирован
// ли документ
if( a4.indexOf != -1) return true;
else return false;
I
// —>
</SCRIPT>
¦Следующий фрагмент кода показывает файл доку-
документа:
<HTML>
<TITLE>The Harley FXSTC</TITLE>
<SCRIPT IANGUAGE="JavaScript">
function ?unRegister{
// присутствует ли набор фреймов?
(top.document.title == "Main Frameset") )
if( a ="R") top. funRecord(document, title) ;
else top. funRemove(document.title) ;
}
function funCheck{ // зарегистрирован ли
// документ?
if( (top. length != 0 )&& (top. document. title =
"Main Frameset") )
return top . ? unCheck ;
else return false,-
</SCRIPT>
<BODY onLoad=" top. funRecord (document .title) "
onCInload=" top. funRemove (document .title) ">
Код, показанный ниже, проверяет, зарегистрирован
ли документ:
if( funCheck("The Softtail Series") )
top.frames[2].fxnames() ; // документ
// аарегистрирован, продолжить выполнение
else // документ не зарегистрирован,
// выполнить альтернативные действия
top.location.href =
"http://www.foo.com/fx.html";
Глава 18
Использование расширенных схем регистрации
Более сложные схемы регистрируют не только доку-
документ, но также и позицию документа в иерархической
структуре фреймов. Если позиция документа изменя-
изменяется из-за различных возможных сценариев загрузки
или модификации сайта, код, содержащий ссылки на
документ, может находить документ с использованием
информации о регистрации документа. Вместо приме-
применения одной переменной или cookie-набора для полу-
получения информации по регистрации, некоторые схемы
используют массив переменных, в котором каждый эле-
элемент (переменная) содержит идентификационную и
позиционную информацию для зарегистрированного
документа. Эти схемы сложны для установки, однако,
их гораздо выгоднее использовать при проектировании
очень больших сайтов, где маленькая ошибка в струк-
структуре может вывести из строя коды ссылок во многих до-
документах.
Набор фреймов hldaho (http://hidaho.com/frameset/) —
это схема регистрации, эффективная для больших, слож-
сложных фреймовых структур. Она регистрирует функции и
расположения функций во фреймовой структуре. Она
определяет расположение фрейма, передавая его имя
(self.name) родительскому фрейму, который присоединя-
присоединяет к этому имени свое собственное имя и передает да-
далее эту информацию родительскому фрейму. Процесс
продолжается все выше по родительским окнам, вплоть
до самого верхнего окна. Также имеется возможность
снятия регистрации заданной функции (все функции
должны иметь уникальное имя) и регистрации имени
фрейма (всех функций, расположенных в этом фрейме)
при закрытии документа.
В набор фреймов hldaho включена функция для про-
проверки, зарегистрирована ли указанная функция (она
возвращает false, если указанная функция не зарегист-
зарегистрирована), а также функция Ехес(), которая вызывает
другие функции и передает им параметры. Поскольку
все имена функции должны быть уникальны, разработ-
разработчик получает возможность вызова требуемой функции,
не зная ее расположения, и передачи параметров в нее
через Exec (function, parameter!, parameter2,...).
Обновления фреймов
Существенная выгода, которую дают фреймы, заключа-
заключается в возможности модификации документа во фрей-
фрейме, не затрагивая при этом другой фрейм. Независимо
оттого, обновляется ли фрейм с помощью ввода пользо-
пользователя в другом фрейме или модифицируется программ-
программно, существует несколько методов для внесения измене-
изменений в соответствующие фреймы. Эти методы могут
использовать HTML (с некоторыми расширениями
Netscape), JavaScript или комбинацию их обоих.
Использование DOM
Часть III
Ссылки
Возможно, самой простой методикой обновления сле-
следует считать использование ссылок для изменения те-
текущего фрейма (загружая новый документ). Для того
чтобы направить новый документ в другой фрейм, ис-
используют дескриптор якоря, имеющий атрибут target,
для которого можно определить значение имени фрей-
фрейма или относительное имя. Относительные слова (в
Netscape они называются magic target names) соответству-
соответствуют относительным свойствам окна, обсуждавшимся ра-
ранее. Относительные имена, применяющиеся для целе-
целевых ссылок, всегда начинаются с символа "_" и всегда
записываются в нижнем регистре. Эти имена — _top,
parent и _self — соответствуют свойствам окна top,
parent и self. Однако, не существует имени _window.
Следующий код представляет фреймы, в которых
ссылка в одном фрейме должна обновить другой фрейм:
COLS=0%,*">
<FRfiME SRC="docl.html" NMSE="framel">
<FRaMESET COLS=0%,*">
<FRAME SRC="frame2.html"
NAME="frame2">
<FRMffi SRC="doc3.html"
NAME="frame3">
</FRAMESET>
Файл frame2.html содержит дополнительную инфор-
информацию для установки фреймов в окне:
<FRSMESET ROWS="*,20%">
<FRSME SRC="doc4.html"
NAME="frame4">
<FRftME SRC=" doc5.html"
NAME=" frame5 ">
</FRAMESET>
Для загрузки нового документа в frame2 с помощью
ссылки в doc4.html (в frame4) эту ссылку записывают
следующим образом:
<А HREF="new.html" TARGET="_parent">
Для загрузки документа в верхнее окно и очистки
всех фреймов используют такую строку:
<А HREF="new.html" TARGET="_top">
Динамические ссылки
Поскольку ссылки в JavaScript являются объектами, а
href и target — свойствами ссылок, можно создать дина-
динамическую ссылку, присваивая другие значения href и
target:
<А HREF="#" TARGET= "_top"
onClick='this.href="new.html";
this.target="_self";'>
Для поддерживающих JavaScript браузеров документ
new.html загрузится в текущий фрейм; если же JavaScript
не поддерживается, то текущий документ загружается в
верхнее окно. (Спецификатор фрагмента, #, без URL и
якорного имени, или идентификатор фрагмента, ссы-
ссылается на текущий документ.) Переназначение свойств
ссылки href и target можно сделать более динамическим
путем объединения операторов присваивания с услов-
условным и другими операторами. В следующем примере при
использовании фреймов файл, устанавливающий фрей-
фреймы, загружается в родительское окно; если же фреймы
не используются, в окно загружается главный документ:
<А HREF="main.html" TARGET="_top"
ondick='if( top.length != О )
** {this. href=" frameset! . html" ;
^this . target="_parent"; }" >
Обратите внимание на кавычки; обработчик собы-
событий должен быть заключен в кавычки (двойные или оди-
одиночные).
Нет необходимости переназначать свойства href и
target для каждой динамической ссылки. В предыдущем
примере атрибут target можно установить в _parent.
Для нефреймовой версии _parent и top эквивален-
эквивалентны. Если пользователь имеет неподдерживающий фрей-
фреймы браузер, то атрибут target игнорируется. Пример мог
быть написан этот путь:
<А HREF="main.html" TARGET="_parent."
onClick='if( parent.length != 0 )
** {this .href="f ramesetl .html" ; } ' >
Дескриптор ссылки может стать довольно длинным
и громоздким, поскольку к его обработчику событий
добавляется все большее количество операторов. Для
упрощения ссылки можно использовать вызов функции:
<А HREP="main. html" TARGET="_top"
onClick=' this.href=theHref();
¦¦•this. target=theTarget () ; ' >
theHref() — пользовательская функция, которая вы-
вычисляет условие и возвращает соответствующее значение
для свойства href. Точно также theTarget() возвращает
соответствующее значение для свойства target. Эти фун-
функции должны вернуть значение независимо от того, яв-
является ли вычисленное условие true или false; только
неподдерживающий JavaScript браузер использует зна-
значения по умолчанию, установленные с помощью атри-
атрибутов TARGET и HREF. В качестве нефреймового аль-
альтернативного примера рассмотрим следующий код:
function theHref(){
if( top.length != 0 )
a = "framesetl.html";
else
a = "main.html";
return a ;
I
Аналогично можно создать theTarget(). Таким же
образом используют функции для других ссылок на стра-
Объекты Frame
яйце, передавая соответствующие URL и целевые име-
имена в вызовы функций. Возможно также для большого
количества ссылок использовать одну-две универсаль-
универсальных функции.
Часто динамические связи не нужны. Как правило,,
страница загружается в текущий фрейм, либо ссылка
появляется в навигационном меню, которое не видимо
в нефреймовой версии и всегда предназначается для
определенного фрейма. Однако, в тех немногих случа-
случаях, когда динамические ссылки необходимы, они ока-
оказываются весьма эффективными. К тому же, поддержка
фреймовой и нефреймовой версий — не единственный
случай, где динамические ссылки бывают нужны; эти ссыл-
ссылки можно устанавливать в любом случае, по желанию.
Свойство location.href
Другой способ обновления фрейма, который не обяза-
обязательно требует применения ссылок, связан с использо-
использованием свойства href объекта Location. Это свойство
можно также применять вместе с обработчиком событий
кнопки формы или с функцией. Не путайте объект Location
со свойством location документа, document.location — свой-
свойство только для чтения, однако можно записывать значе-
значения в window.location.href. Следующие операторы экви-
эквивалентны и модифицируют текущий фрейм, содержащий
начальную страницу http://www.mcp.com/:
location.href = "http://www.mcp.com/";
self.location.href = "http://www.mcp.com/";
window.location.href = "http://www.mcp.com/";
Следующие операторы обновляют, соответственно,
родительское и верхнее окно:
parent.location = "http://www.mcp.com/";
top.location = "http://www.mcp.com/";
Вместо использования относительных свойств
Window можно использовать имя фрейма:
parent.frame3.location.href = "http://www.mcp.com/";
В дополнение к записи свойства href можно также
записывать свойство pathname объекта Location, которое
позволяет определять путь или имя файла от корневого
каталога сервера. (Конечно, имя хоста, равно как и про-
протокол и порт, не зависят от текущей страницы сайта.)
Для загрузки документа http://www.abc.com/foo/
doc2.html в framel, который в настоящее время имеет
адрес: http://www.abc.com/index.htm, используется следу-
следующий код:
framel.location.pathnames"/foo/doc2.html";
Однако, если текущий документ находится по адре-
адресу http://www.def.org/home.html или ftp://ftp.abc.com/
pub/abc.txt, необходимо задействовать свойство href.
Глава 18
Метод write()
Третий способ обновления фрейма состоит в примене-
применении методов write() или writeln(). JavaScript может ди-
динамически генерировать документ во фрейме:
<HTML>
<HEAD>
<TITLE>Updating Demo Frameset</TITLE>
</HEAD>
<FRAMESET COLS=0%,*">
<FRftME SRC="docl.html" NftME="framel">
<FRAME SRC="doc2.html" NM4E="frame2">
</FRAMESET>
</HTML>
Файл docl . html
Файлом docl.html может быть любой файл, даже пу-
пустой. Однако, во избежание ошибки "Document contains
no data" ("Документ не содержит данных") в файл необ-
необходимо поместить, по крайней мере, пробел или символ
возврата каретки.
Динамически загружаемый фрейм может взаимодей-
взаимодействовать с пользователем с помощью ссылок или форм:
<HTML>
<HEAD>
<TITLE>Updating Demo framel</TITLE>
<SCRIFT LMJGUAGE=" JavaScript ">
<; —
function docWrite () {
top.frame2.document.clear();
top. Irame2 .document. write("<HTMLXHEAD>" +
"<TITLE>Dpdating Demo f rame2</TITLE>" ) ;
top . frame2 . document. write (" </HEADXBODY
k-»BGCOLOR=\"" -I- document.forml.bginput.value +
"\">");
top.frame2.document.write("<Hl>Updated Page
top. frame2 .document.write ("Update by " +
document.forml.inputl.value);
top. frame2. document, write < "</ВОБУХ/НТМЦ»';
top. f rame2. document, closet) ¦
</SCRIPT>
</HEM»
<BODY>
<FOKM NAME="forml"
<INPUT TYPE="TEXT"
NaME="inputl">
Select a Background Color<BR>
<INPUT TYPE="RM)IO" NftME="radiol" VALUE="white"
CHECKED
onClick= ' document. f orml .bginput. value=
"white"'>White<BR>
<INPUT TYPE="RADIO" NAME="radiol" VALUE="red"
onClick='document.forml.bginput.value=
"red" '>Red<BR>
<INPUT TYPE="RADIO" NAME="radiol" VALUE="blue"
onClick= ' document. forml. bginput. value=
"blue"'>Blue<BR>
<INPUT TYPE="RAD10" NAME="radiol" VALUE="green"
onClick=" document, forml. bginput. value=
Использование DOM
Часть III
'"green" ¦ >Green<BR>
<P>
<INPUT TYPE="HIDDEN" NftME="bginput" VALUE="white">
-CINPUT TYPE="BOTT0N" VALUE=" Update frame2"
onClick="doeWrite()">
</FORM>
</BODY>
</HTML>
JavaScript-код, используемый для обновления фрей-
фреймов, может оказаться очень сложным. Можно применять
условные операторы, вычисления или любой сценарий
для создания документа, обновляющего фрейм. Игры,
слайдовые демонстрации, карты изображений и резуль-
результаты выполнения запросов в базы данных — вот только
некоторые примеры использования обновлений фрей-
фреймов.
Кеширование файлов
Загрузочные модули, которые требуется включить в об-
обновляемый фрейм, могут заранее кешироваться для пре-
предотвращения загрузки еще немодифицированного фрей-
фрейма. Для кеширования изображения до момента, когда
в нем возникнет необходимость, используют объект
Image. Однако, этот объект недоступен в ранних верси-
версиях JavaScript-браузеров. Другая методика загрузки изоб-
изображения предполагает использование документа в скры-
скрытом фрейме:
<HTML>
<HEAD>
<TITLE>Hidden Frame to Cache Images</TITLE>
</HEAD>
<FRSMESET COLS=00%,*">
<FRAME SRC="docl.html" NAME="?ramel">
<FRAME SRC="cache.html" NftME="frame2">
</FRAMESET>
</HTML>
Следующий код — это неотображаемый документ,
предназначенный только для загрузки изображений, что
обеспечит запись изображений в кеш:
<HTML>
<HEAD>
<riTLE>Updating Demo framel</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var al
0;
</SCRIFT>
</HEAD>
<EODY onLoad="al = 1;">
<IMG SRC="imagel.gif" WIDTH=100 HEIGHT=200>
<IMG SRC="image2. jgp" WIDTH=300 HEIGHT=120>
<IMG SRC="iinage3.gif" WIDTH=2 00 HEIGHT=200>
</BODY>
</HTML>
iB дескрипторах изображений необходимо указывать
размеры для предотвращения проблем, возникающих
при выполнении сценария в разных версиях браузеров.
Несмотря на то что с дескрипторами изображений
обычно советуют использовать атрибут alt, этот атри-
атрибут в данном случае не обязателен, поскольку документ
не должен отображаться в каком-либо браузере, в том
числе и неграфическом.
Переменная al — это флажок, который устанавли-
устанавливается после полной загрузки изображения. Использо-
Использовать этот флажок необязательно, но полезно для предот-
предотвращения выполнения сценария модификации фрейма
до полной загрузки изображений:
if(top.frame2.al !=1 )
alert ("Please wait,
^downloading");
>
elsef
images are still
, . .оставшаяся часть сценария
Сценарии для фреймов с картами
изображений
В Netscape Navigator 2.0 была введена поддержка кли-
клиентских карт изображений (хотя Netscape — не первый
браузер, который стал это делать) наряду с фреймами
и JavaScript. Клиентские карты изображений (Client-side
imagemaps, CSIM) обеспечивают существенную выгоду
по сравнению с существовавшими ранее серверными
картами изображений. С помощью CSIM можно вклю-
включать файл карты как отдельный файл в документ с изоб-
изображением или ссылкой на него. Потребуется только
отправить запрос на сервер для обработки и перенаправ-
перенаправления на соответствующий URL. Пользователи будут
видеть в строке состояния URL-адрес, связанный с кар-
картой. Кроме того, CS1M можно использовать вместе со
старыми серверными картами изображений с целью
обеспечения совместимости со старыми браузерами.
Свойства карт изображений
С картами изображений связаны несколько объектов и
свойств. Дескрипторы области изображения на карте яв-
являются объектами JavaScript. Атрибуты href и target -
свойства объекта Area, которые можно изменять про-
программно через JavaScript. Объект Area содержит обработ-
обработчики событий onClick, onMouseOver и onMouseOut.
Фактически, объект Area имеет те же свойства и собы-
события, что и объект Link. Дескриптор области имеет еще и
атрибут nohref, который предотвращает загрузку URL
документа, присвоенного атрибуту href.
Объекты Frame
JS ПРИМЕЧАНИЕ ЙЧ
Объекты и свойства карты изображений в ранних вер-
версиях JavaScript-браузеров были не доступны. Объект
Area и его свойства появились в JavaScript 1.1. Кро-
Кроме того, в JavaScript 1.1 обработчик событий onClick
и атрибут nohref не функциональны для всех платформ.
Ссылки на объекты Area
На объекты Area можно ссылаться с помощью массива
links. Массив links содержит все объекты Link и Area в
документе. Нумерация элементов начинается с нуля.
Следующий код демонстрирует пример документа со
ссылкой и CS1M.
<HTML>
<HEAD>
<T1TLE>CSIM DEMtX/TITLE>
</HEAD>
<BODY>
<A HREF="docl.html" target="?rameA">The Softtails
<MAP NAME="mapl">
<A NAME="areaA" COORDS=0 ,20 , 80 , 80"
HREF="doc2 .html" TARGET="f rameA">
<A NAME="areaB" COORDS=00,20,180,80"
HREF="doc3 .html" TARGET="frameA">
<A NAME="areaC" COORDS=0 , 100 , 80 ,180"
HREF="doc4 .html" TARGET="frameA">
<A NAME="areaD" COORDS=00 ,100,180, 180"
HREF="doo5 .html" TARGET="frameA">
</MAP>
<1MG SRC="mapl.gifn WIDTH=200 HEIGHT=200
ALT="Menu" USEMAP="#mapl">
< t ~- Код для альтернативных серверньк карт
изображен!^ и текстовых меню для
неграфических браузеров попросту опущен -->.
</BODY>
</HTML>
В приведенном выше примере ссылка упоминается
k;i к document.links[0], поскольку это первый дескриптор
ссылки или области в документе. На область агеаАссы-
агеаАссылаются как на document.lmksf 1], т.к. это второй дескрип-
дескриптор ссылки или области, агеаВ — это document.links[2],
агеаС — document.links[3] и, наконец, areaD —
document. links[4].
На свойства href и target объектов Area, как и в слу-
случае с объектами Link, можно ссылаться и присваивать им
новые значения через массив links. Следующая строка
кода изменяет значение свойства пгегдля агеаВ так, что-
чтобы при нажатии на его область карты изображения вме-
вместо doc3.html загрузился бы документ doc6.html:
document. link [2 ]. href="doc6. html"
Аналогично можно изменять свойство target:
document.link [2].target="frameB"
Свойство и атрибут target должны определяться как
имя фрейма или одно из специальных относительных
слов фрейма (_top, _parent, _self или _blank), но не как
JavaScript-свойства (top, parent и т.п.).
Глава 18
Можно открывать и устанавливать имена новым ок-
окнам, присваивая target имя, которое уже не использу-
используется. Новое окно, открытое таким способом, будет
иметь имя, указанное в качестве значения атрибута
target.
Вызов функции
Дескрипторы области не всегда должны ссылаться на
документ. Можно осуществлять вызов функции, приме-
применяя протокол javascript:, за которым следует имя функ-
функции:
<А NAME="areaA" COORDS=0,20,80,80"
HREF="javascript:funl () ">
Данный сценарий вызовет вместо документа опреде-
определяемую пользователем функцию funl(). Можно также
использовать методы и операторы JavaScript. Эта мето-
методика особенно эффективна для фреймовой версии сай-
сайта, в которой серверная карта изображений представле-
представлена в виде навигационной кнопочной панели. Функция
может включать различные операторы, предназначенные
для определения использования фреймов и установки
некоторых флажков либо проведения вычислений или
оценок. Функция может тогда выполнять соответствую-
соответствующее действие, например, загрузку некоторого докумен-
документа, либо не выполнять никаких действий вообще.
Следующие фрагменты кода содержат простой сце-
сценарий слайдовой демонстрации с кнопочной панелью
для карты изображений, которая позволяет циклически
передвигаться вперед и назад в рамках последовательно-
последовательности слайдов. Карта изображений также содержит кноп-
кнопки возврата в меню, таким образом, пользователь может
выбрать другую слайдовую демонстрацию или вернуть-
вернуться на начальную страницу. Каждая слайдовая демонст-
демонстрация имеет имя последовательности, которое свою пер-
первую часть формирует из имен файлов слайдов. Вторая
часть имени файла — порядковый номер, уникальный
для каждого слайда в последовательности. Каждый из
файлов слайдов имеет три переменных: имя последова-
последовательности, порядковый номер слайда и общее количе-
количество слайдов в последовательности. Сценарий читает эти
три переменные, чтобы загрузить файл, опираясь на ту
часть карты изображений, которая была нажата.
Следующий фрагмент кода устанавливает фреймы:
<HTML>
<HEAD>
<TITLE>Slide Show Main Frameset</TITLE>
</HEAD>
<FRAMESET ROWS="+,55">
<PRAME SRC="slidel.html" NAMK="frameA">
<FRAME SRC="button.html" NAME="f rameB">
</FRAMESET>
</HTML>
Ниже приведен код из файла slidel:
<HTML>
Использование DOM
Часть III
<HEAD>
<TITLE>Slide Show - First Slide</TITLE>
<SCRIPT bANGUAGE="JavaScript">
var al = "slide";//первая часть имен файлов
//слайдов
var a2 = 1;// номер последовательности
var аЗ = 3;// количество слайдов
// -->
</SCRIPT>
</HEAD>
<BODY>
<IMG SRC="slidel.gif" WIDTH=300 HEIGHT=20Q
ALT="The 1992 FXSTC, Softtail Custom">
</BODY>
</HTML>
Следующий фрагмент содержит файл кнопочной
панели:
<НТМ1>
<НЕМ»
<TITLE>Slide Show Demo Image Map</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function funl {
al = top. frames [0] .al; // корневое имя файла
// series последовательности слайдов
а2 = top. frames [ 01 . а2; / / номер
// последовательности
аЗ = top.frames[0] . аЗ; // количество слайдов
if{ a = "?" )
if(a2 = аЗ>
а2 = 0;
if ( а = "г" )
if(a2 = 1)
а2 = аЗ - 1;
else
а2 я а2 - 2;
а2 = а2 + 1;
al += а2;
al += ".html";
top.frames[0].location.href = al;
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR=" 000000">
<MAP NBME="mapl">
<AREA COORDS=,1,75,50"
HREF='javascript:funl("f") '
onMouseOver="window.status="Cycle forward
wthrough slide show";
'¦return true'>
<AREA COORDS=6,1,150,50" HREF="menu.html"
TARGET= " f rameA"
onMouseOver='window.status="Return to Menu
wto Select Another Slide Show";
" re turn true'>
<AREA COORDS=51,1,225,50" HREF="home.html"
TARGET»"_top"
onMouseOver='window.status="Quit Slide Show
4and Return to Home Page";
^return true'>
<AREA COORDS=26,1,300,50"
HREF='javascript:funl("r")'
onMouseOver='window.status="Cycle backward
"• through slide show";
'"return true' >
</MAP>
<IMG SRC="buttons.gif" WIDTH=300 HEIGHT=50
USEMAP="#mapl ">
</BODY>
</HTML>
Работа с фреймовыми URL
Нет никаких принципиальных различий между URL
фреймовых и нефреймовых документов. В случае фрей-
фреймового окна, однако, можно заходить на различные сай-
сайты и использовать различные базовые HREF. Один
фрейм может содержать документ из одного каталога на
сервере, другой фрейм — документ из другого катало-
каталога, а третий фрейм может загружать документ вообще
из другого сервера. Независимо от конкретного фрейма,
к относительному URL в ссылке обращаются из доку-
документа, содержащего ссылку. Можно использовать дес-
дескриптор <BASE>, <BASE HREF="http://www.foo.com/
some.html">, в документе, чтобы установить все ссылки
для базового HREF. Базовый HREF можно отменить,
помещая в ссылку абсолютный URL.
Как и в случае атрибута HREF дескриптора <BASE>,
можно определить базовый целевой фрейм <BASE
TARGET="frameA"> направляет все ссылки в докумен-
документе на указанный фрейм. Можно также отменить базо-
базовый целевой фрейм с помощью атрибута TARGET в ссыл-
ссылке. Например, <HREF="some.html"TARGET="_self>
отменяет целевой фрейм и загружает документ в соб-
собственный фрейм.
^ПРИМЕЧАНИЕ" -'-'ft
Дескриптор <BASE>, <BASE HREF="some.html"
TARGET="someframe">, необходимо помещать в раз-
раздел <HEAD> документа. Для дескриптора <BASE>
не предусматривается какое-либо содержимое и не
существует закрывающего дескриптора <BASE>. Этот
дескриптор с атрибутами HREF и TARGET показан в
¦следующем примере:
<HTML>
<HEAD>
<TITLE>Base Demo</TITLE>
<BASE HREF="http://www.fqo.com/home.html"
TARGET=" f rameA" >
</HEAD>
<BODY>
Дополнительную информацию относительно исполь-
использования URL в фреймах можно найти в этой главе, в
основном, в следующем разделе и в разделе "Обновле-
"Обновление фреймов".
Ссылки на фреймы
При работе с фреймовыми окнами в прикладных про-
программах JavaScript, вероятно, потребуются другие спо-
способы ссылок на окна. JavaScript обеспечивает четыре
Объекты Frame
вида ссылок на окна. Каждый вид реализован как свой-
свойство объекта Window.
!¦
ПРИМЕЧАНИЕ"
т.
Отдельные окна браузера не имеют иерархической
структуры; однако при ссылках на окно, содержащее
код, который открывает другое окно, его зачастую на-
называют родительским элементом. Новое открытое
окно при этом называют дочерним. Любое новое окно
может назначать переменную в других окнах, чтобы
другие окна могли ссылаться на данное окно и его
свойства. Для ссылки на свойство в новом окне про-
просто используют windowName.property.
Рассмотрим следующий код:
newWindow = window.open();
newWindow.location.href = "http://www.incp.com/","
Хотя этот фрагмент и не обеспечивает наиболее эф-
эффективный способ записи кода, он демонстрирует
способ ссылки на свойство дочернего окна. Новое
окно было открыто и получило имя (в данном случае,
newWindow). Затем было присвоено значение
location.href нового окна.
Ссылки на текущее окно
В главе 9 обсуждалось использование window для ссылок
на текущее окно. Однако, тогда не было сказано, что
объект Window также содержит свойство под названием
window, которое может служить инструментом для ссыл-
ссылки на само себя. Кроме того, свойство self объекта Window
— это еще одно средство для ссылок на текущее или
активное окно. Например, следующих две строки кода
программы функционально эквивалентны:
window, defaultstatus = "Welcome to the Goat
Farm Home Page"
self .defaults tatus = "Welcome to the Goat Farm
Home Page"
Поскольку как window, так и self — синонимы теку-
текущего окна, может показаться странным, что оба они
включены в язык JavaScript. Как было показано в пре-
предыдущем примере, объяснение этому — гибкость; по же-
желанию можно использовать как window, так и self.
Однако, насколько полезными могут быть window и
self, настолько же они могут привести к путанице, если
подойти к этому логически. В конце концов, свойство
объекта, которое используется как эквивалентный тер-
термин для самого объекта, довольно необычно. Следова-
Следовательно, будет удобнее считать window и self для объекта
Window зарезервированными словами, а не свойствами.
Поскольку window и self — свойства объекта Window,
нельзя использовать и window, и self в одном и том же
контексте. Например, следующий код работать не будет:
window.self.document.write("<hl>Test.</hl>")
Наконец, в мультифреймовых средах window и self
всегда относятся к окну, в котором выполняется JavaScript-
код.
рРИМЙЧАНЙЕ
В некоторых объектно-ориентированных или основан-
основанных на объектах языках self может относиться к ак-
активному объекту, независимо от его типа. В JavaScript
self относится только к активным объектам Window
или Frame — и ни к чему больше.
Ссылки из родительского фрейма на дочерний
Родительский фрейм может ссылаться на свой дочерний
фрейм одним из двух способов. Во-первых, можно ис-
использовать имя фрейма, которое определяется в парамет-
параметре NAME дескриптора <FRAME>. Например, в следу-
следующем коде переменная myFrameFlicka ссылается на имя
фрейма frameA:
<HEAD>
<TITLE>Parent to Child Demo</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function childCall() {
var myFrameFlicka = self.frameA.name
</SCRIPT>
</HEAD>
<FRAMESET COLS=0%,*">
<FRAME SRC="docl.html"
<FRAME SRC="doc2.html"
</FRAMESET>
</HTML>
KAME="frameA">
NAME="frameB">
Во-вторых, можно ссылаться на дочерний фрейм,
используя массив frames. Каждый фрейм в окне, или
родительский фрейм, является элементом массива. На
элементы массива frames ссылаются помощью frames [i],
где i — число, соответствующее порядковому номеру
фрейма в родительском окне. Фреймы пронумерованы
от нуля до числа, на единицу меньшего общего коли-
количества фреймов. Следующий код определяет четыре
фрейма:
<FRAMESET R0WS=5%,25%,25%,25%">
<FRAME SRC=" docl.html" NAME="f rameA">
<FRAME SRC="doe2.html" NAME="frameB">
<FRAME SRC="doo3.html" NAME="frameC">
<FRAME SFC="doc4.html" NAME="frameD">
</FRAMESET>
Следовательно, массив frames данного окна будет
содержать четыре элемента:
frames [0 ] для фрейма frameA
frames [1] ДЛЯ фрейма frameB
frames [2] для фрейма frameC
frames [3] ДЛЯ фрейма frameD
Обратите внимание, что при ссылках на элемент
массива frames в конце слова frames[i] присутствует "s",
что указывает на множественное число.
Использование DOM
О Часть
Ссылки из дочернего фрейма на
родительский
Как было показано в данной главе, фреймы — это те же
самые объекты Window, но внутри содержащего фреймы
окна. Внутри мультифреймового окна возникает необ-
необходимость различать между собой фреймы, отображае-
отображаемые в браузере. Свойство parent объекта Window помо-
помогает это делать, ссылаясь на родительское окно — окно,
содержащее определение <FRAMESET>. Например,
если требуется получить некоторую информацию о те-
текущем родительском окне, используйте пример из лис-
листинга 18.1.
Листинг
18.1.
childWindow.htm.
<html>
<head>
<title>Child Window</title>
</head>
<SCRIPT LANGUAGE="JavaScript">
< ! —
function getParentlnf о ( ) {
myParentTitle = parent, document, title
alert ("My daddy's name is " +
myParentTitle)
</SCRIPT>
<form>
< input
type="button"
value="Get Info"
onClick="getParentInfо О">
</form>
< /body>
</html>
Кроме получения значений свойств, можно также
обращаться к методам родительского окна. Например,
листинг 18.2 содержит исходный код HTML для роди-
родительского окна фреймов с методом showlnfo(), опре-
определенным без внутренней реализации. Листинг 18.3
показывает, как дочернее окно получает доступ к это-
этому методу. Когда пользователь нажимает на объект
childButton, его обработчик событий onClick вызывает
runDadMethod() с передачей ключевого слова this в ка-
качестве параметра. В свою очередь, runDadMethod() вы-
вызывает метод showlnfo() объекта parent, передавая в па-
параметре имя текущего объекта. На рис. 18.14 показан
результат.
Листинг
18.2.
parentWindow.htm.
<html>
<head>
<title>Parent Window Title</title>
<SCRIPT IANGUAGE="JavaScript">
function showlnfo(objectName)
alert(objectName)
</SCRIPT>
< /head>
<Frameset Cols=5%,65%">
<Frame Name = "FRAME1" SRC="childWindow.htm">
<Frame Name = "FRAME2">
</Frameset>
</html>
СОВЕТ
Для определения пустого фрейма следует престо опу-
опустить атрибут SRC в конструкции <FRAME>.
Листинг 18.3. anotherChildWindow.htm. _
<html>
<head>
<title>Child Window</title>
</head>
<SCRIPT IANGUAGE="JavaScript">
function runDadMethod(curObject) {
parent, showlnfo(curObject .name)
</SCRIPT>
<form>
<input
type="button"
name="childButton"
value="Run Dad's Method"
onClick="runDadMethod(this)
</form>
</body>
</html>
РИСУНОК 18.5. Вызовметода изродительского окна.
Родительское окно зачастую представляет собой са-
самое верхнее окно в мультифреймовой оконной среде, но
это не обязательное требование. Существует также воз-
возможность вкладывать разноуровневые коды установки
фреймов друг в друга, как будет показано ниже, при
Объекты Frame
обсуждении свойства top. Поэтому свойство parent ссы-
ссылается на непосредственное родительское окно текущего
окна. При необходимости обратиться к родительскому
окну следующего уровня используют строку вида:
myGranddadTitle = parent.parent.document.title
В более сложных фреймовых структурах на любой
из фреймов можно ссылаться, используя их позицию в
иерархии фреймов, как показано на рис. 18.6 и в табл.
18.2.
top window
frameA frame В frame С frame D frame E
frameEA frameEB
frameBA frameBB
I
frameBBA frameBBB
РИСУНОК 18.6. Иерархическая структура сайта с
вложенными фреймами.
Таблица 18.2. Ссылки на другие фреймы из
frameBBB.
Фрейм
Ссылка
frameA
frameBA
frameBB
frameEA
top.frameA или top.frames[0]
top.frames[1].frameBA или
top.frames[1].frames[0]
parent, top.frames[1].frameBB или
top.fratnes[1 ].frames[1 ]
top.frames[4].frameEA или
top.frames[4].frames[0]
Приведенная ниже строка используется для ссылки
на заголовок документа в frameEA и присвоения его
переменной al:
al — top.frames[4].frames[0].document.title;
На другие свойства ссылаются совершенно аналогич-
аналогично.
ПРИМЕЧАНИЕ
Важнс обратить внимание на различия в иерархии,
которые могут существовать между двумя похожи-
похожими на вид фреймовыми структурами, как было пока-
показано в разделе "Создание фреймов" ранее в главе.
В JavaScript версии 1.1 и выше появилось свойство
opener, которое обычно ссылается на окно (родительс-
(родительское), из которого было открыто текущее окно. Из ново-
нового (дочернего) окна можно ссылаться на свойство от-
открывшего его родительского окна через top.opener,
property.
Для ссылки на родительское окно из нового откры-
открытого окна в JavaScript 1.0 можно прибегнуть к методике
Глава 18
присваивания. Обычно здесь используют свойство top
объекта Window; однако, в случае необходимости вмес-
вместо top можно использовать self, parent или window. В
следующем фрагменте кода используется свойство top,
поскольку код должен появляться в любом из фреймо-
фреймовых окон. Использование top гарантирует, что соответ-
соответствующее свойство окна верхнего уровня будет иденти-
идентифицировано, self, parent или window может означать
любой фрейм в окне верхнего уровня.
newWindow = window, open("docl.html") ;
newWindow. oldWindow = top;
Используйте приведенный ниже синтаксис для ссыл-
ссылки на свойство в открывшем окне из открытого нового
окна:
top.oldWindow.proper ty
Использование ссылок из дочернего окна на
дочернее окно
Свойство parent важно не только для доступа к родитель-
родительскому окну из дочернего, но также и для ссылки на
любой другой объект в одном из дочерних окон того же
уровня. Как показано на рис. 18.7, любая связь между
дочерними фреймами должна быть реализована через их
родительское окно.
На фреймы одного уровня с разными родительски-
родительскими окнами необходимо ссылаться, используя их абсо-
абсолютную позицию в иерархической структуре:
<FRAMESET COLS=0%,*">
<FRAME SRC="docl.html" KAME="frameA">
<FRAME SRC="doc2.html" HAME="frameB">
</FRAMESET>
В этом примере OKHoframel ссылается на значение кнопки '»: в окне
frame2. Данное окно может сделать это с помощью свойства parent:
buttonLabel = parent.frame2.documentform[0].okButton.value
РИСУНОК 18.7. Использование свойства parent для ссылок па
элементы того же уровня.
Использование DOM
Часть III
Следующий фрагмент содержится в docl.html:
-«FRAMESET ROWS=0%,*">
<FRSME SRC="doc3.html" NaME="frameAA">
<FRAME SRC="doo4.html" ЫЙМЕ=" frameAB ">
</FRAMESET>
Следующий фрагмент содержится в doc2.html:
<FRAMESET ROWS=0%,*">
<FRAME SRC=" doe5.html" NSME="frameBA">
<FRAME SRC="doc6,html" NAME="?rameBB">
</FRAMESET>
framt'BB ссьглается на frameAB таким способом:
top.frames[0].frameAB
Можно также использовать следующую строку:
-top. frames [О] .frames [0 ]
Для межуровневых ссылок не существует промежу-
промежуточного уровня между верхним и родительским окном,
такого как "прародительское окно". Это, видимо, к луч-
лучшему, что родительское окно — единственный термин,
позаимствованный из генеалогии; представьте на секун-
секунду, что ссылка на фрейм выглядела бы как third, cousin,
twice, removed (игра слов: что-то типа "дважды убрать
третьего двоюродного брата").
Если окнам браузера в момент открытия всегда при-
присваиваются имена, для одного из новых (дочерних) окон
не будет проблемой сослаться на другое дочернее окно
через открывшее его (родительское) окно. В этом слу-
случае потребуется просто упомянуть имя окна, как было
показано в предыдущих разделах. Если окну в момент
открытия присвоено имя переменной myWindow, другое
дочернее окно может ссылаться на него таким способом:
top.opener.myWindow
Можно синхронизировать окна теми же методами,
которые применяются для фреймов. Однако, при отсут-
отсутствии единственного окна верхнего уровня браузера или
иерархии окон, одно окно, открывшее другие окна, вы-
выбирается в качестве точки синхронизации. Следующий
фрагмент кода — это пример сценария синхронизации
окон:
<HTML>
<TITLE>The Harley FXSTC</TITLE>
OCRIPT LANGUAGE="JavaScript">
<!-- ¦
function ?unRegister{
// проверить, что страница находится в своем
// окне, а открывающееся окно содержит
/ / корректный документ
if( (top.name=="newWindowl"> &?
(top. opener .document.title="Main Frameset") )
if( a ="R")
top.opener.funRecord(document.title) ;
else top . opener. funRemove (document. title) ;
function funCheck{
// зарегистрирован ли
// документ
if ( <top.name=="newWindowl") &&
(top.opener.document.title=="Main Frameset")
re turn top .opener. f unCheck ;
else return false;
</SCRIPT>
<BODY onLoad="top. funRecord (document.title) "
onUnload="top. funRemove (document.title) ">
Следующая программа проверяет, зарегистрирован
ли документ:
if( funCheck("The Softtail Series")
newWindow2 . frames [2] . fxnames () ; // документ
II зарегистрирован, продолжить действия
else // документ не зарегистрирован,
// инициировать альтернативное действие
top. location.href =
"http://www.foo.com/fx.html";
Как и в случае фреймов, можно использовать более
сложные схемы для регистрации информации о распо-
расположении документа. В этих схемах применяются те же
самые сценарии, как и для фреймов, но с добавлением
еще одного уровня для включения отдельных ОКОН бра-
браузера.
Окно верхнего уровня
Подобно свойству parent в функции, свойство top объек-
объекта Window позволяет ссылаться на самое верхнее окно в
пределах мультифреймового окна или в наборе мульти-
фреймовых окон. При работе с одним мультифреймовым
окном свойства parent и top ссылаются на одно и то же
окно. Однако, если имеются вложенные уровни мульти-
фреймовых окон, top обращается только к окну самого
высокого уровня, a parent может ссылаться как на это,
так и на другое родительское окно.
* СОВЕТ ,
В окне верхнего уровня и родительских окнах удоб-
удобнее всего хранить глобальные методы.
Различие между данными окнами лучше всего про-
проиллюстрировать на примере. Предположим, что имеет-
имеется два набора фреймов. Первый набор фреймов делит
окно браузера горизонтально на фреймы, занимающие
80% и 20% пространства (как показано на рис. 18.8).
Второй набор фреймов разделяет на четыре квадранта
(показанные HajjHC. 18.9) нижнее, занимающее 20%,
подокно окна самого верхнего уровня.
Предположим, что для каждого дочернего фрейма
требуется получить заголовки его верхнего и родитель-
родительского окон. Для этого можно определить общую функ-
функцию с именем getNameQ, которая бы возвращала эту
информацию вызвавшему ее окну. Так же, как дочер-
дочерние окна могут обращаться к методам родительского
Объекты Frame
окна, все фреймы в мультифреймовом окне имеют дос-
доступ к методам окна верхнего уровня. Таким образом,,
окно верхнего уровня — это удобное хранилище для
функций, которая должна быть глобально доступна для
всех окон. Метод getName() определяется следующим
образом:
function getName (callingObject, relation,
parentName) {
callingObject.document.write ("My " + relation +
"'s name is " + parentName +".")
. htm
frmain.htm
bottomFrameset.htm I
Глава 18
Этот метод getName() вызывается дочерним фрей-
фреймом после загрузки. Его можно вызывать, помещая сле-
следующий код в каждом дочернем фрейме:
<SCRIPT LANGUAGE="JavaScript">
top. getName (self, "parent" ,
paren t.document.ti tie)
document.write("<p>")
top.getName (self, "top", top.document. title)
</SCRIPT>
Сценарий использует top для обращения к методу
getName(), использует self для идентификации себя в
качестве вызывающего окна, а также parent и top для
получения заголовков окон. На рис. 18.10 показан ре-
результат после загрузки фреймов.
Листинги 18.4, 18.5 и 18.6 содержат исходный
код для мультифреймового окна верхнего уровня
(topFrameset.htm), мультифреймового окна нижнего
уровня (bottomFrameset.htm) и одного из дочерних
фреймов нижнего уровня (bottomSubFramel.htm).
Листинг
18.4.
topFramesethtm. _
<HTML>
<HEAD>
<TITLE>Top-Level Frameset</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function getName(callingObject, relation,
parentName) (
callingObject. document, write ("My " +
relation + ' ' s name is " + parentName +
РИСУНОК 18.8. Мультифреймовоеокно верхнего уровня.
bottomFrameset.htm
bottomSubframe2.htm
РИСУНОК 18.9.Мультифреймовое окно нижнего уровня.
Параметр callingObject представляет окно, вызываю-
вызывающее функцию. Используя точечную нотацию, в преде-
пределах рассматриваемого окна можно выполнять команду
document.write. Параметры relation и parentName стро-
строки, обеспеченные вызывающим окном, но не управля-
управляемые в данной функции.
</SCRIPT>
</HEAD>
<FRAMESET ROWS="80%,20%">
<FRAME SRC=" frmain.htm"
NAME="main"
MARGINWIDTH=" 1 "
MARGINHEIGHT=" 1 " >
<FRAME SRC="bottomFrameset.htm"
NAME=" footnotes"
MARGINWIDTH=" 1 "
MARGINHEIGHT=" 1 " >
<NOFRAMES>
Warning text should go here for browsers with no
frame support.
<BODY>
</BODY>
</NOFRAMES>
</FRftMESET>
</html>
Листинг 18.5. bottomFrameset.htm.
<HTML>
<HEAD>
<TITLE>Lower-Level Frameset</TITLE>
</HEAD>
<FRAMESET COLS=4%,24%,24%,28%">
<FRRME SRC= "bottomSubframel. htm" >
<FRAME SRC="bottomSubframe2.htm">
<FRAME SRC="bottomSubframe3.htm">
Использование DOM
Часть III
<FRAME SRC="bottomSubframe4.htm">
</FRAMESET>
</HTML>
My partnt't nimt Is Top-Ltv»l Frameset.
My tops лвтч Is Top-Levei Frameset.
toy-top's name l>
Тор-Level Frameset
Mytop'snamels
Тор-Level Frames*
Mytop's name is
Top-Lev*"! Frameset
i
РИСУНОК 1&10. Свойства parent и top.
Листинг 18.6. bottomSubFrame1.htm.
<HTML>
<HEAD>
tnotes Frame in Bottom Frameset</TITIiE>
<SCRIPT IANGUAGE="JavaScript">
top.getName(self, "parent",
^•parent .document. title)
document.write("<p>")
top.getName(self, "top", top.document.title)
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>
ПРИМЕЧАНИЕ V
Возможная проблема, связанная со ссылками на до-
документы в других фреймах и окнах — ограничения си-
системы безопасности, которая не дает JavaScript дос-
доступа к свойствам документов другого сервера. Начиная
с Netscape Navigator 2.02, это ограничение было ре-
реализовано с целью защиты информации о списке по-
посещений пользователя, о паролях в HTML-формах,
структуре каталогов и других конфиденциальных эле-
элементах.
Netscape Navigator 3.0 обеспечивает меру безопасно-
безопасности, называемую data tainting (разрушение данных),
которая разрешает пользователям обращаться к до-
документам другого сервера без возможной угрозы для
системы безопасности. С технологией разрушения
данных код JavaScript может ссылаться и пользовать-
пользоваться свойствами документов из других серверов. Полу-
Полученные данные разрушаются (или портятся) так, что-
чтобы их невозможно было переслать на другой сервер
без пользовательского подтверждения (с целью обес-
обеспечения безопасности и секретности).
Более подробная информация о методике разрушения
данных находится в главе 35.
. ¦
Объект Location
Объект Location формирует URL текущей страницы. Он
имеет двойное назначение:
Устанавливает объект Location для перехода на но-
новый URL.
Извлекает определенные элементы URL и работает
с ними. Без объекта Location для получения необхо-
необходимой информации потребовалось бы выполнять оп-
определенные манипуляции над строкой URI...
Основная структура URL такова:
protocol/Vhostname: port pathname search hash
Типичный URL может выглядеть, например, так:
http://www.acadians.com/javascript/search/
"•Hats?qt=RFC+1738fScol=XL
Свойства объекта Location, каждое из которых явля-
является элементом URL, сведены в табл. 18.
Таблица 18.3. Свойства объекта Location.
Атрибут Описание
HREF Полный URL.
PROTOCOL Начальный элемент URL (информация до
двоеточия).
HOSTNAME Хост и имя домена либо IP-адрес.
HOST Элемент Hostname:port (Имя хоста:порт) из
URL
PORT Коммуникационный порт сервера.
PATHNAME Элемент пути URL.
SEARCH Часть определения запроса URL (ь
с символа "'»
HASH Якорное имя URL (начинается с символа "#").
ПРИМЕЧАНИЕ
Важно отличать объект Location от свойства location
объекта Document. Значения объекта Location изменять
можно, а свойство location объекта Document предназ-
предназначено только для чтения.
Открытие нового URL
Вместо использования специального метода перехода к
новому URLb окне, можно просто открыть новый URL,
установив значение объекта Location. Интересно заме-
заметить, что это можно сделать, присваивая значение URL
объекту непосредственно или же присваивая данное
значение свойству href объекта Location. Например, сле-
следующих две строки выполняют одно и то же действие:
Объект/ Frame
window.location = "http://www.acadians.com/"
window.location.href = "http://www.acadians.com/"
Для создания с помощью JavaScript окна редактиро-
редактирования URL, можно использовать код, приведенный в
листинге 18.7.
Листинг 18.7. moveTo.htm.
<HTML>
<HEAD>
<SCRIPT LANGUAGE
"JavaScript">
function moveon() {
var urlAddress =
urlAddress = document.forms[0].Editl.value
window.location = urlAddress
3
</SCRIPT>
</HEAD>
<BODY>
<FORM>
<INPOT type="text" name="Editl">
<INPUT type="button" value="move"
onClick="moveon()">
</FORM>
</BODY>
</HTML>
В мультифреймовых окнах можно определить значе-
значение объекта Location в других фреймах, ссылаясь на со-
соответствующее имя окна. Например, рис. 18.11 демон-
демонстрирует мультифреймовое окно, в котором можно
изменять URL с помощью ввода текста в форму, распо-
расположенную в нижнем фрейме. Листинг 18.8 показывает
исходный код для этого нижнего фрейма.
[This page intentionally left blank.]
3rotocol//hostname:port pathname
Г
РИСУНОК 18.11. Использование объекта Location для
изменения URL другого фрейма.
Листинг 18.8. frfootno.htm
<html>
<head>
<title>Footnotes Frame in Location Object
Example</title>
<SCRI]?T LANGUAGE="JavaScript">
Глава 18
function gotoPageO {
parent.frames[O].location.href =
window.document.loc.ProtocolField.
options [window.document, loc.
"¦• ProtocolField.selectedlndex] . text
document.loc.HostnameField.value +
document.loc.PathnameField.value
i
</SCRIPT>
</head>
<body>
<pXfont size=5>protocol//hostname:port pathname
</fontX/p>
<form name="loc" method="POST">
Hostname: Pathname:
<select name-"ProtocolField" size=l>
<option>http://</option>
<option>file://</option>
<option>javascript:</option>
<option>ftp:</option>
<option>mailto:</option>
<option>gopher:</option>
<option>about:</option>
</select> <input
type=text
size=23'
maxlength=256
name="HostnameField"
value="www.typehere.com"> <input
type=text
size=20
maxlength=100
name="PathnameField"
value="/"> <input
type=button
name="Go"
value="Go"
onClick="gotoPage() "X/pre>
</form>
</body>
</html>
Работа со свойством protocol
Свойство protocol объекта Location позволяет определять
тип текущего URL. Таблица 18.4 содержит часто ис-
пользуемыепротоколы.
Таблица 18.4. Протоколы объекта Location.
Тип URL Протокол
Web
File
FTP
MailTo
Usenet.
Gopher
JavaScript
Navigator
http:
file:
ftp:
imailto:
news:
gopher:
javascript
about:
Использование ЮМ
Часть III
Объект History
Все, кто много времени провел в Web, вероятно, знако-
знакомы со списком посещений браузера. Также, как список
посещений позволяет пользователю возвращаться на
посещенные сайты, так же объект History в JavaScript
позволяет JavaScript-разработчику переходить к ранее
посещенным Web-страницам. Объект History не имеет
никаких событий, а только свойства и методы, перечис-
перечисленные в табл. 18.5 и 18.6.
Таблица 18.5. Свойства объекта History.
Свойство
Описание
current URL текущего документа.
length Длина списка посещений.
next Следующий URL в списке посещений.
previous Предыдущий URL в списке посещений.
Таблица 18.6. Методы объекта History.
Метод
Описание
Васк() Загружает предыдущий документ из списка
посещений.
Forward() Загружает следующий документ из списка
посещений.
Go() Переходит кзаданномудокументу.
Go(n) Если л> 0, загружает документ, который
находится на л пунктов дальше в списке
посещений.
Go(string) Загружает документ из списка посещений,
URL которого содержит указанную строку.
Определение размеров списка
Для определения количества посещений в списке мож-
можно использовать свойство length объекта History. Пред-
Предположим, что требуется отследить число посещений пра-
правого фрейма мультифреймового окна. Левый фрейм
содержит следующий код:
<HTML>
<HEAD>
<SCRIPT LANGUAGE
= "JavaScript">
function moveon() {
var urlAddress = ""
urlAddress =
document. forms [ 0] . Editl. value
parent.frames[1] .location = urlAddress
document.forms[0].Edit2.value =
parent.frames[1].history.length
</SCRIPT>
</HEAD>
<B0DY>
<FOKM>
type="textn name="Editl">
<INPUT type="button" value="move"
onClick="moveon()">
<IMPUT type="text" name="Edit2">
</FORM>
</B0DY>
</HTML>
Пользователь может применять текстовый объект
Editl для ввода целевого URL. Когда пользователь щел-
щелкает на кнопке "Move" для перехода на указанный URL,
текстовый объект Edit2 изменяется и отображает длину
списка посещений правого фрейма.
Навигация по списку посещений
Одно знание длины списка посещений редко оказыва-
оказывается особо полезным, однако оно может принести боль-
больше пользы, если требуется перемещаться по списку с
использованием объекта History.
Перемещение на одну страницу назад
Метод back() функционально эквивалентен щелчку на
кнопке "Back" (стрелка влево) в инструментальной па-
панели браузера. Например, следующий код перемещает
окно в его предыдущую позицию:
window.history.back()
Перемещение на одну страницу вперед
Как и следовало ожидать, метод forward() — то же, что
и щелчок на кнопке со стрелкой вправо в инструмен-
инструментальной панели браузера. Этот метод используется ана-
аналогично:
window.history.forward{)
Переход к указанной странице по номеру в списке
Метод go() используется для перехода к определенно-
определенному месту в списке посещений. Его синтаксис таков:
[window. ] history .go <delta | "location")
Параметр delta — положительное или отрицательное
целое число, которое определяет количество шагов пе-
перехода. Например, следующая строка — это переход к
следующему документу в списке посещений (эквива-
(эквивалент использования метода forward()):
window.history.goA)
Таблица 18.7 содержит возможные значения delta.
Таблица 18.7. Значения delta.
Метод'
Описание
delta < 0 Перемещает назад на delta пунктов.
delta > 0 Перемещает вперед на delta пунктов.
delta = 0 Перегружает текущий документ.
Объекпи Frame
Переход куказанной странице по строке в списке
В качестве альтернативы можно использовать параметр
location для определения заданного URL в списке. Об-
Обратите внимание, что здесь не нужен точный URL, a
только подстрока. Следующий пример позволяет пере-
перемещаться к URL в списке посещений, который содер-
жит\?\те.аса<Цап8.сот/Шепе\?:
window.history.go("www.acadians.com/filenew")
В приведенный выше пример можно добавить back(),
forward() и go() для обеспечения более полной функци-
функциональности мультифреймовой системы навигации. На
рис. 18.12 показано мультифреймовоеокно. Листинг 18.9
содержит исходный код HTML для родительской стра-
страницы мультифреймового окна, а листинг 18.10 — код для
списка посещений. Правая область окна не содержит
никакого JavaScript-кода.
Ways to
and КзлнвпХ) methods.
Ш
r By court
с By Name
JavaScript Chronicles — Free Subscription
Form
1, What other magazines do you currently subawbe to?
Г К Веек
Г №15
Г Imrnbascil 4dvi3DE
Г Internet Icivlsor
Г PC flwatiue
Г BelphL MaiMnt
Г Deb In
РИСУНОК 18.12. Пример фрейма History,
Листинг 18.9. HistoryFrames.htm._
<html>
<head>
<title>History Object Example</title>
</head>
<Frameset Cols=5%,65%">
<Frame Name = "FRAMEl" SRC="History.htm">
<Prame Name = "FRRME2"
SRC="JavaScriptChronicles.htm">
</Frameset>
</html>
Листинг 18.10. History.htm.
<html>
<head>
<title>History Page</title>
</head>
<body bgcolor="#FFFFFF">
<SCRIPT IANGaAGE="JavaScript">
<i —
function goPrev<) {
Глава 18
parent. frames [ 1 ] . history. back ()
functiongoNext ( ) {
parent. frames [ 1] . history . forward ()
functionmoveOn ( ) {
var urlAddress = '
urlAddress =
document. forms [ 0 ] . LocationBox. value
if (urlAddress != "") {
parent, f rames [1).location=
urlAddress
document, forms [0] - ListLen. value =
parent, frames [1] .history .length)
else {
alert ("Please enter a URL before
^clicking the Go button.")
function jump() (
if (document.formsfO].goParamfl] .checked) (
var goVal = 0
goVal =
parselnt (document, forms [0J .GoBox. value) )
else {
var goVal = ""
goVal = document.forms[0].GoBox.value
,1
parent, frames [1] .history.go(goVal)
</SCRIPT>
<form method="POST">
<h3Xem>Ways to navigate</em></h3>
<li>Use the location object. </li>
<pxinput
type=text
size=20
maxlength=50
name="LocationBox"> <input
type="button"
value="Find"
onClick="moveOn() '
<li>Use the history object's <em>back(></em>
and<em> forward() </em>methods.
<input
<p align=centerXinput
type="button"
value="Slt;ilt,"
onClick="goPrev()
type="button"
value=" figt; Sgt;"
onClick="goNext() "x/p>
<ul>
<li>Use the history object's <em>back<) </em>
and<em> forward() </em>methods.
<blockquote>
<p><input type=radio name="goParam"
value="ByCount">By Covmt</p>
Использование DOM
Часть III
<pxinput type=radio name="goParain"
value="ByNanie">By Name</p>
<pxinput
type=text
size=20
maxlength=30
name="GoBox"> <input
type="button"
value="Go"
onClick="jump() "> </p>
<p>History List Entries: <input
type=text
size=3
maxlength=4
name="ListLen">
</blockquote>
</form>
</body>
</html>
Объект Navigator
Объект Navigator — единственный объект, который выг-
выглядит невписывающимся в иерархию встроенных объек-
Таблица 18.8. Свойства объекта Navigator.
тов JavaScript. На первый взгляд, казалось бы, этот
объект является верхним уровнем пирамиды, посколь-
поскольку программное обеспечение браузера (элемент, пред-
представленный объектом Navigator) содержит информацию
относительно браузера, выполняющего сценарий. Одна-
Однако, объект Navigator не имеет никакого отношения к
другим объектам в иерархии; в действительности, он
обособленный объект, обеспечивающий только способ
получения информации о текущем браузере.
«ПРИМЕЧАНИЕ *"¦'¦ Sf- "¦":
Имейте в виду, что объект Navigator невозможно ис-
использовать для получения информации от браузеров,
которые не поддерживают JavaScript. Если браузер не
поддерживает JavaScript, он не будет обрабатывать
запрос на информацию. Очевидно, что невозможно
применить JavaScript-подпрограмму для определения,
поддерживает ли браузер JavaScript.
Объект Navigator имеет свойства, показанные в табл.
18.8.
Свойство
Описание
appName
appVersiorii
appCodeName
userAgent.
appCodeName
AppMinorVersion
AppName
AppVersion
BrowserLanguage
ConnectionSpeed
CookieEnabled
CpuClass
OnLine
Language
MimeTypes
Platform
Plugins
SystemLanguage
UserAgent
UserLanguage
UserProfile
Имя браузера.
Версия браузера.
Кодовое имя браузера.
Заголовок user-agent для браузера.
Кодовое имя браузера; поддерживается в Navigator 2 и Internet Explorer 3.
Подверсия версии браузера; поддерживается в Internet Explorer 4.
Имя браузера; поддерживается в Navigator 2 и Explorer 3.
Версия браузера; поддерживается в Navigator 2 и Explorer 3.
Языковая конфигурация браузера; поддерживается в Explorer 4.
Скорость, на которой браузер выполнил соединение; поддерживается в Explorer 4.
Работает ли браузер с cookie-наборами; поддерживается в Explorer 4.
Класс процессора на платформе браузера; поддерживается в Explorer 4.
Указывает, находится ли браузер в режиме он-лайн; поддерживается в Explorer 4.
Языковая конфигурация браузера; поддерживается в Explorer 4.
MIME-типы, поддерживаемые браузером; согласуется с Navigator 3 и Explorer 4.
Операционная система, под управлением которой работает браузер; поддерживается в Navigator 4
и Explorer 4.
.Массив подключаемых модулей, установленных в настоящий момент; поддерживается в Navigator 3
и Explorer 4.
Язык операционной системы по умолчанию; поддерживается в Explorer 4.
Заголовок user-agent, посылаемый с браузера на сервер; поддерживается в Explorer 3 и Navigator 2.
Пользовательский язык; поддерживается в Explorer 4.
Доступ к информации пользовательских профилей; поддерживается в Explorer 4.
Объекты Frame
Объект Navigator поддерживают как Netscape Navigator,
так и Microsoft Internet Explorer. Листинг 18.11 демон-
демонстрирует пример отображения информации о браузере
в диалоговом окне, когда пользователь нажимает на
кнопку "Show Browser Info". Рисунки 18.13 и 18.14 по-
показывают сигнальные окна сообщений, которые появ-
появляются в результате работы сценария, соответственно,
в Netscape и в Internet Explorer.
Листинг 18.11. navigatorlnfo.htm.
<HTML>
<HEAD>
<SCRIPT LANGUAGE = " JavaScript">
function displayBrowserlnfо() (
var browserStr = '
browserStr += "Browser: ' +
navigator.аррЫате + "\r"
browserStr += "Version:" +
navigator.appVersion + "\r"
browserStr += " ' +
navigator.appCodeName + "\r"
browserStr += "User agent: " +
navigator. userAgent + "\r"
alert(browserStr)
¦</SCRIPT>
<BODY>
<H1X/H1>
<FORM>
< INPUT
Type="button"
Value="Show Browser Information"
OnClick="displayBrowserInfo()"
</lNPOT>
</FORM>
</BODY>
</HTML>
.. .
РИСУНОК 18.14. Информация о браузере в Microsoft Internet
Explorer.
Резюме
В этой главе детально рассматривались мультифреймовые
и одиночные окна. Объекты Frame, Location и History
обеспечивают средства для работы с соответствующи-
соответствующими аналогами браузеров. Объект Navigator, намного
отличающийся от других объектов JavaScript, позволя-
позволяет извлекать информацию о текущем браузере.
В главе также обсуждались методы использования
JavaScript для ссылок на объекты и свойства в других
фреймах и окнах браузера. Были приведены базовые
примеры создания окна и установки фреймов, а также
рассмотрены способы ссылок на свойства в различных
фреймах и окнах. Кроме того, были даны способы об-
обновления и синхронизации фреймов и окон, а также
несколько примеров окон и фреймов, взаимодействую-
взаимодействующих друг с другом через JavaScript.
Использование JavaScript на фреймовом сайте не-
несколько более сложно, чем использование его на не-
нефреймовом сайте, однако полученные выгоды зачастую
стоят небольших дополнительных усилий по преодоле-
преодолению трудностей. Кратко рассматривались несколько
примеров сочетания JavaScript с фреймами и окнами.
Возможные применения и реализации фреймового сайта
ограничиваются только воображением разработчика
Web-сайта и степенью его трудолюбия.
РИСУНОК 18.13. Информация о браузере в Netscape Navigator.
Другие DOM-объеюы
В ЭТОЙ ГЛАВЕ
DOM-браузеры
Управление DOM-документами и DOM-методы
В главе 13 были рассмотрены основные принципы
объектной модели документа (DOM) и показана стан-
стандартизация DOM-модели с помощью интуитивно по-
понятных представлений в виде деревьев. В этой главе
с задействованием ряда листингов на JavaScript, рас-
рассматривается практическое применение общих DOM-
методов. Кроме того обсуждаются различные DOM-
узлы и элементы и практические способы управления
ими, а также некоторые важные проблемы, связанные
с браузерами.
DOM-браузеры
DOM-модель использует части документа для представ-
представления логической иерархии с помощью дескрипторов
страниц, их последовательности, свойств и атрибутов.
Последние изменения DOM в Netscape Navigator и
Internet Explorer связаны с работой консорциума W3C.
С помощью Netscape Navigator 3 могли быть написаны
и прочитаны атрибуты изображения и якорные деск-
дескрипторы, можно было запрашивать информацию о том,
какие подключаемые модули имеются в наличии, какие
MIME-типы поддерживаются и т.п. В Navigator 4.0 были
Таблица 19.1. XML- и HTML-узлы документов.
предоставлены дескрипторы для уровней дерева и усо-
усовершенствованы методы определения ширины и высо-
высоты контейнеров и окон. Исторически этот уровень
DOM-модели был поддержан в JavaScript, и как Java-
аплеты, так и подключаемые модули могли управлять
DOM с помощью LiveConnect, который является основ-
основным кодом языка создания сценариев JavaScript. В
Internet Explorer 4.0 DOM-модель интегрирована непос-
непосредственно в браузер, а не через язык создания сцена-
сценариев. Это помогает устранить несоответствия между раз-
разными языками создания сценариев, например, различия
в позициях дескрипторов. В результате информация ста-
становится стандартизованной и непротиворечивой для
различных браузеров, причем для взаимодействия с
DOM теперь возможно использовать JavaScript,
VBScript, элементы управления ActiveX, Java-аплеты и
любые другие компоненты языка, совместимые с DOM
API, записанным в OMG IDL. Из этого следует, что
исследования навигационных процессов в главе 13 было
уместным. Узлы ранее описывались как составные час-
части DOM-деревьев и, как упоминалось в главе 13, имен-
именно узлы дают возможность программам взаимодейство-
взаимодействовать с содержимым документа. Все узлы перечислены в
табл. 19.1.
Узел'
Описание
Атрибут
Раздел CDATA
Комментарий
Тип документа
Свойство дескриптора: например, элемент img может иметь атрибут src.
Текстовое содержимое, за исключением символов метки. Метод createCDATASection
создает узел со значением, которое является заданной строкой.
Комментарии для страницы, описывающие код и другие аспекты Web-страницы или всего
Web-сайта.
Каждый документ содержит объект DocumentType или атрибут doctype, который может
быть и null. Интерфейс DocumentType обладает возможностью перечислять такие
специфические объекты.
Другие DOM-объекты
Глава 19
Узел'
Описание
Document Объектное представление полного документа. Интерфейс Document представляет полный
HTML- или XML-документ и предоставляет стандартные методы создания объектов
Document, которые включают элементы, текстовые узлы, комментарии и команды
обработки. Получившиеся объекты Node имеют атрибут ownerDocument.
Element За исключением текста, большинство узлов Element — наиболее общие объекты, по
которым авторы перемещаются при навигации по документу, как показано в следующем
XML-примере:
<element(Jnleashed id=[sq1]Unleashed demo[sq2]>
<subelement1/>
<subelement2><subsubelement/></subelement2>
</elementUnleashed>
Очевидно, что DOM-дерево содержит в качестве самого верхнего узла узел Document,
содержащий узел Element для elementUnleashed, который, в свою очередь, содержит
два дочерних узла Element, subelementi и subelement2, при этом subelementi дочерних
узлов не имеет.
Ссылка на сущности (объекты) Префикс амперсанд (&) указывает, что объект вставлен в документ с помощью ссылки.
Используя DOM Level 2 версии 1.0, редактировать узлы Entity невозможно; скорее,
.каждый EntityReference в структурной модели потребуется заменять копией содержимого'
реального объекта, только после этого появится возможность их модификации. Дочерние
элементы узла Entity предназначены только для чтения, при этом узлы Entity
родительских элементов не имеют.
Атрибуты
systemld типа DOMString (только для чтения). Содержит заданный идентификатор
системы либо null, если он не определен.
notationName типа DOMString (только для чтения). Содержит имя примечания для
непроанализированных объектов либо null для проанализированных.
publicld типа DOMString (только для чтения). Содержит заданный общий идентификатор
либо null, если он не определен.
Ссылка на элемент, атрибут или строку текста.
Команда для синтаксического XML-анализатора; D0M сохраняет эту информацию
обработки в XML-документах.
Атрибуты
Адрес типа DOMString (только для чтения). Это адрес команды обработки или первого
маркера после команды обработки.
Данные типа DOMString — содержимое команды обработки, которая находится между
первым символом (кроме пробела) после адреса и символа непосредственно перед "?>".
Text Объект, содержащий текст.
Узел
Команда обработки
ПРИМЕЧАНИЕ
DOM-модель WWW-консорциума (W3C) поддержива-
поддерживается в Netscape Navigator бив Microsoft Internet Explorer
5. В Navigator 4 написан новый HTML для объекта Layer.
Для изменения текстового элемента с заданным ID и
значением newtext форма приобретет следующий вид:
var lyr = document.layers[id].document
lyr.openO
lyr.write(newtext)
lyr . close ()
Internet Explorer 4.0 реализует другой способ и пре-
предоставляет HTML-элементы документа, использующие
ключевое слово ALL. Для изменения текстового эле-
элемента с заданным ID и значением newtext форма по-
получает следующий вид:
document, all [id] -innerHTML = newtext
Explorer 5 использует ключевое слово ALL для дости-
достижения совместимости сверху вниз. A Navigator 5.0 для
обеспечения совместимости сверху вниз сохраняет мо-
модель Layers для объектов.
"СОВЕТ . ' _¦ - - , ¦ ' i r' :-j
В DHTML версии 4 для всех браузеров потребуется
создать разветвление кода, с помощью которого вы-
выясняется тип браузера и выполняются соответствую-
соответствующие корректировки:
ns4 = (document.layers)? true:false
ie4 = (document, all) ? true .-false
function simpleLayerWrite(id,newtext) {
Использование DOM
Часть III
if <ns4) (
var lyr =
document.layers[id].document
lyr. open ()
lyr.write(text)
lyr.close()
else if (ie4) document, all [id] .
innerHTML = newtext
Далее будет рассматриваться, главным образом, DOM
IIES-реализации (и механизм браузера Gecko). Это при-
примечание, однако, может очень скоро потерять акту-
актуальность, возможно, уже сейчас Netscape Navigator
и Explorer имеют совместимую DOM-модель.
Управление DOM-документами и
DOM-методы
Теперь известно, что DOM-модель содержит полезные
и практические методы управления объектом или струк-
структурой узла документа. Это дает общие методы для вы-
выполнения простых вещей, таких как копирование,
вставка и замена узлов. Подобного рода методы позво-
позволяют формировать легко заменяемые документы, ко-
которые любой разработчик сможет изменить и понять
при условии, что он знаком с DOM-моделью. Методы
предоставляют образцы для непосредственного создания
документов, а также используют ключевой аспект осно-
основанных на объектах документов — возможность повтор-
повторного использования, следовательно, вместо многократ-
Листинг 19.1. Метод cloneNode.
НОГО создания новых узлов и объектов их можно про-
просто копировать. Таким образом, теперь мы вплотную
подошли к "гайкам и болтам" этих методов и их прак-
практического применения при создании и управлении до-
документами, которые рассматриваются в следующих раз-
разделах.
Использование метода cloneNode
Выполнение метода cloneNode задается с помощью его
логического параметра in. Когда он равен true, копиру-
копируется полное поддерево данного узла. С другой стороны,
значение false данного параметра заставляет браузер
копировать только указанный узел и игнорировать его
дочерние и родительские элементы. Применение мето-
метода cloneNode продемонстрировано в листинге I9.1, где
параметр false используется для копирования только
узла, без поддерева. Сценарий не делает ничего, кроме
создания массива узлов, включенных в таблицу, и эте»
достигается с помощью HTML. Сценарий на JavaScript
содержит метод cloneNode, с помощью которого опре-
определяется узел, предназначенный для копирования, а
также вызывается сигнальный диалог, отображающий
состояние копируемого узла. В этом примере сигналь-
сигнальное сообщение показывает, что метод cloneNode вернул
копируемый объект. К данной информации добавляет-
добавляется отображение того, что копируемый объект не имеет
никаких дочерних и родительских элементов, т.е. копи-
копировался только узел. Замена в методе значения парамет-
параметра cloneNode с false на true заставляет браузер копиро-
копировать полное поддерево, включая дочерние и родительс-
родительские элементы узла.
<HTML>
<HEAD>
<TITLE> DOM cloneNode example </title>
</HEAD>
<BODY ID="bodyNode">
<TABLE ID="tableNode">
<TBODY>
<TR ID="trlNode"XTD BGCOLOR="yellow">Row 1, Cell K/TDXTD BGC0LOR="orange">Row 1,
Cell 2</TDX/TR>
<TR ID="tr2Node"XTD BGCOLOR="red">Row 2, Cell K/TDXTD BGCOLOR="magenta">Row 2,
Cell 2</TDX/TR>
<TR ID="tr3Hode"XTD BGCOLOR="lightgreen">Row 3, Cell K/TDXTD BGCOLOR="beige">Row 3,
Cell 2</TDX/TR>
<TR ID="tr4Node"XTD BGCOLOR="blue">Row 4, Cell K/TDXTD BGCOLOR="lightblue">Row 4,
Cell 2</TDX/TR>
<TR ID="tr5Node"XTD BGCOLOR="orange">Row 5, Cell K/TDXTD BGC0LOR="purple">Row 5,
Cell 2</TDX/TR>
</TBODY>
</TABLE>
<SCRIPT IANGUAGE="JavaScript">
tr3Obj = trlNode.cloneNode(false) ;
alert{
"tr3Obj.firstChild = " + tr3Obj .firstChild + "\n" + "tr3Obj .nodeName = " + tr30b j. nodeName
Другие DOM-объекты
II —>
</SCRIPT>
</BODY>
</HTML>
Глава 19
Использование метода insertBefore в DOM
Метод insertBefore обеспечивает средства формирова-
формирования объектных структур, помещая заданные объекты
перед другими указанными объектами. Здесь использу-
используются два параметра, которые являются объектами:
tbodyObj.insertBefore(tr20bj, tr30bj)
Возможное использование метода insertBefore (рав-
(равно как и других DOM-методов) — это формирование
таблицы. Например, можно создать узел, скопировать
его и затем использовать insertBefore для создания таб-
таблицы. Листинг 19.2 показывает конструкцию таблицы,
построенной с использованием этих методов. Объект
tbodyObj содержит три дочерних объекта: trlObj, tr2Obj
и tr3Obj, которые создаются с помощью следующих вы-
выражений:
trlObj = document.createElement ("TR");
trltdlObj = document. createElement ("TD"> ;
trltd2Obj = trltdlObj.cloneNode (false);
tr2tdlObj = trltdlObj.cloneNode <?alse);
При использовании метода insertBefore объекты со-
собираются следующим образом:
tbodyObj.insertBefore < tr30bj);
tbodyObj.insertBefore (tr2Obj, tr3Obj);
tbodyObj.insertBefore (trlObj, tr2Obj);
trlObj.insertBefore (trltd2Obj);
trlObj. insertBefore (trltdlCbj, trltd2Obj);
tr20bj.insertBefore (tr2td2Obj);
tr2Obj. insertBefore (tr2tdlCbj, tr2td2Obj);
Как видно из приведенного выше кодового фрагмен-
фрагмента, последний дочерний объект (tr3Obj) вставляется в
первую очередь, второй дочерний объект вставляется
перед ним, а первый дочерний (trlObj) вставляется пе-
перед вторым (tr2Obj).
Листинг 19.2. Создание таблицы с помощью
insertBefore.
<H?ADJ>-
<T1TLE> Building tables using DOM </TITLE>
</HEAD>
<BODY ID= "bodyNode ">
<SCRIPT IANGUAGE="JavaScript">
rowlcolumnlObj = document.createTextNode("Row 1,
*¦* column 1 ") ;
tableObj = document. createElement ("TABLE") ;
tbodyObj = document.createElement("TBODY") ;
trlObj = document. createElement ("TR") ;
trltdlObj = document.createElement("TD");
trltd2Obj = trltdlObj.cloneNode(false);
tr2tdlobj = trltdlObj.cloneNode(false) ;
tr2td2Obj = trltdlObj.CloneNode(false);
tr3tdlObj = trltdlObj.cloneNode(false);
tr3td20bj = trltdlObj.cloneNode(false);
tr2Obj
tr3Obj
= trlObj.cloneNode(false);
¦ trlObj.cloneNode(false);
rowlcolumn20bj
row2columnlObj
row2column20bj
row3columnl0bj
row3column20bj
rowlcolumn20b j. nodeValue =
row2columnlObj.nodeValue =
rowlcolumnlObj.cloneNode(false);
rowlcolumnlObj .cloneNode (false) ;
rowlcolumnlObj.cloneNode(false);
rowlcolumnlObj.cloneNode(false);
rowlcolumnlObj.cloneNode(false);
"Raw 1, column 2; ";
"Row 2,
column
column
column
column
row2column20bj .nodeValue = "Row 2,
row3columnl0bj ,nodeValue = "Row 3,
row3column20bj ,nodeValue = "Row 3,
return Value = tableObj . insertBefore (tbodyObj) ;
tbodyObj.insertBefore(tr3Obj);
tbodyObj.insertBefore(tr2Obj, tr3Obj);
tbodyObj.insertBefore(trlObj, tr2Obj);
trlObj.insertBefore(trltd2Obj);
trlObj.insertBefore(trltdlObj, trltd2Obj);
tr2Obj.insertBefore(tr2td2Obj);
tr2Obj.insertBefore(tr2tdlObj, tr2td2Obj);
tr3Obj.insertBefore(tr3td2Obj);
tr3Obj.insertBefore(tr3tdlObj, tr3td2Obj);
trltd2Obj.insertBefore(rowlcolumn20bj);
trltdlObj.insertBefore(rowlcolumnlObj);
tr2td2Obj.insertBefore(row2column20bj);
tr2tdlObj . insertBefore (row2columnl0bj) ;
tr3td2Obj . insertBefore(row3column20bj);
tr3tdlObj.insertBefore(row3columnlObj);
bodyNode.insertBefore(tableObj);
// -->
</SCRIPT>
</BODY>
</HTML>
Использование метода swapNode
Метод swapNode меняет местами указанные поддеревья,
встроенные в указанные узлы. Этот метод возвращает
целое поддерево. Применение метода swapNode демон-
демонстрируется в листинге 19.3.
Функция printChildObjects печатает дочерние элемен-
элементы bodyNode вместе со свойством nodeName.
Использование метода removeNode
Выражение removeNode(false) удаляет указанные узлы и
присваивает их дочерние объекты родительскому объек-
объекту удаленного узла:
erasedNode = p3Node.removeNode(false);
Листинг 19.4 иллюстрирует использование метода
removeNode, а также применения функции printChildObjects.
Использование DOM
Часть III
Листинг 19.3. Перемещение абзацев.
<SCRIPT LANGUAGE="JavaScript">
var msg = "" ;
function printChildObjects() {
childcount = bodyNode.childNodes.length;
msg += "bodyNode. childNodes . length = " + bodyNode . childNodes . length + "\n" ;
for (var i = 0; i < childcount; i++) {
msg += "bodyNode.childNodes[i].nodeName = " + bodyNode.childNodes[i].nodeName + "\n"
1
)
printChildObjects();
msg += "Swap Paragraph 2 with paragraphl\n" ;
var b = p2Node;
var swappingNode = p3Node.swapNode(b);
msg += " swappingNode. nodeName = " + swappingNode. nodeName + "\n";
msg += "swappingNode.childNodes.length = " + swappingNode.childNodes.length + "\n";
msg += "p2Node. nodeName = " + p2Node. nodeName + " \n";
printChildObjects () ,-
alert(msg);
// — >
</SCRIPT>
Листинг 19.4. Удаление узлов._
<SCRIPT IANGUAGE="JavaScript">
var msg — " ;
function printChildObjects() {
childcount = bodyNode. childNodes. length;
msg += "bodyNode.childNodes.length = " + bodyNode.childNodes.length + "\n" ;
for (var i = 0; i < childcount; i++) {
msg += "bodyNode.childNodes [i] .nodeName = " + bodyNode. childNodes [i] .nodeName +
"\n"
printChildObjects 0;
msg += "Erase paragraph 3\n" ;
var deletedNode = p3Node. removeMode (false) ;
msg += "deletedNode. nodeName = " + deletedNode. nodeName + "\n";
msg += "deletedNode.childNodes.length = " + deletedNode.childNodes.length + "\n"
printChildObjects ();
alert(msg);
</SCRIPT>
"СОВЕТ. ,: ' v ' >¦
DOM-объекты обращаются к полному содержимому
Web-страницы, включая и графику, которая может
храниться в формате GIF. Первый графический сим-
символ в документе можно изменить путем замены его
свойства src (src означает "source" — источник). В
показанной ниже DOM-форме первое изображение
просто заменяется на изображение с именем NewTitle
в формате GIF.
window.document.images[0].src='New_Title.gif ' ;
Изображения в формате GIF и другие графические
файлы можно редактировать в пакете Paint Shop Pro
от Jasc Software. Эта программа распространяется
свободно и ее можно выгрузить со множества сай-
сайтов, в том числе и с сайта Jasc. Она имеет полезные
инструментальные средства редактирования и эффек-
эффекты, необходимые для создания превосходной Web-
графики.
Резюме
¦Эта глава, посвященная D0M, представляет собой еще
один шаг вперед в изучении JavaScript. В ней обсужда-
обсуждались способы создания и изменения составляющих
сущностей документа. Таким образом, зная структуру
и характеристики DOM-модели, ее можно применять
буквально где угодно, используя практически любой
программный объект, включая приведенные выше сце-
сценарии. Вне этих сценариев можно проделывать то же
самое с элементами управления ActiveX и Java-аплета-
ми. Можно смело заявить о том, что появился новый
ландшафт стандартизованных целевых платформ или
клиентских браузеров, которые впервые общаются на
том же языке, который определяет DOM-модель.
Технологии
программирования на
динамическом HTML
ЧАСТЬ
20. Динамическая подмена
21. Визуальные эффекты
22. Каскадные таблицы стилей
23. Слои
24. Меню и панели инструментов DHTML
25. Взаимодействие с другими технологиями
Динамическая подмена
В ЭТОЙ ГЛАВЕ
Знание событий
Виды динамических подмен
Динамическая подмена (rollover) — это общий ме-
метод совершенствования страниц сайта с использовани-
использованием JavaScript. Фактически, это — одна из первых гло-
глобально используемых функций JavaScript, сохранившая
свою популярность до сих пор. Другие методы, такие
как прокручиваемые сообщения строки состояния и тек-
текстовые поля, исчезли с горизонта.
Знание событий
Создавая rollover-эффекты в рамках сайта, необходимо
глубоко разбираться в соответствующих событиях
JavaScript, Несмотря на то что события уже рассматри-
рассматривались в главе 14, стоит все же вернуться кданной теме.
onMouseOver
Событие onMouseOver используется объектами Link и
Document для определения момента установки указателя
мыши на элементе. Internet Explorer позволяет захваты-
захватывать эти события практически всем элементам на стра-
странице, а не только объекты Links и Document. Пример
демонстрирует захват событий onMouseOver дескрип-
дескриптором <а>:
<а href="http://www.mcp.com"
onmouseover="alert('You rolled over!')">
Here</a>
onMouseOut
Событие onMouseOut весьма напоминает onMouseOver
и точно так же может быть использовано объектами Link
и Document. Это событие определяет, когда указатель
мыши покинул конкретный элемент. Internet Explorer
позволяет захватывать это событие практически всем
элементам на странице, а не только объектам Link и
Document:
i href ="http: //www.mcp.com"
onmouseout="alert ( ' You rolled off !
) ">Here</a>
onMouseDown
Событие onMouseOut используется объектами Link и
Document с целью определения момента нажатия кноп-
кнопки мыши на определенном элементе. Для примера рас-
рассмотрим захват событий onMouseDown в дескрипторе
">Here</a>
<а href="http://www.mcp.com"
onmousedown="alert('You pressed!
onMouseUp
Событие onMouseUp используется объектами Link и
Document для определения момента отпускания кноп-
кнопки мыши, ранее нажатой на определенном элементе. В
примере показан захват таких событий в дескрипторе
<а href="http : //www.mcp. com"
onmouseup="alert ( 'Youreleased! ' ) ">Here</a>
Виды динамических подмен
Каждому разработчику необходимо не только решать,
какой вид rollover-эффектов необходим на сайте, но и
как его реализовать. Многие rollover-эффекты могут
имитировать другие, поэтому все зависит только от
пользовательского браузера и от того, что именно под-
поддерживает этот браузер.
Динамическая подмена
Глава 20
Rollover-эффекты для изображений
Существует несколько методов реализации rollover-эф-
rollover-эффектов для изображений (rollover-изображений), но са-
самый простой заключается в создании двух массивов,
содержащих используемые изображения и ссылки в
документе на индексные расположения в массиве
document.image. Необходимо сохранить все изображе-
изображения в массиве объектов Image. Расположим на страни-
странице два объекта специально для примера, представлен-
представленного на рис. 20.1. Когда пользователь помещает курсор
поверх изображения, происходит замена изображения
на его rollover-версию. Массив изображений создается
с использованием следующего кода:
// Создание массивов для хранения изображений
var overling = new Array () ;
overling[0] = new Image B4 ,24) ;
overlmg[l] = new Image B4 ,24) ;
var defaultlmg = new Array();
defaultImg[0] = new ImageB4,24);
defaultlmg[l] = new ImageB4,24);
II Предварительная загрузка изображений в
// массивы
overlmg[0].src = "back-over.gif";
overling[1] .sre = "forward-over.gif";
defau.'.tlmg [0 J .src
defaultlmg[l].src
"back, gif";
"forward.gif"
РИСУНОК 20.1. Страница с rollover-эффектами
Следующий необходимый элемент — это функция,
выполняющая собственную подмену изображений. Эта
функция принимает два аргумента: первый — индекс-
индексное расположение подменяемого изображения, а второй —
вид свопинга ("over" или "out"). Оператор switch опре-
определяет, из какого массива берется заменяющее изобра-
жениг. После определения массива присваивание, обес-
обеспечивающее замену изображения, реализуется через
свойство src объекта Image:
function rolllmage(img,type){
switch(type){
case "over":
document.images[img].src =
overling [img] .src;
break;
case "out":
document.images[img].src =
defaultlmg[img].src;
break;
Последний шаг связан с захватом событий
onMouseover и onMouseOut. Как упоминалось ранее,
это достигается с использованием дескриптора <а>. В'
листинге 20.1 показан полный исходный код для зах-
захвата событий, а на рис. 20.2 — замененное изображение,
когда над ним находится указатель мыши.
Листинг 20.1. Полный исходный код для реализации
rollover-изображений
<html>
<head>
<title> JavaScript Unleashed-»:/ title>
<script type="text/javascript"
language="JavaScriptl.2">
// Создание массивов для хранения
// изображений
var overling = new Array () ;
overlmg[0] = new Image B4,24) ,-
overling [1] = new Image B4 ,24) ;
var def aultlmg == new Array () ;
defaultImg[O] == new Image B4,24) ;
= new ImageB4,24);
// Предварительная загрузка изображений в
// массивы
overlmg[0].src = "back-over.gif";
overlmg[l].src = "forward-over.gif";
defaultImg[0].src =
defaultlmg[l].src =
"back.gif";
"forward.gif"
// Изменение состояния изображения
// зависимости от события
function rolllmage<img,type){
switch(type){
case "over":
document, images [img].src =
overling [img] .src;
break;
case "out" :
document, images [img] .src =
defaultlmg[img].src;
break;
II—>
</script>
</head>
<body bgcolor="#ffffff">
<table border="l" cellpadding="
cellspacing="O" align="center"
Технологии программирования на динамическом HTML
Часть IV
Ьдсо1ог="#сОсОсО">
<tr>
<td align="center">
<а href="javascript:void@) "
onmouseout="rolllmage<'0','out')"
orunouseover="rolllmage< '0', 'over')">
<img border=" src="baok.gif"
width=4" height=4" alt="Back">
</td>
<td align="center">
<a href="javascript:void@)"
onmouseout="rolllmage ( ' 1', ' out1) "
onmouseover="rolllmage( ' I1 , 'over')">
<img border=" 0 "
src="forward.gif"width=4"
height=4"
alt="Forward"X/a>
</td>
</tr>
</table>
</body>
</html>
РИСУНОК 20.2. Динамическая замена одного I изображений
ПРИМЕЧАНИЕ
В главе 24 прш гея более конкретные примеры
rollover-изображений и подробно рассматривается их
использование.
Rollover-эффекты для слоев
Следующий рассматриваемый нами вопрос — это реа-
реализация rollover-эффектов для слоев. Они генерируют-
генерируются за счет сокрытия и отображения слоев внутри доку-
документа. Эта тема также затрагивается и в главе 23. Сейчас
стоит кратко рассмотреть вопрос реализации доступа к
свойству visibility таблиц стилей (CSS) в JavaScript.
Первое, что потребуется сделать — создать HTML-
документ, который станет основой примера. Здесь не-
необходимо определить ссылку и изначально скрытый
слой. Результирующий документ предельно прост.
<div name="layerl" id="layerl">
Hello World!
<a href="javascript: void<0)"
onmouseout="changeState('layerl','hidden')"
onmouseover="changeState{'layerl',
Rollover to show and hide the layer.
He беспокойтесь, что сейчас слоям уделяется мало
внимания, поскольку эта тема рассматривается позже,
в главе 23. В настоящий момент лучше сфокусировать
внимание на коде JavaScript.
Так же, как и в примере с rollover-изображениями,
для захвата событий onMouseOver и onMouseOut будет
использоваться дескриптор <а>. В дескрипторе <а>
можно заметить три фрагмента кода. Первый фрагмент
находится в атрибуте href. Этот вызов (javascript: со-
сообщает браузеру о том, что при условии выполнения
щелчка кнопкой мыши на ссылке ничего больше не про-
произойдет (void(O)). Второй и третий фрагменты шзыва-
ют функцию changeState() и передают ей две перемен-
переменные. Первая, name (для браузеров Navigator) и id (для
браузеров Internet Explorer) — это экземпляр слоя, а
вторая — индикатор, который скрывает или отобража-
отображает слой.
СОВЕТ
В атрибуте href допускается применение такого син-
синтаксиса, на который ссылаются как на "JavaScript
URL", для вызова функции либо для любого другого
кода на JavaScript.
¦ ¦ . .... ..
Следующий шаг заключается в установке таблицы
стилей для слоя, которая обеспечит его сокрытие. Не-
Несмотря на то что в CSS присутствует несколько свойств,
которые будут рассматриваться в главах 22 и 23, сейчас
примем во внимание только одно свойство visibility.
Несложно заметить, что ему присваивается значение
hidden.
#layerl{
background-color: red;
height: 100;
left: 10;
position: absolute;
top: 50;
width: 100;
visibility: hidden;
</style>
Следующая часть кода необходима лишь для того,
чтобы учесть отличия реализации слоев в браузерах
Navigator и Internet Explorer. Вначале потребуется оп-
Динамическая подмена
ределить, какой из браузеров получает доступ к страни-
странице, и установить переменные, которые позволят исполь-
использовать одну функцию для обработки rollover-эффектов.
Детали реализации обсуждаются в главе 23. Сейчас рас-
рассмотрим только код:
,// Создание глобальных переменных для хранения
// типа браузера.
var isIE = new Boolean (false) ;
var isNav = new Boolean (false) ;
var layer = new String () ;
var style = new String () ;
// Определение, является ли браузер Internet
// Explorer, Navigator и др. Кроме того,
// установка переменной слоя в зависимости от
// необходимого способа доступа.
function checkBrowser () (
if(navigator.userAgent.indexOf("MSIE") != -1) {
is IE = true;
layer = ".all";
style = " . style" ;
}else if (navigator, user Agent. indexOf ("Nav") ! =
-1>(
isNav = true;
layer = ".layers";
style = "" ;
Последняя функция в данном примере отображает
и скрывает слой. Так же, как и в HTML-документе, она
принимает два параметра: имя слоя и состояние, на ко-
которое требуется переключить слой. Благодаря проделан-
проделанной ранее работе, функция содержит только одну стро-
строку кода:
function changeState(layerRef, state){
eval("document" + layer + "['" + layerRef +
"¦]" + style + ".visibility = ¦» + state +
) ;
.1
В функции используется верхнеуровневый метод
eval(), который принимает объект String и выполняет
его как код JavaScript. В нашем примере строка
"document" + layer + »[ •» + layerRef + »¦ ] •• +
style + ".visibility = ¦" + state + ""');
получает значение
document.layerst'layerl'].visibility = "hidden";
для случая браузера Navigator и
document, all [ ' layerl' ] . style .visibility =
"bidden";
для случая Internet Explorer. Сейчас несложно заметить
различия между видами доступа к слоям в этих двух
браузерах.
Теперь, когда создание кода завершено, можно оце-
оценить результаты его работы. В листинге 20.2 предостав-
предоставлен полный исходный код, а на рис. 20.3 — страница в
Глава 20
браузере. Рисунок 20.4 демонстрирует rollover-эффекты
для слоя.
Листинг 20.2. Пример реализации
rollover-эффектов для слоев
<html>
<head>
<title> JavaScript Unleashed</title>
<style type="text/css">
<!--¦
#layerl{
background-color: red;
height: 100;
left: Im-
Imposition: absolute;
top: 50 ;
width: 100;
visibility: hidden;
</style>
<script type="text/javascript"
language="JavaScriptl.2">
// Создание глобальных переменных для
// определения типа браузера.
var isIE = new Boolean (false) ;
var isNav = new Boolean(false);
var unsupported = new Boolean (false) ;
var layer = new String () ;
var style = new String () ;
// Определение, является ли браузер
// Internet Explorer, Navigator или
// каким-либо другим. Установка значения
// переменной слоя в зависимости от вида
// доступа.
function checkBrowser() {
if(navigator.userAgent.indexOf("MSIE") !=
-D{
isIE = true;
layer = ".all";
style = ".style";
} else if(navigator.userAgent.indexOf("Nav")
¦- -1){
isNav = true;
layer = ".layers";
style = "";
)else{
unsupported = true;
,// Take the state passed in, and change
it..
function changeState (layerRef, state) {
eval( "document" + layer + "['» +
layerRef + "']" + style +
".visibility = "' + state + "'");
}
II—>
</script>
</head>
<body onload="checkBrowser()">
<div name="layerl" id="layerl">
Hello World Г
Технологии программирования на динамическом HTML
Часть IV
<а href="javascript :void@) "
onmouseout="changestate('layer 1 ' , 'hidden') "
onmouseover="changeState<'layerl','visible')">
Rollover to show and hide the layer.
</body>
</html>
РИСУНОК 20.3. Ссылка без воздействия rollover-эффекта
ПРИМЕЧАНИЕ
И в Internet Explorer, и в Navigator предусмотрены
собственные реализации CSS, поэтому не удивляйтесь,
если результаты запуска некоторых сценариев будут
отличаться. Например, при загрузке кода из листинга
20.2 Navigator 4 окрашивает только фон текста, а не
весь слой.
РИСУНОК 20.4. Rollover-эффект в действии
Резюме
Несмотря на небольшой объем главы, были описаны
важные характеристики приложений JavaScript. Реали-
Реализация rollover-эффектов на собственном сайте — одно
из простейших и безопасных задач в JavaS t Но не
стоит ограничиваться только информацией, полученной
из книги. Rollover-эффекты могут лежать в основе мно-
многих задач, решаемых с использованием JavaScript. Они
позволяют глубже понять события и доступ к элемен-
элементам страницы, а также знакомят с дизайном интерфей-
интерфейсов.
Остальная часть книги посвящена вопросам созда-
создания визуальных эффектов, CSS и слоев. Будут рассмат-
рассматриваться особенности создания на DHTML инструмен-
инструментальных панелей и меню. Также будут исследоваться
способы взаимодействия компонентов на стра] с ис-
использованием JavaScript.
Визуальные эффекты
В ЭТОЙ ГЛАВЕ
Бегущие строки
Баннеры
Постепенное изменение цветов
Анимированные командные кнопки
На сегодняшний день такие технологии, как JavaScript
и Java, широко применяются в сфере разработки Web-
приложений. Они популярны также благодаря изящ-
изящным операциям, которые можно проделывать с их по-
помощью на Web-сайте. Вспомните, сколько бесполезных
Java-аплетов блуждали по Web во времена, когда возрос-
возросла популярность Java. Однако с появлением JavaScript
горизонты применения различных операций существен-
существенно расширились.
Бегущие строки
Эффект бегущей строки относится к числу наиболее
распространенных в среде разработчиков Web-сайтов.
Цель данного эффекта — передать посетителям сайта
последние новости или пикантные сообщения. Бегущая
строка впервые получила популярность после примене-
применения в Java-аплетах.
Создание бегущей строки в JavaScript тоже предус-
предусматривается, хотя при этом внешний вид ее будет не
столь эффективным, как в Java-аплете. Все это объяс-
объясняется использованием объекта Text в роли контейне-
контейнера для прокручиваемого текста, а ни один из объектов
HTML-формы не сможет поразить пользователя своим
великолепием. У разработчиков не будет проблем с со-
созданием бегущих строк JavaScript, поскольку они не
нуждаются в отдельном аплете. Необходимость в таких
строках возникает очень часто.
Для создания бегущей строки в JavaScript необходимо:
Создать HTML-форму с внедренным объектом Text.
Записать функцию, прокручивающую текст внутри
объекта Text.
Ассоциировать функцию с обработчиком событий
окна on Load для запуска процесса.
Для начала создайте объект Form и внутри него
объект Text. При этом рекомендуется соответствую-
соответствующим образом назвать эти объекты, поскольку они
создаются исключительно для реализации бегущей стро-
строки и ни для чего более. Например, форму стоит назвать
"marqueeForm", а объект Text — "marqueeText" или как-
то по-другому, однако максимально близко по смыслу.
После этого необходимо ввести сообщение как атрибут
value дескриптора <input>. Ниже приводится код
<form>:
<CENTER>
<form name="marqueeForm">
<input name="marqueeText" size=0"
value="THIS JUST IN...JavaScript
is selected as official scripting
language of the 2000 Summer 01ympics">
</form>
</center>
После определения контейнера для бегущей строки
можно приступить к основной части. Для начала опре-
определяются две глобальные константы, используемые в
бегущей строке: скорость прокручивания (в миллисе-
миллисекундах) и количество знаков, прокручиваемых за опре-
определенный временной промежуток. Затем потребуется
создать объект String с именем marqueeMessage:
var SCROLL_RATE = 100;
var SCROLL_CHARS = 1;
var marqueeMessage = new String() ;
Следующий шаг — создание функции JSMarquee(),
придающей обыкновенному объекту Text вид бегущей
строки. Поскольку бегущая строка должна постоян-
постоянно обновляться, не удастся обойтись без рекурсии
JSMarquee() за счет вызова setTimeout() в начале фун-
функции. Метод setTimeout() подробно описывается в гла-
главе 14. Lflo6aflbHaH переменная SCROLL_RATE исполь-
Технологии программирования на динамическом HTML
Часть IV
зуется как параметр метода, определяющий частоту вы-
вызова функции.
Основная задача функции JSMarquee() заключает-
заключается в получении значения объекта Text и присвоению его
строке marqueeMessage. Затем можно смоделировать
перенос слов, отделяя порцию данных сообщения спе-
спереди и переписывая эту порцию в конец строки. Для
этого используется метод substring() объекта String:
function JSMarquee (){
.setTimeout ('JSMarquee {) ' , SCROLL_RATE) ;
marqueeMessage =
document.marqueeForm.marqueeText.value;
document.marqueeForm.marqueeText.value =
marqueeMessage. substring ( SCROLL_CHARS ) +
marqueeMessage.substring( 0, SCROLL_CHARS ) ;
)
На рис. 21.1 показан эффект бегущей строки в мо-
момент, когда пользователь находится на странице.
Полный исходный код для этого примера приводит-
приводится в листинге 21.1.
ПРИМЕЧАНИЕ ,, ,, "..'.'',
Помимо исходного кода, в листинге 21.1 имеется так-
также и дополнительный код JavaScript, поэтому текст
сообщения можно определить как глобальную пере-
переменную. Так его проще поддерживать при условии
частого изменения текста объявления.
Баннеры
Баннеры — еще один компонент, который часто при-
присутствует на Web-страницах. Они привлекают к себе
внимание и применяются, в основном, для рекламных
целей. Обычно их миссия состоит в том, чтобы заинт-
заинтриговать пользователя и заставить его щелкнуть мышью
именно в этом месте. Используя объекты Image, мож-
можно создавать профессиональные баннеры, обходясь без
анимированных GIF-изображений или Java-аплетов.
^ПРИМЕЧАНИЕ ''.'¦'.- ' *?
Перед созданием самого сценария потребуются два
набора GIF-файлов одинаковых размеров. Необходимы
два или три изображения, которые после будут слу-
служить как главные изображения баннера. Для достиже-
достижения эффекта перехода потребуется серия переходных
изображений. Изображения, в случае их последова-
последовательной отрисовки, будут выглядеть подобно анимации.
Для создания удобоваримого эффекта достаточно
будет и пяти-шести переходных изображений.
Следите за общим размером GIF-файлов. Некоторые
пользователи, загружая страницу с 15 GIF-изображе-
GIF-изображениями на скорости соединения 28,8 Кбайт/с могут и
не оценить ее.
Как только GIF-файлы готовы, можно приступить
к созданию баннера в JavaScript:
Листинг 21.1. Реализация бегущей строки с использованием JavaScript
<html>
<head>
<title> JavaScript Unleashed</title>
<script type="text/javascript">
<! —
// объявление переменных
var SCROli_RATE = 100;
var scroll_chars = 1;
var MESSAGE = "THIS JUST in. . .JavaScript is selected as ¦¦ +
"official scripting language of the 2000 Summer Olympics..."
var marqueeMessage = new String () ,-
function JSMarquee () [
setTimeout( ¦JSMarquee{)', SCROLL_RATE ) ;
marqueeMessage = document.marqueeForm.marqueeText.value;
document.marqueeForm.marqueeText.value = [ marqueeMessage. substring;( SCROLt._CHARS ) +
marqueeMessage.substring( 0, SCROLL_CHARS >;
J
</script>
</head>
<body onload="JSMarquee()">
<center>
<form name="marqueeForm">
<input name="marqueeText" size=0">
<script type="text/javascript">
<! —
document. marqueeForm. marqueeText. value = MESSAGE;
II—>
</script>
</form>
</center>
</body>
<)html>
Визуальные эффекты
1. Создайте заглушку для изображения на Web-стра-
Web-странице.
2. Определите массив для хранения исходных изоб-
изображений и для хранения переходных изображений.
3. Создайте программу для управления презентацией
изображений.
4. Определите эту функцию в качестве обработчика
событий onLoad.
p H3~offlciai BtftipClng
РИСУНОК 21.1. Пример бегущей строки
Для начала создайте на Web-странице объект Image,
который послужит заглушкой для всех действий. По-
Поскольку баннер переносит куда-то в другое место, как
только на нем совершается щелчок, очевидно, дескрип-
дескриптор <img> потребуется поместить внутрь ссылки:
<а href = "http://www.mcp.com"
onmouseover="window. status='http://
'-•www.mcp . com1 ¦ return true;"
onmouseout="window.status = ' ' ; return true;">
<img name="billboard" height=9" width=33"
src=" ./visjs .gif">
.¦ПРИМЕЧАНИЕ
Обратите внимание на обработчики событий onMouseOver
и onMouseOut, определенные в объекте Link. Без них
можно обойтись, если URL закодирован жестко. Эти
обработчики необходимы в случае, если с каждым ис-
исходным изображением в баннере связаны различные
адреса URL. В таком случае потребуется предусмот-
предусмотреть массив URL и текст mouseOver, зависящий от ак-
активного изображения.
Внутри раздела <head> поместите дескриптор <script>
и определите набор переменных и объектов. Две гло-
глобальных константы хранят время (в миллисекундах) для
Глава 21
отображения основного и переходного изображений.
Две дополнительные переменные определяются позже:
.// Глобальные константы
var DISPLAYJTIME = 3500;
var TRANSITIONJTIME = 50;
.// Глобальные переменные
var primaryldx = О;
var transldx = 0 ;
Потребуется определить два массива для хранения
информации о наборах начальных и переходных изоб-
изображений. Для каждого элемента массива объявляется
свойство изображения scr.
// Первый массив содержит начальные изображения
JSBillboardArray = new Array ( 3 ) ;
JSBillboardArray[0] = new Image ( 49, 333 ;
JSBillboardArray[0].src = "./visjs.gif";
JSBillboardArray[1] = new Image ( 49, 333 )
JSBillboardArray[1].src = "./url.gif";
JSBillboardArray [2] = new Image ( 49, 333 ) ;
JSBillboardArray[2].src = "./bltwith.gif";
// Второй массив содержит
// изображения
transArray = new Array ( 6
transArray [0] = new Image (
transArray[0].src = "./bw7
transArray[1] = new :
transArray[1].src =
transArray[2] = new
transArray[2] .src =
new
transArray [3] .. src =
transArray [4] = new
transArray [4] ,. src ¦
— new
transArray[5J . src =
/bw6
Image (
"./bw5
Image(
" . /bw4
Image (
•' . /bw3
Image(
11. /bw2
переходные
49, 333 ) ,
•gif";
49, 33 1 )
.gif";
49, 333 ¦
.gif";
49, 333 ]
.gif";
49, 333
.gif";
49, 333
.gif";
Главной функцией, которая используетсядля запус-
запуска баннера, является runJSBillboard(). Сначала она оп-
определяет интенсивность изменения каждого цикла ото-
отображения баннера. Затем это значение применяется для
вызова рекурсивного метода setTimeout(). В конечном
итоге функция runJSBillboardO вызывает вторую фун-
функцию repaint ():
function runJSBillboardO {
changeRate = DISPIAY_TIME +
( transArray. length * TRANSITIONJTIME ) ;
setTimeout( "runJSBillboardO" , changeRate );
repaintO ;
Функция repaint() является основой баннера в.
JavaScript. Она определяет изображение, выводимое на
экран в данном цикле. Первые на очереди — переход-
переходные изображения. Далее на арену выходит функция
repaint(), которая проверяет их состояния и определя-
определяет, должен ли завершиться цикл. Если это действительно
так, активизируется раздел кода if, выводящий на экран
Технологии программирования на динамическом HTML
Часть IV
текущее начальное изображение. В противном случае в
действие вступает раздел кода else:
function repaint () (
if ( transldx > transArray. length - 1 ) {
primaryldx-H- ;
transldx = 0 ;
if ( primaryldx > JSBillboardArray. length - 1 >
primaryldx = 0;
document.billboard.src =
JSBillboardArray[primaryldx].src;
return;
)else{
document.billboard.src =
transArray[transldx],src;
setTimeout( "repaint()", TRANSITIONJTIME ) ;
}
transldx++;
Функция repaintO заслуживает чуть большего вни-
внимания. Раздел if предназначен для вывода на экран на-
начального изображения, в особенности того, что является
текущим в JSBillboardArray. Если это условие выполня-
выполняется, переменная transldx получает значение 0. В сле-
следующий раз переходный цикл начинается с repaint().
Необходимо проверить, возвратилась ли в исходное со-
состояние primaryldx и вернуть управление вызывающей
Функции runJSBillboard().
Благодаря рекурсивному характеру runJSBillboard,
функция repaintO сразу же выполняется заново. В пос-
последний раз обрабатывался раздел if, теперь можно и не
сомневаться, что в этом цикле выполнится раздел else.
Этот раздел кода выводит на экран текущее переходное
изображение из массива transArray. else запускается при
каждом переходном цикле, пока не будет выводится
последнее переходное изображение. В следующий раз
вызывается repaintO. if возвращает в начальное состоя-
состояние все, что уже выполнялось.
ПРИМЕЧАНИЕ
Рекурсия относится к достаточно сложным принципам
программирования. Тем не менее, как видно из пос-
последнего примера, она отличается существенной мо-
мощью и изяществом.
На рис. 21.2 и 21.3 показаны экраны во время цик-
циклического процесса вывода баннера.
В листинге 21.2 предоставлен полный исходный код
реализации вывода баннера.
Листинг 21.2. Создание доски объявлений с
использованием JavaScript
<html>
<head>
<title>JavaScript Unleashed</title>
<script type="text/javascript"
languages"JavaScriptl.1">
/ / Глобальные константы
var BB_URL = 'http://www.mcp.com';
var DISPIAYJTIME = 3 500;
var TRANSITioNJTIME = 50;
./ / Глобальные переменные
var primaryldx = 0;
var transldx = 0;
// Первый массив содержит основные
// изображения
JSBillboardArray = new Array ( 3 ) ;
JSBillboardArray [0] = new Image ( 49, 333 ) ;
JSBillboardArray[0].src = "./visjs.gif";
.JSBillboardArray [1] = new Image ( 49, 333 ) ;
JSBillboardArray[1] .src = "./url.gif " ;
JSBillboardArray [2] = new Image ( 49, 333 ) ;
JSBillboardArray [2] . src. = " . /bltwith. gif" ;
// Второй массив ,содержит переходные
// изображения
transArray = new Array ( ) ;
transArray [ 0 ] = new Image ( ,49, ;,K3 ) ,-
transArray [0] .src «: ". /bw7-.gif ";
transArray [ 1 ] i= new Image ( 49 „ 333 ) ;
transArray [1] .src ¦ "./bw6..gif";.
transArray [2] = new Image ( 49, 333 ) ;
transArray [2] .src ¦ " . /bw5 ,.gif".;
transArray [3 ] = new Image ( ,.1.3, 333 \ ;
transArray [3] .src " "./bw4..gif";
transArray [ 4 ] = new Image ( 49, 333 ) ;
transArray [4] .src = '". /bwS.gif";
transArray [5] = new Image ( 49, 333 );
transArray [5] . src ¦ " . /bw2.gif";
function runJSBillboard О {
changeRate = DISPIAYJTIME +
(transArray. length * TRANS ITION_TIME);
setTimeout("runJSBillboard 0 ", changeRate);
repaintO ;
function repaintO {
if (transldx > transArray. length - 1) (
primary Idx++; // Увеличить индекс
// первичного изображения
transldx =0; // Сбросить индекс
// переходного изображения
if (primaryldx >
JSBillboardArray.length - 1){
primaryldx =0; // Сбросить
// индекс первичного изображения
;t
document.billboard.src =
JSBillboardArray[primaryldx].sic;
return; // Возврат в run JSBillboard ()
}else{
// Отобразить переходное изображение
document.billboard.src =
transArray[transldx].src;
// Рекурсивный вызов repaintO в
// цикле
setTimeout( "repaint()",
TRANSITION TIME ) ;
i
transldx++;
Увеличить индекс
переходного изображения
Визуальные эффекты
</soript>
</head>
<body onload="runJSBillboard() ">
<center>
<a href ="http: //www.mcp.com"
onmouseover="window.status=BB_URL;
return true;" oranouseout="window. status
return true;">
<img name="billboard" height=9"
width=33" src=" . /visjs .gif
</a>
</center>
</body>
</html>
i
РИСУНОК 21.2. Начальное основное изображение
Б
. (
.v::.V-^:>,^ .v:;t;b
.. ..-,: ¦:-
РИСУНОК 21.3. О из пяти переходных изображений
Постепенное изменение цветов
В данной главе рассматривались вопросы создания бан-
неров и прокручиваемых объявлений наподобие, Java-
аплетов. Не обращайте внимание на "очковтиратель-
Глава 21
ство", которое встречается в прессе: мол, Java может не
все. Дело здесь связано с одним лишь моментом — по-
постепенным изменением цвета на HTML-странице.
JavaScript может управлять HTML-документом, чего не
делает Java. Именно поэтому JavaScript работает с подоб-
подобного рода методами гораздо лучше.
РИСУНОК 21.4. Второе основное изображение
Постепенное изменение цвета выполняется при посте-
постепенном изменении значения свойства bgColor объекта
Document. Данное свойство является либо шестнадца-
шестнадцатиричным RGB-триплетом, либо строковым литералом,
представляющим RGB-триплет, например, "aqua" или
"red". Несмотря на простоту работы со строковыми ли-
литералами, при условии установки свойства bgColor на
единовременной основе, потребуется использовать ше-
шестнадцатиричные значения RGB-триплетов в формате
rrggbb.
В JavaScript можно создать функцию JSFade(), ко-
которая будет выполнять смену цвета, а затем обратиться
к этой функции во время загрузки документа. Функция
JSFade() получает несколько параметров.
Начальные значения RGB для красной, зеленой и си-
синей составляющих цвета.
•• Конечные значения RGB для красной, зеленой и си-
синей составляющих цвета.
Количество миллисекунд, необходимых для выпол-
выполнения процесса смены цвета.
Цикл for используется для пошагового выполнения
процесса. Именно с помощью параметра задержки мож-
можно определить, сколько раз сработает цикл for. Опреде-
Определяются две переменные: finishPercent — указывает на
процентную часть оставшегося процесса, startPercent —
указывает на процентную часть выполненного процес-
процесса. Основой выполнения смены цвета является приве-
Технологии программирования на динамическом HTML
Часть IV
денный ниже оператор, который присваивает значение
свойству document.bgCoIor. Значение базируется на сум-
сумме произведений начального значения красного на пе-
переменную startPercent и конечного значения красного
на переменную finishPercent. Эта же операция повторя-
повторяется также для зеленого и красного цветов.
function JSFade(startRed, startGreen, startBlue,
finishRed, finishGreen, finishBlue, delay){
for (var i = 1; i <= delay - 1,- i++) {
var flnishPercent = I/delay;
var startPercent = 1 - flnishPercent;
document.bgColor = Math.floor(startRed *
startPercent + finishRed * finishPercent) *
256 * 256 + Math, floor (startGreen *
startPercent + finishGreen * finishPercent)
* 256 + Math.floor(startBlue * startPercent +
finishBlue * finishPercent ) ;
Затем эту функцию можно вызвать в собственном
сценарии. Например, для реализации смены от цвета
белой ночи к бирюзовому, потребуется выполнить та-
такой вызов:
JSFade B55,255,2400,128,128,170)
Переход цвета от синего к красному:
JSFade @,0,198, 196,2,40,170)
От черного к белому:
JSFade @,0,0,255,255.255,170)
В листинге 21.3 представлен исходный коддля при-
примера смены цветов.
Листинг
21.3.
Использование
JavaScript
Анимированные командные кнопки
За последние три года восприятие Web существенно
изменилось. Изначально задуманная кактекстово-ори-
ентированная среда передачи информации, Web сегод-
сегодня работает с графикой, мультимедиа-информацией и
сложными страницами. Однако, единственным аспек-
аспектом устаревшего нелицеприятного вида остались объек-
объекты форм, например, текстовые поля ввода и командные
кнопки. Для этих управляющих элементов управления,
невозможно даже выбрать шрифт.
Неудивительно, что в настоящий момент многие раз-
разработчики обращаются к JavaScript с целью обеспече-
обеспечения альтернативы одному из общих элементов управле-
управления пользовательского интерфейса — кнопкам. Хотя
объекты графических кнопок пока еще не доступны, с
помощью объекта Image в JavaScript можно сымитиро-
сымитировать их поведение.
ПРИМЕЧАНИЕ \, J,.,.; . ;,.,,. , s J
Так же, как и в примере с баннерами, необходимо
сначала подготовить подходящие GIF-файлы для исполь-
использования на Web-странице.
Сейчас будет показано, как применить JavaScript
для эмуляции вида и формы кнопок в Windows 98/2000,
что впервые появилось в Microsoft Internet Explorer 3.
Кнопка имеет плоский вид, пока пользователь не наве-
наведет на ее указатель мыши, после чего она приобретает
трехмерный вид. Давайте добавим на страницу кнопки
Previous и Next, эмулирующие кнопки Prev и Next бра-
браузера.
для
смены
цвета
фона
документа _
<html>
<head>
<title>JavaScrip Unleashed</title>
<script type="text/javascript">
<! —
function JSFade (startRed, startGreen, startBlue, finishRed, finishGreen, finishBlue, delay) {
for (var i = 1; i <= delay - 1; i++) {
var finishPercent = i/delay;
var startPercent = 1 - finishPercent;
document. bgColor = Math, floor (startRed * startPercent + finishRed * finishPercent) * 256
* 256 + Math, floor (startGreen * startPercent +finishGreen * finishPercent) * 256 +
Math, floor(startBlue *startpercent + finishBlue * finishPercent ); I
</script>
¦</head>
<body>
<script type="text/javascript">
< i
JSFade( 255,255,240,0,128,128,170 ) ;
,11—>
</script>
</body>
</html>
Визуальные эффекты
Для создания анимированных кнопок потребуется
проделать следующее:
Создать заглушки для изображений на Web-страни-
Web-странице под каждую кнопку.
Определить объекты Image и поставить им в соот-
соответствие GIF- и JPG-файлы.
Создать программу для вывода изображений на эк-
экран по запросу.
Добавить код обработчика событий click для объек-
объекта Link.
Для использования объектов Image в качестве заме-
заменителей кнопок потребуется определить дескрипторы
<img>. Однако, поскольку объекты Image не способны
реагировать на события, каждое изображение следует
поместить в объекте Link:
<а href="">
<img src=" . /prev_off.gif" border="
width=2" height=2" name="prev">
<a href="">
<img src=" ./next_off.gif" border="
width=2" height=2" name="next">
Внутри дескриптора <script> раздела <head>
HTML-документа необходимо определить объекты
Image для каждого из четырех используемых изображе-
изображений: два, представляющих плоский вид кнопки, и два,
представляющих трехмерный вид кнопки. Также объек-
объекты Image потребуется связать со внешними файлами:
var prevBtnOff = new Image ( 42, 52 ) ;
prevBtnOff.src = "./prev_off.gif";
var prevBtnOn = new Image ( 42 , 52 );
prevBtnOn.src = ''./prev_on. gif" ;
var nextBtnOff = new Image ( 42, 52 ) ;
nextBtnOf ?. src = "./next__off.gif";
var nextBtnOn = new Image ( 42, 52" ) ;
nextBtnOn,src = "./next_on.gif";
Итак, заглушки в виде дескрипторов <img> для кно-
кнопок Previous и Next определены, а экземпляры объек-
объектов Image для состояний "off и "on" созданы. Следующий
шаг заключается в добавлении функции high]ightButton(),
которая изменяет состояние изображения, выводимого
на экран по запросу.
Функция highlightButton принимает два параметра:
первый — это имя шаблона изображения <img>, а вто-
Листинг 21.4. Анимированные кнопки в JavaScript.
Глава 21
рой — это имя объекта Image, выводимого на экран. Для
ссылки на заглушки изображений <img> можно вос-
воспользоваться встроенным массивом document.images.
function highlightButton{placeholder,
imageObject) {
document. images [placeholder] . src =
eval (imageObject + ",src")
]
Сейчас необходимо вернуться к определениям дес-
дескриптора <img> и добавить в них код соответствующе-
соответствующего обработчика событий. Планируется, что при наведе-
наведении указателя мыши на две анимированные кнопки, они
приобретут трехмерный вид, имея до этого плоский вид.
Для этого потребуется добавить обработчики событий
onMouseOver или onMouseOut. При поступлении собы-
события onMouseOver вызывается функция highlightButton()
для данной кнопки. Затем, когда генерируется событие
onMouseOut, вновь вызывается функция highlightButton(),
которая обеспечит отображение выключенного состоя-
состояния кнопки:
<ahref="javascript:history.back(> "
onmouseover="highlightButton С'Prev', 'prevBtnOn');
window. status= " Previous ' ; return true; "
onmouseout="highlightButton( "Prev', 'prevBtnOff' ) ;
window . status= ' 1 ; return true; ">
<img src=" . /prev_off.gif" border="
width=2" heights2" name="Prev">
<a href="javascript:history.forwardO"
onmouseover="highlightButton( 'Next', 'nextBtnOn');
window. status= ' Next ' ; return true; "
onmouseout="highlightButton( ' Next" , ' nextBtnOff ' )
window.status=' ' ;return true;">
<img src=" ./next_off.gif" border="
width="S2" height=2" name="Next">
Последний шаг связан с добавлением кода, который
реагирует на нажатие анимированной кнопки. Посколь-
Поскольку объект Image не отвечает на событие click, следует
использовать протокол javascript: в свойстве href объек-
объекта Link. Как показано в предыдущем коде, требуемую
функциональность обеспечивают методы back() и
forward () объекта History.
Наконец, потребуется добавить код в обработчики
событий onMouseOver и onMouseOut, который обеспе-
обеспечит вывод соответствующего сообщения в строке состо-
состояния браузера.
На рис. 21.5 и 21.6 показан код в действии.
В листинге 21.4 приводится полный исходный код.
<html>
¦<head>
<title>JavaScript Unleashed</title>
<script type="text/javascript" language="JavaScriptl .
// Определение объектов изображении
Технологии программирования на динамическом HTML
Часть IV
var prevBtnOff = new Image D2, 52) ;
prevBtnOff.src = "./prev_off.gif";
var prevBtnOn — new Image D2, 52);
prevBtnOn.src = "./prev on.gif";
var nextBtnOff = new Image D2, 52);
nextBtnOff.src = "./next_off.gif";
var nextBtnOn = new Image D2, 52);
nextBtnOn, src = "./next__on.gif";
// Изменение изображения, выведенного на экран
function highlightButton(placeholder, imageObject) {
document.images[placeholder].src = eval(imageObject +
</script>
</head>
<body background=" ,/aiback.gif">
<center>
<a href="javascript; history.back() "
retur true;
onmouseout="highlightButton ( 'Prev', 'prevBtnOff ) ; window, status=' ' /return true ;">
<img src=" . /prev_off.gif" border=" width=2" height=2" name="Prev">
<a href="javascript:history. forward)) "
onmouseover="highlightButton( 'Next1, 'nextBtnOn') ; window, status= ' Next' ; return true
onmouseout="highlightButton ( 'Next' , 'nextBtnOff'); window, status= ' ' ;retuj:n true;">
<img src=" . /next_off.gif" border=" width="!
</center>
</body>
</html>
РИСУНОК 21.5. Кнопки в стандартном начальном состоянии.
Резюме
Давайте посмотрим правде в глаза: многие Web-сайты
скучны и совсем не привлекают внимания. Сам по себе
HTML не может сделать ничего более лучшего, нежели
просто поместить плоское изображение на страницу и
вывести его на экран. Для придания большей живости
HTML многие разработчики используют Java-аплеты.
РИСУНОК 21.6. Кнопка Previous приобретает трехмерный вид,
когда на нее наводится указатель мыши.
По мере развития JavaScript, все больше и больше про-
программистов отдают предпочтение этому языку.
В JavaScript 1.1 и 1.2 появились новые возможности
совершенствования внешнего вида Web-сайта. В этой
главе рассматривались четыре наиболее ПОГ
способа создания спецэффектов с использованием
JavaScript: бегущие строки, баннеры, анимир!
кнопки и постепенное изменение цвета.
Каскадные таблицы стилей
В ЭТОЙ ГЛАВЕ
Основные концепции таблиц стилей
Использование стилей в документах
Объекты стилей в JavaScript
Появление каскадных таблиц стилей (CSS) в HTML
дало разработчикам возможность акцентировать внима-
внимание на стиле, совершенствовать внешний вид докумен-
документов и определять для них более совместимые стили.
Перед появлением CSS одним из главных недостатков
публикации информации в Web было отсутствие воз-
возможности управления существующими в тот момент
настольными издательскими средствами. Необходимо
было придумывать различные обходные пути, чтобы все
элементы располагались в правильных местах, а шриф-
шрифты были необходимого размера и вида. Для расположе-
расположения элементов в нужном порядке разработчики зачас-
зачастую прибегали к HTML-таблицам, однако сбои в работе
браузеров сводили на нет все старания.
Весь этот кошмар закончился, когда CSS стали ре-
рекомендацией на Консорциуме World Wide Web (W3C).
CSS помогли разработчикам точно устанавливать шриф-
шрифты, размеры текста и расположение элементов (CSS
positioning, CSS-P).
В главе рассматриваются CSS, а также массивы
Navigator, позволяющие работать со стилями. Это не
значит, что будут исследоваться буквально все аспекты
CSS. Дабы упростить чтение глав 23 и 24 (посвящен-
(посвященных динамическому HTML), приводятся только самые
главные характеристики.
«примечание' ."'¦ ¦"; ,. ';¦':'.
В этой книге не предусмотрено подробное рассмот-
рассмотрение CSS. Исчерпывающее описание CSS может быть
найдено на сайте: http://www.w3.org.
Основные концепции таблиц стилей
Таблица стилей состоит из одного и более параметров
(размер шрифта, стиль шрифта, выравнивание текста,
цвет шрифта и фона, границы, заполнение, высота строк
и т.д.) элементов HTML, которые могут быть связаны или
внедрены в HTML-документы. Данная функция обеспе-
обеспечивает для Web-дизайнеров возможность четко устанав-
устанавливать стиль и расположение по всему документу.
На протяжении следующих нескольких страниц
производится знакомство с этой технологией и расска-
рассказывается, как применить ее в JavaScript. Кроме того
детально описывается методика использования CSS,
поскольку они являются неотъемлемой частью данной
технологии.
Стандарты
Для широкомасштабного внедрения любого вида техно-
технологии необходимо определиться со стандартами или
формализованными методами реализации. CSS вместе
со многими стандартами, используемыми на сегодняш-
сегодняшний день, поддерживается Консорциумом World Wide
Web (W3C). Рассмотрим коротко рекомендацию CSS.
CSS Level 1 (Уровень 1 CSS)
В декабре 1996 г. первая версия CSS приобрела офици-
официальный характер в W3C. Это была первая попытка со-
создания стандартного метода применения стилей в Web-
документах. Такой прогрессивный шаг открыл для
разработчиков новые возможности по усовершенствова-
усовершенствованию документов.
Однако, даже последние обновления рекомендации
в январе 1999 г. не содержали достаточных вещей, не-
необходимых разработчику (таких как способность распо-
располагать элементы на странице). Кроме того, в ней не учи-
учитывались портативные и беспроводные устройства.
Технологии программирования на динамическом HTML
Часть IV
CSS-P
В августе 1997 г. W3C выдал рекомендации по позици-
позиционированию при помощи каскадированых таблиц сти-
стилей (CSS-P). Рекомендация содержала набор свойств,,
позволяющих разработчикам открыто определять распо-
расположение элементов на странице. В комбинации с CSS
все это существенно усилило управление над минималь-
минимальными частицами изображения, обеспечив возможность
создания стильных страниц. Комбинации CSS1 и CSS-
Р были впервые внедрены в браузеры Navigator 4, Internet
Explorer 4 и Opera 3.5.
Level 2 Enhancements (Усовершенствования
уровня 2)
Вторая версия рекомендации CSS, CSS Level 2 или, для
краткости, CSS2 может выполнять дополнительные
операции. Во-первых, рекомендации CSS1 и CSS-P
были объединены в отдельную рекомендацию. Была ре-
реализована концепция медиа-типов, что больше соответ-
соответствовало требованиям стилизации печатного материала.
Добавилось понятие данных, необходимыхустройствам
доступа к Internet. Плюс ко всему, в CSS2 была введена
спецификация вида курсора или указателя для указа-
указательных устройств.
Предложения по поводу Level 3
Группа CSS консорциума W3C на данный момент ра-
работают над уровнем 3 — CSS Level 3 (CSS3). Эта после-
последняя разработка пока еще не готова. В ней предусматри-
предусматривается не только поддержка масштабируемой векторной
графики и интернационализации, но также и ряд усо-
вершенствованийпользовательского интерфейса. Имен-
Именно данная версия должна больше всего приблизить CSS
к глобально поддерживаемой рекомендации. Подобное
влияние HTML 4 оказал на HTML.
Наследование
При определении стилей необходимо помнить о кон-
концепции наследования. Термин наследование (inheritance)
используется для обозначения процесса передачи
свойств от родительского элемента к дочернему. Поня-
Понятия родительский (parent) и дочерний (child) элементов
относятся к HTML-элементам. Они группируются внут-
внутри других элементов. Таблицы стилей позволяют уста-
устанавливать глобальный стиль для документов, а также
обеспечивают возможность передачи стилей другим эле-
элементам внутри элементов, таким образом сокращая вре-
время на определение стиля для каждого из элементов.
Например, внутри элемента <body> могут находиться
дочерние элементы, включая <Ы> и <р>, внутри ко-
которых содержится еще некоторое число дочерних эле-
элементов (например, <ет>). Стиль родительского эле-
элемента наследуется дочерними элементами, если у
последних присутствуют какие-то свойства. Несложно
убедиться, что <р> внутри <body> получит размер
шрифта <body>, если только в <р> он не будет заме-
заменен. Стили наследуются внутри контейнеров, для ко-
которых они определяются. Эта способность обеспечива-
обеспечивает необходимый вид и форму документа.
Размеры шрифта, размещение текста, границы -
наглядные примеры того, как таблицы стилей придают
Web-сайту большую логичность и последовательность.
За счет определения стилей глобально внутри родитель-
родительских элементов происходит их наследование дочерни-
дочерними элементами документа. Все документы могут иметь
одинаковый вид, пока у разработчика есть возможность
управления стилями и их замены во время рабочего се-
сеанса.
.ПРИМЕЧАНИЕ :v i= v"Pc ; . , . Z> ¦*¦>
Очень часто встречаются не унаследованные стили.
Если свойства порожденного объекта отличаются от
свойств исходного объекта, стиль наследоваться не
должен.
Границы и заполнение текста пробелами
С помощью CSS можно определить границы, обрамле-
обрамление и заполнение текста пробелами для элементов блоч-
блочного уровня. Элементы блочного уровня — это такие
элементы, как <hl>, <р>, которые всегда начинаются
с новой строки. Эти свойства позволяют задавать раз-
различные элементы, начиная с границ и завершая обрам-
обрамлением.
Комментарии
Далеко не каждый код может обойтись без коммента-
комментариев. Написание комментариев в CSS напоминает оп-
определение комментариев в других языках программиро-
программирования, за исключением тех, что поддерживают
общеизвестные многострочные комментарии. Напри-
Например,
/* комментарий типа 1*/
вполне приемлемый формат комментария в CSS.
Использование стилей в документах
Существует множество различных методов использова-
использования стилей в документах. Их можно встраивать, исполь-
используя атрибут style внутри секции <style>, или присоеди-
присоединять, используя дескриптор <Iink>. Кроме методов
определения стилей в документе, существуют и спосо-
способы их применения. Стили можно применять глобаль-
глобально, присваивая класс с атрибутом class или на индиви-
индивидуальной основе при помощи атрибута id.
Каскадные таблицы стилей
Глава 22
Определение стилей
Как упоминалось ранее, стили можно определять одним
из трех способов. Под словосочетанием "определение
стилей" подразумевается три расположения стилей. Эти
методы определения стилей применяются при создании
документа, использующего таблицы стилей. Определен-
Определенного способа выполнения данной операции не суще-
существует. Постарайтесь решить эту задачу как можно бо-
более практично.
<style>
Первое размещение определяемого стиля — внутри дес-
дескриптора <style>. Этот дескриптор принимает един-
единственный атрибут (type), сообщающий браузеру о виде
определяемого стиля. Значением данного атрибута для
CSS является text/ess. Между открывающим и закры-
закрывающим дескрипторами находится определение стиля.
В примере показаны четыре различных стиля, которые
применялись к основной текстовой части документа.
Рисунок 22.1 демонстрирует результат загрузки в брау-
браузер. Не переживайте по поводу существования различ-
различных стилей; этот вопрос будет рассматриваться позже.
|
G*tttt, it з« ;, wtdspauii J^ tfi J
Point size of24
Here is some CAP1TAUJ text
РИСУНОК 22.1. Изменение класса для заголовка текста
Листинг 22.1. Определение стилей в дескрипторе
<style>
<html>
<head>
<style type="text/css">
Ы{
color: green;
font-style: italic-
font-size: 12pt;
\
font-size: 24pt;
. newheader{
color: yellow/
#caps<
font-variant: small-caps;
</style>
</head>
<body>
<hl>Green, italic, and a point size of 12</hl>
<hl class="newheader">Yellow, italic, and a
point size of 12</hl>
<hl class="special">Point size of 24</hl>
<P>
Here is some <span i.d="caps ">capitalized
</span> text.
</body>
</html>
hi.special {
<ltnk>
Если пользователь желает, чтобы стили хранились или
устанавливались в едином местоположении, а измене-
изменения выполнялись глобально по всей странице, необходи-
необходимо использовать элемент <link>. Он выполняет функ-
функцию связывания внешних таблиц стилей и помещение
их в документ. Атрибуты элемента <link> (type и href)'
используются для определения типа связи и URL, по
которому размещается внешняя таблица стилей.
Внешние таблицы стилей аналогичны CSS, опреде-
определенным внутри документа. Таблица стилей хранится по
конкретному URL-адресу. HTML-элементы <style> и
</style> в данном случае не нужны. Этот элемент дол-
должен содержаться в разделе <head>. В следующем при-
примере будет показано, как включать таблицу стилей
chapters.css в документ:
<head>
<link rel="stylesheet" type="text/ess"
href="http://www.mcp.com/stylesheets/
chapters.css">
</head>
Атрибут style
Последний метод определения стилей и включения их
в документ связан с использованием атрибута style лю-
любого текстового элемента HTML. Атрибут style приме-
применяется для определения нового стиля, используемого
только для определенного элемента экземпляра. Это
обеспечивает возможность каждому элементу обладать
своим собственным стилем, независимым от других оп-
определенных сталей текущей таблицы стилей. С
низкого уровня включает в себя определение
J для конкретного экземпляра элемента. С
Технологии программированияна динамическом HTML
Часть IV
color: yellow;
#myid{
font-size: 12pt,-
</style>
</head>
<body>
<hl>Green</hl>
<hl class="newheader" id="myid">Yellow and
point size 12</hl>
<hl class="newheader">Yellow and <span
id=" ital" >italic</ spanx/hl>
<h2>This will be default text<h2>
</body>
</html>
Определение старшинства стиля
Чтобы определиться со значением или старшинством
стиля элемента либо свойства, необходимо придержи-
придерживаться следующих правил:
1. Размещайте все ссылки на элемент с помощью се-
селекторов.,
2. Сортируйте ссылки с использованием явных весов.
3. Сортировка должна выполняться от корня таблицы
стилей. Значения по умолчанию заменяются поль-
пользовательскими таблицами стилей, а те, в свою оче-
очередь, — авторскими таблицами стилей.
4. Производите сортировку по специфичности. Рядом
с каждым из трех вариантов поставьте очко, а затем
сложите очки, чтобы получить специфичность:
Количество атрибутов id.
Количество атрибутов class.
Количество имен дескрипторов, на которые осу-
осуществлялись ссылки.
5. Выполняйте сортировку по порядку специфичнос-
специфичности. Из двух правил, одинаковых по весу, преиму-
преимущественным будет последнее.
Объекты стилей в JavaScript
JavaScript 1.2 были введены три новых объекта — tag,
class и id. Они используются в таблицах стиля Эти
объекты применяются для определения типов сталей
"тили можно определить как во внешних таблицах сти-
стилей,
связанных с HTML-документами, так и в самом
документе внутри дескрипторов <style> и </sty!e>
? ПРИМЕЧАНИЕ "*
другие браузеры могут поддерживать или не поддер-
поддерживать действия этого метода, обязательно примите
решение относительно использования этих дескрипто-
дескрипторов для присваивания стилей.
document.tags
На данный момент только
Массив document.tags — это ссылка на дескрипторы
HTML; в действительности, он является подобъектом
объекта Document. После определения следует элемент,
к которому применяется данный массив. За элементом
расположено описание, которое является уже опреде-
определенным свойством стиля (имя которого не всегда совпа-
совпадает с именем, определенным в CSS). Синтаксически
все дескрипторы <р> должны иметь размер шрифта в
20 пунктов:
document, tags -p. fontSize = 0pt" ;
document.classes
document-classes -- массив и подобъект объекта
Document. В данном массиве имеется доступ к дескрип-
дескрипторам со специальным атрибутом class. Класс стилей
используется для одного элемента:
document.classes.fontclass.blockquote.fontSize =
Opt";
Или же он может быть доступен для всех элементов:
document.classes.fontclass. all.fontSize = 0pt";
За объектом в точечной нотации следует имя клас-
класса, а затем элемент, для которого определяется класс.
Классы, определяемые как а», можно применять ко
всем элементам, что продемонстрировано во втором при-
примере.
document.ids
Объект document.ids напоминает document.classes, раз-
различие состоит лишь в том, что некоторые элементы
относящиеся к id, визуализируются с использование1
определенного стиля.
document.ids.myid.fontSize = 0pt";
За дескриптором объекта document.ids следует им id
и, в отличии от объектов document.classes и docHfiiemltags,
оно не воспринимает имя элемента как часть ОПр:деле-
ния. Объекты document.ids используются вместе: эле-
элементами, к которым применяются.
Свойства
В табл. 22.1 приводятся СВОЙСТВА, ХЗОМШЙП ш
объектов стилей JavaScript. М№ЩШ Ш
Таблица 22.1
Имя свойства
.Свойства объектов стилей
К чему применяется
JavaScript
Возможные
значения
каскаоные таблицы стилей ЕТ!П
Глава 22 Ш1
Определение значений
fontSize
IborderS tyle
width
length
align
color
backgroundlmage
backgroundColor
display
listStyleType
whiteS pace
Все элементы
Свойства шрифта
Абсолютные размеры
Относительные размеры
Процентость
fontStyle
lineHeight
verticalAligm
text Decoration
textTransform
textAlign
textlndent
paddings()
borderWidthsQ
imarginsf)
Все элементы
Элементы блочного уровня
Все элементы
Все элементы
Все элементы
Элементы блочного уровня
Элементы блочного уровня
Все элементы
'Все элементы
Все элементы
Свойства текста
Число
Длина
Процентость
Длина
Процентность
Свойства блочного уровня
Число
Процентность
Число
Длина
Процентность
Автоматизация
Свойства блочного уровня
Все элементы
Элементы блочного уровня Длина
Процентность
Автоматизация
Элементы блочного уровня Длина
Автоматизация
Все элементы
Все элементы
Все элементы
Все элементы
Свойство цвета
Цвет
Цвет
Классификационные свойства
Все элементы
Элементы со свойством display
Элементы блочного уровня Normal и рге
x-small, small, medium, large, x-large,
размер в пунктах
smaller, larger
На 150% больше
normal, italic, oblique, small-caps
Количество единиц для увеличения высоты
Абсолютное значение высоты линии
Процент от родительского элемента
baseline, sub, sup, top, text-top, middle,
bottom, text-bottom
none, underline, overline, line-through, blink
capitalize, uppercase, lowercase, none
left, right, center, justify
Количество единиц для отступа
Процент от родительского элемента
Количество единиц для заполнения
Процент от родительского элемента
Количество единиц для ширины рамки
Границы в единицах
Процент от родительского элемента
Документ автоматически определяет
границы
шопе, solid, 3D
Ширина в единицах
Процент от родительского элемента
Документ автоматически определяет
ширину
Длина в единицах
Документ автоматически определяет длину
left, right, none
Имена цветов, цвета RGB.
URL
Имена цветов, цвета RGB.
block, inline, list-item, none
disc, circle, square, decimal, lower-roman,
upper-roman, lower-alpha upper-alpha, none
Технологии программирования на динамическом HTML
Часть IV
Резюме
Появление таблиц стилей предоставило разработчикам
большие возможности по управлению внешним видом
документов. Можно определять стили по умолчанию
внутренне и внешне, и применять их ко множеству эле-
элементов. В настоящий момент доступно большое коли-
количество свойств стилей, что позволяет разработчикам
взять под полный контроль внешний вид содержимого.
Слои
В ЭТОЙ ГЛАВЕ
Универсальные действия
<div> и <iframe>
<1ауег> и <ilayer>
До недавнего времени одним из фундаментальных
ограничений Web-страниц была невозможность распо-
расположения текста или изображений точно в указанном
месте на странице. Кроме того, не существовало спосо-
способов наложения HTML-элементов друг на друга. Один
из наиболее полезных в плане творчества аспектов но-
новых браузеров — поддержка слоев. Слои (layers) позво-
позволяют создавать накладывающиеся прозрачные или
непрозрачные элементы с содержанием в HTML-доку-
HTML-документе, которые вдобавок можно устанавливать точно в
указанном месте. Слои реализуются с помощью несколь-
нескольких различных методов, и те, кто хорошо знаком с из-
издательским миром Web, знают, что именно это чаще
всего приводит в замешательство.
В мире вне браузера Navigator 4 слои создавались с
использованием HTML-дескриптора и многократного
применения свойств позиционирования таблицы стилей
(CSS). отображения и управления порядком располо-
расположения дескрипторов. По своей природе дескриптор
<div> (разделение данных) был логически наиболее
подходящим для создания слоев, и именно его обычно
использовали. Теперь существует Navigator 4, который
был выпущен с набором программ инструментальных
средств для Internet Netscape Communicator в 1997 г.
Navigator 4 содержит два новых дескриптора: <1ауег>
и <ilayer> ("i" обозначает inflow — внутрипотоковый). Эти
дескрипторы предоставили различные пути от стандар-
стандартного использования дескрипторов <div>, которые под-
поддерживает Navigator, до создания слоев в HTML-доку-
HTML-документе. В отличие от дескриптора <div>, дескрипторы
<1ауег> и <ilayer> имеют атрибуты, которые, в сущно-
сущности, позволяют "стилизировать" их. Для создания слоя
с абсолютным позиционированием (т.е. размещения
данного слоя по определенным координатам) исполь-
используют дескриптор <Iayer>. Для создания слоя с относи-
относительным позиционированием (который появляется там,
где размещают дескриптор на HTML-странице) приме-
применяется дескриптор <Науег>.
Единственная реальная выгода от этих двух деск-
дескрипторов Netscape, кроме возможности их стилизации
в пределах атрибутов (что является очень незначитель-
незначительной выгодой), — это возможность помещения в них вне-
внешних HTML-файлов. Такое помещение выполняется с
использованием атрибута дескриптора src. Однако, это-
этому аргументу можно противопоставить существование
дескриптора <iframe> ("i" здесь означает inline — встро-
встроенный), который является частью Рекомендаций для
HTML 4 и имеет возможность стилизации CSS с теми
же самыми функциональными возможностями. К сожа-
сожалению, Navigator 4 не поддерживает этот дескриптор.
В результате получается расхождение в способах созда-
создания слоев.
^ПРИМЕЧАНИЕ . '.
Сказанное выше, вероятно, может вызвать головную
боль, к тому же возникает вопрос — зачем вообще
связываться со слоями? Давайте разберемся. Как упо-
упоминалось ранее, реальная проблема состоит в том,
что Navigator 4 вышел за рамки стандартов. Однако
еще есть надежда: Navigator 5 и 6, браузеры с откры-
открытым кодом (Open Source) от Mozilla.org, поддержива-
поддерживают CSS и HTML 4, включая стили, необходимые для по-
позиционирования, а также дескрипторы типа <iframe>
для помещения внешних файлов.
Этот раздел посвящен специфике создания слоев.
Более подробно они будут рассматриваться позже в гла-
главе, а сейчас можно оценить их использование и выго-
выгоды, которые обеспечивают слои. В этой главе обсужда-
обсуждается не только ряд универсальных действий, но также
и действия при использовании методов <div> / <iframe>
и <layer> / <ilayer> для создания слоев.
Технологии программирования на динамическом HTML
Часть IV
Универсальные действия
Несмотря на расхождения в способах создания слоев, о
котором упоминалось ранее, все движется к более уни-
универсальной реализации. В этом разделе рассматривают-
рассматриваются некоторые универсальные действия и теоретические
аспекты, которые не зависят от метода создания слоев
на Web-страницах.
Использование таблиц стилей для создания
слоев
Как было сказано во введении к главе, стандартный
способ реализации слоев состоит в том, чтобы управлять
ими с помощью таблиц стилей. Этот способ включает
все — от позиционирования и моделирования данных,
содержащихся в слое, до расположения и визуализации
слоев. Свойства CSS перечислены в приведенном ниже
списке.
• position
• left, ight, top и bottom
• height и width
• z-index
• visibility
ПРИМЕЧАНИЕ
Обратите внимание, что в этой главе не будут рассмат-
рассматриваться абсолютно все свойства CSS. Дополнительную
информацию о таблицах стилей можно получить в гла-
главе 22.
. ¦:¦- :;*¦¦ ¦:. . . . . ¦ . ¦ .........
position
Свойство position используется для сообщения браузе-
браузеру, как и где размещать элементы, к которым применя-
применяется это свойство. Существует четыре различных значе-
значения этого свойства (см. табл. 23.1).
Для лучшего понимания работы этих свойств рас-
рассмотрим листинг 23.1. В этом листинге три дескрипто-
дескриптора <р> помещены в раздел <body> документа. Каждый
из них имеет имя и ID (идентификатор) стиля. В раз-
разделе <head> документа каждому 11 > присвоен свой цвет
фона (для отображения различий), а также значения left
и top. Обратите внимание, что свойство position установ-
установлено в absolute. На рис. 23.1 показан результат отобра-
отображения в браузере Internet Explorer.
ПРИМЕЧАНИЕ
В примере преднамеренно не используется дескрип-
дескриптор <div> для демонстрации того, что эти типы сти-
стилей могут применяться к любому элементу.
. Redo О Phy ф
ЯШ
J
:iomft InternetExploter
SI HiloSlalwtj • .:j CairMsJOS .
: ¦ 1 Links "
РИСУНОК 23. '{.Абсолютное позиционирование
HTML-элементов..
Листинг 23.1. Абсолютное позиционирование
HTML-элементов с помощью свойств CSS.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/ess">
#first{
background-color: green;
left: 0 ;
position: absolute,-
top: 0 ;
Isecond{
background-color : red;
left: 30;
position: absolute;
top: 3 0;
#third{
background-color: blue;
left: 60;
position: absolute;
top: 60;
</style>
</head>
<body>
<p name="layerl" id="first">
Layer 1
<p name="layer2" id="second">
Layer 2
<p name="Iayer3" id="third">
Layer 3
... . : . . :...
</body>
</html>
Слои
Глава 23
Таблица 23.1. Значения свойства position.
Значение
Описание
absolute Это значение сообщает браузеру, что будут определяться абсолютные координаты элемента. При
использовании данного значения применяются также свойства top и left. Если они не определены, браузер
полагает, что координаты х и у (верхний левый угол окна браузера) равны 0.
fixed Это значение аналогично absolute, за исключением того, что не перемещается при прокрутке окна.
relative Это значение позволяет сдвигать заданный элемент относительно предыдущего элемента.
static Это значение по умолчанию, которое используется в визуализации HTML в современных версиях браузеров.
left, right, top и bottom
Как видно из предыдущего примера, существуют неко-
некоторые CSS-свойства, которые позволяют определять
точное расположение элемента. Эти свойства, имеющие
числовые значения для координат, нельзя использовать
все сразу. Например, элемент не может установить свой-
свойство right, если уже установлено свойство left. To же са-
самое можно сказать и относительно свойств top и bottom.
Если попытаться сделать это, большинство браузеров по
умолчанию перейдут к значениям свойства, заданным
последним в определении используемых стилей.
Например, рассмотрим листинг 23.2, который пред-
представляет собой расширение предыдущего листинга за
счет добавления четвертого слоя и определения стилей.
Применялись различные комбинации свойств right, left,
top и bottom для размещения блоков в каждом из четы-
четырех углов окна браузера (рис. 23.2).
Листинг 23.2. Использование свойств right, left, top
и bottom.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
<! —
#first{
background-color: green;
left: 0 ;
position: absolute;
top: 0 ;
1
ttsecond(
background-color: red;
position: absolute;
right: 0 ;
top: 0 ,-
#third{
background-color: blue;
bottom: 0 ;
position: absolute;
right: 0 ;
«fourth{
background-color: yellow;
bottom: 0 ;
left: o,
position: absolute;
</style>
</head>
<body>
<p name="layerl" id="first">
Layer 1
<p name="layer2" id="second">
Layer 2
<p name="layer3" id="third">
Layer 3
<p name:
Layer 4
</body>
</html>
;:¦?»!¦¦ ?d* '-.View fjv«
A*ISS |«JrMEMP\763>OiJ.(l'lrirrJ
Layer 4
РИСУНОК 23.2. Определение правой, левой, верхней и нижней
позиций HTML-элементов.
height и width
Следующие два свойства позволяют определять высоту
и ширину слоев. Именно поэтому они носят названия
height и width. Подобно свойствам, которые позволяют
определять расположение слоев, эти два свойства при-
принимают числовые значения для определения того, на-
Технологии программирования на дшшмическом HTML
Часть IV
сколько высоким и широким должен быть слой. Лис-
Листинг 23.3 продолжает совершенствовать предыдущий
пример, определяя для четырех слоев значения height
и width. Результат можно увидеть на рис. 23.3.
Листинг 23.3. Использование height и width для
определения размера слоев.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
^ i
#first{
background-color: green;
height:20;
left: 0 ;
position: absolute;
top: 0
width; 40;
#second(
background-color: red,-
height:10;
position: absolute;
right: 0 ;
top: 0 ;
width: 30;
}¦
#third{
: blue;
bottom: 0;
height:100;
position: absolute;
right: 0;
width: SO;
i
#fourth{
background-color: yellow;
bottom: 0;
height:100;
left: 0;
position: absolute;
width: 200,-
</style>
</head>
<body>
<p name="layerl" id="first">
Layer 1
<p name="layer2" id="second">
Layer 2
<p name="Iayer3" id="third">
Layer 3
<p nami
Layer 4
ipt Unleashed - Mirai.so» Inlumel Endow
Layer 4
I
•
</body>
</html>
РИСУНОК 23.3. Определение высоты и ширины слоев.
z-index
Наступило время разобраться в терминологии слоев. До
этого только определялось как выглядят слои — их сти-
стилевые характеристики. Теперь слои будут располагать-
располагаться так, чтобы получить эффект наложения слоев друг
на друга. Для этого используется свойство z-index.
Свойство z-index содержит числовое значение, ко-
которое определяет расположение слоя относительно окна
браузера, которое по умолчанию является нулевым @).
Установка для z-index значения 1 о г. что слой
размещается поверх окна браузера. Это nopHj в ко-
котором слои появляются на странице. При этом, если
имеются накладывающиеся друг на друга слои, и у
одного из них z-index равен I. то он наложитоя на дру-
другой. Помните, что окно браузера имеет z-index, равный
О, и располагается под слоем 1.
Прежде чем перейти к примеру, посмотрим на лис-
листинг 23.4. В нем есть четыре накладывающихся слоя.
Они накладываются не потому, что для них установле-
установлены значения z-index, а из-за порядка, в котором они по-
появляются в документе. Первый слой — самый \ ижний,
затем следует второй, третий и четвертый (см. рис. 23.4).
Листинг 23.4. Слои с накладывающимися
координатами.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
#first{
background-color: green;
height: 100;
left: 0;
position: absolute;
top: 0
width: 100;
Слои
Глава 23
#second{
iund-color: red;
height: 100
left: 20;
position: absolute;
top: 20;
width: 100;
I
#third{
background-color: blue;
height: 100
left: 40;
position: absolute;
top: 40;
width: 100;
#fourth{
; yellow;
height: 100;
left:
position: absolute;
top: 60;
width:
</sty.te>
</head>
<body>
<p name=" layer 1" id="first">
Layer 1
name="layer2" id="second">
Layer 2
name="layer3" id="third">
Layer 3
<p name="layer4"
Layer 4
</body>
</html>
Как видно из предыдущего примера, порядок слоев
играет важную роль при их отображении. Они действи-
действительно уложены друг поверх друга? Нет — это только
так кажется. Их можно упорядочить, определяя свой-
свойство index. Конечно, если разместить их в том же
порядке, они будут выглядеть точно так же, поэтому
данное свойство чаще всего используется для изменения
порядка, а не для определения стандартного (по умол-
умолчанию) порядка при создании Web-страниц.
Рассмотрим листинг 23.5. Здесь для первого и тре-
слоев устанавливаются значения z-index. По-
Поскольку первый слой должен быть верхним, его z-
index равно 2, a z-index третьего слоя равно 1. На рис.
23.5 показан результат загрузки кода из этого листинга
в браузер.
ja JavdSi;ii|il Unleashed - Mniosoll Inteinol Eiploiei
jit Ц- Vo Fortes Is*
РИСУНОК 23.4. Слои, накладывающиеся из-за порядка
следования в документе.
Листинг 23.5. Изменения значения z-index слоев.
<html>
<head>
< ti tle> JavaScrip t Unleashed*:/ ti tle>
<style type="text/css">
<>—
#first{
background-color: green;
height: 100;
left: 0;
position: absolute;
top: 0 ;
width: 100;
z-index: 2;
#second{
background-color: red;
height: 100;
left: 20;
position: absolute;
top: 20;
width: 100;
I
#third{
background-color: blue ;
height: 100;
left: 40;
position: absolute;
top: 40 ;
width: 100;
z-index: 1;
ttfourth{
: yellow;
height:
left:
position: absolute;
top:
width: 100;
Технологии программирования на динамическом HTML
Часть IV
</style>
</head>
<body>
<р name="layerl" id="first">
Layer 1
<p name="layer2" id="s
Layer 2
<p name="layer3" id="third">
Layer 3
<p name="layer4" id="fourth">
Layer 4
</body>
</html>
РИСУНОК 23.5. Изменение наложения слоев из предыдущего
примера..
visibility
Последнее из рассматриваемых свойств — visibility, ко-
которое принимает четыре разных значения, перечислен-
перечисленные в табл. 23.2. Как и следовало ожидать, это свойство
отвечает за сокрытие и отображение слоев.
Для демонстрации использования этого свойства
возьмем код предыдущего примера и добавим к нему две
строки. Помните два слоя, для которых устанавливались
значения z-index? При этом они стали самыми верхни-
верхними на странице. В определении стиля установим их зна-
значения visibility в hidden. Листинг 23.6 содержит данный
код, а рис. 23.6 демонстрирует, что эти два слоя теперь
не видны.
Листинг 23.6. Использование свойства visibility для
сокрытия элементов.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
<•
#first{
background-color: green;
height: 100;
left: 0;
position: absolute;
top: 0 ;
width: 100;
z-index: 2,-
visibility: hidden;
#second{
background-color: red;
height: 100;
left: 20,-
position: absolute;
top: 20;
width: 100,-
#third{
background- color: blue ;
height: 100;
left: 40;
position: absolute,-
top: 40;
width:
z-index: 1 ;
visibility: hidden;
j
#fourth{
background-color: yellow;
height: 100;
left: 60;
position: absolute;
top: 60;
width: 100;
</style>
</head>
<body>
<p name="layerl" id="first">
Layer 1
<p name="layer2" id=":
Layer 2
<p name="layer3" id="third">
Layer 3
<p name="layer4" id="fourth">
Layer 4
</body>
</html>
Управление накладывающимися слоями
Рассмотренные CSS-свойства позволяют создавать
интересные визуальные эффекты. Например, предполо-
предположим, что требуется отобразить на Web-странице неко-
некоторую диаграмму с отчетными данными. Цель заклю-
заключается в отображении одной диаграммы в каждый
момент времени и предоставлении пользователю воз-
возможностей просмотра других диаграмм.
Слои
Глава 23
Таблица 23.2. Значения свойства visibility.
Значение
Описание
collapse Это значение аналогично collapse (см. ниже) всегда, кроме случаев использования в таблицах,
hidden Это значение скрывает элемент.
inherit Это значение по умолчанию, определенное в браузере; принимает то же самое значение, что и его
родительский элемент.
visible Это значение делает элемент видимым.
РИСУНОК 23.6. Сокрытие слоев.
Возможно, те, кто работает в среде Windows, вспом-
вспомнят, что для достижения подобных целей можно ис-
использовать окно со вкладками (по одной вкладке для
каждой диаграммы). Точно такой же эффект на Web-
странице можно создать при помощи слоев.
Однако, при создании слоев важно помнить, что
ими необходимо эффективно управлять. Воспроизведе-
Воспроизведение вкладок, списков либо элементов меню, применяе-
применяемых в каждодневных прикладных программах, — весьма
непростое дело. Необходимо запоминать предыдущее
состояние элемента или даже набора элементов, чтобы,
когда один из них изменяется, все остальные также бы
изменялись. Например, при нажатии вне области меню
оно должно исчезать, т.е. требуется перехватывать со-
события нажатия на кнопку мыши. В данной главе эти
темы не обсуждаются; они подробно рассматриваются
в главе 24.
Создание мультипликационных эффектов
Другой интригующей возможностью слоев является
создание мультипликации. Поскольку JavaScript позво-
позволяет позиционировать слои, можно создавать рекурсив-
рекурсивные юдпрограммы, в которых слои будут как бы сколь-
скользить или прыгать по документу. Именно комбинация
HTML и JavaScript позволяет создавать динамический
HTML (DHTML).
Используя слои, JavaScript и таблицы стилей, мож-
можно создавать (с помощью HTML) элементы на страни-
странице, улучшать их внешний вид (через CSS), а также уп-
управлять этими элементами (с помощью JavaScript). С
такими модификациями, как улучшенная поддержка
DOM-модели и XML (extensible Markup Language -
расширяемый язык разметки) в браузерах, возможнос-
возможности становятся поистине безграничными.
<div> и <iframe>
Теперь, когда известны основы создания слоев, пришло
время познакомиться с их спецификой. Даже при том,
что Netscape-метод использования <1ауег> и <ilayer>
для реализации слоев был отвергнут, все же стоит о нем
поговорить позже в главе. А сейчас будет обсуждаться
более универсальный метод реализации слоев — через
дескрипторы <iframe> и <div>.
Определение блоков данных
Первый шаг в создании слоев должен заключаться в
определении блока данных, предназначенных для дан-
данного слоя. В случае браузера его окно должно считать-
считаться первым слоем. При нажатии на меню оно отобража-
отображается поверх окна — т.е. это второй слой поверх первого
слоя (окна браузера). При нажатии на выпадающем под-
подменю появляется еще один слой (который может при-
принадлежать или нет тому же уровню, что и первый).
Методом определения этих блоков данных являет-
является применение дескриптора <div>. Этот дескриптор со-
создает определенную иерархическую структуру блоков в
документе. В терминах выполнения этот дескриптор
подобен дескриптору <р>, за исключением того, что
<р> предназначен как для определения начала нового
абзаца, так и для следующих за ним данных как состав-
составляющих данный абзац. Дескриптор <div>, напротив,
только определяет данные, но не сообщает браузеру, как
их отображать.
Перед рассмотрением метода перемещения слоев или
блоков <div> изучим атрибуты этого дескриптора и их
значения. Все эти атрибуты сведены в табл. 23.3.
Технологии программирования на динамическом HTML
Часть IV
23.3. Атрибуты дескриптора <div>.
Значение Описание
align Используется для выравнивания данных, содержащихся внутри дескриптора <div>, может принимать значения
left (по левому краю), right (по правому краю), center (по центру) и usiily (по ширине). Этот атрибут был
отвергнут в пользу применения CSS.
class Разделенный запятыми список классов стилей, которые делают дескриптор экземпляром этих классов.
Определяет направление любого текста, содержащегося в дескрипторе. Значение Iti означает слева направо,
а значение > t — справа налево.
id Часто используется в таблицах стилей для определения типа стиля, который должен применяться к данным
внутри дескриптора.
Идентифицирует язык для текста внутри дескриптора.
mame Используется для именования экземпляра блока. Может применятся в JavaScript для управления слоями,
style Позволяет определять стиль внутри дескриптора, а не в таблице стилей.
title Обеспечивает более информативный заголовок для дескриптора по сравнению с дескриптором <title>,
который применяется для всего документа.
Определение блока данных
Использование дескриптора <div> — совершенно про-
простое дело. Все, что необходимо — это пространство вок-
вокруг элементов, которые необходимо определить как блок
данных. Листинг 23.7 демонстрирует, как это сделать.
Как видно из листинга, в этом примере содержится два
блока <div>. Внутри первого находятся две горизонталь-
горизонтальных линии (дескрипторы <hr>) и текст DIV 1. Во вто-
второй блок включен заголовок третьего уровня (дескрип-
(дескриптор <h3>) и абзац (дескриптор <р>). В него также
входит некоторый текст перед и после каждого блока
<div>TaK, чтобы было видно, где они начинаются и за-
заканчиваются. Результат выполнения этого листинга в
браузере Opera показан на рис. 23.7.
Листинг 23.7. Использование дескриптора <div>.
<html>
<head>
<title>JavaScript Unleashed*:/title>
</head>
<body>
Before the first block.
<div name="layerl">
<hr>
DIV 1
<hr>
After the first block.
<br>
Before the second block.
<div name="layer2">
<h3>
DIV 2
</h3>
<P>
I am inside the second DIV block.
After
</body>
</html>
the second block.
Before the first blot
DfVI
After the first block.
Before the
DIV 2
I am inside the sect
After the second bbclc
РИСУНОК 23.7. Определение блоков данных в документах.
Позиционирование блоков <div>
Теперь рассмотрим применение позиционирования к
блокам данных. Для этого необходимо присвоить свой-
свойства id дескрипторов и определить свойства ст :й для
каждого из них. Определим сначала расположение, раз-
размер и цвета фона, поскольку это очевидно. Все элемен-
элементы рассматривались ранее в главе. Листинг 23.8 содер-
содержит необходимый код, а рис. 23.8 показывает, как будет
выглядеть отображение кода в браузере. Как видно из
рисунка, позиционирование было установлено так, что-
чтобы второй блок помещался слева от первого, а первый
накладывался на часть текста.
Листинг 23.8. Применение таблиц стилей и
позиционирования к блокам <div>.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
ttflrst{
background-color: green;
height: 100;
Left: 275;
position; absolute ,¦
top: 40;
width: 100;
I
ttsecondf
background-color: red;
height: loo;
left: 100,-
position: absolute;
top: 55;
width: 100;
<7style>
</head>
<body>
Before the first block.
<div name="layerl" id="first">
<hr>
DIV 1
<hr>
After the first block.
<br>
Before the second block.
<div name="layer id="second">
<h3>
DIV 2
</h3>
I am inside the second DIV block.
After the second block.
</body>
</htirl>
/правление с помощью JavaScript
Сейчас, после П 'о как проделаны первые шаги в созда-
создании слоев и определении их характеристик, можно до-
добавлять возможности JavaScript. В этом разделе иссле-
исследуются JavaScript-способы динамических замен,
отображений и перемещений слоев.
ПРИМЕЧАНИЕ
Главная цель этой главы заключается в представлении
слоев. Если уже есть понимание методики создания
слоев и обращения к ним через JavaScript, можно
сразу перейти к главе 24, где более подробно рас-
рассматривается практическое применение этих двух тех-
технологий.
1Я вещь, которую следует понять во время изу-
изучения JavaScript для манипуляции слоями, — это синтак-
синтаксис. Из-за различий между Internet Explorer и Navigator,
к слоям обращаются различными методами.
В браузерах Navigator к слоям обращаются через мас-
массив layers. В дескрипторе <div> имеется атрибут name,
с помощью которого можно определить имя слоя. Сле-
Слои
Глава 23
дующая строка кода используется для обращения к пер-
первому слою:
document.layers ['layer']
Beforethe first block After the first block.
Before the sccondblock. Afterthe second
РИСУНОК 23.8. Позиционирование блоков данных.
В Internet Explorer, в отличие от Navigator, к слоям
обращаются через массив all. Значение, определяющее
слой, к которому обращаются, содержится не в атрибуте
name дескриптора <div>, а в атрибуте id. В предыдущем
примере для обращения к первому слою применяется
показанная ниже строка кода. Обратите внимание, что
здесь применяется first — значение атрибута id:
document.all ['first']
ПРИМЕЧАНИЕ
Это не единственный способ обращения к слоям из
кода JavaScript. Однако, это лучший способ для уче-
учета особенностей Navigator и Internet Explorer, посколь-
поскольку он требует минимального объема кодирования.
В среде Navigator можно обращаться к свойствам слоя
сразу же после объявления document.layers[7aj>e/'j'Vame1].
Для случая Internet Explorer, однако, к ним обращаются
через массив style, что означает применение синтаксиса
примерно такого вида — document.all {'layerName'].style.
Рассмотрим пример.
Предположим, что isNav означает, что использует-
используется браузер Navigator, a isIE — что используется Internet
Explorer. Следующий условный оператор if из листинга
23.8 скрывает первый слой.
if(isIE){
document.all['first'].style.visibility —
"hidden";
}else if(isNav){
document.layers['layerl'].visibility = "hidden";
Технологии программирования на динамическом HTML
Часть IV
При создании сценариев, предназначенных для ра-
работы в обоих браузерах, в дескрипторе <div> исполь-
используют одно и то же значение как для name, так и для id.
Кроме того, потребуется хранить в переменной ссылку
на массив, к которому обращаются. Можно сделать то
же самое для требований стиля в Internet Explorer. Сле-
Следующий псевдокод решит упомянутые проблемы.
var layer = new String ();
var style = new String () ;
if(isIE){
.layer = ".all";
style = "style";
}else if<isNav){
layer = " . layers" ;
style = "
Теперь имеется достаточно информации для форми-
формирования фун! работающей во всех браузерах, ко-
которая будет работать со слоями. Однако, требуется пред-
предпринять последний шаг — включить использование
метода eval(). Этот метод будет обрабатывать строку как
JavaScript-вызов. Можно "построить" требуемый вызов
для доступа и изменения свойств слоя, например, свой-
свойства visibility.
В листинге 23.9 все рассуждения собраны вместе.
Как видно из листинга, с помощью некоторых CSS-P-
свойств был создан одиночный слой, который появля-
появляется под двумя кнопками в окне браузера. После загруз-
загрузки страницы вызывается функция checkBrowser(),
которая определяет, что это за браузер — Internet Explorer
или Navigator. Там также хранится необходимый мас-
массив для доступа к слоям — layer.
Каждая из кнопок выполняет вызов функции
changeState(), передавая значение и ссылку на слой.
Значение сообщает функции, надо ли отображать пере-
переданный слой. Затем эта функция считывает переданные
ей параметры и при помощи метода eval() изменяет со-
состояние слоя. На рис. 23.9 показан вид страницы перед
нажатием кнопки "Hide". Пример одинаково хорошо
работает как в Internet Explorer, так и в Navigator.
Листинг 23.9. Доступ к слоям через JavaScript.
<html>
<head>
<t it le> JavaScript Unleashed*:/title>
<style type="text/css">
<! —
#layerl{
background-color: green;
height: 100;
left: 10;
position: absolute;
top: 50;
width: 100,
I
—>
</style>
<script type="text/javascript"
language="JavaScriptl.2">
<! —
// Глобальные переменные для браузера
var layer = new Stri ig () ;
var style = new String-() ;
// С каким браузером инеем дело:
// Explorer, Navigator, или другой?
// Установка соответствующих значений
// переменных для браузера.
function checkBrowser(){
if(navigator.userAgent.indexOf("MS1E")
'=-l){
layer = ".all";
.style = ".style";
)else if(navigator.userAgent.
;"Nav") != -1) {
layer = ".layers";
style = '
/ / Изменение состояния .
function changeState (layerRef, stati
eval ("document" + layer + "['" +
layerRef + " ' ] " + style +
" .visibility = ' " + state + >
}
II—>
</script>
</head>
<body onload="checkBrowser () ">
<div name=" layerl" id="layerl">
DIV 1
</div>
<form name="forml">
<input type="button" value="Hide"
onclick="changeState( ' layerl1 , 'hidden')">
<input type="button" value="Show"
onclick="changeState('layerl' ,'visible') ">
<form>
</body>
</html>
РИСУНОК 23.9. Содержимое страницы перед нажатием
кнопки.
Вставка внешних файлов
Используя дескриптор <iframe>, можно выполнять встав-
вставку внешних файлов. Это дает возможность лучше управ-
управлять содержимым и обеспечивает механизм включения
содержимого из различных расположений.
ПРЕДУПРЕЖДЕНИЕ'
Даже при том, что дескриптор <iframe> является час-
частью Рекомендаций для HTML 4, в браузерах Navigator он
в настоящее время не поддерживается. Однако, под-
поддержка этого дескриптора будет добавлена в Navigator
,5 (называемый также Mozilla), браузер с открытым ис-
исходным кодом от Mozilla.org. Пока же для эмуляции
функциональных возможностей этого дескриптора мож-
можно воспользоваться дескриптором <ilayer> браузера
Navigator 4.x.
Слои
Глава 23
Хороший пример применения этого дескриптора -
создание на сайте раздела свежих новостей. Предполо-
Предположим, что требуется обновлять новости ежедневно, од-
однако не хочется ежедневно обновлять каждую страни-
страницу, на которой они появляются. Используя дескриптор
<iframe>, можно ссылаться на одну страницу, содержа-
содержащую сегодняшние новости. При этом изменения будут
производиться только в одном месте и появятся на всех
соответствующих страницах.
Сказанное стоит проиллюстрировать примером. Как
видно из листинга 23.10, вызывается внешняя страни-
страница с именем news.html (которая находится в листинге
23.11). Дескриптор ссылается на эту страницу с помо-
помощью src и других атрибутов. На рис. 23.10 для <iframe>
задана граница, чтобы слой был более четко виден. В
табл. 23.4 перечислены атрибуты дескриптора <iframe>.
Листинг 23.10. Использование дескриптора <iframe> для загрузки внешних файлов.
<html>
<head>
<title>JavaScript Unleashed</title>
<style type="text/css">
^ i ——
#layerl{
height: 100;
left: 10;
position: absolute;
top: 50;
width: 100;
i
> >
</style>
ocript type="text/javascript" language="JavaScriptl.2">
<? —
У/ Глобальные переменные для представления типа браузера
var isIE = new Boolean (false) ;
var isNav = new Boolean (false) ;
var unsupported = new Boolean(false) ;
var layer = new String () ;
var style = new String () ;
// Определение типа браузера:
// Explorer, Navigator, или другой. Установка переменной
// слоя вэависимоста! от требуемой формы доступа,
function checkBrowser()(
if(navigator.userAgent.indexOf("MSIE") != -1) {
isIE = true;
layer = ".all";
style = ".style";
}else if(navigator.userAgent.indexOf("Nav") != -1){
isNav = true;
layer = ".layers";
style = "";
}else<
unsupported = true;
// Изменение состояния.
function changeState (layerRef, state) {
eval ("document" + layer + " ['" + layerRef
Estate + );
styie
.visibility =
Технологии программирования на динамическом HTML
Часть IV
II—>
</script>
</head>
<body onload="checkBrowser()">
<ifraine name="layerl" id="layerl" src="news .html" frameborder="l"
noresize scrolling="no"X/iframe>
<form name="forml">
<input type="button" value="Hide" onclick="changeState('layerl','hidden')">
<input type="button" value="Show" onclick="changeState('layerl','visible')">
<form>
</body>
</html>
Таблица 23.4. Атрибуты дескриптора <iframe>.
Значение
Описание
align Используется для выравнивания данных внутри дескриптора <ifra ie>. Допустимыми значениями являк
left, right, top, middle и bottom. От него отказались в пользу CSS.
class Разделенный запятыми список классов стиля, который определяет дескриптор как экземпляр указанных
классов.
Может принимать значения 0 или 1 для указания, существует ли граница вокруг фрейма,
height Определяет высоту <iframe>.
id Часто используется таблицами стилей для определения стиля, который должен применяться к данным в
дескрипторе.
Jongdesc Ссылается на более полное описание содержимого дескриптора.
marginheight Количество пикселов между содержимым фрейма и верхней и нижней границами.
Количество пикселов между содержимым фрейма и правой и левой границами.
name Используется для именования блока. Применяется в JavaScript для управления слоями,
noresize Если присутствует, изменение размеров фрейма со стороны пользователя запрещав'
scrolling Принимает значения auto, yes или по для определения, должны ли отображаться полосы npoi
src Определяет URL, в котором хранится содержимое <iframe>.
style Позволяет указывать определение стиля внутри дескриптора вместо внешнего указания в таблице стилей.
title Позволяет обеспечить более информативный заголовок для <iframe> по сравнению с дескриптором <title>,
который относится ко всему документу.
width Определяет ширину <iframe>.
Листинг 23.11. Содержимое внешнего файла.
<html>
<head>
<title>JavaScript Unleashed*:/title>
</head>
<body bgcolor="red">
<P>
rhis is the news pag<
</body>
</html>
РИСУНОК 23.10. Результат загрузки листинга 23.10'в Internet
Explorer.
Из сказанного выше становится понятно, что воз-
возможности управления слоями с помощью 'avaSc
весьма обширны. Однако, как упоминалось ранее, су-
существует некоторое несоответствие между основными
браузерами. Internet Explorer более точно реализует стан-
стандарты HTML 4 и ECMAScript, a Navigator вводит ряд
новых дескрипторов для обра( 31 слоев. В следующей
версии они будут поддерживать Рекомендации для
HTML 4, пока же необходимо ограничиться дескрип-
дескрипторами <1ауег> и <ilayer>.
В последнем разделе главы обсуждаются эти деск-
дескрипторы и способы их использования. Хотя здесь уже
были представлены базовые Принципы, однако, деталь-
детальное рассмотрение формирования DHTML с помощью
этих дескрипторов приводиться не будет.
<1ауег> и <ilayer>
В Navigator слои определяются с помощью дескрипто-
дескрипторов <1ауег> и <ilayer>. Элементы <1ауег> позволяют
точно располагать слой на странице, а элементы <ilayer>
появляются везде, где их размещает текущий документ.
Свойства дескрипторов <1ауег> и <ilayer> собраны в
табл. 23.5.
Как видно из таблицы, эти дескрипторы содержат
большинство тех же самых атрибутов, что и другие деск-
дескрипторы, применяемые при создании DHTML. Однако,
в отличие от других элементов в браузерах Navigator слой
имеет свой собственный JavaScript-объект: объект Layer.
ПРИМЕЧАНИЕ '" ". ¦*¦"'
Этот объект был описан в главе 9, поэтому его мето-
методы и свойства здесь подробно рассматриваться не
будут.
Пример страницы со вкладками
Для лучшего понимания функциональности дескрипто-
дескрипторов <1ауег> и <ilayer>, стоит обратиться к нескольким
примерам. Возьмем четыре изображения в формате GIF
Слои1
Глава 23
и с их помощью отобразим диаграммы на странице со
вкладками (см. рис. 23.11). Каждое из этих изображе-
изображений присваивается отдельному слою HTML-документа.
Элементам <1ауег> устанавливаются одинаковые пара-
параметры left и top для выравнивания их друг относитель-
относительно друга.
<layer name="tab3" left=5 top=55>
<img src="./1994tab.gif">
</layer>
<layer name="tab2" left=5 tqp=55>
<img src="./1995tab.gif">
</layer>
<layer name="tabl" left=5 top=55>
<img src="./1996tab.gif">
</layer>
<layer name="tabO" left=5 top=55>
<img src="./1997tab.gif">
</layer>
ПРИМЕЧАНИЕ
В слоях используется концепция "последний должен быть
первым" (или "самым верхним"). Обратите внимание,
что в приведенном выше коде вкладка для 1997 г. в
HTML-файле была определена последней. Определенный
в последнюю очередь элемент слоя считается самым
верхним и будет отображаться поверх всех остальных.
С целью обеспечения лучшего взаимодействия с
пользователем был определен еще один слой, содержа-
содержащий форму со списком выбора. Пользователь теперь
может выбирать для просмотра элемент из списка. Мож-
Можно определить обработчик событий onChange, который
бы вызывал функцию showTab() и передавал ей в каче-
качестве параметра выбранную опцию. Ниже показан соот-
соответствующий код:
Таблица 23.5. Свойства дескрипторов <1ауег> и <Мауег>.
Свойство
Описание
above Положение объекта Layer повышается в порядке z-order всех слоев документа (null, если слой — самый
верхний).
backg'ound URL изображения, используемого в качестве фона для слоя.
below Положение объекта Layer понижается в порядке z-order всех слоев документа (null, если слой — самый
нижний).
bgcolor Цвет фона для слоя.
clip Определяет прямоугольник отсечения, который является видимой областью слоя. Все, что находится вне
этого прямоугольника, отображаться не будет.
heigh1: Высота слоя в пикселах.
left Координата в пикселах слоя по оси X относительно начала координат его родительского слоя.
name Имя слоя.
src URL для источника, содержащего данный слой.
top Координата в пикселах слоя по оси Y относительно начала координат его родительского слоя.
visibility Определяет атрибуты видимости слоя, show отображает слой, hide скрывает слой, a inherit заставляет слой
наследоватьусловия видимости от его родительскогослоя.
width Ширина слоя в пикселах.
z-index z-порядок слоя относительно элементов того же уровня и родительского элемента.
Технологии программирования на динамическом HTML
Часть IV
<layer name="seleot" left=00" top=5
width=50">
<center>
document.layers t"tab"+idx].visibility =
'inherit';
Select the year to viewr
<form name="selectForm">
<select name="pickYear" size="l"
onchange="showTab(this. selectedlndex),;
return false ;">
<option selected>1997</option>
<option>1996</option>
<option>1995</option>
<option>1994</option>
</seleot>
</form>
</center>
</layer>
РИСУНОК 23.11. Изображение в формате GIFna странице со
вставками.
ПРИМЙАНИЕ
Оптимальнее всего было бы иметь карту изображения,
определенную для границ вкладок. Связывая с этими
областями обработчик событий onClick, можно смо-
смоделировать стандартный элемент управления типа стра-
страницы со вкладками.
Теперь создадим функцию showTabQ для отобра-
отображения выбранной диаграммы. Для этого сначала не-
необходимо скрыть все слои, а затем сделать выбранный
слой видимым. Следующий код использует массив
document.layers для прохода через каждый слой в доку-
документе и скрывает все слои, кроме Select. Затем выбран-
выбранной вкладке присваивается значение inherit, что делает
ее видимой.
function showTab (idx) {
for (var i =! 1; i < document, layers, length;
){
if(document.layers[i].name != 'Select'))
document.layers[i].visibility = 'hide'
При просмотре и тестировании кода из списка вы-
выбора можно выбрать год для отображения соответству-
соответствующей диаграммы. На рис. 23.12 показаны результаты
выбора 1996 г.
Листинг 23.12 содержит полный исходный код для
этого примера.
Листинг 23.12. Использование слоев для
моделирования Web-страницы со вкладками..
<html>
<head>
<title>JavaScript Onleashed</title>
<script type="text/javascript"
language="JavaScriptl.2">
function showTab(idx) {
for (var i = 1; i <
document.layers.length; i++){
if(document.layers[i].name !=
'Select'){
document.layers[i].visibility =
'hide';
:i
ч
document.layers["tab"+idx] .visibility =
1 inherit' ;
I
II—>
</script>
</head>
<body bgcolor="Silver">
<h4>
AMAZING SCUBA GEAR
Sales History
/h4>
< layer name="tab3" left=5 top=55>
<img src=" . /1994tab.gif">
</layer>
<layer name="tab2" left=5 top=55>
<img src=" . /1995tab.gif ">
</layer>
<layer name="tabl" left=5 top=55>
<img src="./1996tab.gif">
</layer>
<layer name="tabO" left=5 top=55>
<img src=" ./1997tab.gif">
</layer>
<layer name="select" left=00" top="S5"
width=50">
<center>
Select the year to view:
<?orm name="selectForm">
<select name="pick Year" size="l"
onchange="showTab(this.selectedlndex);
return false;">
<option selected>1997</option>
<option>199 6</option>
<option>1995</option>
<option>l994</option>
</select>
</form>
</center>
</layer>
</body>
</html>
-;. i':':"»?'
„¦.'¦"..'¦—-'
;,„. „, \ -,
'i* «*¦ 'J
&•!•« '""' f1»-*1 *
:.-.-¦¦¦
'm-{: i
"¦¦иг!
*].
РИСУНОК 23.12. Слом с диаграммой для 1996г. сделан видимым.
Пример со сталкивающимися шариками
Во втором примере будет создаваться мультипликаци-
мультипликационный эффект. Для получения эффекта сталкивающе-
сталкивающегося шарика воспользуемся тремя разными изображени-
изображениями в формате GIF, которые будут содержать картинки
зеленого, красного и разноцветного шарика. Поместим
каждый из шариков в отдельный элемент <1ауег>:
<layer name="greenball" width=3" height=3"
left=" top="l">
<img src="./grnball.gif">
</layer>
<layer name="redball" width=3" height=3"
le?t=5" top=35">
<img src="./redball.gif">
</layer>
<layer name="colorball" width=3" height=3"
left=55" top=15">
<irng src=" . /clrball .gif
</layer>
Параметры width и height элементов <Iayer> имеют
те же самые размерности, что и GIF-изображения. Па-
Параметры left и top — случайные числа в пределах кар-
картинки, которые произвольно задаются как 400 пикселов
по горизонтали и 200 пикселов по вертикали. Они бу-
будут служить в качестве координат начального положе-
положения шариков.
Слои
Глава 23
После элемента <script> внутри раздела <head> до-
документа можно определить ряд глобальных перемен-
переменных, используемых в подпрограммах мультипликации.
Для каждого из шариков применяется метод offset()
объекта Layer, который позволяет изменять позицию
слоя с использованием диапазона изменений значений
х и у, или delta. Запишем для каждого шарика пару зна-
значений диапазона изменений х и у:
var
var
var
var
var
var
grnX =
grnY =
redX =
redY =
colorX
colqrY
2;
2.
2;
-2
=
=
5;
2;
4
Таким образом, при использовании в offset() эти
переменные требуют, чтобы зеленый шарик сместился
влево на 2 пиксела и вниз на 2.5 пиксела, красный ша-
шарик — влево на 2 и вниз на 2 пиксела, а разноцветный
шарик — влево на 2 и вниз на 3 пиксела.
Определим также в сценарии, что новое свойство
объекта Window с именем flickerFree будет установлено
в true. Это свойство помогает обеспечить эффекты бо-
более плавной мультипликации:
window.flickerFree = true;
Перед работой с элементами <1ауег> в данном
JavaScript-коде потребуется присвоить переменным
ссылки на каждый слой. В разделе <body> документа
добавим новый элемент <script> и поместим в него сле-
следующий код:
<script type="text/javascript"
language="JavaScriptl.2">
<¦ i
Var green = document.layers["greenball"];
var red = document.layers['redball'];
var color = document.layers['colorball1];
II-->
</script>
Используя массив document.layers, можно обращать-
обращаться к каждому из слоев по имени и присваивать их пе-
переменным, представляющим слои в сценарии.
ПРИМЕЧАНИЕ
В отличие от определенных ранее числовых перемен-
переменных, нельзя размещать этот код установки значения
объекта Layer в разделе <head> сценария, посколь-
поскольку он ссылается на элементы, определенные позже,
В разделе <body>. Следовательно, ЭТОТ КОД присва-
присваивания должен обрабатываться после определения
элементов <1ауег>.
Определение функций мультипликации
Следующий шаг связан с созданием сценария, факти-
фактически выполняющего мультипликацию. Изначальная
Технологии программирования на динамическом HTML
Часть IV
цель довольно проста: отобразить каждый шарик в дви-
движении, опираясь на ранее определенное значение
offset(). Однако, в действительности кроме определения
этих основных функциональных возможностей потре-
потребуется проделать очень многое.
Потребуется отслеживать координаты х и у каждо-
каждого шарика перед каждым обращением к offsetQ. Если
этого не делать, шарики очень быстро покинут грани-
границы изображения 400x200 и границы самого HTML-до-
HTML-документа. Поэтому, если свойство left объекта Layer на-
находится между 0 и 400, а свойство top — между 0 и 200,
то метод offset() вызывается. Однако если слой не со-
соответствует этим условиям, процесс выполняется в об-
обратном направлении, имитируя рикошет шарика.
Посмотрим, как это реализуется в сценарии. Будут
использоваться две функции:
¦• StartTheBallRoIlingO — основная рекурсивная фун-
функция, ответственная за вызов каждого шарика для
целей мультипликации. Она также выполняет необ-
необходимые корректировки значений смещения, когда
шарик покидает границы изображения.
• moveBall() — отвечает за перемещение шарика в рам-
рамках изображения. Она анализирует свойства top и left
шарика и вызывает действие offsetO, если они удов-
удовлетворяют условиям. Если условия не выполняют-
выполняются, эта функция обращается к StartTheBallRoIlingO,
которая корректирует смещение.
Поскольку moveBall() вызывает StartTheBallRoIlingO,
возможно, имеет смысл сначала рассмотреть moveBall(),
а затем вернуться к StartTheBallRoIlingO. Функция
moveBallO получает три аргумента: ссылка на объект
шарика, и его значения смещения по х и у. Как упоми-
упоминалось ранее, она проверяет свойства left и top шарика
и реализует один из следующих пунктов:
Выполняет offsetO и возвращает значение 'ok" в
StartTheBallRoIlingO.
Возвращает в вызвавшую функцию значение
"topBoundary1, обозначая, что свойство top не удов-
удовлетворяет условию.
Возвращает в вызвавшую функцию значение
'IeftBoundary1, обозначая, что свойство left не удов-
удовлетворяет условию.
Код приобретет следующий вид:
function moveBall (ball, offsetX, offsetY){
if ((ball, left < 400) &S (ball.left > 0)) {
if {(ball, top < 200) SS (ball.top > 0)) (
ball.offset(offsetX, offsetY);
return 'ok' ;
}else{
return 'topBoundary';
}else{
return 'leftBoundary'
Теперь рассмотрим функцию, которая обращается к
moveBallO. Для каждого из трех шариков StartTheBallRoIlingO
вызывает moveBallO и затем анализирует результаты
выполнения. Для зеленого шарика код выглядит так:
if (moveBall(green, grnX,
1topBoundary'){
grnY = 0-grnY;
green.offset(grnX,
}else{
if(moveBall(green,
'IeftBoundary') {
grnX = 0-grnX;
green.offset(grnX,
grnY) ==
grnY);
grnX, grnY) =
grnY)
!¦
Если moveBallO завершилась успешно и вернула зна-
значение 'ok', сценарий переходит на следующий шаг. Од-
Однако, если возвращается 'topBoundary" (или "IeftBoundary'),
это означает, что необходимо подкорректировать значе-
значение смещения по у (либо по х). Для этого неудовлетво-
неудовлетворительное значение смещения заменяется на новое, де-
делая его равным нулю минус его текущее значение. Затем
выполняется действие offsetO, которое смещает шарик
в обратном направлении. Код совершенно аналогичен
для красного и разноцветного шариков:
if(moveBall(red, redx, redY) == 'topBoundary'){
redY = 0-redY;
red.offset(redX, redY);
)else{
if (moveBall (red, redX, redY) ==
1IeftBoundary'){
redX = 0-redX;
red.offset(redX, redY);
)
5
if(moveBall(color, colorX, colorY) ==
1topBoundary')(
colorY = 0-colorY;
color.offset( colorX, colorY ) ;
)else I
if(moveBall( color, colorX, colorY) ==
'IeftBoundary'){
colorX = 0-colorX;
color.offset! colorX, colorY);
I
}
Наконец, вызывается setTimeout(), чтобы сделать
этот полный процесс рекурсивным:
setTimeout("StartTheBallRoIlingO ", 2) ;
Заключительный шаг связан с фактическим запус-
запуском шарика за счет установки StartTheBallRoIlingO в ка-
качестве обработчика для события on Load окна:
<body onload="startTheBallRolling(>">
После определения функций мультипликации код
следует протестировать. На рис. 23.13 и 23.14 показан
результирующий мультипликационный эффект.
Листинг 23.13 содержит полный исходный код де-
демонстрационной версии BallsGoneWild.
РИСУНОК 23.13. Шарики в движении.
Листинг 23.13. Мультипликационные эффекты на
Web-странице.
<html>
<head>
<title>JavaScript Unleashed</title>
<script type="text/javascript"
language="JavaScriptl.2">
// Глобальные переменные
var grnX = 2 ;
var grnY = 2.5;
var redX = 2;
var redY = -2;
var colorX = 2 ,-
var colorY = 3 ;
// Эффекты плавной анимации
window. flickerFree = true;
function moveBall (ball, offsetX,
[(ball.left < 400) && (ball.left > 0
if ((ball.top < 200) ss (ball.top > 0) ) {
ball.offset(offsetx, offsetY) ;
return ' ok *
)else{
return ' topBound
)else{
return ' leftBoundary ' ;
1
function startTheBai: i (
if grnX, grnY)
'topBoundary1 ) {
Слои
Глава 23
grnY = 0 - grnY;
green.offset(grnX, grnY);
)else(
эп, grnX, grnY)
1leftBoundary'){
grnX = 0 - grnX;
green.offset(grnX, grnY);
f (moveBall (red, redX, redY)
'topBoundary')(
redY = 0 - redY;
red.offset(redX, redY) ;
)else{
if (moveBall (red, redX, redY) ==
1 leftBoundary' ) {
redX = 0 - redX;
red.offsetfredX, redY) ;
i
if (moveBall (color, colorX, colorY)
'topBoundary') (
colorY = 0 - colorY;
colorX, colorY )
)else{
if (moveBall( color, colorX, colorY)
'leftBoundary ' ) {
colorX = 0 - colorX;
iet ( colorX, colorY) ;
i
setTimeout ("startTheBallRollingO" , 2) ;
</script>
</head>
<body onload="startTheBallRolling()">
<layer name="gre
height=3" left=" top="l">
<img src="./grnball.gif">
</layer>
<layer name="redball" width=3" height=3"
left=5" top=35">
<img src="./redball.gif">
</layer>
<layer name="colorball" width=3"
height=3" left=55" top=15">
<ixng src=" ./clrball.gif ">
</layer>
<script type="text/javascript"
language="JavaScriptl .2">
<! —
Var green = document.layers["greenball"] ;
var red = document.layers['redball'];
var color = docume
//—>
</script>
</body>
</html>
Технологии программирования на динамическом HTML
Резюме
Слои представляют собой одно из наиболее значитель-
значительных достижений в HTML за последние несколько лет.
Они позволяют выйти за рамки последовательного тек-
текстового процессора и погрузиться в мир HTML, графи-
графики и дизайна. JavaScript эффективно работает со слоя-
слоями, обеспечивая разработчикам полный контроль их
поведения. Результаты получаются великолепными.
РИСУНОК 23.14. Шарикивдействии.
Меню и панели инструментов
DHTML
В ЭТОЙ ГЛАВЕ
Начальные предположения
Проектирование меню
Создание инструментальных панелей
Знание языка JavaScript и способов его практичес-
практического применения — две совершенно разные вещи. Мно-
Многие способны выучить язык программирования, понять
его синтаксис и семантику. Однако очень немногие до-
достигают действительного мастерства в применении сво-
своих знаний для решения практических задач, т.е. при со-
создании реальных приложений.
Динамический HTML (DHTML) впервые появился
в четвертых версиях браузеров Internet Explorer и Netscape
Navigator. Оба эти браузера поддерживали JavaScript,
слои и таблицы стилей, необходимые для проектирова-
проектирования страниц, у которых полный набор динамических
свойств постоянно находился на исходной Web-страни-
Web-странице. Именно это способствовало возникновению
DHTML, и с тех пор такие технологии применяются на
многих сайтах, придавая им яркость и усиливая функ-
циональныевозможности.
В этой главе рассматриваются два примера DHTML-
приложений. Первый пример — меню, а второй — ин-
инструментальная панель. Как и в повседневной практи-
практике, придется решить, какие браузеры поддерживать и
выяснить все отличительные особенности работы бра-
браузеров в рамках реализации примеров.
Начальные предположения
Перед началом создания проекта DHTML возникает
несколько вопросов, которые задает себе каждый разра-
разработчик. Некоторые из них обсуждались в главе 23, тем
не менее, имеет смысл еще раз напомнить о них:
Какие браузеры требуется поддерживать? Помните,
что в настоящее время только Navigator 4+ и Internet
Explorer 4+ обладают всеми функциональными воз-
возможностями, необходимыми для создания DHTML-
приложений.
Требуется ли адаптировать код под не поддержива-
поддерживающие браузеры?
Насколь изящно требуется обходить возникающие
проблемы в неподдерживающих браузерах?
Вопросы подобного рода уже обсуждались ранее,
поэтому детализация здесь будет излишней. Стоит лишь
напомнить, что выбор поддерживаемых браузеров явля-
является важным шагом, который определяет способы про-
проектирования не только текущих версий программы, но
также и будущих ее версий.
В дополнение к этим вопросам разработчик также
должен задаться вопросом:
Возможно ли сделать это?
Как выглядят планы на будущее?
Существует ли лучший путь для реализации
проекта?
Выяснение возможностей
Этот вопрос зачастую игнорируется. JavaScript воспри-
воспринимается как простой язык, которому может кто угод-
угодно научиться. Это могло бы быть верным для версии 1.0
или 1.1, но 1.2 преподносит нечто совершенно новое.
Начиная с этой версии, возможности JavaScript суще-
существенно возросли, обеспечивая большее количество
объектов для поддержки DOM-модели, а также соответ-
соответствующие XML-технологии. Создание DHTML-прило-
DHTML-приложения не настоль просто, может показаться на первый
взгляд, а различия в версиях браузеров превращают этот
процесс в весьма утомительную задачу.
Планы на будущее
Еще одно соображение, которое необходимо учесть, —
это планы на будущее. Netscape и Microsoft выпускают
Технологии программирования на динамическом HTML
Часть IV
браузеры каждый год, а то и чаще, и это означает, что код,
скорее всего, придется обновлять достаточно часто.
В планах на будущее неплохо было бы рассмотреть
все — от готовящихся стандартов до новых версий бра-
браузеров. Нужно также стараться оставаться на гребне вол-
волны новых технологий, дабы иметь сведения о всех воз-
возникающих проблемах и ошибках программ в различных
версиях. Проектирование DHTML-приложений — труд-
трудная задача, однако после выполнения работы вознаграж-
вознаграждение не заставит себя долго ждать.
Учет API
В заключение стоит обсудить тему использования в
JavaScript интерфейса программирования приложений
(Application Programming Interfaces, API). При создании
DHTML в определенный момент может возникнуть
мысль: "Должен же существовать более простой способ
решения данной задачи; кто-то наверняка уже должен
был делать это ранее".
Скорее всего, мысль верна. Выгодная сторона JavaScript,
который ни что иное как язык программирования для
Internet, состоит в том, что можно обнаружить (если
немножечко поискать), что другие разработчики уже
создали требуемые функции, например, реализующие
перемещение слоев. Кроме того, можно обнаружить, что
многие разработчики уже создали объекты наподобие
каскадного меню или объекты графического редактора.
Не стоит в очередной раз изобретать велосипед, если
обнаруживается, что кто-то уже написал нужный вам
код; просто изучите этот код и воспользуйтесь им при
создании своего сайта.
"¦СОВЕТ ;.-....,¦ ^ •",. ..,; ¦"¦_ /''
Приложение А содержит ссылки на хорошие сайты,
которые содержат полезную информацию по JavaScript
API.
Проектирование меню
При проектировании DHTML-меню возникают доста-
достаточно очевидные вопросы, например, какие меню и
пункты в нем необходимы, и какие должны обеспечи-
обеспечиваться функциональные возможности. К тому же, по-
потребуется решить вопрос по поводу оформления меню.
Какие планируются цвета и размеры? Насколь длинной
должна быть строка меню, и вообще, где меню будет
отображаться?
Все это вопросы, на которые придется ответить, что-
чтобы потом применять соответствующее форматирование
и стили для создания желаемого вида сайта. Для наше-
нашего примера меню поставим перед собой следующие
цели:
Работа только с Internet Explorer.
Серая строка меню в верхней части окна браузера.
Две опции меню: "Go" и "Help".
Меню "Go" будет содержать три ссылки на популяр-
популярные сайты для разработчиков под браузеры Netscape
и Microsoft.
Меню "Help" будет содержать один пункт "About",
после выбора которого должно отображаться диало-
диалоговое окно с информацией о меню.
Диалоговое окно "About" будет содержать изображе-
изображение и кнопку, закрывающую окно.
Определение слоев
Первая вещь, которая будет сделана в плане создания
нашего меню — это определение слоев и самой строки
меню. Для этого можно использовать комбинацию
HTML и CSS. В HTML будут применяться дескрипто-
дескрипторы <div> для задания слоев и дескрипторы <table> для
определения диалогового окна. Будут также использо-
использоваться дескрипторы <а> для работы с событиями щел-
щелчков на пунктах меню. Код раздела <body>, реализую-
реализующий меню, содержится в листинге 24.1. .
Одним из важных моментов при создании любого
JavaScript-приложения является повторное использова-
использование кода; в этом примере повторно используется часть
кода из главы 23. Читатель увидит несколько знакомых
имен функций и функциональных возможностей. По-
Поскольку планируется, что меню будет поддерживаться
только в Internet Explorer, код выяснения типа браузера
здесь отсутствует, однако если требуется поддержка
Navigator, требуется заменить функцию на ту, которая
использовалась в листинге 23.9 главы 23.
Как видно из листинга 24.1, для каждого из слоев
определяются id и name. Это позволяет применять сти-
стили так, чтобы можно было управлять видом и представ-
представлением этих слоев. Для установки стилей требуется не-
несколько определений. Ниже приведен соответствующий
список:
• Запрещение подчеркивания дескрипторов <а>,
Определение цвета и расположения строки меню.
Определение цвета и расположения пунктов "Go" и
"Help" в меню.
Определение цвета, расположения и сокрытия "Go"
и "Help" в меню.
Определение цвета, расположения и сокрытия диа-
диалогового окна "About".
Листинг 24.2 содержит определения таблиц стилей,
которые потребуются для форматирования.
Меню и панели инструментов DHTML
Глава 24
Листинг 24.1. Определение слоев в HTML
<body bgeolor="#ffffff" link="#000000" vlink="#000000" alink="#O00000" onload="checkBrowser(
<div name=Mmenubar" id="menubar"X/div>
<div name="go" id="go">
<a href="javascript:void@)"
onmousedown="changeState('helpmenu','hidden'); changeState('gomenu','visible')">
Go</a>
<div name="help" id="help">
<a hre?="javascript:void @) "
onmousedown="changeState< ' gomenu " , ' hidden ' ) ;changeState ( ' helpmenu ' , 'visible ' ) ">
Help</a>
div name=" gomenu" id="gomenu">
<ahre?="http: / /developer. netscape . com" >
DevEdge</a>
<hr size="l">
<a href="http://www.mozilla.org">
Mozilla.org</a>
<hr size="l">
<a href="http://msdn.microsoft.com">
MSDN</a>
div name=" helpmenu" id="helpmenu">
<a hre?="javascript:void @)" onclick="changeState{ 'helpmenu', 'hidden');
changeState( 'about' , 'visible ' ) ">
About. . .</a>
<div name="about" id="about">
<table border=">
<tr>
<td>
<img src="info-icon.gif"width=2" height=2">
</td>
<td>
This DHTML Menu was created by R. Allen Wyke for JavaScript
Unleashed.
</td>
</tr>
<tr>
<td colspan=" align="right">
<form name="f orml">
<input type="button" value="Close" onclick="changeState('about', 'hidden1)">
<form>
</tr>
</table>
</body>
Листинг 24.2. Определение стиля для меню. top: о,-
" ; width: 100%;
<style type="text/css">
<!--
/* Глобальные стили */ /* Свойства меню */
а{ #help{
text-decoration: none; background-color : #c0c0c0;
',) position: absolute;
right: 0 ;
/* Свойства устанавливающие фон целого иен» */ too- О-
#шепиЬаг{ , '
background-color: #c0c0c0;
left: 0; #go{
position: absolute; background-color: #c0c0cO;
left: 0;
Технологии программирования на динамическом HTML
Часть IV
position: absolute;
top: 0;
/* Свойства активного меню, скрытого вплоть
ло щелчка */
#gomenu {
background-color: ttcOcOcO;
left: 10;
position: absolute;
top: 20;
visibility: hidden;
width: 80;
#helpmenu{
background-color; #c0c0c0;
right: 10;
position: absolute;
top: 20;
visibility: hidden;
width: 80;
I
,/* Свойства диалогового окна About */
#about(
background-color: gray;
border: 2px solid black;
height: 50;
left: 100;
position: absolute;
top: 50;
visibility: hidden;
vertical-align: left;
width: 200;
</style>
Теперь, когда практически все ясно и слои определе-
определены, самое время воспользоваться динамизмом DHTML.
Обработка действий
Первая вещь, которую необходимо сделать в динамичес-
динамической части меню — это выяснить, является ли браузер,
выполняющий запрос, браузером Internet Explorer. Для
этого запишем короткий оператор if, который будет вы-
выдавать сообщение для браузеров, отличных от Internet
Explorer:
if(navigator.userAgent.indexOf("MSIE") == -1){
alert ("This menu is supported in Internet
""Explorer" ) ;
window.back();
J
Несложно заметить, что если браузер — не Internet
Explorer, код выдаст сообщение, которое отправит
пользователя обратно на страницу, с которой он при-
пришел.
Как и в коде из главы 23, объявляется ряд глобаль-
глобальных переменных String для установки layer и style для
браузеров Internet Explorer. Значения этих переменных
устанавливаются после загрузки страницы в функции
checkBrowser(), которая выглядит следующим образом:
var layer =* new String () ;
var style = new String () ;
function checkBrowser(){
layer = ".all";
style = ".style";
'J
Последняя необходимая часть кода — обработка со-
сокрытия и отображения слоев. Если посмотреть внима-
внимательнее, можно увидеть, что это — тот же самый код,
который применялся в главе 23, только немного упро-
упрощенный.
function changeState(layerRef, state){
eval ("document" + layer -f " ['" + layerRef +
"']" + style + ".visibility = "' 4- state +
Это завершающий код части <script> проектируемо-
проектируемого меню. Полностью эта часть приводится в листинге
24.3.
Листинг 24.3. Код для реализации меню.
<script type="text/javascript"
,language=" JavaScriptl . 2">
// Глобальные переменные,
var layer = new String() ;
var style = new StringO/
// Это браузер Navigator?
if(navigator.userAgent.indexOf("Nav") != -1){
alert ("This menu is not supported in
'-¦Navigator") ;
window.back();
i
/ / Установка переменных слоя и сфиля .
function checkBrowser () {
layer = ".all";
style = ".style";
I
// Изменить состояние.
function changeState(layerRef, state){
eval ("document" + layer + "['" + layerRef +
'" ' ] " + style + " .visibility = ' " + state +
1
</script>
Использование меню
Как только написание кода для меню завершено (лис-
(листинг 24.4), его можно загрузить в браузер для тестиро-
тестирования. Меню должно иметь вид, показанный на рис.
24.1. Как видно из рисунка, CSS позволяет размещать
Меню и панели инструментов DHTML
Глава 24
пункты меню в самой верхней сроке окна браузера и
запрещать подчеркивание ссылок. Кроме того, стоит
обратить внимание, что определение элемента menubar
позволяет изменять размеры и оставляет серый фон для
меню.
5 Ja»«5cnpl (Meoihn) - Micmioll Inlcirar ?крГо
'
r>/¦: 41" • :;
РИСУНОК 24.1. Меню, загруженное в браузер.
Листинг 24.4. Полный исходный код реализации
меню.
<htanl>
<head>
<ti tle>JavaScript Unleashed</title>
<script type="text/javascript"
language="JavaScriptl.2">
< ! —
// Это браузер Navigator?
if (navigator .userAgent. indexOf ("MSIE")= -1) {
alert ("This menu is supported in Internet
^Explorer");
window . back () ;
I
/ / Глобальные переменные
var layer = new String () ;
var style = new String () ;
// Установка переменных слоя и стиля,
function checkBrowser () {
layer = ".all";
style = ".style";
/ / Иэменить состояние .
function changeState {layerRef, state){
eval < "document" + layer t " | ' ' +
layerRef + ' ¦ ] " + style +
1 + state + "'") ;
</script>
<style type="text/css">
<> —
/* Глобальные стили */
text-decoration: none;
/* Свойства установки фона целого меню */
#menubar{
background-color: #c0c0c0;
left: 0 ;
position: absolute;
top: 0 ;
width: 100%;
' Свойства меню */
#help{
background-color: #c0c0c0;
position: absolute;
right : 0 ;
top: 0 ;
1
#go{
background-color: #c0c0c0;
left: 0;
position: absolute;
top: 0 ;
/* Свойства активного меню, скрытого
вплоть до щелчка */
ttgomenu
background-color: #c0cOc0;
left: 10;
position: absolute;
top: 2 0;
visibility: hidden;
width: 80;
')
#helpmenu(
backgr ound- color : #c0c0c0;
right: 10;
position: absolute;
top: 20;
visibility: hidden;
width: 80;
1
/* Свойства диалогового окна About '
#about{
background-color: gray;
border: 2px solid black;
height: 50;
left: 100;
position: absolute;
top: 50;
visibility: hidden;
vertical-align: left;
width: 200;
</style>
</head>
<body bgcolor="#ffffff" link="#000000"
vlink=" #000000" alink="#000000"
onload="checkBrowser{)">
<div name="menubar" id="menubar"X/div>
<div name="go" id="go">
Технологии программирования на динамическом HTML
Часть IV
<а hre?="javascript: void(O)"
onmousedown="changeState(¦helpmenu', 'hidden')
changeState('gomenu','visible')">
Go</a>
<div name="help" id="help">
<ahref=" javascript: void @)"
onmousedown="changeState( 'gomenu','hidden'
changeState <¦ helpmenu', 'visible') ">
Help</a>
<div name="gomen
<ahr
DevEdge</a>
<hr size="l">
<a hre
Mozilla. org</a>
<hr size="l">
<a hr<
MSDN</a>
<dlv name="helpme
<a hre
onclick="changeState('helpmenu','hidden');
changeState('about1, 'visible') ">
About...</a>
<div name="about" id="about">
<table border=">
<tr>
<td>
<img src="info-icon.gif" width=2"
height=2">
</td>
<td>
This DHTML Menu was created by R.
Allen Wyke for JavaScript
Unleashed.
</td>
</tr>
<tr>
<td colspan=" align="right">
<?orm name="forml">
<input type="button" value=
onclick="ehangeState('about','hidden')">
<form>
</tr>
</table>
</body>
</html>
После щелчка на пункте меню "Go" в левом верхнем
углу всплывает меню ссылок на сайты. Как показано на
рис. 24.2, эти URL-ссылки отображаются и в строке со-
состояния браузера.
Последним пунктом меню является пункт "Help".
При нажатии на него появляется опция "About", в ре-
результате выбора которой отображается диалоговое окно,
показанное на рис. 24.3.
la
Я
! r •-
:
ц
¦"':¦.¦
|
¦ .
¦
¦
РИСУНОК 24.2. Щелчок Ю пункте меню "Go".
РИСУНОК 24.3.Диалоговое окно "About".
Описание дополнительных возможностей
Теперь, когда создано меню, несомненно, захочется
расширить его возможности. Ниже приведен список
пунктов, после реализации которых можно получить
усовершенствованные возможности для создания ваших
собственных DHTML-меню. Можно также посетить
са'йт DevEdgc Netscape (http://developei
где имеется свободный доступ к объекту Menu.
Поддержка браузера Navigator.
• Щелчок вне области всплывшего меню должен зак-
закрывать его.
Изменение позиции диалогового окна "About".
Создание каскадных меню.
Меню и панели инструментов DHTML
Создание инструментальных панелей
Создание инструментальных панелей — одна из лучших
вещей, которой можно научиться, имея дело с DHTML.
При этом, вероятно, придется задействовать все свои
способности, чтобы заставить инструментальную панель
работать и взаимодействовать с другими инструменталь-
инструментальными панелями желаемым способом. Формирование
инструментальной панели требует не только использо-
использования JavaScript, но также CSS и слоев. Ключевая про-
проблема состоит в определении внешнего вида инструмен-
инструментальной панели и способов ее функционирования.
Затем можно приступать к проектированию размеще-
размещения, кода и стиля.
Применение событий
Первое, что может потребоваться при проектировании
инструментальных панелей — это события. В приложе-
приложении, подобном браузеру, при нажатии кнопок и пере-
пересечении их курсором мыши видно, что эти события
вызывают изменения состояния кнопки.
Для начала стоит построить инструментальную па-
панель, г:одо(шую инструментальной панели браузера. Эта
панель будет выглядеть и функционировать как новые
инструментальные панели из Internet Explorer 3+ и
Navigator 4+.
Что должно происходить?
Первое, что необходимо, — это задокументировать, что
должно происходить в инструментальной панели. От-
Откройте окно браузера и понаблюдайте, как изменяется
состояние кнопок при проходе по ним мышкой и при
нажатии на них. На рис. 24.4—24.6 показано, изменение
состояний кнопок в браузере Navigator 4.
-Щ
Na visitor 4.'Й8
read and figft
:•:-:= ^U.
РИСУНОК 24.4. Обычная инструментальная панель.
Н есложно заметить, что существуют три состояния,
которые потребуется смоделировать. Когда пользова-
пользователь переводит курсор мыши на кнопку, необходимо
Глава 24
сгенерировать событие для выполнения определенной
задачи. Кроме того, необходимо восстановить первона-
первоначальное состояние кнопки, когда пользователь убирает
мышку с кнопки без нажатия на нее.
¦ с A PI
РИСУНОК 24.5. Прохождение мышки над кнопкой.
l&Vwaon «О»|еп]-ЗЮ№¦ НаЦсдр»
ян
'Netscape*
. NETSCnl'K
j
ШШШШШШ
Navigatoi
rigjst С |954-ДИй М<
N
М.08
т' pffi
РИСУНОК 24.6. Нажатие на кнопку инструментальной панели.
Что может происходить?
В перспективе совершенствования разработки под Web
могут быть созданы все необходимые функциональные
возможности для инструментальной панели. Существуют
события для перемещения курсора мыши на элемент и с
этого элемента, а также для нажатия и отпускания кноп-
кнопки. С помощью свойства Image.src, которое может заме-
заменять одно изображение на странице на другое, можно
смоделировать перемещение курсора мыши и нажатие
кнопок. Это свойство обеспечит визуальные эффекты.
Для кнопок потребуется также выполнять опреде-
определенные задачи. Для этого будет использоваться событие
onClick в дескрипторе <а>. Если пользователь нажима-
нажимает на кнопку, щелчок захватывается и обрабатывается.
Ниже приведен список используемых кнопок вместе с
их функциями.
Технологии программирования на динамическом HTML
Часть IV
• Back. Эта кнопка моделирует кнопку "Back" или
"Previous" браузера. Будут использоваться разные ме-
методы для работы в Internet Explorer и Navigator с
целью демонстрации того, как можно создавать нуж-
нужные программы с учетом разных браузеров.
• Forward. Эта кнопка моделирует кнопку "Forward"
или "Next". Будут использоваться разные методы
для работы в Internet Explorer и Navigator с целью
демонстрации того, как можно создавать нужные
программы с учетом разных браузеров.
• Ноте. Эта кнопка моделирует кнопку "Ноте" в бра-
браузерах Navigator. Internet Explorer данный метод не
поддерживает.
• Reload/Refresh. Эта кнопка моделирует кнопку
"Reload" или "Refresh" браузера, которая приводит к
повторной обработке и визуализации текущей стра-
страницы. При помощи метода Date.getTime() будет ото-
отображаться загрузка страницы.
• Find. Эта кнопка моделирует опцию меню Edit -»
Find, которая обеспечивает поиск текста в окне бра-
браузера. Internet Explorer этот метод не поддерживает.
• Print. Эта кнопка моделирует кнопку "Print" браузе-
браузера — вызов диалогового окна Print для печати теку-
текущей страницы.
В дополнение к перечисленным шести кнопкам, бу-
будет также использоваться форма с текстовым полем,
которое позволяет вводить URL и щелкать на кнопке
"Go" для загрузки URL в окно браузера.
Теперь, когда выяснены все требования, приступим
к реализации приложения. Будет рассматриваться как
создание изображений, так и написание кода.
Описание проблем проектирования
Прежде чем приступать к написанию какого-либо кода,
следует принять несколько решений относительно спо-
способов записи и хранения кода. Большинство функцио-
функциональных возможностей меню можно включить в HTML-
дескрипторы — не такое существенное увеличение
объема кода. Однако, функциональные возможности,
которые предоставляет пример, могут быть задейство-
задействованы и в другом месте, потому стоит прибегнуть к бо-
более модульному подходу.
Хранение кода
До начала создания приложения необходимо решить,
где будет храниться код. Здесь следует опираться на то,
¦что именно конструируется. Для текущего приложения
весь код будет храниться в рамках HTML-документа.
Если сайт располагается во множестве мест, тогда код
лучше хранить во внешнем JavaScript-файле (с расши-
расширением js).
Модульное программирование
Спланируем это приложение как можно более модуль-
модульным, чтобы код при необходимости мог использовать-
использоваться в другом месте. Для этого придется создать множе-
множество функций, обрабатывающих информацию.
Для приложения можно выделить три различных
набора функциональных возможностей:
¦• Image State Change (Изменение состояния изображе-
изображения). Эта функция, вызываемая в методе rolllmage(),
будет отвечать за изменение изображения при пере-
перемещении на него курсора мыши либо при нажатии
кнопки.
• Button Processing (Обработка кнопки). Эта функция,
вызываемая в методе process(), будет выполнять за-
задачи, возложенные на кнопку. Когда пользователь
нажимает на кнопку, эта функция реагирует соот-
соответствующим образом.
• URL Handling (Обработка адресов URL). Эта фун-
функция, вызываемая в методе takeBrowser(), будет
брать данные, введенные в форму, и направлять
браузер в указанное расположение.
Создание изображений
В отличие от других приложений, для Web-приложения
потребуется обеспечить максимум компонентов, кото-
которые могли бы погрузиться в любой интерфейс. Поми-
Помимо подобъектов объекта Form, необходимо создать все
собственные изображения и интерфейсные компонен-
компоненты. Из-за характера задачи также потребуется обеспе-
обеспечить версии изображений для событий прохождения
курсора мыши по изображению и нажатых состояний
кнопок.
Ранее упоминалось, что кнопка на инструменталь-
инструментальной панели должна изменить свое состояние, при пе-
перемещении по ней курсора мыши, а также в ситуации,
когда она нажата. Для работы примера возникает необ-
необходимость в следующих изображениях:
• Normal. Изображение по умолчанию.
• Rollover. Значение по умолчанию, отображаемое с
белой рамкой толщиной в 1 пиксел слева и сверху и
серой рамкой толщиной в 1 пиксел справа и снизу.
'• Pressed. Значение по умолчанию, отображаемое с се-
серой рамкой в 1 пиксел слева и сверху, и с белой рам-
рамкой в 1 пиксел справа и снизу.
Написание HTML-кода
Первое, что будет создаваться — это HTML-код, кото-
который содержит макет инструментальной панели. Суще-
Существует несколько компонентов для интерфейса проек-
проектируемой инструментальной панели (см. рис. 24.7).
tr-geffimeQ (reload v^njca^^n)- 9505192
РИСУНОК 24.7. Проектируемый интерфейс.
С иелью упрощения будем использовать таблицы
для хранения и упорядочения кнопок. Таблица будет
содержать три строки с шестью ячейками в верхней
строке и по одной ячейке во второй и третьей строках.
Фон таблицы будет серый, а документа — белый.
Первая строка таблицы будет содержать изображе-
изображения, составляющие инструментальную панель. Каждое
изображение окружается дескрипторами <а>, чтобы
можно было перехватывать события нажатия мыши. В
настоящее время Navigator не позволяет использовать
такие события в дескрипторах <img>, хотя Internet
Explorer это разрешает, так что придется предусмотреть
некоторую кодовую оболочку. Ниже показан пример
одной ячейки изображения.
<td align="center">
<а href="javascript:process('back') "
onmouseup="rolllmage('0' , ' up') "
onmousedown="rolllmage('0','down')"
onmouseout="rolllmage('0','out')"
oranouseover="rolllmage('0','over')">
<img border=" src="back.gif" width=4"
height=4" alt="Back"X/a>
</td>
Листинг 24.5. HTML-часть панели инструментов.
Меню и панели инструментов DHTML
Глава 24
Во второй строке инструментальной панели содер-
содержится текстовое поле, в котором пользователь будет вво-
вводить URL. Когда пользователь нажимает кнопку "Go",
браузер начинает загружать URL. HTML-код для этого —¦
простой дескриптор <form>. Кнопка использует обра-
обработчик событий onClick(), чтобы вызвать функцию, ко-
которая перенаправляет браузер на соответствующий
URL. Атрибут colspan применяется для корректного раз-
размещения ячейки по ширине всей таблицы. HTML-код
выглядит так:
<td colspan=">
<form name="netsite">
<Ь>
Location:
<input type="text" size=0" value="Enter a
URL here" name="where">
<input type="button" value="Go"
onclick="takeBrowser(this. form> ">
</form>
</td>
Последняя строка всего лишь содержит результаты
вызова метода getTime() экземпляра объекта Date. Это
делается для того, чтобы пользователь мог видеть рабо-
работу кнопки "Reload". Когда пользователь нажимает
"Reload", числовое значение, отображаемое в этой ячей-
ячейке, изменяется, подтверждая фактическую перегрузку
страницы. HTML-код для этой строки следующий:
<td colspan=">
Result of Date. getTime () (reload verification) :
<script type="text/javascript"
language=" JavaScript!.. 2">
<! —
document, write ( (new DateO) .getTime ());
</script>
</td>
Три строки в комбинации с дескриптором <body>
составляют всю интерфейсную часть инструментальной
панели. Листинг 24.5 показывает, что у нас уже имеет-
имеется к настоящему моменту.
<body bgcolor="#ffffff">
<table border="l" cellpadding=" cellspacings" align="center" bgcolor="#c0c0c0">
<tr>
<td align="center">
<a href="javascript:process('back')"
onmouseup="rolllmage('0','up')"
onmousedown="rolllmage(' 0 ' , 'down')"
onmouseout="rolllmage(' 0 ' ,'out')"
onmouseover="rolllmage(' 0 ' , 'over')">
<img border=" src="back.gif" width=4" height=4" alt="Back"X/a>
</td>
<td align="center">
<a href="javascript:process('forward')"
onmouseup="rolllmage (' 1', 'up')"
oranousedown="rolllmage('1','down')"
onmouseout="rolllmage('1','out')"
onmouseover="rolllmage('1','over')">
<img border=" src="forward.gif" width=4" height=4" alt="Forward"X/a>
Технологии программирования на динамическом HTML
Часть IV
</td>
<td align="oenter">
<а href =" j avascript: process {' home' >"
onmouseup="rolllmage{'2','up')"
onmousedown="rolllmage {' 2' , ¦ down' ) "
onmouseout="rolllmage('2','out')"
onmouseover="rollltnage(' 2' , • over') ">
<img border=™ src="horoe. gif" width=4" height=4" alt="Home"X/a>
</td>
<td align="center">
<a href="j avascript: document. location. reload < \"
onmouseup="rollImage('3','up')"
onmousedown="rolllmage(" 3' , r down')"
onmouseout="rolllmage('3','out')"
onmouseover="rolllmage('3",'over') ">
<img border=" src="reload.gif" width=4" height=4" alt="Reload"X/a>
</td>
<td align="center">
<a href="javascript:process ('find')"
oranouseup="rollImage('4','up')"
onmousedown="rolllmage (M',' down')"
onmouseout="rolllmage <' 4' ,'out')"
onmouseover="rolllmage('4','over')">
<img border=" src="search.gif" width=4" height=4" alt="Search"X/a>
</td>
<td align="center">-
<a href="} avascript: process (' print')"
onmouseup="rolllmage('5','up')"
onmousedown="rolllmage|'5','down1)"
onmouseout="rolllmage{' 5','out1) "
onmouseover="rolllmage('5','over')">
<img border=" src="print.gif" width=4" height=4" alt="Print"X/a>
</td>
</tr>
<tr>
<td colspan=">
<form name="netsite">
<Ь>
Location:
<input type="text" size=0" value="Enter a URL here" name="where">
<input type="button" value="Go" onclick="takeBrowser (this.form) ">
</form>
</td>
</tr>
<tr>
<td colspan=">
Result of Date . get Time ( ) (reload verification) :
<script type="text/javascript" language=" JavaScriptl .2">
<! —
document. write ( (newDate (> ) . getTime (> ) ;
II—>
</script>
</tr>
</table>
</body>
Реализация rollover-эффектов для
изображений
Для реализации rollover-эффектов для изображений
используется объект Image, который, надо признать,
ограничивает применимость приложений до браузеров,,
поддерживающих JavaScript 1.1. Прежде всего рассмот-
рассмотрим свойство src, которое позволяет изменять изобра-
изображение. Как видно в HTML-коде из листинга 24.5, каж-
каждый из дескрипторов <а>, обрамляющих изображение,
вызывает функцию roillmagc(), которая будет опреде-
определена в данном разделе.
Вначале потребуется объявить все используемые
изображения. Поскольку планируется использовать раз-
различные состояния, лучше всего сохранить их в масси-
массиве. Это позволит обращаться к изображениям в массиве
Меню и панели инструментов DHTML
и в документе с помощью тех же самых индексных зна-
значений. Например, на первое изображение в документе
можно ссылаться через массив document.images таким
образом:
document.images [0]
Если хранить изображения версий "нажатия" и "кур-
"курсор понерх изображения" в двух разных массивах с од-
одной и той же индексацией [0], то для выполнения под-
подмены изображений в функцию можно передавать только
одну переменную позиции. Ввиду того что требуется
также восстановить предыдущее состояние изображение
(значение по умолчанию), возникает необходимость в
объявлении трех массивов. Ниже показан код для созда-
создания этих массивов и для записи изображений в них:
// Массив для хранения изображений версий
// "нажатия"
var overling = new Array () ;
overlmg[0] = new ImageB4,24);
overling [1] = new Image B4,24);
overling [2] = new Image B4,24);
overlmg[3j = new Image B4,24);
overlmg[4] = new ImageB4,24);
overling[5] = new Image B4,24);
// Массив для хранения изображений версий
// "курсор поверх изображения"
var downlmg = new Array О ;
downlmgtO] = new ImageB4,24);
downlmg[1] = new Image B4,24);
downlmg[2] = new Image B4,24);
downlmg[3] = new ImageB4,24);
downlmg[4] - new ImageB4,24);
downlmg [5] = new Image B4,24);
// Массив для хранения изображений по
,'/ умолчанию
var def aultlmg i= new Array () ;
defaultImg[0] := new ImageB4,24) ;
defaultlmg[l] := new ImageB4,24);
defaultlmg[2J = new ImageB4,24);
def aultlmg [3] •= new Image B4,24) ;
def aultlmg [4] ¦= new ImageB4,24);
def aultlmg [5] = new Image B4 ,24) ;
// Загрузка over «-изображений
overtmg[0].src = "back-over.gif";
overling[1] .src = "forward-over.gif";
overling [2]. src = "home-over.gif";
overling[3] .src = "reload-over.gif";
overling[4] .src = "search-over.gif";
overling[5] . src = "print-over.gif";
.// Загрузка down-изображений
downlmg[0].src = "back-down,gif";
downlmg[1] .src = "forward-down.gif";
downlmg[2].src = "home-down.gif";
downlmg[3].src = "reload-down.gif";
downlmg[4].src — "search-down.gif";
downlmg[5].src = "print-down.gif";
// Загрузка изображений ПО умолчанию
defaultImg[0].src = "back.gif";
defaultlmg[l].src = "forward.gif";
defaultlmg[2] .src = "home.gif";
,1 1-158
Глава 24
defaulting [3].src = "reload.gif";
defaultlmg[4].src = "search.gif";
defaultlmg[5].src = "print.gif";
Сейчас необходимо определить функцию. Это гораз-
гораздо проще, чем можно было ожидать. Функция будет
принимать два параметра. Первый параметр — индекс
обрабатываемого изображения. Вызов функции, содер-
содержащийся в дескрипторе <а>, передает числовое значе-
значение, которое представляет его расположение в докумен-
документе. Например, для первого изображения потребуется
передать 0, для второго — 1 и т.д. Помните, что нуме-
нумерация этого списка начинается с нуля, поэтому перво-
первому изображению соответствует индекс 0.
Второй параметр — это тип rollover-эффекта. Для
нашего примера возможны четыре типа: over, out, up и
down. Переданное значение анализируется в операторе
switch и выполняется соответствующая подмена изобра-
изображения с использованием свойства src экземпляров
объекта Image — как в документе, так и в массивах.
Полное определение функции выглядит следующим об-
образом:
function rolllmage(img,type){
switch(type){
case "over":
document.images[img] .src = overImg[img].src;
break;
case "out":
document.images[img].src =
defaultlmg[img].src;
break;
case "up":
document.images[img].src =
defaultlmg[img].src;
break;
case "down":
document, images [img] .src = downlmg [ img] .src;
break;
I
1
Приведенный код обеспечивает необходимую реали-
реализацию rollover-эффектов для изображений.
Реализация поля адреса
Во второй строке примера для инструментальной пане-
панели находится текстовое поле, которое позволяет пользо-
пользователю вводить URL, после чего нажимать "Go" для
переадресации браузера. Как было показано в HTML-
коде, эта кнопка обращается к функции takeBrowser()
и передает ей объект this.form. Как только функция
вызвана, она будет использовать переданную ей ссыл-
ссылку на объект Form, присвоит ее переменной и обратит-
обратится к значению текстового поля. Затем для изменения
страницы, загруженной в настоящий момент в браузер,
задействуется свойство location.href, и, таким образом,
браузер переадресуется на введенный пользователем
новый адрес URL.
Технологии программирования на динамическом HTML
Часть IV
Эта функция не выполняет проверку ошибок, поэто-
поэтому, если пользователь вводит некорректное значение,
браузер просто сообщает о невозможности загрузки стра-
страницы. Из показанного ниже кода видно, что к значению
текстового поля обращаются через имя поля, опреде-
определенное в атрибуте name.
function takeBrowser(ref) {
var form = ref; *
location.href = form.where.value;
3
Обработка событий, связанных с кнопками
Последняя необходимая функция будет отвечать за соб-
собственно обработку. Эта функция имя которой process(),
принимает один параметр. Параметр будет вычислять-
вычисляться в операторе switch для шести возможных кнопок.
Кнопки "Find" и "Ноте" в Internet Explorer не рабо-
работают, поэтому необходимо возвращать сигнальное диа-
диалоговое окно, сообщающее об этом факте. Существует
также ряд других функций, которые реализуются по-
разному в браузерах Navigator и Internet Explorer; им
также потребуется уделить внимание. Введем перемен-
переменную, которая будет сообщать о том, является ли дан-
данный браузер браузером Internet Explorer. Это логическое
значение будет храниться в переменной isIE, которая
будет проверяться в первой строке кода функции. Код
для данной функции выглядит следующим образом:
function process (item) {
var isIE = new Boolean (navigator .userAgent.
indexOf ("MSIE") != -1) ;
switch(item){
case "find":
if(isIE){
alert ("Internet Explorer does not
wsupport this method") ;
>elseI
window.find();
)
break;
case "print":
window. print (),°
break;
case "home":
if(isIE) {
alert("Internet Explorer does not
wsupport this method") ,'
}else{
window.home();
)
break;
case "reload":
document.location.reload();
break;
case "forward":
if (isIE){
history.forward();
)else{
window.forward() ;
j
break;
case "back":
if(isIE){
hi story, back () ;
felse{
window. back () ;
)
break;
Проверка результатов
На данный момент рассмотрены все HTML- и JavaScript-
коды, поэтому теперь можно протестировать получен-
полученное приложение. Окончательный код содержится в ли-
листинге 24.6, а рис. 24.8 и 24.9 демонстрируют rollover-
эффекты для кнопок. При тестировании программы
наблюдайте за изменениями строки, содержащей теку-
текущее время, она должна изменяться после щелчка на
кнопке "Reload". Результат нажатия на кнопки "Find" и
"Print" очевидны, поскольку при этом всплывают диа-
диалоговые окна. Если требуется проверить кнопки
"Forward" и "Back", загрузите несколько страниц в бра-
браузер, тем самым обеспечив переходы браузера вперед и
назад.
Листинг 24.6. Полный исходный код для инструментальной панели.
<html>
<head>
¦<t it le> JavaScript Unleashed</title>
<script type="text/javascript" language="JavaScriptl.2">
// Массивы для хранения изображений
var overling = new Array { ) ;
overling[01 = new ImageB4,24)
overling [1] = new Image B4,24)'
overling[2] ш new Image B4,24)
overling [3] — new ImageB4,24)
overlmg[4] = new Image B4,24)
overling[5] = new ImageB4,24)
var downlmg = new Array () ;
downlmg[0] = new ImageB4,24)
downlmg[1] = new ImageB4,24)
Меню и панели инструментов DHTML
Глава 24
downlmg[2] = new Image B4,24) ;
downlmg[3] = new ImageB4,24) ;
downlmg[4j = new ImageB4,24) ;
downlmg[5] = new Image B4,24) ;
var defaultlmg = new Array () ;
defaultImg[O] = new Image B4,24) ;;
def aultlmg [1] - new Image B4,24) ;
de?aultlmg[2] = new Image B4,24) ;
defaultlmg[3] - new Image B4,24) ;
def aultlmg [4] ¦ new Image B4 ,24) ;
defaultlmg[5j = new Image B4,24) ;
// Загрузка изображений в массивы
overlmg[0] .sro = "back-over.gif";
overling [1].src
overling [2].src
overlmg[3].src
everImg[4].src
overling [5] .src
"forward-over.gif" ;
"home-over.gif" ;
"reload-over.gif" ;
"search-over.gif";
"print-over.gif";
пришедшего
обытия.
downImg[0].srс = "back-down.gif";
downlmg[l].src = "forward-down.gif";
downlmg[2].src = "home-down.gif";
downlmg[3].src = "reload-down.gif";
downlmg[4] . src= "search-down.gif";
downlmg[S].src = "print-down.gif";
defaultlmg[0].src = "back.gif";
defaultlmg[l] .src = "forward.gif";
defaultlmg[2].src = "home.gif";
clefaultImg[3] .src ¦ "reload.gif";
defaultlmg[4].src = "search.gif";
defaultlmg[5].src ¦ "print.gif";
// Изменение состояния в зависимости
functionr oil Image (img,type) {
switch(type){
case "over" :
document, images [img] .sre = overling [img] .src;
break;
case "out" :
document.images[img].src = defaultlmg [img] .sre;
break;
case "up" :
document, images [img] .src = defaultlmg [img] .src,:
break;
case "down":
document, images [img] .src = downlmg [img] .src;
break;
J
// Обработка адреса URL, введенного в текстовом поле
function takeBrowser (ref) {
var form = ref;
location.href = form.where.value;
I
// Обработка нажатий кнопок
function process(item){
var isIE = new Boolean (navigator .userAgent. indexOf ("MSIE") != -1) ;
switch(item){
case "find":
if(isIE)(
alert ("Internet Explorer
}else{
window.find() ,-
1
break;
case "print" :
i
does not support this method") ;
Технологии программирования на динамическом HTML
Часть IV
window, print () ;
break;
case "home":
if (isIE){
alert ("Internet Explorer does not support this method") ;
}else{
window. home <) ;
}
break;
case "reload":
document.location, reload ( ) ;
break;
case "forward":
if (isIE){
history.forward{) ;
window. forward ();
}
break;
case "back" :
if<isIE){
history.back () ;
>else{
window. back ( > ;
}
break;
>
</script>
</head>
<body bgcolor="#ffffff">
<table border="l" cellpadding=" cellspacing="O" align="center" bgcolor="#cOcOcO">
<tr>
<td align="cet\ter">
<a href="javascript:process< 'back') "
onmouseup="rolllmage ( ¦ 0 ¦ , ' up ¦ ) "
onmousedown=" roll Image ( ' О ' , ' down" ) "
onmouseout="rolllmage ( '0 ' , ' out ' ) "
onmouseover="rolllmage< ¦ 0 ' , ' over' ) ">
<img border=" src="back.gif" width=4" height=4" alt="Back"X/a>
</td>
<td align="center">-
<ahref="javascript:process{ 'forward') "
onmouseup="rolllmage ( ' 1 ' , ' up ' ) "
onmousedovm="rolllmage ( ¦ 1 ¦ , ¦ down ' ) "
onmouseout="rolllmage( ' 1 ' , ' out " ) "
onmouseover="rolllmage ( ' 1 l , * over * ) ">
<img border=" src=" forward.gif" width=4" height=4" alt="Forward"X/a>
</td>
<td align="center">
<ahref=" javascript:process( 'home') "
onmouseup="rolllmage ( ' 2 ' , ' up " ) "
onmousedown="rolllmage( ' 2 ' , ' down " ) "
onmouseout= " rolllmage ( " 2 ' , ' out ' ) "
onmouseover="rolllmage ( ' 2 ' , ' over ' ) ">
<img border=" src="home.gif" width=4" height=4" alt="Home"X/a>
</td>
<Td align="center">
<ahref="javascript:process< 'reload') "
onmouseup="rolllmage ( ' 3 ' , ' up'' ) "
onmousedown="rolllmage ( ' 3 ' , ' down ' ) "
onmouseout="rolllmage ( '3 ' , ' out ' ) "
onmouseover="rolllmage < ' 3 ' , ' over ' ) ">
<img border=" src="reload.gif" width=4"height=4" alt="Reload"X/a>
</td>
<td align="center">
<ahref=" javascript:process < ' find') "
Меню и панели инструментов DHTML
Глава 24
onmouseup="rolllmage{'4',' up'>"
onmousedown="rolllmage('4','down')"
onmouseout="rolllmage('4' ,'out')"
onmouseover="rolllmage('4','over1)">
<img border=" src="search.gif" width=4" height=4" alt="Search"X/a>
</td>
<td align="oenter">
<a href="javascript :process( 'print') "
onmouseup="rolllmageA5l,"up")"
oranousedown="rolllmage(' 5','dovm')"
onmouseout="rolllmage('5','out') "
onmouseover="rolllmage<'S','over')">
<img border=" src="print.gif" width=4" height=4" alt="Print"X/a>
</td>
</tr>
<tr>
<td colspan=">
<form name="netsite">
<b>
Location:
<input type="text" size=0" value="Enter a URL here" name="where">
<input type="button" value="Go" onelick="takeBrowser {this.form) ">
</form>
</td>
</tr>
<tr>
<td colspan=">
Result of Date . getTime () (reload verification) :
<script type="text/javascript" language="JavaScriptl.2">
<! —
document.write((new Date()) .getTime());
II—>
</script>
</td>
</tr>
</table>
</body>
</html>
. . ¦ ¦ . ¦:¦¦-.
РИСУНОК 24.8. Курсор мыши над кнопкой.
Резюме
В главе уделялось внимание подробностям, связанным
с реализацией DHTML на сайте. Полученные знания
РИСУНОК 24.9. Нажатие кнопки инструментальной панели.
помогут приступить к созданию динамических страниц
с использованием не только JavaScript, но также и дру-
других HTML-элементов и CSS.
Взаимодействие с другими
технологиями
В ЭТОЙ ГЛАВЕ
Подключаемые модули браузера
Элементы управления ActiveX
Java-аплеты
LiveAudio
Вне зависимости от того, хорошо ли вы знакомы с
программированием на JavaScript или же пока являет-
является новичком в этом деле, вы, скорее всего, еще не рас-
раскрыли всех функциональных возможностей данного
языка. Web-разработчики знают, что существует множе-
множество других технологий, таких как Java-аплеты и эле-
элементы управления ActiveX, которые можно использо-
использовать для усиления впечатления, производимого сайтом.
В главе рассматриваются несколько технологий по-
подобного рода, а также их использовании в JavaScript.
Некоторые из технологий предназначены только для
определенных браузеров, тем не менее, и они являют-
являются допустимыми.
Подключаемые модули браузера
Современные браузеры собственными средствами могут
поддерживать содержимое всего лишь нескольких видов
файловых форматов, к которым относятся тексты (вклю-
(включая HTML) и изображения. Однако для работы вне
Web-браузеров люди для решения различных задач
постоянно используют множество других файловых
форматов.
Например, большинство прикладных программ об-
обработки текстов имеют собственные файловые форма-
форматы (например, формат .doc файла Microsoft Word), так
же дело обстоит и с приложениями электронных таблиц,
презентаций, мультимедиа и т.д. Если Web-браузер под-
поддерживает различные файловые форматы, появляется
возможность построения различного содержимого, в
любой момент доступного через Web, не говоря уже о
применении Internet для новых и увлекательных спосо-
способов представления информации.
Однако, для Netscape (или любой другой компании)
создание в браузере собственной поддержки всех ис-
используемых файловых форматов было бы непрактичным
из-за слишком больших затрат денежных и временных
ресурсов. Так что для большинства браузеров решение
отдается в пользу технологии подключаемых модулей.
|дамЕЧАниеч.. ;> *' "¦ ''¦„;, '¦> \: ¦• *¦¦'-"
Хотя в главе обсуждаются различные технологии, с
которыми JavaScript может взаимодействовать, здесь
не будет говориться о применении этих технологий на
Web-страницах. Например, не будет детально рассмат-
рассматриваться использование дескрипторов <applet>,
<object> и <embed>, а также их атрибутов. Для
получения дополнительной информации по этой теме
посетите сайты Microsoft Developer Network (htfp://
msdn.microsoft.com) либо Netscape DevEdge (http:/ /
developer.netscape.com), а также сайт V/ЗС-консор-
циума (http://www.w3.org).
Подключаемые модули и MIME-типы
Подключаемые модули идентифицируют тип передава-
передаваемых им данных в зависимости от MIME-типов. Иден-
Идентифицируя тип данных, подключаемый модуль может
выбирать соответствующий способ их обработки.
MIME является стандартом Internet, который опре-
определяет способы передачи файловых форматов (не тек-
текстовых) в почтовых сообщениях Internet. (Более подроб-
подробная информация может быть найдена в Internet Requests
For Comment (RFCs) 1521 и 1522.) Толчком для созда-
создания упомянутого стандарта послужила необходимость
передачи через электронную почту не только докумен-
документов, содержащих простой текст. MIME теперь позволяет
прикладным программам электронной почты работать
с отформатированным текстом, файлами приложений и
другими типами файлов, расширяющих сообщения.
Стандарт MIME может обрабатывать любой файловый
Взаимодействие с другими технологиями
формат, включая текст, PostScript, файлы изображений,
звуковые, видео- и сжатые файлы.
MIME-ТИПЫ определяют тип содержимого и специ-
специфический подтип различных файловых форматов. Это
стоит пояснить на примере.
MIME-ТИП для файлов с расширением .wav (Microsoft
audio) определяется как audio/x-wav. audio описывает
звуковой тип или категорию поддерживаемых файлов,
а Х-Wav — определенный тип файла (или подтип), под-
поддерживаемый с учетом требований браузера, для интер-
интерпретации файлов .wav.
После начала работы браузер начинает просматри-
просматривать все установленные подключаемые модули и при-
присваивает MIME-типы соответствующим подключаемым
модулям, которые могут прочитать их. При выявлении
в процессе просмотра MIME-типа браузер загружает
присвоенный (или зарегистрированный) подключаемый
модуль в память, и MIME-тип обрабатывается этим
подключаемым модулем. MIME-тип может отображать-
отображаться одним их трех способов:
Встроенный (inline). Появляется на странице вмес-
вместе с другим содержимым. Размер области подклю-
подключаемого модуля определяется предварительно уста-
установленными значениями параметров height и width
дескриптора, используемого для загрузки этого под-
подключаемого модуля.
Полный (full). Подключаемый модуль занимает все
окно браузера за исключением инструментальных
панелей.
Скрытый (hidden). Подключаемый модуль выполня-
выполняется в фоновом режиме (подобно некоторым аудио-
модулям).
Определение устанавливаемых
подключаемых модулей
Определение того, какие в клиентском браузере уста-
установлены подключаемые модули и какие поддерживают-
поддерживаются MIME-типы, дает разработчику Web-страницы мно-
множество возможностей по управлению содержимым,
предназначенным для отображения пользователям. На-
Например, один из сценариев разработки мог бы выглядеть
так: "Если пользователь имеет подключаемый модуль,
отображается страница со всеми соответствующими
MIME -типами, а иначе — альтернативное содержимое".
В большинстве браузеров (но только не в Internet
Explorer) JavaScript помогает выполнить это.
JavaScript-браузеры содержат два встроенных объек-
объекта, которые дают весьма полезную информацию о под-
подключаемых модулях и MIME-типах, поддерживаемых
браузером клиента:
Глава 25
navigator.plugins. Этот объект, представляющий со-
собой свойство объекта Navigator, — массив всех под-
подключаемых модулей, в настоящий момент установ-
установленных в браузере клиента. Поскольку такой массив
фактически является подобъектом объекта Navigator,
он имеет следующие свойства:
name. Имя подключаемого модуля (например,
Shockwave).
filename. Имя файла подключаемого модуля.
description. Описание подключаемого модуля
(обеспечивается поставщиком модуля).
length. Количество элементов в массиве.
[...]. Массив объектовтшеТурев, которые может
прочесть подключаемый модуль.
navigator.mimeTypes. Это свойство, представляющее
собой подобъект объекта Navigator, — массив всех
mimeTypes, поддерживаемых в браузере клиента. По-
Подобъект имеет следующие свойства:
type. Имя MIME-типа (например, audio/x-wav).
description. Описание MIME-типа (обеспечивает-
(обеспечивается поставщиком модуля).
enabledPlugin. Подключаемые модули, которые
могут прочесть данный MIME-тип.
suffixes. Расширения имен файлов, с помощью
которых идентифицируются MIME-типы (на-
(например, .wav для MIME-типа audio/x-wav). Рас-
Расширения отделяются друг от друга запятыми.
Объект Plugins
Используя эти объекты в сочетании с JavaScript, мож-
можно довольно быстро определить, установлен ли подклю-
подключаемый модуль. Ниже приведен пример, в котором вы-
выясняется наличие подключаемого модуля Macromedia
Shockwave. Если данный подключаемый модуль при-
присутствует, файл загружается и отображается. Если нет,
отображается альтернативная информация:
var DesiredPlugin =
navigator.plugins["Shockwave"];
// ссылка на имя объекта подключаемого модуля
if (DesiredPlugin) {
document, write ( ' <embed src="mymovie.dir"
wheight=40" width=20">' > ;
}else{
document.write(' <img src="movietitle.jpg"
^*height=40" width=20">') ;
)
Объект navigator.plugins также содержит метод refresh(),
который заставляет браузер находить все установленные
подключаемые модули и соответствующим образом под-
подстраиваться. Если с методом refresh() используется ар-
Технологии программирования на динамическом HTML
Часть IV
гумент true (например, navigator.plugin.refresh (true)), то
наличие нового подключаемого модуля регистрируется
без выхода и перегрузки окна браузера.
При использовании navigator.plugins.refreshltrue] бра-
браузер перегрузит только страницы, которые изменяются
из-за изменения подключаемого модуля. Однако, по
умолчанию (если метод refresh|) не используется)
браузер перегружает все страницы, которые содер-
содержат любые типы файлов.
Объект MimeTypes
Используя новый объект navigator.mimeTypes, можно
достаточно быстро определить, поддерживает ли брау-
браузер клиента определенный MIME-тип. В следующем
примере выясняется, поддерживает ли браузер MIME-
тип application/x-director (для кинофильма Macromedia
Director Shockwave). Далее следует логическое продол-
продолжение, как в предыдущем примере:
var DesiredMimetype =
navigator.mimeTypet"application/x-director"];
if (DesiredMimetype) (
document.write('<embed src="mymovie.dir"
k»height=40" width=20">1 > ;
>else{
document:. write < '<imgsrc="movietitle. jpg"
1-height=40" width=20">r > ;
:i
Можно также использовать простой цикл JavaScript
для отображения всех MIME-типов, поддерживаемых
клиентским браузером:
for (var i = 0; i < navigator . mimeTypes. length ;
i++) I
document.write(navigator. mimeTypes[i].type +
СОВЕТ .,
Дополнительная информация об этих объектах может
быть найдена в главе 9.
Элементы управления ActiveX
ActiveX-технология Microsoft также предоставляет ме-
методы внедрения в HTML-документы элементов управ-
управления (в данном случае — OLE-приложения Microsoft).
Элемент управления OLE, внедренный таким образом
в HTML, становится элементом управления ActiveX, ко-
который распознается Microsoft Internet Explorer 3+ и
Netscape Navigator, оснащенным подключаемым моду-
модулем ActiveX.
^ПРИМЕЧАНИЕ *J.^Lr^ "^ v'Z^iT..! -.«." ^
В настоящее время эти элементы управления поддер-
поддерживается только на платформе Windows. Однако
Microsoft работает над методами расширения техно-
технологии ActiveX для других поддерживаемых платформ,
включая MacOS, Solans и HP-UX.
Если такой браузер загружает HTML-документ с эле-
элементом управления ActiveX, который еще не присут-
присутствует в хост-машине браузера, браузер загружает его с
сервера. Так должно происходить, потому что эти эле-
элементы управления в действительности являются OLE-
объектами и могут выполняться только в браузерах на
совместимой с OLE-приложением платформе, такой как
Microsoft Windows. Это создает проблему переносимо-
переносимости для тех пользователей браузеров, которым требует-
требуется обратиться к такому документу.
Понятие элемента управления ActiveX
Если ActiveX — новый термин, рассмотрим следующие
два варианта. В зависимости от того, на что вы будете
опираться, каждый из вариантов будет более приемле-
приемлемым. Если следовать от Web или Java, элемент управ-
управления ActiveX — это ответ Microsoft на Java-аплеты,
мини-приложения, которые могут выполняться внутри
окна браузера. А если опираться на разработку баз дан-
данных Windows, элементы управления ActiveX можно
считать Web-эквивалентами и VBX (элементами управ-
управления Visual Basic), VCL (компонентами Delphi) или
OCX (элементами управления OLE). Как будет показа-
показано далее, связь с OCX — нечто гораздо большее, неже-
нежели простое сравнение.
Прежде чем компания Microsoft решила, что ActiveX —
наилучший термин с точки зрения маркетинга, тот же
элемент управления назывался OCX. Элементы управ-
управления ActiveX были встроены в OLE-технологию, доступ-
доступную в течение нескольких лет. Однако, следует отметать,
что элементы управления ActiveX требуют меньше затрат,,
чем стандартные элементы управления OLE. Поскольку
для элементов управления ActiveX не применяются
ссылки или внедрения объектов, как, например, для
документа Word, часть OLE-технологии из ActiveX была
удалена. В результате остался один компонент — более
быстрый и занимающий меньше места.
Основная причина появления Java связана с необхо-
необходимостью достижения переносимости для всех сред. В
противоположность этому, главное достоинство элемен-
элементов управления ActiveX — это совместимость с домини-
доминирующей на рынке операционной системой Windows 9x,
NT и, в настоящий момент, Windows 2000. Совмести-
Совместимость проявляется в том, что те же самые элементы уп-
управления ActiveX, которые применяются на Web-стра-
Web-страницах, могут использоваться любым Windows-приложе-
Windows-приложением либо инструментальным средством, работающим
с OCX. Причина заключается в использовании Windows
большинством пользователей Web; в конечном итоге
элементы управления ActiveX становятся естественным
расширением рабочего стола.
Взаимодействие с другими технологиями
Ниже приведен пример HTML-кода для встраивания
элемента управления OLE (в данном случае OLE-объек-
OLE-объекта ButtonCtrl) в HTML-документ:
<object id="MyButton" width="83" height=7"
classid="CLSID:3472D900-5A27-llCF-8Bll-
OOAAOOC00903">
<ра*ат name="ExtentX" VALUE=196">
<param name="ExtentY" VALUE=14">
</object>
Строка для атрибута classid — значение CLSID-ВХО-
да средства управления OLE ButtonCtl, в системном ре-
реестре Windows. К счастью, нет необходимости записы-
записывать такой код вручную. Код в приведенном примере
генерировался приложением ActiveX Control Pad от
Microsoft. ActiveX Control Pad, в дополнение к возмож-
возможностям ручного редактирования текста HTML-докумен-
HTML-документов, обеспечивает полуавтоматическое размещение и
создание сценариев для элементов управления ActiveX.
При использовании приложения ActiveX Control Pad для
размещения элемента управления ActiveX в HTML-до-
HTML-документе можно вызвать список всех элементов управле-
управления OLE, доступных в системном реестре Windows. Все
элементы управления OLE доступны авторам HTML-1
документов.
" РЕСУРС ' i • - : ¦* "'" ¦ ЩЖШ
Более подробное описание ActiveX Control Pad выходит
за рамки данной книги. ActiveX Control Pad можно выг-
выгрузить из Developer Network Online Microsoft. Его же
можно отыскать по адресу http://msdn.microsoft.com/
workshop/components/dtctrl/setupdcp.exe.
Элементы управления ActiveX имеют набор собы-
событий, каждое из которых связано с частью кода JavaScript
(или, скорее, JScript). Например, элемент управления
ButtonCtl содержит событие onClick, аналогичное собы-
событию типа Button в HTML-форме. Элемент управления
ActiveX может быть произвольно сложным; например,
элемент Calendar содержит следующие события, кото-
которые могут задаваться в коде сценария: AfterUpdate,
BeforeUpdate, Click, DblClick, KeyDown, KeyPress,
KeyUp, NewMonth и NewYear. Ниже показан пример
кода события для элемента управления ActiveX:
<script type=" text/javascript" ?or="MyButton"
event="onClicle() ">
alert('hello universe1);
II—>
</script>
Реализация защиты
ActiveX содержит систему цифровых подписей, встро-
встроенную в его компоненты. Разработчик компонент может
"поставить" цифровую подпись на элементе управления
ActiveX, чтобы гарантировать пользователям заявленное
Глава 25
происхождение программного обеспечения. Эта цифро-
цифровая подпись отображается в Internet Explorer при загрузке
элемента управления. Пользователь, глядя на нее, реша-
решает, продолжать ли загрузку. Если элемент управления
не имеет цифровой подписи, пользователи уведомляют-
уведомляются о его неизвестном происхождении и выполняется
запрос на подтверждение загрузки.
Можноустановитьпроцесс"автоматическогоодобре-
ния"для поставщика, которому вы доверяете, чтобы
все компоненты из этого источника одобрялись авто-
автоматически.
Доступ с помощью JScript
Как только элемент управления ActiveX будет встроен
в документ, можно добавлять JScript-код и работать с
ним, как с любым другим объектом JScript, т.е. устанав-
устанавливать свойства, реагировать на события или обращаться
к методам элементов управления ActiveX.
Сразу же после начала использования элементов
управления ActiveX становится ясно, что в присоеди-
присоединении к ним JScript-кода нет ничего сверхъестествен-
сверхъестественного. Если знать свойства и методы элемента управле-
управления, для создания сценария можно воспользоваться
обычным JScript-редактором.
В листинге 25.1 показан пример JScript-кода для
реализации ответа на метод Click командой кнопки.
Листинг 25.1. Использование JScript для
взаимодействия сэлементом управления ActiveX.
<html>
<head>
<title> JavaScript Unleashed</title>
<script type="text/javascript">
<! —
function loadBox() (
alert ("The Great Question") ;
</script>
<script type="text/javascript"
for="ConanandButtonl" event="Click() ">
var msg = "She loves me" ;
var altMsg = "She loves me not" ;
if (CoiranandButton 1 .Caption = msg) {
CommandButtonl.Caption = altMsg;
window.defaultStatus = altMsg;
}else{
if(CommandButtonl.Caption = altMsg){
CommandButtonl.Caption = msg;
window.defaultStatus = msg;
}
J
.11—>
</script>
</head>
<body onload="loadBox()">
<object id="CommandButtonl" width="98"
height=2"
Технологии программирования на динамическом HTML
Часть IV
classid="CLSID:D7053240-CE69-HCD-A777-
00DD01143C57">
<param name="VariousPropertyBits"
value=68435483">
<param name="Caption" value="She loves me">
<param name="Size" value=096;678">
<param name="FontCharSet" value=">
<param name="FontPitchAndFamily" value=">
<param name="ParagraphAlign" value=">
<param name="FontWeight" value=">
</object>
</body>
</html>
Поскольку дескриптор <object> не позволяет добав-
добавлять обработчики событий в виде его параметров, для
добавления параметров for и event потребуется прибег-
прибегнуть к альтернативному синтаксису обработки событий
Microsoft, который предполагает использование расши-
расширенного синтаксиса дескриптора <script>. Подобным
способом можно сообщить JScript, для чего предназна-
предназначены объект и событие внутри дескрипторов <script>.
Сценарий, реализующий задачу из листинга 25.1, выг-
выглядит следующим образом:
<script type="text/javascript"
for="CommandButtonl" event="Click() ">
<! —
var msg = "She loves me";
var altMsg = "She loves me not" ;
if(CommandButtonl.Caption == msg){
CommandButtonl.Caption = altMsg;
window.defaultStatus = altMsg;
>else{
if(CommandButtonl.Caption == altMsg){
CommandButtonl.Caption = msg;
window.defaultStatus = msg;
</script>
Java-аплеты
Одной из наиболее полезных особенностей JavaScript
является возможность взаимодействия с Java-аплетами,
JavaScript-сценарии могут вызывать Java-методы, иссле-
исследовать и изменять Java-переменные и управлять Java-
аплетами. В свою очередь, Java-аплеты могут обращаться
к JavaScript-методам, свойствам и структурам данных.
^ПРИМЕЧАНИЕ .Vs" '7 ¦¦•,.' -*¦..''. ,"?ч'' *- ' -
Этот метод доступа к Java-аплетам называется LiveConnect
и поддерживается только браузерами Navigator.
Доступ к Java из JavaScript:
JavaScript-сценарии взаимодействуют с Java-аплетами,
выполняющимися на HTML-странице, путем обраще-
обращения к членам (методам и полям) Java-объектов аплета.
Любой метод Java, объявленный с модификатором
public, доступен из JavaScript, и любое поле Ja\a, объяв-
объявленное как public, доступно для управления и измене-
изменения. Первый шаг организации связи JavaScript с Java-
аплетом — это создание ссылки на аплет. Как только
этот шаг выполнен, становится возможным обращаться
непосредственно к любому из членов аплета.
Примечание ¦¦¦ ¦ * - •
LiveConnect — это Netscape-технология на стороне
клиента, которая обеспечивает непротиворечивое уп-
управление данными между тремя главными клиентски-
клиентскими средами Navigator — подключаемыми модулями,
Java и JavaScript. Дополнительную информацию отно-
относительно LiveConnect можно найти на сайте DevEdge
Netscape по адресу http://developer.netscape.com.
Технология LiveConnect позволяет JavaScript связы-
связываться с Java следующими способами:
Прямые вызовы методов Java
Управление Java-аплетами
Управление подключаемыми модулями Java
Ссылки на аплеты
Аплеты, выполняющиеся в документе, в JavaScript до-
доступны через массив document.applets. Например, на
первый аплет, определенный в текущем документе, из
JavaScript можно ссылаться как на document .applets[O]. На
тот же аплет можно также ссылаться как на document,
applets ["appletName"J или просто document.appletName,
если его имя было определено в дескрипторе <applet>.
Имя аплета можно указать в дескрипторе <applet>,
присвоив значение атрибуту name. Например, дескрип-
дескриптор
<applet name="myApplet" code="testApplet. class"
width=00" height=00" mayscriptX/applet>
создает аплет класса testApplet с именем myApplet. Если
это первый аплет на странице, он будет называться
document.applets[O], document.appletsf'appletName"] или
document. myApplet.
JavaScript-сценарии могут также ссылаться на Java-
аплеты, выполняющиеся в других фреймах того же
окна браузера. Например, если Java-аплет выполня-
выполняется в фрейме с именем framel, к нему можно обращать-
обращаться из фрейма того же уровня следующим образом:
parent, framel. document.myapplet.
Подключаемые модули Java
В JavaScript каждый подключаемый модуль на Web-
странице считается элементом массива embeds. Напри-
Например, document.embedsfO] — первый встроенный объект
на странице.
Взаимодействие с другими технологиями
Если подключаемый модуль связан с классом Java
netscape.plugin.Plugin, к его статическим переменным и
методам можно обращаться тем же способом, который
был продемонстрирован в предыдущем разделе для до-
доступа к переменным, методам и свойствам Java-аплета.
Доступ к JavaScript из Java
Для доступа к JavaScript-методам, свойствам и структу-
структурам данных из Java-аплета необходимо сначала импор-
импортировать пакет javascript Netscape. Это делается с ис-
использованием следующего синтаксиса:
import netscape.javascript.*
netscape.javascript определяет класс JSObject и
объект исключения JSException. Следует предоставить
аплету доступ к JavaScript, объявив атрибут mayscript
(без аргументов) для дескриптора <applet>. Это предот-
предотвратит доступ из аплета к JavaScript на странице без
знаний, имеющихся у разработчика. Если атрибут
mayscript не будет объявлен, возникнет ошибка.
Прежде чем обращаться к JavaScript, необходимо полу-
получить дескриптор окна Navigator. Для этого воспользуйтесь
методом getWindow класса netscape.javascript.JSObject:
winHandle = JSObject.getWindow(this)
winHandle — это переменная типа JSObject.
Для обращения к объектам и свойствам JavaScript
необходимо применять метод getMember класса
netscape.javascript.JSObject. Это можно сделать, вызвав
getMember для поочередного обращения к каждому
объекту JavaScript. Однако, в первую очередь следует
удостовериться в существовании дескриптора окна
JavaScript (он получается при помощи метода getWindow).
Для вызова JavaScript-методов можно воспользовать-
воспользоваться методами call и eval класса netscape.javascript.
JSObject. Повторим, что необходимо применить
getWindow для получения дескриптора окна JavaScript,
и затем при помощи call или eval обратиться к методу
JavaScript. Синтаксис выглядит так:
• JSObject.getWindow().call("methodName", arguments)
methodName — имя вызванного JavaScript-метода,
a arguments — массив аргументов, передаваемых
в данный метод.
• JSObject.getWindow().eval(" expression")
expression — JavaScript-выражение, вычисляемое
для JavaScript-метода.
Использование JSObject
Поскольку сложный JavaScript-объект (например, мас-
массив или объект Window) отражаются в Java в виде объек-
объектов типа JSObject, важно знать, как управлять этими
Глава 25
объектами и извлекать информацию их них. Когда
JSObject представляет массив JavaScript, полезно уметь
исследовать отдельные элементы массива, а когда
JSObject вводит Window, Document, History или подоб-
подобные им JavaScript-объекты, неплохо уметь проверять их
свойства.
На первый взгляд может показаться заманчивым
способ обхода проблемы путем разложения объектов
JavaScript на более простые объекты. После такого раз-
разложения полученные элементы можно было бы послать
Java как наборы простых объектов, где они бы переве-
перевелись в Java-объекты String, Double и Boolean.
Главный недостаток такого подхода, помимо боль-
большого объема дополнительной работы, состоит в том, что
этот способ не оставляет никакой возможности для об-
обработки объектов переменного размера. Если неизвест-
неизвестно заранее, сколько элементов будет содержать массив,
не найдется способа передать каждый отдельный эле-
элемент в Java-метод, поскольку Java-методы принимают
набор аргументов, устанавливаемый в процессе компи-
компиляции. Вероятно, лучше будет просто передать Java
сложные объекты JavaScript и научиться работать с
ними.
' ПРИМЕЧАНИЕ "Г
Убедитесь, что атрибут mayscript присутствует в дес-
дескрипторах <applet> для всех аплетов, которые пла-
планируется использовать с JSObject. Без этого аплет не
получит доступа к объектам и свойствам JavaScript. Эта
мера была разработана для того, чтобы позволить
авторам HTML-кода включать непроверенные Java-an-
леты в свои страницы без переживаний на предмет
того, что эти аплеты получат доступ к потенциально
критичной информации, предназначенной только для
JavaScript.
В качестве конкретного примера предположим, что
необходимо использовать JavaScript в качестве GUI для
Java-аплета построения графика по точкам. Ниже пока-
показаны объявления переменных и функций.
<soript type="text/javascript">
<!--
var xvals = new Array () ;
var yvals = new Array () ;
function addPoint(x, y) (
xvals[xvals.length] = x;
yvals[yvals.length] = y;
¦)
function plotPoints() {
document.myApplet.plotPoints(xvals, yvals);
</script>
а также HTML-форма с обработчиками событий:
<form>
<input type=text name="xval">
Технологии программирования на динамическом HTML
4acn»IV
<input type=text name="yval">
<br>
<input type=button value="Add Point"
onclick="addPoint(form.xval.value,
form.yval.value)">
<br>
«Cinput type=button value="Plot Points"
onclick="plotPoints()">
</form>
Можно собрать координатные пары (х, у), исполь-
использующие два текстовых входных поля и функцию addPoint()
и послать их аплету в одном большом пакете с помо-
помощью функции plotPoints().
Это позволяет передавать аплету произвольное чис-
число точек, из которых требуется составить график, но
требует разложения массивов точек в Java. Java-метод
plotPointsQ из этого примера дает хорошее представле-
представление о том, что можно сделать с объектами JSObject. Код
выглядит следующим образом:
public void plotPoints (JSObject xvals, JSObject
yvals){
Double length = (Double)
xvals.getMember("length");
int n = Math.round(length.doubleValue());
for (int i = 0; i < n; i++) {
try{
String sx = (String) xvals.getSlot(i) ;
String sy = (String) yvals.getSlot (i) ;
Double x = new Double (sx) ;
Double у = new Double (sy) ,-
doPlot(x, y) ;
)catch(NumberFormatException e)
System.err.println("Illegal point
*¦» specification") ;
Рассмотрим более подробно части программы, стро-
строка за строкой.
public void plotPoints(JSObject xvals, JSObject
yvals)
Этот метод получает два объекта JSObject — массив
х-координат и массив у-координат. Обратите внимание,
что массивы JavaScript, даже числовые, в Java не пока-
показываются как массивы одного из встроенных числовых
типов Java. Если функция вместо этого записывается с
сигнатурой:
public void plotPoints(double[] xvals, doublet]
yvals)
то любая попытка вызова ее из JavaScript потерпит не-
неудачу. Вы окажетесь связанными с объектами JSObject
вместо требуемых числовых массивов.
Double length = (Double) xvals. getMember
i ("length");
Вызов getMember() — первый шаг, необходимый
для преобразования аргументов из формы, в которой
они были переданы, к используемой форме. Метод
getMemberQ применяется для получения свойства length
одного из объектов массива (оба массива имеют одну и
Ту же длину). getMemberQ возвращает универсальный
Object (базовый класс для всех Java-объектов), однако
его требуется затем привести к соответствующему типу.
Известно, что свойство length массивов JavaScript — чис-
числовое, а JavaScript-числа отражены в Java как Double,
поэтому объект, возвращенный getMember(), приводит-
приводится к Double.
Обратите внимание, что в выбранном здесь типе нет
никакой гибкости; числа, доступные из JSObject дол-
должны приводиться к Double. Только когда числовые зна-
значения JavaScript передаются непосредственно в Java как
аргументы функций, они могут появляться как Java-
типы, отличные от Double.
int n = Math.round(length.doubleValue ());
Хотя этот оператор не содержит непосредственно
JSObject, он демонстрирует полезное выражение для
преобразования JavaScript-числа в используемый в Java
тип числа. Программисты часто будут получать объек-
объекты Double, тогда как им нужнее другие типы, следова-
следовательно, их необходимо будет преобразовать. В этом слу-
случае метод doubleValueQ объекта Double используется для
получения фактического числового значения, а метод
roundQ пакета Math — для получения целого числа,
наиболее приближенного к данному значению.
String sx = (String) x.getSlot (i) ;
.String sy = (String) у .getSlot (i) ;
Внутри цикла возникает необходимость в способе
получения числового значения каждого элемента объек-
объектов JSObject, представляющих массивы xvals и yvals.
Здесь метод getSlotQ применяется для извлечения от-
отдельного элемента массива с данным индексом. Метод
getSlot() берет индекс в качестве аргумента и возвращает
объект JavaScript, соответствующий этому индексу.
getSlot(), подобно getMember(), возвращает универсаль-
универсальный Java-объект, поэтому его снова потребуется приве-
привести к нужному типу. Как было сказано, массивы xvals
и yvals содержат JavaScript-строки, следовательно, в дан-
данном случае требуется использовать Java-тип String.
На первый взгляд это может показаться странным,
т.к. элементами массива обычно являются числа, но
String — действительно то, что нужно в данном случае.
Вспомните, что значения массивов были получены из
текстовых полей ввода HTML-формы. В JavaScript, если
строка выглядит как число (состоит полностью из.
цифр), это еще не делает ее числом.
Double х = new Double(sx);
Double у = new Double (sy)/
Нам понадобится способ преобразования строк, ко-
которые выглядят как числа, в фактически числа, и для
этого больше всего подойдет упоминаемый ранее кон-
Взаимодействие с другими технологиями
струкгор Double. Ему потребуется String в качестве ар-
аргумента, и он вернет объект Double, соответствующий
значению с плавающей точкой двойной точности, пред-
представленному String. Если String не представляет число-
числового значения, применяется NumberFormatException,
поэтому операторы будут вложены в блок try. В случае
возникновения исключения попытка помещения точки
в график прерывается и начинается следующая итера-
итерация цикла.
doPlot(x, у) ;
Имея значения координат (х, у), извлеченные из
JSObject, осуществляется вызов гипотетического низко-
низкоуровневого метода рисования по точкам.
Хотя исчерпывающее изучение класса JSObject вы-
выходит за пределы этой книги, еще один пример помо-
поможет продемонстрировать несколько его методов. Пред-
Предположим, что требуется добавить к аплету метод,
составляющий график по всем точкам, которые пользо-
пользователь уже ввел в форму, и не дожидающийся нажатия
кнопки "Plot Points" пользователем. Метод, который
показан ниже, позволяет аплету выйти в JavaScript-мир
и рассматривать требуемые ему объекты JavaScript вся-
всякий раз, когда это потребуется:
private void getPoints(){
.// Получить окно и документ.
JSObject window = JSObject.getWindow(this);
JSObject document = (JSObject)
window.getMember("document");
// Получить массивы точек.
JSObject xvals = (JSObject)
document.getMember("xvals");
¦ JSObject yvals = (JSObject)
docuemnt.getMember("yvals");
// Вызов plotPointsO
plotPoints(xvals, yvals);
1
Рассмотрим более подробно строки из новых мето-
методов и концепции, не применявшиеся в предыдущем при-
примере.
private void getPoints(){
Обратите внимание, что этот метод — private, т.е. он
не предназначен для вызова из JavaScript. Обратите так-
также внимание, что здесь не требуются аргументы, по-
поскольку вся информация, необходимая для решения за-
задачи, содержится в JavaScript. Главное достоинство
примера состоит в том, что Java-аплеты могут свобод-
свободно отыскивать объекты и свойства JavaScript, причем
для этого не требуется никаких пользовательских дей-
действий со стороны JavaScript.
JSObject window = JSObject.getwindow(this);
Класс JSObject содержит статический метод getWindowO,
который может использоваться аплетом для получения
Глава 25
JavaScript-объекта Window, соответствующего окну, содер-
содержащему этот аплет. Возвращенный объект — это про-
просто тот же самый объект, обозначенный как Window в
JavaScript. getWindowO — особо важный и полезный
метод, т.к. он является единственным способом, с по-
помощью которого Java-аплет может получить "новый"
JSObject (т.е. JSObject, не полученный из другого, су-
существовавшего ранее, объекта JSObject) без явной пе-
передачи его из JavaScript; класс JSObject не содержит
конструкторов public. Аргументом для getWindowO яв-
является непосредственно объект аплета.
JSObject document = (JSObject)
window.getMember([sql]document[sq2]);
После получения объекта Window метод getMember()
используется для извлечения свойства по его имени. В
данном случае свойством является объект Document
окна, т.е. объект, обозначенный window.document в
JavaScript. Переменные xvals и yvals, как и все перемен-
переменные, определенные на "верхнем уровне" JavaScript-сце-
JavaScript-сценария, являются свойствами объекта Document. Слож-
Сложные объекты JavaScript, такие как Document, отражаются
в Java как JSObjects, следовательно, Object, возвращен-
возвращенный getMember(), будет приводиться к этому типу.
JSObject xvals = (JSObject)
document.getMember("xvals");
JSObject yvals = (JSObject)
document.getMember("yvals");
Как только получен объект Document, можно при-
приступать к извлечению необходимых переменных. Для
достижения этой цели еще раз применяется метод
getMember(). Объекты xvals и yvals являются JavaScript-
массивами, которые представляются в Java как JSObject,
поэтому объекты, возвращенные getMember(), снова
приводятся к этому типу.
PlotPoints (xvals, yvals) ;
Теперь, когда получены JSObject, представляющие
массивы xvals и yvals, можно вызвать метод plotPoints()
изнутри Java точно так же, как он вызывался из JavaScript.
Стоит отметить два других метода класса JSObjects —
call() и eval(), которые имеют следующие прототипы:
public Object call(String methodName, Object
argsH);
public Object eval(String s) ;
callO вызывает метод methodName своего объекта с
аргументами, хранящимися в массиве args. Это эквива-
эквивалентно запросу
this.methodName(arg[0], arg[l], . . .);
из JavaScript. Например, следующий код в аплете
JSObject window = JSObject.getWindow(this);
Object args[] = { "Hello, world!" };
window.call("alert" , args);
Технологии программирования на динамическом HTML
Часть IV
эквивалентен такому JavaScript-коду:'
alert("Hello, world!");
Метод eval() объекта вычисляет строку аргумента
как выражение JavaScript. Вычисление производится в
пределах контекста объекта. Замена последней строки
в предыдущем примере на
window.eval(alert("Hello, world!')");
обеспечивает тот же самый результат. Обратите внима-
внимание на использование одинарных кавычек внутри двой-
двойных.
Трансляция типов данных
Одним из наиболее трудных и запутанных аспектов в
вызовах Java-методов из JavaScript является получение
совпадения типов аргументов, переданных Java, с типа-
типами аргументов, ожидаемых Java-методом. Если два на-
набора аргументов не соответствуют друг другу, происхо-
происходит сбой в обращении к функции и выдается сообщение
об ошибках, в котором говорится, что JavaScript не мо-
может найти Java-метод, который бы ожидал передавае-
передаваемые аргументы.
Java — строго типизированный язык (т.е. каждая пе-
переменная имеет совершенно определенный, объявлен-
объявленный тип), поэтому для всех Java-методов должно быть
объявлено заранее, сколько аргументов они ожидают,
какого типа и каком порядке. В Java-программе любая
попытка вызова метода с последовательностью аргумен-
аргументов, которая в точности не соответствует объявленной
последовательности для данного метода, приводит к
ошибке на этапе компиляции.
JavaScript, напротив, имеет гораздо менее строгий
контроль типов и, как интерпретируемый язык, должен
осуществлять всю необходимую проверку во время вы-
выполнения. JavaScript-переменные не имеют объявленно-
объявленного типа; фактически, их можно не объявлять вообще, а
вместо этого просто ссылаться на них. Той же самой
JavaScript-переменной может быть присвоена строка в.
одном операторе, целое число в следующем операторе
и массив — еще в одном.
Как JavaScript-объекты преобразовываются в Java-
объекты при передаче их методам Java? Откуда Java зна-
знает, как найти Java-тип, который точно соответствует
структуре JavaScript-объекта? Коротко говоря, он вооб-
вообще этого не делает. Вероятно, такого объекта не суще-
существует. Если объект не относится к одному из опреде-
определенных исключений, Java не обязательно имеет класс,
который в точности отражает тип JavaScript-объекта,
поэтому он просто присваивает это значение типу по
умолчанию (JSObject), предназначенному представлять
JavaScript-объекты в Java.
К счастью, в упомянутые выше исключения входят
некоторые из наиболее часто используемых типов дан-
данных, в том числе и три основных типа данных
JavaScript: строки, числа и логические переменные.
JavaScript-строки (т.е. строковые константы и перемен-
переменные, которым в последнюю очередь были присвоены
строки) появляются в Java как экземпляры Java-типа
String. JavaScript-числа (числовые константы и перемен-
переменные, которым в последнюю очередь были присвоены
целые или действительные числовые значения) преоб-
преобразуются в Java-объекты Double. Логические перемен-
переменные JavaScript (true и false) станут Java-объектами
Boolean.
Другой особый случай касается JavaScript-объектов,
которые являются оболочками для Java-объектов. Такие
объекты просто "изымаются из оболочек" и преобразовы-
преобразовываются в исходные Java-типы. Хотя сей факт в настоящее
время не задокументирован, существует дополнительная
гибкость при передаче JavaScript-чисел непосредствен-
непосредственно Java-методам. Попытка сделать вызов наподобие
document.myApplet.setNumberC.7);
окажется успешной, если аплет myApplet содержит ме-
метод с сигнатурой
public void setNumber (type x) ;
где type — один из следующих типов: Double, double,
float, long, int, short, char или byte, хотя документация
гласит, что приемлем только Double. В случаях, когда в
аплете имеется много перегруженных методов, ожида-
ожидающих один из указанных выше типов, выбирается пер-
первый такой метод (метод, самый близкий к началу файла
исходного кода на Java). Нарушение лексикографичес-
лексикографического расположения — вероятно, не лучший способ ре-
решить конфликты между перегруженными методами;
скорее всего, скоро будет предложен другой механизм.
Предположим, что для контроля приемлемых значе-
значений theText применяется метод setText(), и требуется
найти способ выяснения, привел ли вызов setTextQ к
успешной установке theText. Новая функция, которая
возвращает логическое значение, отображающая успех
или неудачу, может выглядеть следующим образом:
public boolean setText(String s) {
if <s.equals("Hello world!")){
// Я устал оа? этой строки. Не используйте ее.
return false;
;)else{
theText = s;
return true ;
В JavaScript-сценарии, включающем строку
Взаимодействие с другими технологиями
var changed = document, myApplet.setText ("Hello
«world!")
значение, возвращенное setText(), сохранится в changed.
Тем не менее остается вопрос: как Java-значение Boolean,,
возвращенное setText(), будет преобразовываться в
JavaScript-объект? В данном случае ответ прост и инту-
интуитивно понятен: Java-значение Boolean станет JavaScript-
значением boolean, когда оно вернется JavaScript.
Передача Java-объектов в JavaScript не всегда настоль
проста — для точного перевода каждого объекта существу-
существует ряд правил. Впрочем, часто все происходит именно
так, как нам нужно. Java-массивы становятся JavaScript-
массивами, числовые типы Java становятся JavaScript-
числами, Java-значения Boolean — JavaScript-значени-
JavaScript-значениями boolean, a Java String — JavaScript String. В заклю-
заключение рассмотрим полный набор используемых правил
для управления преобразованиями:
Числовые типы Java (byte, char, double, float, int, long,
short) становятся JavaScript-числами.
Java-значения Boolean становятся JavaScript-значе-
JavaScript-значениями boolean.
Java JSObject преобразуются в свои исходные
JavaScript-объекты.
Java-массивы становятся JavaScript-объектами Array.
Все другие Java-объекты преобразуются к JavaScript-
объектам, помещенным в оболочки, и могут исполь-
использоваться для обращения к первоначальным Java-
объектам.
При попытке преобразования JavaScript-объекта в
оболочке в JavaScript-строку, число или логическое
значение, вызывается метод исходного Java-объекта
toString(), doubleValueO или booleanValue(), если он су-
существует, и значение, возвращенное из соответствующе-
соответствующего метода, становится значением преобразованного
объекта. Если требуемый метод не существует, преоб-
преобразование дает сбой. Обратите внимание, что Java-стро-
Java-строки корректно работают в JavaScript даже при том, что>
они были переданы JavaScript как объекты-оболочки.
Любая попытка использовать их в контексте, в котором
ожидаются JavaScript-строки, приводит к корректному
преобразованию этих строк.
Подробнее о Java-аплетах
Выше в этой главе рассматривались способы взаимодей-
взаимодействий JavaScript/Java. Теперь хорошо известно, что мож-
можно сделать и, до некоторой степени, как это работает.
Далее более подробно исследуется, что фактически про-
происходит при вызове этих методов и свойств из различ-
различных гред.
Глава 25
Вызов Java-методов
Предполагая, что LiveConnect включен, можно исполь-
использовать следующий синтаксис для обращения к Java-ме-
Java-методу:
Packages . packageName.className .methodName
где packageName и className — свойства объекта Packages.
Имя Packages в вызовах можно опустить в пакетах
Navigator по умолчанию — Java, Sun или Netscape. Напри-
Например, на Java-класс java.lang.System можно ссылаться как
java.Iang. System или Packages.java.lang. System.
Рассмотрим пример. В приведенном ниже коде
JavaScript использует доступ к Java для вывода сообще-
сообщения на Java-консоль:
<script type="text/javascript">
<!--
java.Iang. System.out.println ("Greetings from
^JavaScript") ;
// — >
</script>
Установка Java-свойств
Хотя это не самый хороший стиль программирования
для Java-классов — предоставлять всем прямой доступ
к компонентам данных (называемым также свойствами
или полями), объявляя их public, но иногда бывают си-
ситуации, в которых это оправдано. Когда Java-аплеты
содержат поля public, у JavaScript-сценариев появляет-
появляется возможность непосредственно изменять их так же,
как они вызывают Java-методы public. Например, рас-
рассмотрим следующий фрагмент Java-аплета:
public String theText;
public void setText(String s) {
theText = s;
>
Наилучшим стилем программирования будет уста-
установка текста следующим образом:
document, my Applet. setText ("Hello world! ") ;
Для достижения того же результата можно было бы
записать:
document.myApplet.theText = "Hello world!";
Те же правила, которые управляют трансляцией
JavaScript-объектов в Java-объекты в процессе обраще-
обращения к функции, применимы и в данном случае. Здесь
имеется в виду, что таким образом могут быть установ-
установлены только Java String, Double, Boolean, JSObject и
примитивные числовые типы, поскольку все JavaScript-
переменные первоначально отражаются в Java в виде
одного из этих типов.
Использование Java-пакетов
Возможности взаимодействия JavaScript с Java не огра-
ограничены аплетами. JavaScript-сценарии имеют также
Технологии программирования на динамическом HTML
Часть IV
прямой доступ к статическим методам и полям базовых
Java-пакетов, они могут даже создавать новые Java-объекты.
Java-пакеты доступны в JavaScript через массив Packages
документа. Например, Java-naKeTJavaJang.System, исполь-
используемый для консольного ввода-вывода, будет называть-
называться в JavaScript Packages.java.lang. System, a Java-пакет
java.lang.Math — Packages.java.lang. Math. Следова-
Следовательно, для записи значения "пи" на Java-консоли мож-
можно использовать следующий код:
var pi = Packages.Java.lang.Math.PI;
Packages . Java. lang.System.out.println("pi is: " +
Pi)?
Для сокращения в ссылке к трем заданным по умол-
умолчанию пакетам —Java, sun и netscape — можно безопас-
безопасно опустить ключевое слово Packages. To есть, в пре-
пределах JavaScript-объекта Document имена Java, sun и
netscape представляют собой, соответственно, альтер-
альтернативные имена для Packages.java, Packages.sun и
Packages.netscape. Используя эти имена, можно пере-
перезаписать пример с "пи" следующим образом:
var pi = Java. lang.Math. PI,-
Java.lang.System.out.println("pi is: " + pi) ;
Также возможно создавать новые Java-объекты ди-
динамически, используя операцию new. Это удобный спо-
способ обратиться к некоторьш из мощных встроенных сер-
сервисных Java-классов — хэш-таблицам, стекам, векторам,
датам и т.п. — без написания полного Java-аплета. В
следующем примере на JavaScript создаются два Java-
объекта Date, и затем они сравниваются с помощью
метода after класса Date для выяснения, является ли те-
текущая дата последней.
var theDate = new Java. util. Date (); // текущая
// дата
var deadline = new Java. util. Date @0, 6, 26);
II 26 июля 2000 г.
if (theDate.after(deadline)) {
alert ("I missed my deadline!");
)else{
alert ("Made it!") ;
Управление аплетами
После получения ссылки на аплет, следующим шагом
будет установка связи с ним путем активизации одного
из его методов. Например, если аплет имеет общедос-
общедоступный метод hello(), который не содержит никаких
аргументов, этот метод можно вызвать следующим об-
образом:
document.myApplet.hello();
Создание приведенного выше вызова из JavaScript
производит такой же эффект, как вызов из Java метода
hello() объекта аплета. Для еще одного примера пред-
предположим, что имеется Java-аплет с музыкой из кино-
кинофильма, в котором требуется включать и выключать
звуке использованием JavaScript. Если аплет предостав-
предоставляет методы, подобные показанным ниже, для управ-
управления звуковой дорожкой кинофильма можно вызывать
эти методы из JavaScript:
public void soundtrackOn();
public void soundtrackOff();
Если желательно свести все управление звуковой
дорожкой кинофильма к простому щелчку кнопкой
мыши, можно использовать JavaScript в качестве "про-
"провода" для присоединения переключателей HTML-фор-
HTML-формы к Java-аплету. Следующий пример демонстрирует
применение элемента form метода onClick для взаимо-
взаимодействия с аплетом:
<?orm>
<input type="radio" checked="true" name="sound"
onclick="document.myApplet.soundtrackOn()">
On
<br>
<input type="radio" name="sound"
onclick="document.myApplet.soundtrackOff()">
Off
</form>
Значения для обработчика событий onClick опреде-
определяют, что методы soundtrackOn() или soundtrackOff()
аплета с именем myApplet вызываются всякий раз при
нажатии соответствующего переключателя. В качестве
более сложного примера (который иллюстрирует пере-
передачу аргументов Java-методам), предположим, что ап-
аплет также содержит метод с прототипом
public void changeText(String s) ;
который при вызове изменяет текст, отображаемый ап-
аплетом, на значение, передаваемое в строке s. Если в
форму добавить следующие элементы
<input type="text" name="newtext">
<input type="button" value="Change Text"
onclick="document.myApplet.changeText(form,
newtext.value)">
пользователи смогут вводить в текстовом поле новые
строки, которые будут отражаться в аплете. При нажа-
нажатии кнопки "Change Text" значение текстового поля из-
извлекается, преобразуется в String Java и передается как
аргумент в метод аплета changeText(). Это весьма мощ-
мощный инструмент. Возможность передачи JavaScript-
объектов Java-методам позволяет быстро и легко конст-
конструировать привлекательные графические пользователь-
пользовательские интерфейсы из стандартных HTML-форм, усили-
усиливая их за счет обработчиков событий JavaScript, и при-
применять их для управления Java-аплетами.
LiveAudio
LiveAudio, неотъемлемая часть браузера Netscape Navigator,
представляет собой встроенный подключаемый модуль,
позволяющий браузеру Navigator запускать звуковые
файлы собственными средствами. По сути дела,
Live Audio расширяет Navigator в сторону распознавания
нового типа содержимого. Это означает, что большин-
большинство пользователей Web теперь может свободно получать
и прослушивать аудиофайлы при наличии соответству-
соответствующего оборудования. Это, в свою очередь, открывает
для Web-разработчика новый мир больших возможнос-
возможностей — возможностей восприятия информации и развле-
развлечений "через уши".
LiveAudio интегрирован в среду Navigator и может
легко управляться через JavaScript и LiveConnect. Эти
преимущества наряду с широкой доступностью LiveAudio,
требуют его детального обсуждения. Lлaвa содержит
примеры LiveAudio и демонстрирует способы примене-
применения JavaScript для управления им.
Эта книга, вероятно, окажется последней, содержа-
содержащей информацию о LiveAudio. Промышленность раз-
развивается в направлении создания встроенных проигры-
проигрывателей, таких как G2 Player Real и Microsoft Windows
Media Player, для обработки аудио- и видеофайлов.
Как утверждается на Web-сайте Netscape, LiveAudio
был создан с учетом всех функциональных возможнос-
возможностей LiveConnect. Это означает, что можно пользовать-
пользоваться любыми преимуществами LiveConnect и JavaScript
для управления внедренными (или встроенными)
LiveAudio-элементами. С помощью LiveConnect JavaScript
может взаимодействовать с LiveAudio, позволяя про-
программно выполнять следующие действия:
Создание альтернативных интерфейсов управления
звуком.
Задержку загрузки аудиофайла, пока пользователь
не выполнит действие (например, нажатие кнопки
"Play").
Создание интерфейсных кнопок с шумовыми эффек-
эффектами.
Обеспечение аудиорасширения для взаимодействия
с пользователем. Например, можно заставить объект
говорить, что он делает при нажатии или перемеще-
перемещении курсора мыши поверх него.
Использование JavaScript-методов
JavaScript обеспечивает для LiveAudio несколько мето-
методов управления, чтобы дать возможность разработчику
легко управлять аудиофайлами, внедренными в Web-
страницу. Для этих методов доступен JavaScript, одна-
однако, где-то на странице потребуется встроить консоль
LiveAudio.
Взаимодействие с другими технологиями
Глава 25
Рассмотрим методы управления LiveAudio через
JavaScript::
¦• play(). Включает звук. Можно определить значение
цикла, подобно значению атрибута loop, с необяза-
необязательным URL для звука, если исходный URL не ис-
используется.
stop(). Останавливает звук, если он был включен.
• pause(). Пауза для звука в текущей позиции. Для
продолжения воспроизведения можно использовать
методы play() или pause().
start_time() и end_time(). Позволяют переустанавли-
переустанавливать время начала и конца воспроизведения. Значе-
Значения определяются в секундах.
start_at_beginning() и stop_at_end(). Устанавливают
время начала и конца воспроизведения на начало и
конец звукового файла.
setvol(). Устанавливает громкость звука в интервале
от 0% до 100%.
fade_to(). Устанавливает громкость, плавно изменяя
ее от текущего значения.
fade _from_to(). Позволяет определить два значения
и плавно регулировать звук от одного значения к
другому.
¦• IsReady(). Возвращает true, если звуковой файл заг-
загружен и Готоц к воспроизведению.
IsPlaying(). Возвращает true, если звук воспроизво-
воспроизводится.
IsPaused(). Возвращает true, если воспроизведение
звукаприостановлено.
GetVolume(). Возвращает текущую громкость.
Эти методы обеспечиваются через свойство document.
embeds, которое содержится в массиве <embeds> на те-
текущей странице. Для применения одного из перечис-
перечисленных методов просто обращаются к нему, используя
следующий формат:
document.embedName.method () ;
Например, вызвать метод play() во внедренном про-
проигрывателе myRadio можно с помощью такого кода:
document.myRadio.play();
Воспроизведение звуков в ответ на
JavaScript-события
Как упоминалось ранее, JavaScript можно использовать
для вызова звука в любом месте сайта. Тем не менее,
зачастую наиболее пригодным местом для вызова зву-
Технологии программирования на динамическом HTML
Часть IV
ков, усиливающих впечатления пользователя, оказыва-
оказываются JavaScript-события. Следующий пример использует
эту концепцию, демонстрируя способ вызова несколь-
нескольких звуков на Web-странице путем захвата и обработки
событий onLoad, onUnLoad, и onClick обработчиками
событий JavaScript.
В этом примере (см. листинг 25.2) звук (type.wav),
привязанный к нажатию клавиш, воспроизводится после
загрузки страницы. Для демонстрации события onClick
предполагается, что после щелчка на гиперссылке поль-
пользователь слышит звук кассового аппарата, а при нажа-
нажатии на кнопку — звук выстрела. Кроме того, при уходе
со страницы пользователь услышит звук разбиваемого
стекла. Результирующее окно браузера показано на рис.
25,1.
Листинг 25.2. Управление звуками при помощи
JavaScript.
<html>
<head>
<title>JavaScript Unleashed*:/title>
<script type="text/javascript">
<! —
function playSound(sfile) {
// Загрузка и воспроизведение аудио-
// файла
window. location, href=s?ile;
У
II—>
</script>
</head>
<bodyonLoad="playSound("Type.wav' >"
onUnLoad="playSound{ 'Glass.wav') ">
<h2>
Sounds on JS Events
</h2>
<hr>
The following are examples of JS event
handlers used to play sounds.
<hr>
<a href="#" onClick="playSound(' Cashreg.wav1) ">
Click here for sound
<form name="forml">
<input type="button" value="Play"
onClick="playSound('Gunshot.wav')">
</form>
</body>
</html>
Следующий пример демонстрирует способ примене-
применения некоторых встроенных JavaScript-методов для уп-
управления звуковыми файлами. Код, показанный в лис-
листинге 25.3, позволяет загружать звук и затем управлять
им с помощью нескольких кнопок. Обратите внимание
на использование скрытой консоли для первоначально-
первоначального вызова LiveAudio. На рис. 25.2 находится получив-
получившаяся в окне браузера страница.
Sounds on JS Events
The fallowing are MCamplf of JS eVEU
t Ъакйеге vsed w play sounds.
Л1 Rm1****.
РИСУНОК 25.1. Примеры вызова звуков в ответ на JavaScript
события.
7 #" ^
i Г
^ ^йд^а
Embedded Sounds in JavaScript
Tbis document ioebdes a hidden embedded sourict, which к leaded afierlbe page-is loa-dled You я ю Ц
РИСУНОК 25.2. Управление внедренными звуками с помощью
JavaScript.
Листинг 25.3. Управление внедренными звуками с
помощью JavaScript.
<html>
<head>
<title>JavaScript Onleashed</title>
</head>
<body>
<h2>
Embedded Sounds in JavaScript
<embed mastersound name="soundl"
src="test.wav" volume=00" hidden="true"
autostart="false">
<hr>
This document includes a hidden embedded
sound, which is loaded after
the page is loaded. You can use the
JavaScript buttons below to control
the sound.
Взаимодействие с другими технологиями
<hr>
<form name="forml">
<input type="button" value="Play"
onclick="document.soundl.play(true)">
<input type="button" value="Pause"
onclick="document.soundl.pause()">
<input type="button" value="Stop"
onclick="document.soundl.stop ()">
</form>
</htm.L>
Резюме
В главе рассматривались некоторые способы взаимодей-
взаимодействия JavaScript с другими технологиями. Была пред-
Глава 25
ставлена технология подключаемых модулей Netscape
и объяснены различия между подключаемыми модуля-
модулями, вспомогательными приложениями и MIME-типами.
Здесь также обсуждались проблемы интегрирования
элементов управления ActiveX с JScript. Было выясне-
выяснено, что такое ActiveX-технология и как ее можно ис-
использовать при создании сценариев. Кроме того, рас-
рассматривались вопросы взаимодействия с Java-аплетами
через LiveConnect.
Глава завершилась обсуждением способов примене-
применения обработчиков событий JavaScript для вызова звуков
на НТМГ-странице, а также способов установки вне-
внешних аудиопроигрывателеи в качестве вспомогательных
приложений прослушивания аудиофайлов.
Избранные программные
технологии
ЧАСТЬ
В ЭТОЙ ЧАСТИ
26. Гарантия работы сценариев в браузерах
Netscape и Microsoft
27. Методы выяснения типа браузера
28. Навигация по сайту с использованием JavaScript
29. Формы и верификация данных
30. Персонализация и динамические страницы
¦31. Сопоставление шаблонов с помощью
регулярных выражений
32. Технология манипуляции данными со стороны
клиента
33. Обработка ошибок
.34. Отладка
35. JavaScript и безопасность в Web
Гарантия работы сценариев в
браузерах Netscape и Microsoft
В ЭТОЙ ГЛАВЕ
Версии языка и версии браузера
Сравнительный анализ JavaScript-диалектов
Ошибки
Первоначальный вид JavaScript, как и всех компью-
компьютерных языков, претерпел несколько изменений. Наи-
Наибольшее число изменений было внесено в версии JavaScript
1.1 и 1.2. В этих версиях основные функциональные
возможности постоянно модифицировались, и програм-
программистам становилось все сложнее создавать JavaScript-
код, который работал бы в разных браузерах. Обычно
такие проблемы обходили, избегая использования тех
особенностей, из-за которых возникали проблемы со-
совместимости, однако проблемы JavaScript существова-
существовали и в рамках базовых функциональных возможностей!
Еще большую сумятицу внесла компания Microsoft,
коренным образом изменившая JavaScript, дабы не
покупать лицензию на ее использование. Результатом
стала еще одна разновидность JavaScript — от Microsoft,
получившая название JScript. В конечном итоге на
JavaScript начали смотреть как на нечто очень непосто-
непостоянное..
К счастью, Netscape и Microsoft признали, что Ва-
Вавилонскую башню из JavaScript строить ни к чему. Они
представили язык на утверждение комитету стандарти-
стандартизации ЕСМА (European Computer Manufacturers
Association — Европейская Компьютерная Ассоциация
Изготовителей), который и собрал воедино язык
ECMAScript 1.0 (ЕСМА262). Стандарт был очень быс-
быстро принят как Netscape, так и Microsoft.
После этого события базовые функциональные воз-
возможности JavaScript стабилизировались в версиях
JavaScript 1.3 и JScript 3.0. Эта стабильность сохраня-
сохраняется и на сегодняшний день в JavaScript 1.4 и JScript 5.O.
Проблемными областями сейчас являются не они, а ско-
скорее интеграция в JavaScript новых Web-технологий, та-
таких как каскадирование таблиц стилей (CSS).
Из сказанного выше ясно, что JavaScript претерпел
некоторые изменения, которые все еще проявляются в
различиях способов создания сценариев. В главе расска-
рассказывается, какие версии браузеров поддерживают функ-
функциональные возможности JavaScript.
Версии языка и версии браузера
Возможно, вы несколько запутались во всех этих номе-
номерах версий JavaScript и JScript и номерах версий брау-
браузеров Microsoft и Netscape. Таблица 26.1 показывает
соотношения версий языка и версий браузеров.
Таблица 26.1. Соотношение версий языка и
версийбраузера.
Браузер
Netscape Navigator
Microsoft Internet
Explorer
Версия
2.0
3.0
4.0-4.05
4.06-4.7X
6.0
3.0
4.0^.5
5.0'
5.5
Язык
JavaScript 1.0
JavaScript 1.1
JavaScript 1.2
JavaScript 1.3
JavaScript 1.4 и 1.5
JScript 1.0
JScript 3.0
JScript 5.0
JScript 5.5
Как видно из приведенной таблицы, весьма важно
знать, какие браузеры будут использовать заказчики для
просмотра Web-страниц. Решив в первую очередь, ка-
какие браузеры будут поддерживать создаваемые Web-стра-
Web-страницы, можно сберечь немалое время на разработку. С дру-
другой стороны, если есть некая особая функциональная
Избранные программные технологии
Часть V
возможность JavaScript, которую требуется использовать
на Web-странице, тогда следует выбирать браузер, со-
соответствующий такой версии JavaScript, которая поддер-
поддерживает необходимые функциональные возможности,
либо воспользоваться методикой выяснения типа брау-
браузера (см. главу 27).
Сравнительный анализ JavaScript-
диалектов.
JavaScript был детищем Sun Microsystems. Navigator
Netscape стал первым браузером, интерпретирующим
язык и обеспечивающим расширенные функциональные
возможности JavaScript за счет взаимодействия с под-
подключаемыми модулями и средой Java. Вскоре после этого
Microsoft ввела в игру JScript. Как упоминалось ранее,,
JavaScript в течение первых лет своего существования
претерпел достаточно много изменений. Только теперь,
наконец, основные функциональные возможности
JavaScript стабилизировались и язык получил возмож-
возможность взаимодействовать с другими Web-технологиями.
Хотя текущая версия JavaScript довольно стабильна,
может потребоваться поддержка старых браузеров, а для
этого очень пригодится знание сроков появления и из-
изменения всех функциональных возможностей данного
языка. Еще более важно помнить, что часто требуется
правильное выполнение сценариев в обоих браузерах —
Microsoft и Netscape. Поэтому полезно рассмотреть раз-
различные JavaScript-диалекты, а также браузеры, обеспе-
обеспечивающие их поддержку.
JavaScript от Netscape
Этот раздел состоит из пяти подразделов — по одному
на каждую версию JavaScript. Каждый подраздел дета-
детализирует все объекты, свойства, методы, обработчики
событий, встроенные функции, операции и операторы,
которые являются новыми для данной версии.
Для получения наиболее актуальной информации о
новых версиях JavaScript посетите Web-сайт Netscape
по адресу http://devedge.netscape.com/tech/
javascript/ index.html
JavaScript 1.0
Основная спецификация JavaScript 1.0 сначала поддер-
поддерживалась в Netscape Navigator 2.0. Ниже приведены
списки оригинальных функциональных возможностей
объектов, функций, операций и операторов.
Объекты
Button Form Location Reset
Checkbox Frame Math Select
Date
Document
FileUpLoad
Embed
Функции
escape
eval
parseFIoat
Операции
!!
&= * *==
++ += <
== > >=
Операторы
delete
do...while
for
Function
Hidden
History
Link
parselnt
unescape
=
I
1
>>
for... in
function
if...else
Navigator
Option
Password,
Radio
% %= &
/ 1**1 I/
1 l=
<<= <= =
Submit
Text
Textarea
Window
&&
/=
_=
>>= >>> >>>= new
return
while
with
Таблицы с 26.2 по 26.4 содержат исходные свойства,
методы и обработчики событий.
Таблица 26.2. Свойства, поддерживаемые в
JavaScript 1 .0 и следующих версиях.
Свойство
actioni
aLinkColor
appCodeName
appName
appVersion
ibgColor
checked
cookie
defaultChecked
defaultStatus
defaultValue
document
E
elements
encoding
fgColor
form
frames
hash
host
hostname
Объект
Form
Document
Navigator
Navigator
INavigator
Document
Checkbox, Radio
Document
Checkbox, Radio
Window
Password, Text, Textarea
Frame, Window
Math
Form
Form
Document
Checkbox, FileUpload, Hidden,
Password, Radio, Reset, Select,
Submit, Text, Textarea
Frame, Window
Link, Location
¦Link, Location
Link, Location
Свойство
Объект
href
tastMadifted
length
linkColor
links
LN10
LN2
location
LOG10E
LOG2E
imethod
name
options
parent
pathname
PI
port
protocol
se/ected/ndex
self
search
SQRT1_2
SQRT2
Status
previous
prototype
referrer
search
selected
self
target
text
title
top
userAgent
URL
vlinkCotor
value
window
Link, Location
Document
Form, Frame, History, Select,
String, Window
Document
Document
Math
Math
Document, Window
Math
Math
Form
Button, Checkbox, FileUpload,
Form, Frame, Hidden,
Password, Radio, Reset,
Submit, Text, Textarea, Window
Select
Frame, Window
Link, Location
Math
Link, Location
Link, Location
¦Select
Window
Link
Math
Math
Window
History
Date
Document
.Location
Option
Frame
Form, Link
Option
Document
Frame, Window
Navigator
Document
Document
Button, Checkbox, FileUpload,
Hidden, Option, Password,
Radio, Reset, Submit,
Text, Textarea
Frame
Гарантия работы сценариев в браузерах Netscape и Microsoft
Глава 26
Таблица 26.3. Методы, поддерживаемые в
JavaScript 1 .0 и последующих версиях.
Метод
abs
acos
alert
anchor
asin
atan
atan2
back
big
blink
bold
blur
ceil
char At
charCodeAt
clearTimeout
click
close
concat
confirm
r;os
exp
fixed
floor
focus
fontcolor
fonts ize
forward
fromCharCode
get Date
getDay
getHours
getMinutes
getMonth
getSeconds
getTime
getTimezoneOffset
getYear
go
handleEvent
indexOf
italics
llastlndexOf
Объект
Math
Math
Window
String
Math
Math
Math
History
String
String
String
Password, Reset, Select, Text, Textarea
Math
String
String
Window
Button, Reset, Submit
Document, Window
String
Window
Math
Math
String
Math
Checkbox, Password, Reset, Select,
Text, Textarea
String
String
History
String
Date
Date
Date
Date
Date
Date
Date
Date
Date
History
Password, Select
String
String
String
Избранные программные технологии
ЕМУ
Метод
Часть V
Объект
link
log
imatch
max
min
open
parse
pew
propt
random
round
select
setDate
setHours
setMinutes
setSeconds
sefTime
setTimeout
setYear
sin
small
sqrt
strike
sub
submit
substring
sup
tan
toGMTString
toLocaleString
toLowerCase
toSource
toString
toUpperCase
UTC
write
writeln
Таблица 26.4. (
String
Math
String
Math
Math
Document, Window
Date
Math
Window
Math
Math
FileUpLoad, Text, Textarea
Date
Date
Date
Date
Date
Frame, Window
Date
Math
String
Math
String
String
Form
String
String
Math
Date
Date
String
Math
Date, Math
String
Date
Document
Document
Обработчики событий, подцержива-
емые в JavaScript 1.0 и последующих версиях.
Обработчик
событий
Объект
onBlur
onChange
Password, Radio, Reset, Select, Text,
Textarea
Select, Text, Textarea
Обработчик
событий
Объект
onClick Button, Document, Radio, Reset,
Submit, Text
¦onDblClick Document
onFocus Password, Radio, Reset, Select, Text,
Textarea
onKeyDown Document
¦onKeyPress Document
onKeyUp Document
onLoad Window
onUnLoad Window
onMouseDown Button, Document
onMouseOver Link
onMouseUp Button, Document
onSelect Textarea
onSubmit Form
JavaScript 1.1
JavaScript 1.1 поддерживается в Netscape Navigator 3.
Ниже приводятся списки объектов, функций, опера-
операций, операторов, расширений дескрипторов и изменен-
измененных (по сравнению с предыдущими JavaScript-версия-
JavaScript-версиями) возможностей.
Объекты
Applet
Area
Array
Boolean
Функции
taint
Операции
typeof
Оператор
continue
Function
Image
MimeType
Number
untaint
void
Расширения дескрипторов
В дескриптор <SCRIPT> был
SRC.
Object
Package
Plugin
String
добавлен атрибут
• Атрибут LANGUAGE для <SCRIPT> может опре-
определять версию языка.
Был добавлен дескриптор <NOSCRIPT>,
Поддержаны сущности JavaScript (такие как
&{myVar};).
Возможности
• Добавлена LiveConnect — возможность связи Java и
JavaScrip.
Гарантияработы сценариев в браузерах Netscape и Microsoft
Глава 26
Добавлена возможность обнаружения доступных
подключаемых модулей.
Добавлены прототипы объектов, т.е. возможность
создания свойств, которые появятся во всех объек-
объектах одного и того же типа.
• Добавлена возможность динамического изменения
объектов Select.
Добавлена возможность передачи строк между сце-
сценариями в разных окнах или фреймах.
Изменен способ индексации свойств Object. Если
свойство определено по имени, необходимо всегда
ссылаться на него по имени. Точно так же, если
свойство определено через индекс, на него всегда
ссылаются, используя этот индекс.
eval() вместо встроенной функции стал методом каж-
каждого объекта.
• Добавлена возможность печати и сохранения дина-
динамического HTML, сгенерированного с помощью ме-
методов writeQ и writeln(), с использованием соответ-
соответствующей команды из меню "File".
• Изменены три встроенных функции:181ЧагЧ, parseFloat
и parsclnt, каждая из которых теперь выполняется
одинаково на всех платформах.
• Добавлена возможность удаления объекта, устанав-
устанавливая ссылку на него равной Null.
• Добавлена возможность динамического сброса обра-
обработчиков событий.
Добавлена поддержка преднамеренного искажения
данных для целей безопасности.
• Добавлена возможность использования строк в каче-
качестве индексов массивов.
Таблицы с 26.5 по 26.7 содержат расширения свойств,
методов и обработчиков событий, добавленные в
JavaScript 1.1.
Таблица 26.5. Свойства, поддерживаемые в
JavaScript 1 ¦ 1 и следующих версиях.
Свойство
Объект
Свойство
Объект
applets
arguments
border
caller
closed
complete
constructor
current
Document
Function
Image
Function
Window
Image
Object
History
defaultSelectedl
description
domain
embeds
enabledPlugin
filename
formName
forms
hash
height
history
host
hostname
href
hspace
images
Java
length
lowsrc
MAXVALUE
mimeTypes
MINJ/ALUE
NaN
NEGATIVEJNFINITY
name
netscape
next
opener
pathname
plugins
|port
POSITIVEJNFINITY
previous
protocol
prototype
search
src
suffixes
sun
target
type
vspace
width
Option
MimeType, Plugin
Document
Document:
MimeType
Plugin
Document
Document
Area
Image
Window
Area
Area
Area
Image
Document
Packages
Array, Plugin
Image
Number1
Navigator
Number
Number
Number
Image, Plugin
Packages
History
Window
Area
Document, Navigator
Area
Number
History
Area
Boolean, Function, Image, Number,
Object
Area
Image
MimeType
Packages
Area
Button, Checkbox, FileUpload, Hidden,
MimeType, Password, Radio, Reset,
Select, Submit, Text, Textarea
Image
Image
Избранные программные технологии
Часть V
Таблица 26.6. Методы, поддерживаемые в
JavaScript 1.1 и следующих версиях.
Метод
Объект
blur
Button, Checkbox, FileUpload, Frame, Submit,
Window
click
eva!
focus
javaEnabled
join
refresh
reload
replace
reset
reverse
scroll
sort
split
taintEnabled
toSource
toString
valueOf
Checkbox
Object
Button, FileUpload, Frame, Submit, Window
Navigator
Array
Plugins
Location
Location
Form, Reset
Array
Window
Array
String
Navigator
Array, Boolean
Array, Boolean, Number, Object
Object
Таблица 26.7. Обработчики событий, поддержива-
поддерживаемые в JavaScript 1.1 и следующих версиях.
Обработчик Объект
событий
onAbort Window, Image
onBlur Button, Checkbox, FileUpload, Frame, Submit,
Window
FileUpload
Checkbox
Window, Image
Button, Checkbox, FileUpload, Frame, Submit,
onChange
onClick
onError
onFocus
Window
on Load Image
onMouseOut Area, Link
onMouseOver Area
onReset Form
JavaScript 1.2
JavaScript 1.2 поддерживается в Netscape Navigator 4.0-
4.05. Приведенные ниже списки перечисляют расшире-
расширения объектов, операторов и возможностей, которые
были добавлены в JavaScript 1.2 и в предыдущих вер-
версиях не поддерживаются.
Объекты
Anchor
Event
Layer
Операторы
export
import
Возможности
RegExp
Screen
labeled
switch
¦• Добавлена возможность управления слоями.
Добавлена возможность программного управления
таблицами стилей.
• В метод ореп() окна добавленыдополнительные па-
параметры, позволяющие осуществлять дополнитель-
дополнительную настройку открываемого окна.
• Если параметр LANGUAGE дескриптора <script> ра-
равен JavaScriptl.2, операции равенства (== и !=)
сравнивают только операнды только подобных ти-
типов.
Таблицы с 26.8 по 26.10 содержат расширения свойств,
методов и обработчиков событий, добавленные в JavaScript
1.2.
Таблица 26.8. Свойства, поддерживаемые в
JavaScript 1.2 и следующих версиях.
Свойство
Объект
above
anchors
arity
background
below
bgColor
data
document
height
innerHeight
innerWidth
language
layers
layerX
layerY
left
locationBar
menuBar
modifiers
.name
outerHeight
outerWidth
Layer
Document
Function
Layer
Layer
Layer
Event
Layer
Document, Event
Window
Window
Navigator
Document
Event
Event
Layer
Window
Window
Event
Anchor, Layer
Window
Window
Гарантия работы сценариев е браузерах Netscape и Microsoft
Свойство
радеХ
pageXOffset
pageY
pageYOffset
parentLayer
personalbar
platform
scree nX
screenY
scrollbars
siblingAbove
siblingEelow
src
statusbar
target
text
top
toolbar
type
visibility
which
width
X
У
zlndex
Кроме того,
Объект
Event, Layer
Window
Event, Layer "
Window
Layer
Window
Navigator
Event
Event
Window
Layer
Layer
Layer
Window
Event
Anchor, Link
Layer
Window
Event
Layer
Event
Document, Event
Anchor
Anchor
Layer
поддерживаются все свойства, связан-
ные с объектами RegExp и Screen.
Таблица 26.9.
JavaScript 1.2
Метод
Back
CaptureEvents
Clearlnterval
ClearTimeout
compile
concat
Методы, поддерживаемые в
и следующих версиях.
Объект
Window
Document, Layer, Window
Frame, Window
Frame
RegExp
Array, String
disableExternalCapture Window
enable ExtemalCapture Windwow
exec
find
forward
getFullYear
getMilliseconds
getSeiection
RegExp
Window
Window
Date
.Date
Document
Метод
getUTCDate
getUTCDay
getUTCFullYear
getUTCHours
getUTCMilliseconds
getUTCMinutes
getUTCMonth
getUTCSeconds
handleEvent
home
load
match
move Above
imoveBelow
move By
moveTo
moveToAbsolute
pop
print
push
releaseEvents
replace
resizeBy
resizeTo
irouteEvents
scroll By
scrollTo
search
setFullYear
setinterval
setMilliseconds
setUTCDate
setUTCFullYear
setUTCHours
setUTCMilliseconds
setUTCMinutes
setUTCMonth
setUTCSeconds
setinterval
shift
slice
splice
stop
substr
Глава 26 Bill
Объект
Date
Date
Date
Date
Date
Date
Date
Date
Area, Button, Checkbox, Document,
Form, Image, Layer, Link, Password,
Radio, Reset, Select, Submit, Text,
Textarea, Window
Window
Layer
String
Layer
Layer
Layer, Window
Layer, Window
Layer
Array
Frame, Window
Array
Document, Layer, Window
String
Layer, Window
Layer, Window
Document, Layer, Window
Window
Window
String
Date
Window
Date
Date
Date
Date
Date
Date
Date
Date
Frame
Array
Array, String
Array
Window
String
Избранные программные технологии
Часть V
Метод
Объект
test
toSource
tollTCString
unshift
unwatch
watch
RegExp
Array
Date
Array
Object
Object
Таблица 26.10. Обработчики событий, поддержи-
поддерживаемые в JavaScript 1.2 и следующих версиях.
Обработчик
событии
Объект
onBlur
onDblClick
onDragDrop
onFocus
onKeyDown
onKeyPress
onKeyUp
onLoad
onMouseDown
onMouseOut
onMouseOver
onMove
onResize
Layer
Unk
Window
Layer
llmage, Link, Textarea
Image, Link, Textarea
llmage, Link, Textarea
Layer
Unk
Layer
Layer
Frame, Window
Frame, Window
JavaScript 1.3
JavaScript 1.3 поддерживается в Netscape Navigator 4.06-
4.7x. Ниже приведены списки расширения функций и
возможностей, добавленные в JavaScript 1.3 и не под-
поддерживаемые в предыдущих версиях.
Функции
IsFinite isNaN
Возможности
Соответствие ECMAScript 1.A
Поддержка Unicode.
Новые операции строгого равенства ===== и !==.
Изменения в операциях равенства == и ! =.
Запрещение применения простого присваивания в
условном операторе типа if (x = у).
Любой объект с определенным и ненулевым значе-
значением (включая объект логического типа, равный
false) при передаче его в условный оператор счита-
считается равным true.
Таблица 26.11 содержит список расширений мето-
методов, добавленных в JavaScript 1.3.
Таблица 26.11. Методы, поддерживаемые в
JavaScript 1.3 и следующих версиях. _
Метод
Объект
apply Function
call Function
toSource Array, Date, Function, Number, Object, String
toString String
JavaScript 1,4
Компания Netscape не выпускала новых версий брау-
браузера до тех пор, пока не появился JavaScript 1.4. Новые
функциональные возможности версии 1.4 перешли в
JavaScript 1.5 и поддерживаются в Netscape Navigator
6.0. Ниже приведены списки расширений операций и
операторов, добавленных в JavaScript 1.4 и не поддер-
поддерживаемых в предыдущих версиях.
Операции
in instanceof
Операторы
catch throw try
JavaScript 1.5
JavaScript 1.5 — последняя реализация Netscape, кото-
которая поддерживается в Netscape Navigator 6.0. Ниже при-
приводится список расширений возможностей, добавлен-
добавленных в JavaScript 1.5 и не поддерживаемых в предыдущих
версиях.
Возможности
Согласование с ECMAScript 3.0.
Ошибки времени выполнения программы проявля-
проявляются через исключения.
Расширения регулярных выражений.
Таблица 26.12 содержит список расширений мето-
методов, добавленных в JavaScript 1.5.
Таблица 26.12. Методы, поддерживаемые в
JavaScript 1.5.
Метод
Объект
toFixed
toExponential
Number
Number
JScript от Microsoft
Этот раздел включает три подраздела, по одному на
версию JScript. В каждом подразделе подробно рассмат-
Гарантия работы сценариев в браузерах Netscape и Microsoft
Глава 26
риваются все объекты, свойства, методы, обработчики
событий, встроенные функции, операции и операторы,
новые для конфетной версии JScript.
1 СОВЕТ
5
Для получения актуальной информации о новых версиях
JScripi посетите Web-сайт Microsoft по адресу http://
msdn.microsoft.com/scripting/JScript/default.hfm.
JScript 1.0
JScript 1.0 поддерживается в Microsoft
.3.0. Ниже приведены списки основных
кций, операций
Объекты
Area
Button
Checkbox
Date
Document
Embed
FileUpLoad
Form
Frame
Функции
escape
eval
parseFloat
Операции
-
&= -
+ 4 += ¦
—= > :
Операторы
For
for. ..in
function
if...else
и операторов.
Function
Hidden
History
Link
Location
Math
Navigator
Option
Password
parse tnt
unescape
! != % %=
¦= , / /**/
Л— ¦ 1 1
~ 1 1 1 =
< << <<= < =
>= >> >>= >>>
return
while
with
Internet Explorer
объектов, фун-
Radio
Reset
Select
String
Submit
Text
Textarea
Window
& & &
// /=
r
»>= new
Таблицы с 26.13 по 26.15 перечисляют основные
свойсгва, методы и обработчики событий.
Таблица 26.13. Свойства, поддерживаемые в
JScript 1.0 и следующих версиях.
Свойство
Объект
action
aLinkColor
appCodeName
applet:;
appName
Form
Document
Navigator
Document
Navigator
Свойство
Объект
appVersion .Navigator
bgColor Document
checked Radio
cookie Document
defaultChecked Radio
defaultStatus Window
defaultValue Password, Text, Textarea
document Frame, Window
E Math
elements, Form
encoding i Form
fgColor Document
form Button, FileUpload, Hidden, Password,
Radio.Reset, Select, Submit, Text,
Textarea
form Reset, Select, Submit
frames Frame, Window
hash Area, Link, Location
host Area, Link, Location
hostname Area, Link, Location
href Area, Link Location
llastModified Document
length Form, Frame, History, Select, String
linkColor Document
Ilinks Document
LN10 'Math
iLN2 Math
location Document, Window
'LOG10E Math
L0G2E iMath
method Form
name Button, FileUpload, Form, Frame,
Hidden,Password, Radio, Reset, Select,
Submit, Text.Textarea, Window
options Select
parent 'Frame, Window
pathname Area, Link, Location
PI Math
port Area, Link, Location
protocol! Area, Link, Location
previous History
referrer Document
search Area, Link, Location
selected Option
selectedlndex Select
self .Frame, Window
¦¦¦¦ Избранные программные технологии
В?Ш| Часть V
Свойство
SQRT1_2
SQRT2
status
target
Г' <t
title
top
type
userAgent
URL
vlinkColor
value>
window
Таблица 26
JScript 1,0
Метод
abs
acos
alert
anchor
asin
atari
atan2
back
big
blink
bold
blur
ceil
charAt
charCodeAt
clear Timeout
click
close
confirm
cos
¦¦!P
fixed
floor
focus
fontcolor1
Объект
IMath
Math
Window
Area, Form, Link
Option
Document
Frame, Window
Button
iNavigator
Document
Document
Button, FileUpload, Hidden, Option,
Password, Radio, Reset, Submit, Text,
Textarea
Frame
.14. Методы, поддерживаемые в
и следующих версиях.
Объект
Math
Math.
Window
String
Math
Math
Math
History
String
String
String
Button, Checkbox, Password, Radio,
Reset, Select, Text, Textarea
Math
String
String
Window
Button, Radio, Reset, Submit
Document, Window
Window
Math
Math
String
Math
Button, Password, Radio, Reset, Select,
Text, Textarea
String
Метод
fontSize
forward
fromCharCode
¦getDate
getDay
getHours
getMinutes
getMonth
getSeconds
getTime
getTimezoneOffset
getYear
go
indexOf
italics
lastlndexOf
link.
Imj
«пах
min
open
parse
pr.r
prompt
random.
round
select
setDate
setHours
setMinutes.
setMonth
setSeconds
setTime
setTimeout
setYear
sin
sqrt
strike
s;ub
submit
substring
sup
'; in
toGMTString
toLocaleString
toLowerCase
Объект
String
History
String
Date
Date
Date
Date
Date
Date
Date
Date
Date
History
String
String
String
String
IVyiath
IVIdU 1
Math
Math
Document, Window
Date
Math
Window
Math
Math
FileUpLoad, Passwor
Date
Date
Date
Date
Date
Date
Frame, Window
Date
Math
Math
String
String
Form
String
String
Math
Date
Date
¦String
Гарантия работы сценариев в браузерах Netscape и Microsoft
Метод
JoSource
toString
toUpperCase
UTC
write
writeln
Объект
Math
Date, Math
String
Date
Document
Document
Таблица 26.15. Обработчики событий, поддержи-
поддерживаемые в JScript
Обработчик
событий
on Blur
onChange
onClick
onDblClick
onFocus
onKeyDown
onKeyPress
onKeyUp
onLoad
onUnLciad
onMouseDown
onMouseOver
onMouseUp
onSelect
onSubmit
JScript 3.0
1 .0 и следующих версиях.
Объект
Password, Radio, Reset, Select, Text,
Textarea
Select, Text, Textarea
Button, Document, Radio, Reset,
Submit, Text
Document
Password, Radio, Reset, Select, Text,
Textarea
Document
Document
Document
Window
Window
Button, Document
Link
Button, Document
Textarea
Form
JScript 3.0 поддерживается в Microsoft Internet Explorer
4.0-4.5. Ниже приводятся списки расширений объектов,
операций и операторов, добавленных в JScript 3.0 и не
поддерживаемых е
Объекты
Applet
Array
Boolean
Event
Image
MimeType
Операции
typeof
Операторы
continue
delete
i предыдущих версиях.
Number
Object
Plugin
RegExp
Screen
void
do...while import switch
export labeled
Таблицы с
Глава 26 ШШЯ
26.16 по 26.18 содержат свойства, мето-
ды и обработчики событий, добавленные в JScript 3.0.
Table 26.16. (
Овойства, поддерживаемые в JScript
3.0 и следующих версиях.
Свойства
$*
$&
$_
$¦
$¦
$+
$1,$2,[е1]$9
all
anchors
arguments
arity
availHeight
availWidth
border
caller
checked
closed
colorDepth
complete
constructor
current
data
defaultChecked
defaultSelected
description
domain
embeds
enabledPlugin
filename
form
formName
forms
global
height
history
hspace
ignoreCase
images
innerHeight
innerWidth
input
language
Объект
RegExp
RegExp
RegExp
RegExp
RegExp
RegExp
RegExp
Document
Document
Function
Function
Screen
Screen
Image
Function
Checkbox
Window
Screen
Image
Object
Historv
1 II \J LVy 1 у
Event
Checkbox
Option
MimeType, Plugin
Document
Document
MimeType
Plugin
Checkbox
Document
Document
RegExp
Event, Image, Screen
Window
Image
RegExp
Document
Window
Window
RegExp
Navigator
Избранные программные технологии
Часть V
выбрать способ обхода ошибок с помощью методики
выяснения типа браузера, описанной в главе 27, или
вообще не использовать в сценарии спорные методы
решения.
Поскольку ошибки браузера существенно отличают-
отличаются в зависимости от версий браузеров, каждая из них в
отдельности рассматриваться не будет. При создании
сценария лучше всего в первую очередь учитывать
ошибки именно тех браузеров, которые будут поддер-
поддерживать данный сценарий. Как только принято решение
о типах браузеров, стоит потратить некоторое время на
обзор ошибок, связанных с этими браузерами. Потру-
Потрудитесь убедиться, что ошибки браузеров не мешают сце-
сценариям.
Компания Netscape проделала громадную работу по
обеспечению доступа к полному списку всех ошибок,
имеющих отношение к JavaScript и связанных с брау-
браузерами Netscape. Этот список ошибок находится на их
сайте по адресу http://devedge.netscape.com/support/
bugs/known/ JavaScript.html.
Microsoft, напротив, не поддерживает доступный
список связанных с JScript ошибок, следовательно, по-
понадобится потратить какое-то время на поиск описания
ошибок на сайте Microsoft (msdn.microsoft.com).
Резюме
В главе рассматривались реализация JavaScript в брау-
браузерах Microsoft и Netscape. На заре своего появления
язык JavaScript создавал программистам множество про-
проблем, но сейчас, наконец-то, стабилизировался — бла-
благодаря усилиям Netscape, Microsoft и ЕСМА. Однако,
несмотря на стабильность JavaScript, не все могут ис-
использовать самые новые браузеры. По этой причине важ-
важно знать, какие функциональные возможности JavaScript
поддерживаются в различных версиях браузеров, а так-
также принимать во внимание, что каждый браузер имеет
свой набор досадных ошибок. Информация из этой гла-
главы поможет обеспечить качественную работу сценари-
сценариев в браузерах Microsoft и Netscape.
Методы выяснения типа
браузера
В ЭТОЙ ГЛАВЕ
Подход "Все или ничего"
Подход "Выяснение по месту"
Перед описанием темы главы автору хотелось бы
представить читателям Джо. Джо — Web-разработчик,
который имеет огромное желание оживить собственный
Web-сайт, создав с помощью JavaScript специальные
эффекты, упрощенную навигацию по сайту, анимиро-
ванньге кнопки и возможности верификации данных.
Потратив немалую энергию и сделав все задуманное,
Джо вспомнил, что следовало бы убедиться в том, что
все разработанное под Netscape Navigator будет работать
и в Microsoft Internet Explorer, а также в старых верси-
версиях Netscape Navigator. Да, жизнь не удалась. Специаль-
Специальные эффекты опирались на неуниверсальные объекты
Layer, а в коде было задействовано много объектов
Array, которые вызывают проблемы в Navigator 2.O. В
результате получилось, что сайт оказался пригодным
только тем, кто располагал той же версией браузера, что
и у Джо.
Хотя Джо — вымышленный персонаж, та же груст-
грустная история часто повторяется при реальной разработ-
разработке сайтов. Если разработчик использует JavaScript-код,
он несомненно столкнется с подобными проблемами.
Учитывая различные степени совместимости JavaScript-
диалектов, несовместимость — первое, о чем необходи-
необходимо помнить в процессе разработки сценария. В конце
концов, главная цель использования JavaScript заключа-
заключается в расширении возможностей Web-сайта. Если про-
проигнорировать проблемы совместимости, то пользовате-
пользователи, применяющие браузеры, которые не поддерживают
вашу версию JavaScript, будут весьма разочарованы.
Поэтому первой целью у разработчика Web-страниц
должна быть разработка "надежного" сценария — сце-
сценария, максимизирующего возможности более поздних
версий JavaScript, но при этом учитывающего возмож-
возможности браузеров, обеспечивающих меньшую степень
поддержки. В этой главе рассматриваются два метода
выяснения типа браузера клиента.
Подход "Все или ничего"
Первая методика, которую можно обозначить как под-
подход "Все или ничего", определяет, может ли выполнить-
выполниться сценарий целиком или он полностью игнорируется
браузером. Для применения такой методики в параметре
language дескриптора <script> потребуется определить
ожидаемый диалект. Операторы в пределах дескрипто-
дескриптора <script> будут игнорироваться, если браузер не под-
поддерживает заданную версию JavaScript.
Преимущество использования данной технологии
состоит в том, что можно быть уверенным — если бра-
браузер понимает параметр language, то он обеспечит полную1
поддержку требуемого JavaScript-диалекта. Недостаток
технологии связан с тем, что браузеры, не поддержива-
поддерживающие указанный диалект, принудительно игнорируют
весьсценарий.
Подход "Выяснение по месту"
Альтернативой подхода "Все или ничего" является ме-
метод "Выяснение по месту" (иногда называемый "обна-
"обнаружение браузера"). Эта технология предполагает опре-
определение версии браузера в сценарии перед выполнением
кода, критичного к версии JavaScript.
Хотя эта методика несколько сложнее, однако она
обладает преимуществом в том, что здесь возможно обес-
обеспечить альтернативную функциональность для браузе-
браузеров, не поддерживающих конкретную версию JavaScript.
При помощи объекта Navigator в JavaScript можно по-
получить четыре вида полезной информации, связанной с
браузером.
Избранные программные технологии
Часть V
Тип браузера
Свойство appName объекта Navigator предоставляет имя
браузера клиента. Двумя наиболее популярными брау-
браузерами по праву считаются Netscape и Microsoft Internet
Explorer. Следующая строка отображает имя браузера:
document.write(navigator.appName);
Если требуется идентифицировать другие типы бра-
браузеров, необходимо использовать свойство userAgent
объекта Navigator. Это свойство содержит большой
объем информации, но если организовать поиск опре-
определенной строки через метод indexOf(), можно иденти-
идентифицировать имя браузера. Поскольку значением явля-
является строка, неплохо ее преобразовать к нижнему
регистру с целью упрощения сравнения. Таблица 27.1
содержит некоторые из наиболее частых значений свой-
свойства userAgent и соответствующие им типы браузеров.
Таблица 27.1. Значения свойства userAgent.
Значение
mozilla
msie
opera
webtv
Браузер
Netscape Navigator
Microsoft Internet Explorer
Opera
WebTV
Следующий фрагмент кода определяет различные
типы браузера с использованием свойства userAgent:
var browserType =
navigator.userAgent.toLowerCase();
If (browserType.indexOf('mozilla1)
document.write("Netscape Navigator");
else if (browserType.indexOf('msie')
document.write("Microsoft Internet Explorer");
else if (browserType.indexOf('opera')
document.write("Opera");
else if (browserType.indexOf('webtv')
document.write("WebTV");
Г.<ЭД " ';L',. ; «. ^^ ^ .*3^1:
Для получения дополнительной информации о строке
userAgent посетите Web-сайт по адресу http://
www.it97.de / JavaScript / JS_tutorial / bstat/navobj.html.
Версия браузера
Свойство appVersion объекта Navigator предоставляет
сценарию информацию о версии клиентского браузера.
Следующая строка программы отображает версию бра-
браузера на экране:
document.write(navigator.appVersion);
Если преобразовать это свойство в число с плаваю-
плавающей точкой (т.е. не целое) с помощью метода parseFloat(),
все можно свести к простым математическим сравнени-
сравнениям. Почему это удобнее, будет показано в следующем
разделе при определении версии JavaScript. Следующая
строка кода содержит способ создания такого значения
с плавающей точкой:
var browserVersion =
parseFloat(navigator.appVersion);
Версия JavaScript
Версия
JavaScript
1 0
:0
11
1 2
1.2
1 3
1.4
14
Браузер
iNavigator
Internet Explorer
Navigator
Navigator
Internet Explorer
iNavigator
Navigator
ilnternet Explorer
Воспользовавшись знаниями о JavaScript-диалектах,
полученными из главы 26, можно определить, какая вер-
версия JavaScript используется по типу браузера и инфор-
информации о версии, упоминавшейся выше. Таблица 27.2
показывает, как тип браузера и информация о версии
соответствует версии JavaScript.
Таблица 27.2. Версии JavaScript.
Версия
браузера
¦2Q
3.0
3.0
4.0-4.05
4.0
4.06-4.5
5.0
5.0
Платформа операционной системы
Свойство platform объекта Navigator представляет ин-
информацию о платформе операционной системы клиен-
клиента. Следующая строка программы отображает платфор-
платформу операционной системы:
document.write(navigator.platform);
Эта информация будет необходима, если, например,
предпринимается попытка обойти в Macintosh ошибку,
которая существует только в Netscape Navigator. В боль-
большинстве случаев эта информация не нужна, но если все-
таки она потребуется, то вам уже известно, как ее по-
получить.
Пример динамического позиционирования
Теперь, когда рассмотрено множество способов получе-
получения информации о клиентском браузере и его операци-
операционной системе, рассмотрим соответствующий пример.
Одно из самых больших и досадных различий меж-
между Navigator и Internet Explorer на сегодняшний день —
это способы динамического позиционирования. Netscape
выполняетдинамическое позиционирование, используя
Методы выяснения типа браузера
свой объект Layer, a Microsoft — используя HTML-дес-
HTML-дескриптор <div>. Для реализации динамического позици-
позиционирования, которое будет работать одинаково хорошо
в браузерах как Netscape, так и Microsoft, потребуется
записать код на JavaScript для определения типа кли-
клиентского браузера.
Листинг 27.1 создает два слоя (один красный и дру-
другой обычный текст), используя в одном случае дескрип-
дескрипторы <div>, в другом —дескрипторы <1ауег>. Красный
блок содержит кнопки, которые перемещают блок вдоль
окна браузера. Красный блок также имеет кнопку, ко-
которая заставляет текстовое поле исчезать и вновь появ-
появляться (см. рис. 27.1). Фактическое движение выполня-
выполняется путем изменения значений свойств слоя в случае
слоев в Netscape или через таблицу стилей в случае бло-
блока <div>. Дополнительную информацию об использо-
использовании слоев и дескриптора <div> можно найти в главе
23.
Листинг 27.1. Обнаружение браузеров Navigator и!
Internet Explorer.
<html>
<body>
<script language="JavaScript">
//Создать дескриптор <1ауег>, если это netscape
if(navigator.appName.indexOf("Netscape") != -1)
document.write('<layer id="redBox" ') ;
//Создать дескриптор <div>, если это Microsoft
if(navigator.appName.indexOf("Microsoft") != -1)
document.write("<div id='redBox1 ") ;
//Установить стиль, используемый красным блоком
document.write('style="position:absolute; ') ;
document.write('left:150px; ') ;
document.write('top:150px; ');
document.write('background-color:red;">');
</script>
This is
<form>
'<inpu t:
<input
<inpu1:
<inpul:
</form>
a block of moving buttons
type="button"
value="UP"
onClick="moveOp()">
type="button"
value="DOWN"
onCLick="moveDown О ">
type="button"
value="LEFT"
onClick="moveLeft()">
type="button"
value="RIGHT"
onClick="moveRight(> "XBR>
type="button"
value=" SHOW/HIDE Text Box"
onClick="showHide()">
<script language="JavaScript">
Глава 27
//Если это Netscape, выдать закрывающийся
//дескриптор </layer>
if {navigator.appName.indexOf ("Netscape") != -1)
document. write ( "</layer>") ;
У/Если это Microsoft, выдать закрывающийся
//дескриптор </div>
if (navigator.appName.indexOf ("Microsoft") != -1)
document.write("</div>");
II—>
¦</script>
<script language="JavaScript">
//Если это Netscape, создать текстовый блок
//через <layer>
if (navigator.appName. indexOf ("Netscape") != -1)
¦!
document.write ( '<layer id="textBox" >');
document .write ("Here is some text defined as
a block") ,-
document.write("</layer>");
//Если это Microsoft, создать текстовый блок
//через <div>
if (navigator.appName.indexOf ("Microsoft") != -1)
(
document.write ("</div>");
document.write("<divid=¦textBox'>") ;
document, write ("Here is some text defined as
'^a block") ;
document.write ( "</div>1> ;
1
II—>
</script>
<script language="JavaScript">
var isNetscape = 0 ;
var isMicrosoft = 0;
//Определение типа браузера
if (navigator. appName. indexOf ("Netscape") != -1)
isNetscape = 1 ;
if (navigator,appName.indexOf ("Microsoft") != -1)
isMicrosoft = 1 ;
//Переместить красный блок на 20 пикселов вверх
function move Op ( )
i
if (isNetscape)
document, layers. redBox.pageY+=( -20) ;
if(isMicrosoft)
document, all. redBox .style .pixelTop+= ( -20) ;
)
//Переместить красный блок на 20 пикселов вниз
function moveDown ( )
Ч
if(isNetscape)
document. layers. redBox.pageY+=20;
if (isMicrosoft)
document. all. redBox. style. pixelTop+=20
J
//Переместить красный блок на 20 пикселов влево
function moveLeft()
¦i
if(isNetscape)
Избранные программные технологии
Часть V
document.layers.redBox.pageX+=(-20);
if(isMicrosoft)
document.all.redBox.style.pixelLeft+=(-20) ;
стить красный блок на 20 пикселов
//вправо
function moveRight()
if (isNetscape)
document.layers.redBox.pageX+=2 0;
if(isMicrosoft)
document.all.redBox.style.pixelLeft+=20;
}
//Скрыть или отобразить текстовый блох
function showRide()
if(isNetscape)
//Если текстовый блок скрыт, сделать его
//видимым
if(document.layers.textBox.visibility ==
"hide")
document.layers.textBox.visibility="inherit";
else
document.layers.textBox.visibility="hide";
1
if(isMicrosoft>
¦I
//Если текстовый блок скрыт, сделать его
//видимым
if(document.all.textBox.style.visibility ==
"hidden")
document.all.textBox.style.visibility^1 visible";
else
document.all.textBox.style.visibility="hidden";
</script>
</body>
</html>
. ПРВДУПРЕЖДЕНИЕ
В Netscape Navigator, как вы, вероятно, обратили вни-
внимание, при перемещении кнопок текст, связанный с
кнопками, иногда двигается в беспорядке. Это проис-
происходит из-за того, что при изменении свойства layer
Netscape не обновляет весь экран. Internet Explorer в
данном случае работает лучше, поскольку он обнов-
обновляет экран при изменении свойств таблицы стилей. Кро-
Кроме того, Netscape случайным образом перекрашива-
перекрашивает фон слоя в красный цвет.
В последнем примере метод indexOf() применялся
для поиска строки "Netscape" или "Microsoft" в свойстве
appName объекта Navigator. В зависимости от того, ка-
какая строка найдена, значение true присваивается либо
переменной isNetscape, либо переменная isMicrosoft.
Эти переменные затем используются для определения,
какие именно функциональные возможности браузера
должны применятся.
Если в сценарии требуется более детальная инфор-
информация о браузере, полезно создать функцию, которая
определяет и тип браузера, и его версию. Например, фун-
функция determineCurrentBrowser(). показанная в следующем
коде, исследует свойства appName и appVersion объекта
Navigator и затем на их основе устанавливает значение
глобальной переменной CURRENT_BROWSER:
/* Глобальные переменные */
var CORRENT_BROWSER = new String () ;
РИСУНОК 27.1. Обнаружение браузеров Navigatoru Internet
Explorer.
I*
determineCurrentBrowser() {
var bwr = navigator. appName ;
var ver = parseFloat(navigator.appVex
if ( bwr = "Netscape" fifi ver >= 5)
CURRENT_BROWSER = "Netscape !
.if ( bwr = "Netscape" fifi ver >= 4.06 &&
ver <=4.5) CURRENT_BROWSER = "Netscape
«4.06 - 4.5",-
if ( bwr = "Netscape" && ver >= 4 ss
ver <= 4.05) C0RRENT_BROWSER = "Netscape
>.0 - 4.05";
if ( bwr == "Netscape" && ver = 3 )
CURRENT_BROWSER = "Netscape 3.0"
if ( bwr = "Netscape" Si ver = 2 )
CURRENT_BROWSER = "Netscape 2.0";
В качестве альтернативы, можно забыть о браузерах
и сосредоточиться на самых высокоуровневых возмож-
ностях предлагаемой версии JavaScript. Преимущество
такого метода состоит в том, что зачастую он оказыва-
оказывается проще применительно для операций сравнения:
/* Глобальные переменные
var JS VERSION
Методы выяснения типа браузера
Глава 27
function JSVersionCheok() {
var bwr = navigator.appName;
var ver = parseFloat(navigator.appVersion);
if ( bwr = "Netscape" && ver >= 5)
JS_VERSION = 1.4;
if (~bwr = "Netscape" ?? ver >= 4.06 S&
ver <=4.5) JS_VERSION = 1.3;
if ( bwr = "Netscape" SS ver >= 4 SS
ver <= 4.05) JS_VERSION = 1.2;
if ( bwr == "Netscape" && ver = 3 )
JS_VERSION = 1.1,-
if ( bwr = "Netscape" && ver = 2 )¦
JS VERSION = 1.0;
Резюме
В главе были рассматривались два метода, которые мож-
можно использовать для преодоления несовместимости в
сценариях. Первичная цель применения JavaScript со-
состоит в расширении возможностей Web-сайтов. Если
проигнорировать проблемы совместимости, то пользо-
пользователи, применяющие браузеры, которые не поддержи-
поддерживают выбранную разновидность JavaScript, не смогут
получить то, что ожидали. Таким образом, при создании
сценариев необходимо задействовать методы выяснения
типа браузера, которые расширяют возможность приме-
применения более поздних версий JavaScript, но при этом так-
также учитывают браузеры, обеспечивающие меньшую сте-
степень поддержки.
Навигация по сайту с
использованием JavaScript
В ЭТОЙ ГЛАВЕ
Исследование технологий навигации
Создание сценария для динамической
инструментальной панели
Использование объекта History
Исследование технологий навигации
JavaScript перекладывает большую часть работы по дос-
доставке и форматированию содержимого на браузер вмес-
вместо реализации этих операций на стороне сервера. Одной
из положительных черт подобного управления со сторо-
стороны клиента является усовершенствование навигации.
Вместо обеспечения простых статических ссылок, свя-
связывающих Web-страницы сайта, разработчики могут
теперь задействовать JavaScript для управления отобра-
отображением информации на сайте.
До появления фреймов было трудно добавлять на-
навигационные средства к Web-странице без того, чтобы
ограничить по нескольким направлениям схему разме-
размещения информации на сайте и его содержимое. Напри-
Например, отображение карты, постоянно показывающей вид
сайта, можно было реализовать только за счет помеще-
помещения ее на каждую страницу. Карта должна была иметь
достаточно небольшие размеры, дабы не отвлекать
пользователя. Если просматриваемая страница была
слишком длиной, карта во время просмотра страницы
пользователем часто оказывалась недоступной. Ограни-
Ограничение сайта до одной страницы не могло, конечно же,
рассматриваться в качестве варианта, а если карта сайта
была доступна только на протяжении части времени про-
просмотра, это выглядело весьма непрофессионально.
Фреймы помогают решить эту проблему. Разбиение
окна браузера на подокна позволяет сохранять карту
сайта видимой все время, пока пользователь просматри-
просматривает разные страницы HTML-документа. За счет щелч-
щелчков на ссылках, находящихся на карте сайта, новая стра-
страница отображается в другом фрейме. JavaScript для этого
не требуется. Просто используйте атрибут target деск-
дескриптора <А> для указания на любой требуемый фрейм.
Однако, возникает вопрос — что делать, если текущая
страница содержит форму ввода данных, которая долж-
должна быть отправлена перед переходом к другой страни-
странице? Отправка формы с помощью кнопки "Submit" — это
хорошо, но она переведет пользователя на новую стра-
страницу, не содержащую карту. В ряде случаев лучшим
выходом может оказаться предоставление пользователю
возможности перемещения по всему сайту без необхо-
необходимости нажатия на кнопку отправки формы после ее
заполнения. Это достигается с помощью JavaScript, если
только поместить формы в фреймы.
В случае, если карта сайта достаточно велика, в каж-
каждый момент времени можно отображать только часть
карты. При этом возникает необходимость в обновле-
обновлении карты. Как обновить карту, отправить форму, ото-
отобразить полный документ и проследить местонахожде-
местонахождение пользователя с помощью одного щелчка мыши?
Самый простой путь для этого — JavaScript. Описан-
Описанные в главе навигационные методы демонстрируют
способы создания и использования динамической ин-
инструментальной панели, а также использование JavaScript-
объекта History.
Создание сценария для динамической
инструментальной панели
Инструментальная панель один из элементов стандарт-
стандартного пользовательского интерфейса, часто используемо-
используемого для навигации практически в любом приложении. В
JavaScript динамическая инструментальная панель — это
панель, которая изменяется в результате взаимодействия
пользователя с ней. Для примера ниже показана инст-
инструментальную панель, которая управляет простой слай-
слайдовой демонстрацией. Четыре кнопки на инструменталь-
Навигация по сайту с использованием JavaScript
ной панели используются для перемещения вперед и
назад по массиву слайдов. Две других кнопки исполь-
используются для запуска или останова автоматического цик-
цикла по всем слайдам. Логический путь создания такой
программы состоит в построении двух объектов — Button
и Toolbar.
Создание объекта Toolbar
Инструментальную панель можно рассматривать как
набор кнопок, поэтому дадим объекту Toolbar имя
buttonSet. Листинг 28.1 показывает конструктор buttonSet,
который обычно устанавливает все свойства и методы,
доступные в инструментальной панели.
Листинг 28.1. Конструктор объекта buttonSet.
function buttonSet(name)
* Описание: конструктор объекта кнопки.
* Аргументы: name - Имя переменной buttonSet.
// Свойства
this.name = name;
this.startlndex = ;
this.length = 7;
this.isBusy = false;
// Метода
this.addBtn = addBtn;
this, print = print;
this.clear = clear;
return this ;
1
Метод addBtn создает и добавляет в buttonSet новый
объект Button. Метод print записывает buttonSet в HTML-
документ. Метод clear устанавливает все кнопки, содер-
содержащиеся в пределах buttonSet, в их первоначальное со-
состояние доступности/недоступности. Эти методы
подробно описываются в следующих разделах.
Использование объекта Button
Объект buttonSet используется для управления одним и
более объектов Button. Каждый объект Button содержит
информацию о нажатии кнопки или отображении ее в
виде HTML-элемента <lmg>. Листинг 28.2 показывает
две функции, которые применяются для создания но-
нового объекта Button.
Листинг 28.2. Метод click и конструктор объекта
Button.
function click()
f
Глава 28
* Аргументы: Нет.
*/
eval(this.command) ;
I
function button (name, file, alt, url, spacer,
condition, command)
* Описание: объект кнопки.
* Аргументы:
* name - Имя кнопки в HTML-коде.
* file - URL изображения кнопки.
* alt - Атрибут alt для кнопки.
* url - URL соответствующего buttonSet.
* spacer - количество пикселов после кнопки.
* condition - условный оператор, который
* определяет, должна ли
* отображаться эта кнопка.
* commmand - Команда, которую реализуем
* кнопка.
// Свойства
this, name = name;
this.file = file;
this.alt = alt;
this.url = url;
this.spacer = spacer;
this. condition = condition;
this.command = command;
// Методы
this.click =
return this ;
click;
/*
* Описание: Метод объекта кнопки. Реализует
* команду этой кнопки.
Свойство name представляет HTML-имя кнопки.
Свойство file кнопки — исходный URL-адрес изображе-
изображения кнопки. Свойство alt хранит значение HTML-атри-
HTML-атрибута alt. Свойство U RL применяется в качестве свойства
HREF якоря, связанного с изображением кнопки. Ис-
Используя графический файл с прозрачностью, свойство
spacer определяет, сколько места осталось для размеще-
размещения изображения еще одной кнопки справа от данной.
Это позволяет создавать в инструментальной панели
различные разделы либо помещать туда изображения
кнопок разной величины. Button будет отображаться
только, если его условное выражение равно true. Это —
ключ к определению того, какие кнопки отображены и
доступны для нажатия. Всякий раз когда объект
buttonSet присутствует на HTML-странице, необходи-
необходимо смотреть на условное выражение для каждого объек-
объекта Button, чтобы определить, доступен ли Button для
щелчка. Если доступен и пользователь щелкает на кноп-
кнопке, команда выполняется. Строка команды может быть
любым оператором JavaScript в случае, если она выпол-
выполняется в контексте документа, в котором был создан
buttonSet.
Избранные программные технологии
Часть V
Созданиеэкземпляровинструментальной
панели
С помощью приведенных ниже строк кода программа
слайдовой демонстрации создает новый объект buttonSet
и сбрасывает его текущее состояние.
Toolbar = new buttonSet("Toolbar");
Toolbar.cleax ();
При создании нового экземпляра buttonSet важно,
чтобы аргумент, переданный конструктору, был равен
имени переменной создаваемого объекта. Это позволя-
позволяет объекту buttonSet создавать команды JavaScript, ис-
используя собственное имя. Метод clear() используется
для установки и сброса значений глобальных перемен-
переменных, использующих buttonSet для определения, какие
из его кнопок разрешены для нажатия. Листинг 28.3 по-
показывает метод clear(), реализованный для приложения
Slide Show.
Листинг 28.3. Метод clear() объекта buttonSet.
function clear ()
/*
* Описание: Метод объекта buttonSet.
* Используется для сброса всех
1 глобальных переменных, на
* поторые ссыпаются пноппи в
* buttonSet на основе своих
'* УСЛОВНЫХ выражений.
* Аргумента!: Нет.
*/
gIsRunning=false;
Как только новый экземпляр buttonSet создан, при-
приложение Slide Show с использованием метода addBtn()
создает кнопки. Первая создаваемая кнопка показана в
следующем коде:
Toolbar.addBtn("First","graphics/first.gif",
"First Picture",0,"true",
"changeSlide (¦first')");
Листинг 28.4 отображает полный код метода addBtn(),
который создает новый объект Button и затем добавляет
его в buttonSet.
Листинг 28.4. Метод addBtnQ объекта buttonSet.
function
addBtn(name,file,alt,spacer,condition,command)
* Описание: Метод об-ькта buttonSet, которьм
* добавляет новую кнопку set.
* Аргументы: name - (string) Имя кнопки в
* HTML-коде.
* file - (string) URL изображения
* кнопки.
* alt - (string) Атрибут alt
* кнопки.
spacer - (integer) колияество
пикселов после кнопки.
condition - (string) условный
операторf которьм
определяет, должна
ли отображаться
кнопка.
commmand - (string) Команда,
которую реализует
кнопка.
var i = this.length;
this[i] = new button(name,file,alt,
"javascript:parent. "+this.name+" ["+i+']"+
".clickO ",spacer,condition,command) ;
this.length++;
Аргумент url, указанный для конструктора кнопки в
листинге 28.4, заслуживает дополнительного внимания.
Эта строка будет использоваться как свойство
HREF изображения кнопки. Приведенный ниже пример —
это HTML-код, сгенерированный для первой кнопки
Slide Show:
<Д href="javascript:parent.Toolbar[7].click)) ">
<img src="graphics/first.gif" alt="First
Picture" width=4" height=4" border=0>
Когда пользователь щелкает на изображении, вызы-
вызывается метод click() седьмого свойства объекта Toolbar.
Седьмой элемент в объекте Toolbar (который, по суще-
существу, является массивом) — это элемент, в котором при
помощи метода addBtn() был сохранен первый объект
Button. Это — лучший способ вызвать метод click() в
любом фрейме, хорошо работающий как в браузере
Microsoft, так и в Netscape. Объект buttonSet установ-
установлен таким образом, что программист, использующий
его, не должен следить за нумерацией кнопок.
Отображение инструментальной панели
Глобальная переменная glsRunning будет иметь значе-
значение true, если программа слайдовой демонстрации ав-
автоматически проходит через каждый слайд; иначе она
будет равна false. Эта переменная используется в четы-
четырех объектах Button для отображения двух кнопок од-
одновременно. Одна иллюстрирует активное состояние, а
другая — заблокированное (кнопка недоступна для щел-
щелчка, что отображается на экране бледными цветами).
Следующие примеры содержат две кнопки, которые за-
зависят от glsRunning:
Toolbar.addBtn("Start", "graphics/auto. gif",
"Start Slideshow", 0, "gIsRunning=false",
"changeSlideCstart1}") ;
Toolbar. addBtn (" StartGrey" , "graphics/
**autoGrey.gif", "Start Slides how", 0,
"gIsRunning=true", "");
Навигация по сайту с использованием JavaScript
Кнопка StartGrey отображается только, если значе-
значение glsRunning равно true. Если же glsRunning равна
false, отображается кнопка Start. Если кнопка Start до-
доступна и пользователь совершает на ней щелчок, в фун-
функции changeSIideO выполняется следующий код:
if(command = "start") {
glsRunning = true;
Toolbar.print(window.frames[2].document);
gTimer =
window.setTimeout("startAuto()",1500);
.)
Значение переменной glsRunning установлено в true,
а инструментальная панель помещена в выбранный
объект Document. Текущая инструментальная панель
удаляется и создается новая HTML-страница, содержа-
содержащая новую инструментальную панель, которая учиты-
учитывает новое состояние glsRunning. Это означает, что
кнопка StartGrey будет доступной, а кнопка Start даже
не помещена на новую страницу. Это дает иллюзию ус-
установки запрета выбора кнопки "Start", тогда как на
самом деле это совсем другая кнопка. В листинге 28.5
показан метод print(), который отвечает за подготовку
новой HTML-страницы.
Метод print() начинается с установки флажка isBusy
в true, что предотвращает нажатие пользователем других
кнопок во время обновления инструментальной панели.
Листинг 28.5. Метод printQ объекта buttonSet.
Глава 28
Затем формируется базовый URL, который приравнива-
приравнивается к базовому URL текущего окна. Он сохраняется в
переменной topBase и используется при генерации дес-
дескриптора <base> для нового документа с инструменталь-
инструментальной панелью. Предполагается, что имя файла для уста-
устанавливающего фреймы HTML-документа и"меет длину
двенадцать символов, например, SIideSilw.htm. Это дол-
должно обеспечить согласование с версиями до Netscape
Navigator 3.0.
^ПРЕДУПРЕЖДЕНИЕ ^ , ',
Если ошибиться в определении базового URL для сге-
сгенерированного при помощи JavaScript HTML-докумен-
HTML-документа, то версии Netscape Navigator до 3.0 не смогут
понять некорректный URL.
Метод print() продолжает работу, открывая, доступ
к целевому документу. Затем метод записывает каждую
строку HTML, требуемую для формирования Web-стра-
Web-страницы с инструментальной панелью. Для центрирования
кнопок можно воспользоваться таблицей. Цикл for при-
применяется для последовательной записи каждой кнопки,
которая сохраняется в buttonSet. Если был задан сим-
символ пробела, напечатается пустой графический символ
и "размножится" до требуемого количества пикселов. На-
Наконец, документ закрывается и окно браузера обновля-
обновляется.
function print (dob j)
* Описание: Метод об"ьекта buttonSet.
* Аргументы: dobj - объект document, содержащий buttonSet.
*/
this.isBusy = true;
var spacelnt;
var DQOOTE = 'V";
var topBase = "" ;
var basePath = ""+window.location.pathname;
var baseDir = "";
var baseFile = basePath.substring(basePath.length-10,basePath.length);
baseDir = basePath.substring@,basePath.length-12);
topBase=window.location.protocol+"//"+window.location.host+baseDir;
dObj .open 0;
dObj.bgColor = parent.frames[0].document.bgColor;
dObj.writeln('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">');
dOb j . writeln (' <htmlxhead>') ,•
dObj.writeln('<title>Toolbar</title>');
dObj.writeln('<base href = ¦ +DQOOTE+topBase+DQtJOTE+' >') ;
dObj.writeln('<script language="JavaScript">');
dObj.writeln('</script>');
dObj.writeln('</head>') ;
dObj.writeln('<body bgcolor="'+ parent.frames[0].document.bgColor.toUpperCase()+'
dObj.writeln('<center>');
dObj.writeln('<table width=00%" border=">');
dObj .writeln ('<trxtd align="center">') ;
//Вывод кнопок, начиная со свойства с номером i.
Избранные программные технологии
Часть V
for(var i = this.startlndex; this.length > i; i++)
(
if(eval(this?i].condition)>
II
dObj .write ("<A HREF = " 4-this[i] .url+'">') ;
dObj.write('<img src=" '+this[i] .file+'" alt=" '+tiia[i].alt+'" width=4" height=4"
*»border=0>' ) ;
dObj .write( ' </A>" ) ;
// Добавить пустое пространство, если это определено.
spacelnt = 0 + this[i] .spacer;
if(spacelnt != 0)
t
dObj .write ( '<imgsrc="graphics/space.gif" width= '+spacelnt+' height= 24 border=0>') ;
I
dObj .writeln( •</tdx/trX/table>1) ;
dObj.writeln('</center>');
dObj .writeln< 1</bodyX/html>!) ;
dObj . close (У ;
this.isBusy = false;
Обновление инструментальной панели
Как можно понять из сказанного выше, обновления
инструментальной панели проводить легко, необходимо
только вызвать метод print(). Просто установите глобаль-
глобальные переменные, от которых зависят кнопки, и вызовите
prmt(). Документы в других фреймах могут также обнов-
обновлять инструментальную панель. Например, несложно
изменить приложение Slide Show так, чтобы пользова-
пользователь не смог запустить слайдовую демонстрацию, начи-
начиная с последнего слайда. Для этого потребуется добавить в
метод clearO новую глобальную переменную с именем
gCanStart к методу clear() и установить ее равной false.
Затем необходимо изменить addBtn, которая вызывается
для кнопок Start и StartGrey так, чтобы она учитывала
вновь появившуюся gCanStart. Новый код будет выгля-
выглядеть следующим образом:
Toolbar.addBtn("Start", "graphics/auto.gif",
"Start Slideshow", 0, "gIsRunning=?alse &&
wgCanStart=true", "changeSlide ('auto') ") ;
Toolbar.addBtn("StartGrey", "graphics/
*•autoGrey.gif", "Start Slideshow", 0,
*¦¦ "gIsRunning=true || gCanStart=false", "") ;
Затем потребуется вставить в раздел <head> после-
последнего слайдового документа следующий сценарий:
<script language="JavaScript">
<! —
var savedState;
savedState = parent.gCanStart;
parent.gCanStart=false;
parent.Toolbar.print(parent.frames[2].document);
parent.gCanStart=savedState;
</script>
И наконец, необходимо добавить еще один вызов
метода print () объекта Toolbar, срабатывающий при вы-
выходе из документа:
<body onUnload="parent.Toolbar.print(parent.
wframes [2] .document) ">
Приведенная строка кода вернет инструментальную
панель в предыдущее состояние после перехода к сле-
следующему слайду.
Если при переходе к следующему слайду устанавли-
устанавливаются глобальные переменные и обновляется инстру-
инструментальная панель, исчезает необходимость обновления
инструментальной панели через обработчик событий
on Unload. Используя подобный подход, можно в каж-
каждом документе определять, какие кнопки отображать,
зная, что эта информация будет сбрасываться каждый
раз при загрузке следующего документа.
Использование приложения Slide Show
На сопровождающем CD-ROM находится каталог, со-
содержащий все файлы, необходимые для приложения
Slide Show. Для активизации мультифреймового окна
просто загрузите slideshow.htm в браузер. Инструмен-
Инструментальная панель используется здесь для передвижения по>
слайдам и по соответствующим их описаниям. Рисунок
28.1 демонстрирует, как приложение Slide Show выгля-
выглядит после загрузки в браузер.
В программу входят пять слайдов. Инструментальную
панель можно использовать для продвижения вперед или
назад по слайдам (соответственно, с помощью третьей и
второй кнопок). Можно также воспользоваться первой
и четвертой кнопками для перемещения к первому и
последнему слайду. Последние две кнопки справа запус-
запускают и останавливают продвижение по слайдам. Обра-
Обратите внимание, что последняя кнопка недоступна и ото-
отображается соответствующим образом. Это кнопка
StartGrey. После щелчка на кнопке Start (с изображе-
изображением стрелки вправо и эллипса) программа слайдовой
Навигация по сайту с использованием JavaScript
демонстрации начинает циклически проходить по каж-
каждой паре HTML-документов. На рис. 28.2 показан экран
браузера в процессе слайдовой демонстрации. Обратите
внимание, что кнопка останова доступна, тогда как
кнопка Start — нет.
\Щ- JavaScript Unleashed - Nolscnpc
I ¦ ¦¦ > ¦¦¦'¦-•St:-r :V"
Faster tilting a stroll
РИСУНОК 28.1. Инструментальнаяпанелъ приложения Slide
Show.
avaScript Unleashed - Nelscope
?i!e
^Cowith big ears.
.И
m га
РИСУНОК 28.2. Слайд в процессе выполнения программы
слайдовой демонстрации.
Обсуждение дополнительных
возможностей
Ключевой объект buttonSet можно изменить еще боль-
больше. Например, его можно модифицировать с целью
обеспечения поддержки вертикальных инструменталь-
инструментальных панелей вместо горизонтальныхлибо даже для реа-
реализации обоих видов панелей. Для этого просто измените
метод print(), добавив после каждой кнопки дескриптор
<br>. Можно также создать инструментальную панель
в отдельном окне браузера. Такая панель может исполь-
Глава 28
зоваться как навигационный инструмент или даже как
справочное меню. Никакие модификации для этого не
требуются. Просто передайте в метод print() объект
Document нового окна.
Использование объекта History
До сих пор рассматривались способы навигации по пред-
предварительно созданным Web-страницам. Но что если на
Web-странице необходимо обеспечить навигационные
средства управления, которые обладали бы функцио-
функциональными возможностями, характерными для инстру-
инструментальных панелей браузеров? К счастью, JavaScript
предоставляет специальный объект History, который
позволяет передвигаться по Web-сайтам, которые бра-
браузер отображал ранее. В том числе и по Web-страницам,
которые создавали не вы. Объект History способен это
делать, поскольку в нем хранится список всех посещен-
посещенных URL-адресов.
Для навигации по списку URL объект History име-
имеет некоторые встроенные методы навигации вперед и
назад. Метод backO загружает URL предыдущего посе-
посещенного Web-сайта. Метод forward() загружает следу-
следующий URL в списке посещений.
Кроме того, объект History имеет еще один метод и
ряд свойств. К сожалению, из соображений безопасно-
безопасности многие браузеры не позволяют использовать допол-
дополнительный метод и свойства. В действительности, это
не очень большой недостаток, поскольку большинство
возможностей объекта History реализовано в методах
back() и forward().
Для демонстрации применения объекта History сто-
стоит создать простенькую страницу, которая содержит
всего две навигационных кнопки. Одна кнопка будет пе-
переводить пользователя на предыдущий URL из списка
посещений, а другая — на следующий URL в этом спис-
списке. Кнопки будут использовать свои обработчики собы-
событий onClick для вызова двух методов History, которые
обсуждались ранее. Код такой Web-страницы показан
в листинге 28.6.
Листинг 28.6. Использование объекта History для
целей навигации.
<html>
<head>
<title>Using the History object</title>
</head>
<body>
<center>
<hl>Navigating with the History object</hl>
Press one of the following buttons to navigate.
<hr>
<form>
Избранные программные технологии
Часть V
<input type="button"
value="Back"
onClick="window.history.back()">
<input type="button"
value="Forward"
onClick="window.history.forward()">
</form>
</center>
</body>
</html>
Для исследования особенностей работы кнопок нач-
начните с загрузки одного из предпочитаемых Web-сайтов
(попробуйте www.diasoft.kiev.ua). Как только Web-сайт
загрузится, напечатайте URL-адрес, используемый в
листинге 28.6. Затем введите URL другого не менее
любимого сайта (www.osadesign.com), который отлича-
отличается от URL первого загруженного сайта. Теперь щелк-
щелкните на кнопке "Back" в панели браузера. В браузере
отобразится Web-страница, показанная на рис. 28.3.
Теперь можно использовать навигационные кнопки для
перехода на любой из только что посещенных Web-сай-
Web-сайтов.
Резюме
JavaScript может выполнять несколько действий сразу,
следовательно, появляется возможность создавать более
сложные навигационные средства. За счет нажатия
пользователем всего лишь одной кнопки JavaScript мо-
может верифицировать данные, отправлять формы, обнов-
обновлять фреймы, а также изменять содержимое других
фреймов.
Ий- Using the History object - Neturapn
Go
Navigating with the History object
Press one of tht following buttons to nawgate
РИСУНОК 28.3. Навигация с использованием объекта History.
На примере инструментальной панели был проде-
продемонстрирован способ обновления HTML-страницы для
создания иллюзии доступности/недоступности кнопок
во время взаимодействия с ними. Также был показан
метод изменения содержимого трех фреймои одним
щелчком на кнопке. Объект buttonSet с небольшими
модификациями несложно применять при проектиро-
проектировании других Web-страниц.
Объект History предоставляет пользователям функ-
функциональные возможности Web-браузера за счет создания
на Web-страницах кнопок "Forward" и "Back". Это мо-
может оказаться предельно полезным при создании окон,
которые не содержат нормальные инструментальные
панели браузера, но при этом нужда.тся в манипуляци-
манипуляциях ранее посещенными страницами.
Формы и верификация данных
В ЭТОЙ ГЛАВЕ
Установка пользовательской обратной связи
Верификация данных, введенных
пользователем
Создание интерактивных форм
Создание повторно используемого кода
верификации
Пример: тестер цветов JavaScript
После выхода HTML 2.0 у разработчиков появилась
возможность создавать на Web-страницах интерактив-
интерактивные формы. HTML обеспечивает механизмы создания
таких форм:
Клиент-серверная модель. Web-браузер поддержива-
поддерживает общий графический пользовательский интерфейс
(GUI), запускаемый специальным HTML-сценари-
HTML-сценарием. С помощью CGI-программы на серверной части
могут реализоваться определяемые доменом процес-
процессы.
Независимость от платформы. Web-браузер работа-
работает со множеством платформ. Во время разработки
форм не стоит беспокоиться о специфике платфор-
платформы.
Прозрачность сети. Сетевые коммуникации встрое-
встроены в пару Web-6pay3ep/Web-cepBep и реализованы
через протокол HTTP.
Стандартизованный GUI. Формы были стандартизо-
стандартизованы под HTML 2.0. Пользователь, знакомый с эле-
элементами формы, может применить эти знания при
создании любых форм для Web либо для корпоратив-
корпоративной сети.
Интерфейсу HTML-форм присущи свои недостатки:
• Динамическая обратная связь с пользователем. У
HTML-формы нет средств для обеспечения динами-
динамической информации по запрашиваемому вводу на
основе элемента формы.
Проверка формы клиентской части. HTML-формы не
могут осуществлять проверку отдельных элементов
формы, набора элементов или целой формы клиен-
клиентской части.
¦• Диалоговые окна. HTML-формы не могут динами-
динамически предупреждать пользователя об ошибках вво-
ввода или выдавать запрос на дополнительный ввод.
Подтверждение пользователя. Формы не могут зап-
запрашивать подтверждение перед выполнением необра-
необратимых действий.
Интерактивность элементов формы и окна. В HTML-
формах интерактивность ограничивается обработкой
CGI-кода на серверной части.
Для JavaScript характерны эти недостатки. Этот язык
строится на основных свойствах HTML и создает более
мощный GUI-интерфейс клиентской части. В главе чи-
читатель познакомится с методами внедрения таких свойств
в JavaScript. LjiaBy завершает приложение, написанное
на JavaScript. Все эти возможности применялись с це-
целью внедрения инструментальных средств выбора цве-
цветов текста и фон.
Изрядное внимание в главе уделяется обработчикам
событий. Их можно рассматривать как обратные вызо-
вызовы, связанные с формой или ее элементами. Они явно
¦определяются как часть формы или дескриптора эле-
элемента формы. Обработчики событий вызываются при
наличии события, инициируемого пользователем. Они
поочередно вызывают определенный фрагмент или фун-
функцию кода JavaScript. В табл. 29.1 перечислены обработ-
обработчики событий JavaScript.
Избранные программные технологии
Часть V
Таблица29.1 Обработчики событий JavaScript
Обработчик
событий
Связанные объекты
Генерируемое событие
onBlur
onChange
onClick
onFocus
OnKeyDown
OnKeyPress
Button, Checkbox,
Text, Textarea
Radio,
Select, Text, Textarea
Button, Checkbox,
Button, Checkbox,
Text, Textarea
Textarea
Textarea
Radio,
Radio,
Select, Submit,
Link, Reset, Submit
Select, Submit,
Textarea
Window
OnMouseDown Button
Link
OnMouseUp Button
OnReset
onSelect
onSubmit
OnUnload
Form
Text, Textarea
Form
Window
Объект Form теряет фокус ввода.
Значение объекта Form изменяется.
Выполнен щелчок на объекте формы.
Объект Form получает фокус ввода.
В пределах объекта Form выполнено нажатие клавиши.
В пределах объекта Form выполнено нажатие и отпускание
клавиши.
В пределах объекта Form выполнено отпускание кнопки.
Web-браузер завершил загрузку объекта Window.
В рамках объекта Form выполнено нажатие кнопки мыши.
Пользователь перемещает курсор мыши над ссылкой.
В рамках объекта Form выполняется отпускание кнопки
мыши.
Форма была сброшена.
Пользователь выбрал текст в рамках объекта Form.
Форма была отправлена.
Пользователь завершил работу с окном.
Установка пользовательской обратной
связи
Если форма разработана качественно, пользователь смо-
сможет легко и быстро определить вид запрашиваемой инфор-
информации. В простых формах подобное задание идеально'
выполняется с помощью продуманных меток, прилега-
прилегающих к каждому элементу формы. В сложных формах
потребуется задействовать детальное объяснение спосо-
способа заполнения формы. С помощью JavaScript можно
ввести пользовательский запрос дополнительных дан-
данных, относящийся к каждому полю. Эта возможность
позволяет обеспечивать дополнительную информацию
о запросах, функциях, элементах формы в тот момент,
когда она необходима. Проделывая такую операцию,
можно уменьшить объем текста, используемого для обо-
обозначения элементов формы, атакже упростить внешний
вид формы.
Подсказки пользователям реализуется через обработ-
обработчики событий JavaScript и строку состояния браузера.
Обработчик событий onFocus можно применить для
выполнения функции, определяемой пользователем, в
момент, когда объект Form получает фокус ввода. Точ-
Точно так же, обработчик событий onMouseOver применя-
применяется для выполнения функции, определяемой пользо-
пользователем, независимо от того, в каком месте над ссылкой
располагается указатель. Эти обработчики событий мож-
можно использовать для вызова функции, выводящей на
экран командную строку в строке состояния браузера.
Создание формы для обратной связи
пользователем
Следующий пример проиллюстрирует поддержку с по-
помощью JavaScript обратной связи в строке состояния
браузера. Представьте себе на минутку, что необходи-
необходимо создать интерфейс HTML-формы для усовершен-
усовершенствованного автоматического тостера. Основная цель —
создание простого интерфейса, с помощью которого
первый встречный сможет приготовить аппетитный
тост. На рис. 29.1 показан пример такого интерфейса.
I The Amazing Automated Toaster
I Bread Product: laW"
' Quantity: (Г
Toastiness:|5oj
Buttered: Yes й No с
РИСУНОК 29.1 Форма автоматического тостера.
Формы и верификация данных
Пользователь может установить значения четырех
вводимых объектов:
• Объект Selection, представляющий вид хлеба.
• Объект Text, представляющий ожидаемое количество
кусочков хлеба.
• Объект Text, представляющий степень поджаривания
(в цифрах).
¦ • Два переключателя, указывающих, добавлять ли мас-
масло.
Объекты Selection и Text связаны с обработчиками
событий onBlur и onFocus. Эти обработчики выводят на
экран и перемещают определенные пользовательские
строки, связанные с введенными объектами. Обработ-
Обработчик событий onClick увязывает переключатели с фор-
формой обратной связи.
Свойство window.defaultStatus устанавливается для
вывода сообщений приветствия по умолчанию, когда
поступление другой информации отсутствует.
Код для примера с тостером показан в листинге 29.1.
Поскольку в действительности тостера нет, после запол-
заполнения формы код отсылает почту. В этом листинге не-
необходимо заменить адрес на текст your_mail_ID. Каж-
Каждый раз когда встречается часть кода в скобках, его
необходимо заменять на информацию, зависящую от
пользователя или сайта.
Тестирование пользовательской формы
CGI-программы обычно составляются с целью обработ-
обработки данных со всей формы. Однако, возможно, потребу-
Листинг 29.1 toaster.htnii
Глава 29
ется создать форму еще до того как CGI-программа бу-
будет доступна. Может быть, необходимо отладить фор-
форму без обращения CGI-программы. Ниже приводятся
простые способы проверки формы, обходящие CGI-
программу:
Для большинства сайтов доступна CGI-программа с
именем test-cgi, если в форме используется метод get.
Воспользуйтесь следующим дескриптором:
<f ormaotion=http : //your_site_name /cgi-bin/
gi method="get">
После отправки формы пользователь получает стра-
страницу, содержащую, помимо других элементов, зна-
значения элементов формы из передаваемой страницы.
Несмотря на то что CGI-файл test-cgi поддержива-
поддерживается многими серверами, его точное расположение и
доступность могут зависеть от сайта. Администратор
Web-сайта сможет сообщить читателю о деталях.
CGI-программа post-query доступна на большинстве
сайтов, если форма использует метод post. Исполь-
Используйте следующий дескриптор формы:
<form action=http://your_site_name_/cgi-bin/
^test-query method="post">
После отправки формы пользователь получает стра-
страницу, содержащую, помимо других элементов, пары
имя/значение, соответствующие элементам передава-
передаваемой формы. Несмотря на то что post-query поддер-
поддерживается большинством серверов, его точное распо-
расположение и доступность могут зависеть от сайта. О'
деталях вам сообщит администратор Web-сайта.
<!— ИеЬ Page for controlling an automated toaster
— Note: Since we don't really have an automated
mail the results back to the developer
<html>
<head>
<title>The Amazing Automated Toaster</title>
<script language="JavaScript">
<!— начало сценария
function setstatus(str)
toaster
—>
window. status = str;
return true ;
1
var greeting="Hello! How about some nice toasted bread products!1";
window.defaultStatus = greeting;
,// окончание сценария —>
</scri;?t>
</head>
<body>
<hl>The Amazing Automated Toaster</hl>
<?orm action="mailto:your_mail_ID" method="post">
<font size=5>Bread Product:</font>
<select name=tfproduct"
Избранные программные технологии
Часть V
onFocus="setstatus('select desired bread product from list.1)"
onBlur="setStatus('')">
<option>Bread
<option>Waffle
< option>B agel
<option>Roll
<option>Muffin
<option>Croissant
<option>Scone
</select>
<br>
<font size=5>Quantity:</font>
<input type="text" name="quantity" value="l" size=4 maxlength=4
onFocus="setstatus( 'Enter quantity of bread products desired A-1000). ¦) "
onBlur="setStatus('')">
<br>
<font size=5>Toastiness:</font>
<input type="text" name="toastiness" value="S0" size=3 maxlength=3
onFocus="setstatus(" Enter degree of toastiness from 0-100 @=untoasted 100=burnt).')'
onBlur="setStatus('')">
<br>
<font size=5>Buttered:</font>
<font size=5>Yes</font>
<input type="radio" name="buttered" value="yes" checked
onciick="setstatus('Do you want butter on the bread product?')">
<font size=5>No</font>
<input type="radio" name="buttered" value="no"
onClick="setstatus('Do you want butter on the bread product?')">
<hr>
<input type="submit" value="Start Toaster">
<input type="reset">
</form>
</body>
</html>
Если в форме применяется метод post, можно сде-
сделать так, чтобы результаты отправлялись на вашу
учетную запись. Воспользуйтесь следующим деск-
дескриптором формы:
<form action="mailto:your_maiI_ID"
method="post">
После отправки формы пользователь получает по
электронной почте сообщение, содержащее пары
имя/значение, соответствующие элементам формы
из передаваемой страницы. (Используя Netscape
Navigator и Microsoft Internet Explorer, пользователь
получает предупреждение перед отправкой формы по
электронной почте. Это не ошибка, а всего лишь мера
предосторожности. Пользователь уведомляется о
том, что получатель формы сможет увидеть адрес
пользователя в заголовке сообщения. Иначе говоря,
отправка формы по почте не является анонимной.)
Вывод окон сообщений
JavaScript обладает несколькими способами связи с
пользователем через всплывающие окна предупрежде-
предупреждения и два вида диалоговых окон. Эти методы применя-
применяются для передачи пользователю важной информации,
подтверждения выбора и запроса дополнительной ин-
информации. Окна предупреждения часто используются
при отладке.
Метод alertQ обеспечивает передачу пользователю
короткого сообщения. Он является методом объекта
Window. Для его активизации определять объект Window
не обязательно. Метод alert() можно применять для со-
сообщения пользователю об ошибке ввода, как показано
в следующем коде:
alert {"Error: value outside valid range of 0 to
^«240 volts.")
Именно благодаря этой строке кода осуществляет-
осуществляется вывод сообщения на экран (см. рис. 29.2):
РИСУНОК 29.2 Предупреждающее сообщение.
Формы и верификация данных
Кроме того, метод alertQ можно использовать как
помощь при отладке, скажем для вывода строки, содер-
содержащей отладочную информацию:
var dlxjstr = "Value of 'wattage' = " + wattage;
alert(dbgstr);
Такой метод применяется для трассировки програм-
программы на JavaScript:
function CalculateWattage (volts, amps)
¦I
var dbgstr = "CalculateWattage < " + volts +
11," + amps + " ) " ;
alert(dbgstr) ;
Каждый раз при вызове функции CalculateWattage()
всплывает предупреждающее сообщение, указывающее
на вызов и передаваемые аргументы. По завершении
процесса отладки программы код отладки можно уда-
удалить или закомментировать. Более детальная информа-
информация по использованию окна сообщений для отладки
кода JavaScript приводится в главе 34.
Метод confirm() похож на метод alert(), однако по-
позволяет отвечать на сообщение. Ответы ограничены дву-
двумя вариантами — ОК и Cancel (Отмена). Если пользо-
пользователь выбирает ОК, метод возвращает true, а если
Cancel — значение false:
function submitCallback()
!
if (selfDestructSelected == true)
return confirm ("Invoke self-destruct
*-• mechanism in 60 seconds?");
else return true
<f orm
onSubmit="return submitCallback()">
Этот код вызывает отображение диалогового окна
подтверждения (рис. 29.3).
РИСУНОК 29.3Диалоговое окно подтверждения
Щелчок на ОК приводит к продолжению передачи.
При нажатии Cancel возвращается false, которое посту-
поступает в объект Form и препятствует отправке формы.
Метод prompt() — еще один метод Window. Он обес-
обеспечивает возможность ввода пользователем произволь-
произвольного значения:
var f.ivColor=prompt ("What\ ' s your favorite color?")
Можно указать необязательный второй аргумент,
который рассматривается в качестве значения по умол-
умолчанию:
Глава 29
var duration=prompt ("Enter duration in
^months: " , 6) ;
Эта строка кода обеспечивает отображение диалого-
диалогового окна, которое показано на рис. 29.4.
РИСУНОК 2 9, ^Диалоговое окно ввода
Пользователь обычно вводит информацию через эле-
элементов ввода на форме, а диалоговое окно ввода долж-
должно применяться лишь в редких случаях, когда существует
настоятельная потребность в такого рода информации.
В следующем примере осуществляется запрос адреса
электронной почты пользователя.
<html>
<scrlpt language="JavaScript">
<!—начало сценария>
function sendEmail(formObj)
f
if(formObj.emailSpecials.checked)
{
ans = prompt ("Please enter your email
^-address.");
formObj.email.value=ans;
//конец сценария-->
</script>
<center>
<hl>Bob's Music Store</hl>
To receive our free catalog by mail please
enter your email address below.
<form name="addressForm"
onSubmit="sendEmail(this)">
<table>
<tr>
<td>Name:</td>
<tdxinput type="text" name="name"X/td>
</tr>
<tr>
<td>Address</td>
<tdxinput type="text" name="address"X/td>
</tr>
<tr>
<td>City</td>
<tdxinput type="text" name="city"X/td>
</tr>
<tr>
<td>State</td>
<tdxinput type="text" name="state"x/td>
</tr>
<tr>
<td>Zip</td>
<tdxinput type="text" name="zip"x/td>
</tr>
<tr>
<td colspan=2Xinput type="checkbox"
name="emailSpecials">
Please email me about special deals !</td>
Избранные программные технологии
Часть V
<input type="hidden" name="email" value=
<input type="submit" name="submit"
value="Submit">
</form>
</center>
</html>
i^НАПОМИНАНИЕ *" j2—
Когда всплывает диалоговое окно или окно сообщения,
пользователь должен переключить внимание на окно
и соответствующим образом ответить. Именно по упо-
упомянутой причине предупреждающие сообщения и ди-
диалоговые окна не рекомендуется использоваться очень
часто.
.Использование сообщения о состоянии
Другой способ обеспечения обратной связи с пользова-
пользователем во время ввода данных предполагает использова-
использование сообщений о состоянии. Сообщения о состоянии —
это те фразы, которые можно наблюдать в строке состо-
состояния в нижней части окна браузера. JavaScript позволяет
изменять все, что представляется в этой строке. Это дает
возможность отправлять пользователю сообщения, во
время его взаимодействия с HTML-формой. Считается,
что сообщения в строке состояния в меньшей степени
отвлекают внимание пользователя по сравнению с диа-
диалоговыми окнами, однако им присущ один недостаток
— они менее заметны. В листинге 29.2 показан пример
использования дополнительной помощи во время вво-
ввода данных.
Листинг 29.2 Отображение сообщения о состоянии
<html>
<head>
<title>JavaScript Unleashed</title>
<script language= "JavaScript">
<!
function statusMsg(msgType) {
var message = "";
if (msgType = "string") {
message = "Any characters can be used
if(msgType = "integer") {
message = "Please enter a whole number
I
else if (msgType = "dollar") {
message = "Please enter a dollar amount
'¦'here, (e.g. 19.99)";
else if (msgType = "credit") {
message = "Please enter a credit card
'"number here. Do not use dashes . " ;
I
window.defaultStatus = message;
window.status = message;
";i
II—>
</script>
</head>
<body onFocus="statusMsg('')">
<form name="forml" action="#" method="post"Xbr>
First Name <input type="text"
size=20
maxlength=20
name="Integer"
onFocus="statusMsg(' string1) "Xbr>
Last Name <input type="text"
size=20
maxlength=20
name="Integer"
onFocus="statusMsg(' string') "Xbr>
Age <input type="text"
,size=5
maxlength=5
name="Integer"
onFocus="statusMsg ('integer') "Xbr>
Amount <input type="text"
,size=6
maxlength=6
name="Dollar"
onFocus="statusMsg ('dollar') "Xbr>
Card # <input type="text"
size=16
maxlength=lб
name="Credit"
onFocus="statusMsg (' credit1 > "Xbr>
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
Когда пользователь перемещает курсор на поле либо
же его автоматически помещает туда браузер, обработ-
обработчик событий onFocus вызывает функцию statusMsg(). В
сроке состояния выводится соответствующее сообщение
за счет установки свойства status объекта Window. Фун-
Функция statusMsg() позволяет очистить строку состояния,
передавая в нее пустую строку. Очистка происходит в
случае щелчка на любом месте окна браузера за преде-
пределами текстовых элементов. При этом активизируется
обработчик событий onFocus, сбрасывающий сообщение
о состоянии.
«НАПОМИНАНИЕ ^-. Щ .Щ^Г?ГЖ™^ Щ W
Неплохо также установить свойство окна defaultStatus
для вывода на экран того же сообщения о состоянии.
Разработчик может не волноваться по поводу того, что
его сообщение исчезнет, как только пользователь
протащит указатель мыши по экрану. Подобный спо-
способ идеален и в случае применения фреймов, когда
требуется "приклеить" сообщение, даже если пользо-
пользователь передвигает указатель мыши в другой фрейм.
Формы и верификация данных
Верификация данных, введенных
пользователем
Перед появлением JavaScript верификация формы осу-
осуществлялась CGI-программой. Такой подход был эф-
эффективным, но требовалось, чтобы вся форма была пол-
полностью заполненной и переданной на сервер до соб-
собственно процесса верификации. В некоторых средах,
например, с низкоскоростным соединением с World
Wide Web, может произойти существенное отставание
между моментами передачи формы и возврата сообще-
сообщения о найденной ошибке. Более того, ожидая передачи
формы на верификацию, пользователь не получит об-
обратную связь до тех пор, пока вся форма не будет за-
завершена. Непосредственная обратная связь исключи-
исключительно важна, поскольку пользователь только что ввел
информацию и в настоящий момент он может воспри-
воспринять обратную связь в соответствующем контексте.
Быстрая обратная связь может повлиять на последую-
последующее поведение пользователя и снизить количество оши-
ошибок, связанных с заполнением формы. И наконец, на
Web-странице обычная CGI-программа уведомляет об
ошибках ввода. Пользователь должен вновь вернуться к
форме, чтобы внести необходимые изменения, что пре-
прерывает естественный процесс ввода данных в форму.
Верификация ввода данных в форму
Для проверки корректности информации в текстовых
элементах формы используются два обработчика собы-
событий. Обработчик событий onBlur вызывается, когда эле-
элементы текста или текстовой области формы теряют фо-
фокус ввода. Обработчик событий onChange вызывается,
когда происходит изменение содержимого элемента тек-
текста или текстовой области.
Говорят, что элемент имеет фокус, если любые дан-
данные, вводимые пользователем, направляются именно в
этот элемент. Когда текст или текстовая область элемента
обладают фокусом, это значит, что текстовый курсор
находится именно на данном элементе. При переклю-
переключении пользователя на другой элемент (с использовани-
использованием мыши или клавиши табуляции), начальный элемент
теряет фокус.
Обработчик onBlur вызывается каждый раз, когда
поле ввода теряет фокус. Пользователь может поменять
данные в поле либо же оставить их неизменными. Об-
Обработчик событий может вызывать верификационный
код для неизмененных данных или значений по умол-
умолчанию в поле. Для этого потребуется соответствующим
образом приспособить код.
Обработчик событий onChange вызывается только в
случае изменения содержимого поля. Если пользователь
сразу же выбирает поле (возможно, для просмотра об-
обратной связи в строке состояния), а затем другое поле,
Глава 29
обратный вызов, определенный пользователем, уже не
выполняется. Несмотря на свою эффективность, этот
метод имеет свои недостатки. Предположим, что пользо-
пользователя необходимо предупредить о вводе неверных дан-
данных в поле. Если пользователь производит щелчок на
поле, а затем передумывает вносить изменения, или же
набирает те же неправильные данные, это не будет рас-
рассматриваться как изменение. В таком случае запуск об-
обработчика событий onChange не выполняется. Поэтому,
если решено применять onChange, потребуется прове-
проверять введенные данные во время передачи (через обра-
обработчики событий onSubmit и onCIick).
В следующем примере организуется текстовое поле
для ввода количества элементов. Корректными значени-
значениями являются 100 и 1000. Обработчик событий onBlur
вызывается для запуска функции верификации. Тексто-
Текстовый объект ввода передается в обработчик. Если введен-
введенные данные не верны, происходит следующее:
Всплывает окно предупреждения, уведомляющее
пользователя об ошибке.
• Фокус ввода возвращается в текстовое поле.
• Текст выделяется (иподсвечивается), и поэтому его
можно легко распознать.
¦Обратите внимание на то, что обработчик onFocus
обеспечивает для текстового поля пользовательскую об-
обратную связь — возможно, для того, чтобы проинфор-
проинформировать пользователя о минимальных и максимальных
указаниях:
function validateQuantity (quantobj)
if <quantObj .value < 100)
alert("Minimum order
quantobj.focus();
quantobj.select();
100 units.");
else if (quantObj.value > 1000) {
alert("Quantities greater than 1OOO "
4- "units require special order.")
quantobj.focus();
quantobj.select();
3
return;
<h2>Enter number of units:</h2>
<input type="text" name="quantity" value=00"
length=4
maxlength=4 onFocus="quantFeedback()"
onBlur="validateQuantity (this) ">¦
Обеспечение согласованности
Иногда между несколькими полями ввода существует
взаимосвязь. На рис. 29.5 показана часть формы, запол-
Избранные программные технологии
Часть V
няемой данными о бюджете отдела. Пользователь дол-
должен ввести общий бюджет, а затем распределить его по
трем категориям.
П-": Department BudgBt- Netscape
¦ Ble Edit ^iew ?u~<?anirncriice!or !^*rp ¦¦ .
Department Budget
Total Budget (OOO's dollars
Salaries (OOO.'s dollars) i
Expenses {000's dollars) :
Capital Equipwen dollars) :
ПН Г
" " '". ¦ J
|2000
A300
J30 0
I-JOO
1 i ¦
Ш n\x\\
., a;
.-i.-.v ¦¦.,¦.:¦¦.- .-¦.".!'.¦:¦. ..¦ ¦¦¦
РИСУНОК 29.5 Форма для ввода данных о бюджете
В сумме три категории должны формировать общий
бюджет. Перед появлением JavaScript проверка суммы
была невозможной до передачи формы на обработку
Gl-программой. С появлением JavaScriipt ситуация
изменилась: верификация суммы возможна до отправ-
отправки формы, что экономит время пользователя и сохра-
сохраняет рабочий контекст (т.е. перед и после проверки
Web-страница остается неизменной). Ниже показана
часть кода такой формы:
<form name="myform" method="post"
action="actionURL" onSubmit=" return
validateBudget(myform)">
<h2>Department Budget<7h2>
<pre>
Total Budget [OOO's dollars): <input type="text"
name="totalBudget" value="
onBlur="validateNumeric(this)">
Salaries (OOO's dollars): <input type="text"
name="salaries" value="
onBlur="validateNumeric(this)">
Expenses (OOO's dollars):
name="expenses" value="
onBlur="validateNumerio(this)">
Capital Equipment @0
type="text" name="capital" value="
onBlur="validateNumeric(this)">
</pre>
<input type="submit" name="submit"
value="Submit">
</form>
Обработчик событий onBlur вызывает пользователь-
пользовательскую подпрограмму верификации, которая следит, что-
чтобы пользователь вводил корректные цифровые данные
в каждое поле. Показанная ниже функция необходима
для проверки совпадения суммы категорий с общим
бюджетом:
function validateBudget(formObj)
i
var calcBudget =
parselnt(formObj.salaries.value,10)
+ parselnt(formObj.expenses.value,10)
+ parselnt(formObj.capital.value,10);
var totalBudget =
parselnt(formObj.totalBudget.value,10);
if (calcBudget != totalBudget) {
alert("Error: total budget is not equal
+ "sum of allocations."),
return false;
else return true;
:i
Эта функция отображает окно предупреждения,
если допущена ошибка, и приостанавливает процесс.
ПРЕДУПРЕЖДЕНИЕ
Язык HTML все еще пребывает в развитии. В большин-
большинстве случаев браузеры игнорируют незнакомые деск-
дескрипторы или ключевые слова, которые могут изменять-
изменяться в стандарте HTML либо в расширениях HTML,
поддерживаемых разными поставщиками. Это очень
выгодно пользователям Web-браузеров, поскольку ник-
никто не желает, чтобы браузер аварийно завершался
каждый раз, когда он встречает незнакомый дескрип-
дескриптор или ключевое слово.
В большей степени упомянутая проблема касается
программистов, работающих с JavaScript. Если разра-
разработчик допустил ошибку в написании имени обработ-
обработчика событий или другого ключевого слова внутри дес-
дескриптора HTML, программа должным образом функ-
функционировать не будет, а браузер не укажет на ошибку.
Используя в форме обработчики событий JavaScript,
не мешало бы проверить код на присутствие (аналь-
(анальных опечаток.
Обеспечение бизнес-правил
Стратегия, относящаяся к форме, должна передаваться
пользователю через поясняющие тексты внутри формы
либо через отдельный справочный документ (соответ-
(соответствующим образом связанный с формой), а может, и
обоими способами. JavaScript можно задействовать для
проверки соответствия этой стратегии (бизнес-правил)
ввода данных.
Предположим, что форма позволяет определять день
перевозки груза, но при этом имеется бизнес-правило,
запрещающее осуществлять перевозку в выходные. При
помощи кода JavaScript несложно проверить, не выпа-
выпадает ли перевозка на выходные. Таким образом удовлет-
удовлетворяется это бизнес-правило:
,// Вычислить дату погрузки, исходя из данных,
// введенных пользователем. Возвращав'
// объект date.
function calcShipDate(formObj)
var day = parselnt(formObj.shipDay.value);
Формы и верификация данных
var month =
parselnt(form0bj.shipMonth.value);
var year =
parselnt(formObj.shipYear.value);
var hrs = 0;
var min = 0 ;
var see = 0;
shipDate =
new Date(year,month,day,hrs,min,sec) .
return shipDate;
I
// Проверка бизнес-правила, касающегося погрузки
/ / — не отправлять груз в выходные.
// Проверка, не относится ли дата к
// прошлому или текущему времени.
function shippingPolicy (formObj)
{
var shipDate = calcShipDate (formObj) ;
var day = shipDate . getDay () ;
var currentDate = new Date();
i f (shipDate.getTime() <
*¦>currentDate .getTime () ) {
alert ("Error: ship date must be
*¦ future date. ") ;
formObj.shipDay.focus();
formObj.shipDay.select();
return false;
if (day =0) {
alert ("Sorry, we cannot ship on
'-'Sunday.1') ;
formObj.shipDay.focus();
formObj. shipDay. select( ) ;
return false;
)
else if (day =6) {
alert ("Sorry, we cannot ship on
^Saturday.");
formObj. shipDay. focus() ;
formObj.shipDay.select();
return false;
->
else return true ;
<form name="myform" method="post"
action="actionURL"
onSubmit="return shippingPolicy(myform)">
Если пользователь вводит дату, приходящуюся на
субботу или воскресенье, он уведомляет о соответству-
соответствующем бизнес-правиле. На поле ввода даты устанавли-
устанавливается фокус, информация в нем выделяется, а форма
не отправляется. Код также накладывает запрет на пе-
перевозку груза в тот же день.
ПРИМЕЧАНИЕ
Проверяя даты с использованием JavaScript, необхо-
необходимо помнить, что время и дата соответствуют на-
настройкам на пользовательском компьютере. Возмож-
Возможно, клиентские и серверные программные средства
работают в различных временных зонах. Кроме того,
существует ненулевая вероятность некорректной ус-
Глава 29
тановки времени на клиентской части, т.е. ошибочной
даты или времени.
Проверка на завершенность
Формы, в основном, состоят из набора обязательных и
необязательных полей. При отсутствии обязательных
полей форма не сможет функционировать должным об-
образом. И опять-таки, для проверки присутствия этих
полей можно воспользоваться JavaScript.
В следующем примере рассматривается форма, зап-
запрашивающая у пользователя контактную информацию
(см. рис. 29.6). В данном случае обязательными поля-
полями являются имя, адрес, домашний номер телефона, а
все остальные поля — необязательны.
Contact Information (U.S.)
Last Name; |Latta
Address: J1632 Caffenin» Way
City/Town: 'Бхргевво j stafe: [f>^! Zip Code: J7B_260,
Home phone:p
Wort Phone :|=
PAX:
iO2-5S5-1643
E-mail Address: |I
Quest: \?° 1_earn . Ja.va?<\
Favorite Color: j
РИСУНОК 29.6 Форма сконтактнойинформацией
После передачи формы вызывается функция вери-
верификации. Если одно из обязательных полей пусто,
пользователь уведомляется об этом и форма не отправ-
отправляется. Код для формы с контактной информацией
показан в листинге 29.3.
Листинг 29.3 contacthtm
<html>
<head>
<title>Contact Information</title>
<script language="JavaScript">
<!-- Начало сценария
// Проверка, заполнены ли все обязательные поля
function validateComplete(formObj)
if (emptyField(formObj.firstName))
alert("Please enter your first name.");
else if (emptyField(formObj.lastName))
alert("Please enter your last name.");
else if (emptyField(formObj.addressl) ss
emptyField(formObj.address2))
alert ("Please enter your address.");
Избранные программные технологии
Часть V
else if (emptyField(formObj.city))
alert("Please enter your city or
else if (emptyField(formObj.state))
alert ("Please enter your state."),-
else if (emptyField(formObj.email))
alert("Please enter your E-mail
waddress.");
else return true;
return false;
// Проверка, является ли поле пустым
function emptyField (textobj)
{
if (textObj .value, length = 0) return true;
for (var i=0; KtextObj .value.length;
++i) {
var ch = textobj ,value.charAt(i);
if (oh != ' ' ?& ch != '\t')
return false ;
i
return true ;
// Конец сценария -->
</script>
</head>
<body>
<hl>Contact Information (U.S.)</hl>
<form name="myform" action="actionURL"
method="post" onSubmit="return
validateComplete (document .myform) ">
<pre>
First Name: <input type="text" name="firstName">
Last Name: <input type="text" name="lastName">
Address: <input type="text" name="addressl">
<input type="text" name="address2">
</pre>
City/Town:
<input type="text" name="city" size=12>
State:
<input type="text" name=" state" size=2>
Zip Code :
<input type="text" name="zip" size=5>
<pre>
Home Phone :<input type="text" name="homePhone"
size=12>
Work Phone:<input type="text" name="workPhone"
size=12>
FAX: <input type="text" name="FAX"
size=12>
E-mail Address: <input type="text" name="email">
Quest: <input type="text" name="quest">
Favorite Color: <input type=Mtext"
name="favColor">
</pre>
<hr>
<input type="submit" name="submit"
value="Submit">
</form>
<body>
<html>
Код реализует очень базовую проверку — считает-
считается, что поле присутствует, если оно не пустое. В дан-
данном случае не вскрывается различие между корректной
и некорректной датами, что, однако, достигается до-
дополнительной простой проверкой. Например, можно
проверить, чтобы строка штата содержала аббревиату-
аббревиатуру из двух букв, а номер телефона — требуемое коли-
количество цифр. В общем случае, можно выполнять про-
простые проверки на клиентской части и более сложные —
на серверной.
^ПРИМЕЧАНИЕ ~У' * -:"' '"',''
Предыдущий пример реализует форму контактной
информации для англоязычных пользователей, про-
проживающих в США. Internet — всемирная сеть. В не-
некоторых странах за именем следует отчество, штаты
отсутствуют, ZIP-коды не применяются, а язык пользо-
пользователей - не английский. Однако, любимый цвет есть
у каждого. Вопрос интернационализации в данной книге
не рассматривается. Несмотря на это, необходимо
учитывать место проживания потенциальных пользова-
пользователей и соответствующим образом проектировать
формы.
Создание интерактивных форм
Перед появлением JavaScript простейшие интерактив-
интерактивные формы должны были взаимодействовать с CGI-
программой на сервере. Применяя JavaScript, можно
создавать интерактивные формы, где взаимодействие
¦будет полностью проводиться на клиентской части, при
этом можно будет не совершать путешествие на сервер-
серверную часть.
Интерактивное программирование на JavaScript об-
обладает несколькими ограничениями. Желательно дина-
динамически изменять каждый элемент страницы. После-
Последние версии браузеров Netscape и Microsoft
динамически изменяют содержимое страницы без обра-
обращения к серверу. Все это достигается благодаря DHTML
и каскадным таблицам стилей (CSS). К сожалению, эти
стандарты все еще совершенствуются и внедряются
только в относительной степени. Перед тем как ввести
ограничения на использование браузеров, в которых
будет работать HTML-файл, необходимо учесть, что
после однократной визуализации страницы и формати-
форматирования элементов Web-браузер ом, код JavaScript уже
ничего не сможет изменить.
Если после записи страницы нельзя внести измене-
изменения в ее форматирование, что же остается делать? JavaScript
позволяет создавать взаимосвязь между следующими
элементами:
Элементы формы на одной и той же странице.
Элементы формы и другое окно.
Элементы формы и другие фреймы.
Формы и верификация данных
Глава 29
Для совершенствования формы можно воспользо-
воспользоваться и ранее описанными методами: обратной связью
с пользователем, окнами сообщений, верификацией дан-
данных, вводимых пользователем. Можно изменить всю
страницу, полностью переписав ее. В этом случае бра-
браузер стирает текущую страницу и выполняет полное пе-
переформатирование новой страницы. Можно также из-
изменить цвет фона страницы (свойство Document), но не
цвет текста. Это невозможно, поскольку текст страни-
страницы уже был визуализирован в определенном цвете.
Использование вычисляемых полей
Следующий пример, показанный на рис. 29.7, отлича-
отличается от примера с бюджетом, рассмотренного в начале
главы. В данном примере появилось новое текстовое
поле remainder. Несмотря на то что изменение текста
или графики страницы после ее записи невозможно,
можно изменять элементы формы. В данном случае про-
происходит изменение текстового элемента remainder, зна-
значение которого основано на значениях других элементов.
Пользователь вводит общий бюджет и другие категории,
а после этого в текстовом поле выводится сумма денег,
оставшихся после распределения по категориям.
. I Ч ¦]¦ Ill.lj-.4l1 iiill! |' ¦ ¦ Сг ¦!::¦. :н ¦
Department Budget
|2D00
Total Budget (CCO's dollars):
Salaries @00's dollars):
Expenses (OOO's dollars):
Capital Equipment (OOO's dollars
Unallocated Remainder:
1300
\500
РИСУНОК 29.7. Пример вычисляемого бюджета.
В этом примере используется обработчик событий
onChange для внесения изменений в поле remainder вся-
всякий раз, когда меняется одно из значений других тек-
текстовых полей. Когда пользователь отправляет форму,
сценарий пересчитывает сумму остатка. Если значение
ее раьно нулю, форма передается, в противном случае
на экран выводится предупреждающее диалоговое окно.
Код гримера показан в листинге 29.4:
Листинг 29.4. Инструментальное средство введения
бюджета отдела.
<html>
<head>
<title>Department
<! - начало сценария
function calcRemainder(formObj)
var calcBudget =
parselnt(formObj.salaries.value,10)
+ parselnt(formObj.expenses.value,10)
+ parselnt(formObj.capital.value,10);
var totalBudget =
parselnt(formObj.totalBudget.value);
var unalloc = totalBudget - calcBudget;
formObj .remainder.value = unalloc;
function validateBudget(formObj)
calcRemainder (formObj);
var unalloc = fortnObj . remainder. value;
if (unalloc != 0) {
alert("Error: Total budget is not
+ "to sum of allocations.");
return false;
i
return true ;
)
// конец сценария —>
</script>
</head>
<body>
<form name="myform" method="post"
action="actionURL" onSubmit="return
validateBudget(myform)">
<h2>Department Budget</h2>
<pre>
Total Budget (OOO's dollars): <input type="text"
name="totalBudget" value="
onChange="calcRemainder(myform)">
Salaries (OOO's dollars): <input type="text"
name="salaries" value="
onChange="calcRemainder(myform)">
Expenses (OOO's dollars): <input type="text"
name="expenses" value="
onChange="calcRemainder(myform)">
Capital Eo^iipment (OOO's dollars): <input
type="text" name="capital" value="
onChange="calcRemainder(myform)">
<input
type="text"* name="remainder" value=">
</pre>
<input type
</form>
</body>
</html>
="submit" name="submit" value="Submit">
Budget</title>
<script language="JavaScript">
JavaScript можно использовать для написания не-
небольших интерактивных приложений, где все процес-
процессы проходят на клиенткой части. В листинге 29.5 пред-
представлены вычисления значения будущих инвестиций.
Пользователь вводит начальную сумму, процент, а за-
затем количество лет, в течение которых планируется по-
погасить инвестиции. На рис. 29.8 показан экран после
загрузки сценария в браузер. Обратите внимание, что
Избранные программные технологии
Часть V
вывод функции calculate() отображается в текстовых
полях ввода, как описывалось ранее.
Compound Interest Calculator
(loop
Present Value:
I Interest Rate<*):
Years. o? c< A2
|6.0
Total interest:
Future Value:
РИСУНОК 29.8 Форма сложных процентов
Здесь не требуется применение CGI-программ по-
поскольку все процессы реализуются на стороне клиента.
Заметьте, что вместо объекта Submit в форме использу-
используется объект Button. Кроме того, вместо обработчика со-
событий onSubmit применяется onClick. Семантика объек-
объекта Submit и обработчика onSubmit задействуется, когда
Web-браузер передает форму на сервер. Однако, по-
поскольку требуется, чтобы процессы выполнялись на кли-
клиентской части, необходимо использовать обработчик
событий onClick и функцию calculate(), когда кнопка
нажата. Для достижения большей степени реальности
кнопка была названа Calculate, тем не менее, ее назва-
название вполне можно изменить и на Submit. До тех пор
пока пользователь не просмотрит исходный код страни-
страницы, невозможно увидеть, что за HTML используется на
клиентской части и CGI-сценарий — на серверной ча-
части. Код примера представлен в листинге 29.5.
Листинг 29.5 Вычисление сложных процентов
<html>
•<head>
<title>Compound Interest Calculator</title>
<script language="JavaScript">
<!— начало сценария
function calculate(formObj)
(
var presentval =
parseFloat(formObj.presentval.value);
var intRate =
parseFloat(formObj.intRate.value)/100.;
var years =
parseFloat(formObj.years.value);
var futureVal = presentval *
Math.pow(A.0+intRate),years);
var totallnt = futureVal - presentval ;
futureVal = Math. round(futureVal*100 . 0) /
100.0;
totallnt = Math.round(totallnt*100.0)/
100.0;
formObj .futureVal.value =¦¦ futureVal,
formObj.totallnt.value = totallnt;
return;
)
// конец сценария —>
</script>
</head>
<body>
<hl>Compound Interest Calculator</hl>
<form name="myform">
<pre>
Present Value: <input type="text"
name="presentVal">
Interest Rate(%) : <input type="text"
name="intRa te">
Years of Compounding: <input: type=lftext"
name="years">
<input type="button" name="calc"
value="Calculate" onclick="calculate(myform)">
</pre>
<hr>
<pre>
Total Interest: <input type="text"
name="totallnt">
Future Value: <input type="text"
name="futureVal">
<pre>
</form>
</body>
<html>
Создание повторно используемого
кода верификации
В следующих разделах рассматриваются способы вери-
верификации наиболее общих типов данных, используемых
во время работы в Internet. Эти примеры применяются
в библиотеках кодов, которые хранятся в отдельном
файле либо в исходном документе с набором фреймов.
Во всех примерах в качестве одного из аргументов пе-
передается объект текстового элемента. Такая возможность
позволяет в случае необходимости изменять текстовые
поля в процессе проверки данных. Для более специфич-
специфичной проверки данных воспользуйтесь регулярными выра-
выражениями (Regular Expressions), о которых речь пойдет в
главе 31.
Целые числа
Код, представленный в листинге 29.6, проверяет вводи-
вводимые числа, являются ли они целыми. Сценарий вызы-
вызывается, как только пользователь щелкает на кнопке
Validate. Результат (true или false) выводится в тексто-
текстовом поле Result. По этим результатам можно опреде-
определить, прошли ли данные проверку.
Формы и верификация данных
Листинг 29.6 Проверка целостности чисел
<html>
<head>
<title>Integer Validation*:/ title>
<script languages"JavaScript">
<!—начало сценария
function isInt(textObj> {
var newValue = textobj . value ;
var newLength = newValue. length;
for (var i = 0; i != newLength; i++)
aChar = newValue. substring<i,i+l) ;
if (aChar < " I I aChar > "9") {
return false;
J
)
return true ;
}
// конец сценария-->
</script>
</head>
<body>
<hl>Integer Validation</hl>
<form name="?orml">
<input type="text"
s.ize=16
maxlength=l€
name="data">
<input type="button"
name="CheckButton"
value="Validate"
onClick="document.forml.result.value =
islnt(document.forml.data)">
<br>
Result <input type="text"
size=16
maxlength=16
name="result">
</form>
</body>
</html>
Строки
Код в листинге 29.7 проверяет допустимость символов,
вводимых в строку: это должны быть буквы и несколь-
несколько других символов. Другие символы определяются
переменной extraChars. Если пользователь вводит не-
небуквенный символ или знак, не определенный этой
переменной, функция возвращает false. Такой код мож-
можно применить для верификации имен, поскольку неко-
некоторые из них содержат точки, пробелы, дефисы и за-
запятые .
ЛИСТИНГ 29.7 Проверка строки
<html>
<head>
<title>String Validation/title>
<script language="JavaScript">
<!—начало сценария
function isString(textobj) {
var newValue = textObj.value;
var newLength = newValue.length;
|Глава 29
var extraChars=". -," ;
var search;
for (var i = 0; i != newLength; i++) {
aChar = newValue.substring(i,i+1) ;
aChar = aChar.toUpperCase () ,-
search = extraChars.indexOf(aChar),
.if (search = -1 && (aChar < "A" |
aChar > "Z") ) (
return false;
return true ;
>
// конец сценария—>
</script>
</head>
<body>
<hl>String Validation</hl>
<form name="forml">
<input type="text"
size=16
maxlength=l6
name="data">
<input type="button"
name=" Che ckBu tton "
value="Validate"
onClick="document.forml.result.value
isString(document.forml.data)">
<br>
Result <input type="text"
size=16
maxlength=l6
name="result">
</form>
</body>
</html>
Денежные значения
Код из листинга 29.8 использует технологию, несколь-
несколько отличную от применяемой в примерах проверки
строк или целочисленных значений. Вместо выполне-
выполнения прямой верификации, выполняется форматирова-
форматирование, а значение выводится на экран в виде денежной
суммы с двумя десятичными разрядами. Это еще один
пример использования объекта Text функцией с целью
изменения значения объекта. Если функция не смогла
преобразовать данные, представленные в виде денежной
суммы, по умолчанию принимается значение 0.
Листинг 29.8 Денежный формат
<html>
<head>
<title>Money Format</title>
<script language= "JavaScript">
<!--начало сценария
function moneyFormat(textobj) {
var newValue = textObj.value;
var decftmount = "" ;
var dolAmount = "" ;
var decFlag = false;
var aChar = "";
Избранные программные технологии
Часть V
// Игнорировать все, кроме целых и
// десятичных чисел.
for (i=0; i < newValue. length; i++) {
aChar = newValue.substring(i,i+l);
if(aChar >= " SS aChar <= "9") {
if(decFlag) {
decAmount = "" + decAmovmt + aChar;
}
else {
dolAmount = "" + dolAmount + aChar;
if(aChar = ".") {
if(decFlag) {
dolftmount = "v
break;
deeFlag=true;
// Убедимся, что вместо суммы появляется
// хотя бы 0.
if(dolAmount = "") {
dolAmount = "О";
>
// Убрать ведущие нули.
if(dolAmount.length > 1) {
while (dolAmount. length > 1 SS
dolAmount.substring@,1) = ") {
dolAmount =
dolAmount.substringA,dolAmount.length);
// Округлить десятичное значение.
if(decAmount.length > 2) {
if(decAmount.substring B,3) > ") {
decAmount =
parselnt(decAmount.substring@,2)) + 1;
if(decAmount < 10) {
decAmount = " + decAmount;
else {
decAmount =
+ decAmount;
else {
decAmount = decAmount.substringfO,2);
if (decAmount = 100) {
decAmount = 0";
dolAmount = parselnt (dolAmount) + 1;
J
// Заполнить справа decAmount
if(decAmount.length == 1) {
decAmount = decAmount + ";
'l
if (decAmount. length ==0) {
decAmount = decAmount +¦ 0"
// Проверка на наличие отрицательных
// значений и сброс textobj
if(newValue.substring @,1) != '-' ||
(dolAmount = " SS decAmount = 0")) {
textobj.value = dolAmount + "." +
decAmount;
else(
textObj. value = ' -' + dolAmount +
decAmount;
1
// Конец сценария—>
</script>
</head>
<body>
<hl>Money Format</hl>
<form name="forml">
<input type="text"
size=16
maxlength=l6
name=" data">
<input type="button"
name="CheckButton"
value="Format"
onClick="moneyFormat(document.forml.data)">
</form>
</body>
</html>
Кредитные карточки
Один из важнейших аспектов ведения бизнеса в Web
связан с принятием заказов, оплачиваемых через кредит-
кредитные карточки. С помощью JavaScript можно проверить
номер кредитной карточки до того, как произойдет ее
сохранение на сервере с целью конечной проверки. В
листинге 29.9 показано, как можно выполнить проверку
номера. Он должен соответствовать основным прави-
правилам, которые были установлены компаниями, поддер-
поддерживающими кредитные карточки. Если в процессе про-
проверки выясняется, что был введен неправильный номер,
об этом следует проинформировать пользователя и
предложить ввести номер заново. Если пользователь не
желает вносить изменения во введенный номер, его
можно снова принять и выполнить окончательную про-
проверку на серверной части, прибегнув к помощи услуг
электронной коммерции.
Код, представленный в листинге 29.9, можно исполь-
использовать только для предварительной проверки номера
кредитной карточки. Использование сервиса электрон-
электронной коммерции на серверной части — единственный
путь полной верификации кредитной карточки.
Функция isCreditCard начинается с игнорирования
введенных пользователем тире. Затем число поступает
в алгоритм вычисления кода, известного как контрольная
сумма. Если контрольная сумма совпадает с последней
цифрой номера кредитной карточки, значит номер кар-
карточки корректен. Однако даже если номер успешно про-
Формы и исрификащт данных
шел проверку, это не значит, что счет существует, рав-
равно как и то, что он не был закрыт. Это лишь означает,
что введенный номер соответствует всем правилам.
При желании получить более подробную информацию
о том, как происходит подсчет контрольной суммы, ее
можно найти на сайте http://www.websitfer.com/
cardtype.html.
Листинг 29.9. Верификация кредитной карточки.
<html>
<head>
<title>Credit Card Validation</ title>
<script language="JavaScript">
< ! - -начало сценария
function isCreditCard(textObj) {
/*
* Функция проверки ввода номера кредитной
* карточки.
* В случае корректности контрольной сунны
* функция возвращает true.
*/
var ccNum;
var odd = 1;
var even = 2;
var calcCard = 0;
var calcs = 0;
var ccNum2 = " " ;
var aChar = ' ' ;
var cc ;
var r;
.ccNum = textob j . value ;
for (var i = 0; i != ccNum. length; i++) (
aChar = ccNum.substring(i,i
iffaChar = '-'> {
continue ,*
I
ссНшл2 = ccHum2 + aChar;
cc = parselnt (ccNum2) ;
if(cc == 0) {
return false;
r = ccNum. length / 2 ;
if(ccNum.length - (parselnt(r)*2) =0) {
odd = 2;
even = 1 ;
J
for (var x = ccNum. length - 1; x > 0; x — )
r = x / 2;
if(r < 1) {
f
if(x - (parselnt(r) * 2) != 0) {
calcs = (parselnt(ccNum.charAt(x -
1») * odd;
else {
Глава 29
calcs = (parselnt(ccNum.charAtfx -
1))) * even;
if(calcs >= 10) {
calcs = calcs - 10 + 1;
calcCard
calcCard + calcs;
calcs = 10 - (calcCard % 10) ;
if (calcs = 10) {
calcs = 0 ;
if (calcs =
(parseInt(ccNum.charAt(ccNum. length - 1))))
return true ;
}
else {
return false;
// конец сценария—>
</script>
</head>
<BODY>
<hl>Credit Card Validation</hl>
<form name="forml">
<input type="text"
size=16
maxlength=l6
name="data">
<input type="button"
name="Che ckButton"
value="Validate"
onClick="document.forral.result.value
isCreditCard(document.forml.data)">
<br>
Result <input type="text"
size=16
maxlength=16
name="result">
</form>'
</body>
</html>
Пример: тестер цветов JavaScript
В следующем примере, показанном на рис. 29.9, исполь-
используются описанные в главе возможности внедрения тес-
тестера цветов. Одной из важнейших задач разработки
HTML-формы является выбор цветов фона и символов,
что обеспечит эстетическое наслаждение и четкость.
Многие комбинации соответствуют этим критериям, а
многие — нет. Тестер цветов JavaScript позволяет выби-
выбирать два цвета и просматривать в отдельном окне, как
выглядит эта комбинация. В окне содержится HTML-
код для спецификации комбинации цветов. Пользова-
Пользователь может вырезать и вставить это определение прямо
в HTML-код.
Избранные программные технологии
Color Checker
Text Color:
Red: |'J Green: |o Blue: jo
Background Color: .
Red:|?5 ^ Blue: B5
wmmwmmm
Sample Text
Use: <bodybgco!or-"#?HOB"
tBtt-"#O0000O":>
Text Color=(l
BackgroundC6lor=B3J,255,255)
I Using the Color Checker
The Color Display Checker is a utility that
I allows you to display a user selected text
I color against a user selected bat
' color. Colors rue entered as GRB triplets: a
set of and blue values that
comprise the color. Each value can range
from 0 to 255. Colors arc selected for a
color and for a NkI color.
РИСУНОК 29.9. Проверочное устройство цвета.
Определение значений цветов происходит с исполь-
использованием триплетов RGB (красный-зеленый-синий).
Этот триплет содержит три значения, представляющие
красную, зеленую и синюю составляющие цвета. Упо-
Упомянутые значения лежат в диапазоне от 0 до 255. На-
Например, триплет B55,0,0) представляет чистый красный
цвет. В табл. 29.2 перечислены некоторые RGB-значе-
RGB-значения цветов.
Таблица 29.2 RGB значения цветов
RGB значение
Цвет
@,0,0)
B55,0,0)
B55,255,0)
B55,0,255)
@,255,0)
@,255,255)
@,0,255)
A28,128,128)
B00,200,200)
B55,255,255).
Черный
Красный
Желтый
Ярко-красный
Зеленый
Голубой
СИНИЙ1
Темно-серый
Светло-серый
Белый
Так же как и в интерактивных формах, все процес-
процессы проходят на стороне клиента. Программа определяет
конструктор для объекта Color, в котором содержится
RGB-триплет. Объекты Color имеют метод setColor(),
который устанавливает RGB-триплет и вычисляет его
эквивалент в виде шестнадцатиричных значений, кото-
которая применяется для установки цвета в HTML-дескрип-
HTML-дескрипторе <body>. В программе используется два экземпля-
экземпляра объекта Color: один — для цвета символов, другой —
для цвета фона. Обработчик событий onBlur вызывает
программу, выполняющую проверку (validateRGBQ)
каждый раз, когда одно из шести текстовых по «ей вво-
ввода теряет фокус.
Хотя форма не имеет кнопки Submit, у нее есть
объект Button с именем Submit. Метод onClick обраща-
обращается к функции processForm(), которая и вносит изме-
изменения. Она создает окно для вывода, которое распола-
располагается отдельно от программы тестера цветов. Ссылка
на окно производится через popWin. Функция
processForm() проверяет, равно ли popWin значению
null. Если это так, processForm() с использованием ме-
метода Windopen() создает отдельное окно Color Sample.
Далее все происходит несколько запутанно. Пользо-
Пользователь может закрыть окно Color Sample. Единственный
способ определить, что произошло заключается в про-
проверке значения popWin.document. Если значение popWin
является null, тогда значение popWin.document — null,
из чего следует, что окно Color Sample было закрыто. В
данном случае потребуется воссоздать окно Color Sample.
Функция processForm() вызывает функцию <JoSample(),
которая генерирует содержимое окна Color Sample.
В дескрипторе <body> мож:но заметить экземпляр
обработчика событий onUnload, который вызывается
каждый раз, когда происходит закрытие окна. Он обра-
обращается к функции closePopWin(), закрывающей окна
Color Sample и Help, если они существуют. Обратите
внимание на кнопку с именем HelpButton. Когда пользо-
пользователь щелкает на этой кнопке, программа создает но-
новое окно со справочной информацией. В листинге 29.10
показан полный исходный код для инструментального
средства Color Checker.
Листинг 29.10. Инструментальное средство Color
Checker.
<html>
<head>
<title>Color
Checker</title>
<script language="JavaScript ">
- начало сценария
// Конструктор для объектов цветов
function color(r,g,b) {
this.setColor = setColor,-
this.setColor(r,g,b);
// Метод установки цветов объектов
function setColor(r,g,b){
this.red = r ;
i = g/
this.blue = b;
this.hex = rgb2hex(r,g,b);
// Преобразование RGB-триплета в строку с
// шестнадцатиричными значениями
function rgb2hex(r,g,b){
var str = '"#' + num2hex(r) + г
num2hex +
Формы и верификация данных
return(str)t
11
// Преобразование цифровой строки в
// шестнадцатиричную
function num2hex(n){
var str = "";.
var hexstring = 123456789abcdef'¦ ;
while (true) {
digit =
hexstring.substring( (n%16>, (
str = digit +¦ str;
n = n » 4 ;
if (n шш 0) break;
// Заполнение строки, если необходимо
if (str.length < 2) {
str = '0' + str;
}
return(str);
// Проверка значешй компонентов RGB
function validateRGB(textObj) {
var str = textObj .value;
if (str. length =0) {
userAlert(textObj) ;
.return false ;
1
for (var i = 0; i < str. length; ++i) {
var ch = str.charAt(i) ;
if (ch<"O" I I ch>'9') {
userAlert(textObj);
return false;
1
i
var value = parselnt (str,10) ;
if (value < 0 I I value > 255) (
userAlert(textObj) ;
return false;
")
else {
return true;
J
// Предупреждение пользователя об оиибке ввода
function userAlert (textObj) {
alert("Please enter a value between 0 and
^255.");
textObj .focus () ;
textObj , select( ) ;
i
// Запись фрейма для отображения примера
functi ondoSample (doc, tc, be ) {
var mytext—"<hl>Sample Text</hl>" ;
doe.open<);
doc . write ( "<htmlXheadXtitle>ColorSample</
titlex/head>") ;
doe.write{'<body bgcolor=' + be. hex + '
text=' + tc.hex + ¦>');
doc.write (mytext) ;
doc .write('Use: Slt;:body bgcolor=' + be. hex
1 text='+ tc.hex + 'Sgt;1);
Глава 29
doc.write("<br>Text
Color=(",tc.red, ",",tc.green,", ^tc.blue,") ");
doc.write("<br>Background
Color=(",be.red,",",bc.green,",",be.blue,")");
doc.write("</bodyx/html>") ;
doc.close ();
I
// Обработка переданной формы
function processForm(myform) {
var winFeatures =
"scrollbars,width=400,height=250";
if ( (validateRGB (my form, redtxt) SS
validateRGB (rryf oral, grntxt) SS
validateRGB (myform, blutxt) SS
validateRGB (myform, redbg)
validateRGB (myform . grnbg) & &
validateRGB(myform.blubg) ) = false) {
return false;
)
var textColor = new
color (myform. redtxt. value , myform. grntxt. value ,
my form, blutxt .value) ;
var backColor = new
color (myform. redbg. value , my form, grnbg, value ,
myform.blubg.value);
¦if (popWin =^ null)
popWin =
window, open ("", "PopWindow",winFeatures) ;
else {
if (popWin. document = null) {
popWin —
window.open( " ", "PopWindow",winFeatures) ;
doSample (popWin. document, textColor, backColor )
popWin . focus ( ) ,'
return true;
I
// Установка начальных значений формы
function resetForm(myform) {
my form. redtxt . value = 0 ;
myf orm . grntxt . value = 0 ;
myf orm. blutxt. value = 0;
myform. redbg . value = 255;
my form . grnbg . value = 255;
myf orm . blubg . value = 255;
processForm(myform) ;
// Предложение ввести корректные значения
function setPrompt() {
window. status="Please enter a value between
and 255.";
return true ;
// Закрыть всплываюиие окна
functionclosePopWin( ) {
if (popWin != null ss popWin . document ! =
null)
popWin . close ( ) ;
if (helpWin != null SS helpWin . document ! —
null)
helpWin. close();
I
Избранные программные технологии
Часть V
/ / Очистка строки
function clear Prompt () {
window.status="";
return true ;
//Вывод страницы со справочной информацией
function displayHelp() {
var winFeatures =
"scrollbars,width=400,height=250";
if (helpWin == null)
helpWin =
window, open ("", "HelpWindow", winFeatures) ;
¦else if (helpWin. document = null)
helpWin =
window, open ("", "HelpWindow", winFeatures) ;
helpWin.document.open() ;
helpWin . document .write ( "<htmlXheadXtitle>Color
^Checker Help </titleX/head>") ;
helpWin . document . write ( "<body
^»bgcolor=fff f ff>") ;
helpWin.document.write ("<hl>ColorChecker
helpWin. document. wri te ("<h2>Using the Color
helpWin. document, write ("The Color Display
^Checker is a utility that ");
helpWin. document, write ("allows you to display
^a user selected text ") ;
helpWin. document, write ("color against a user
w selected background color. ") ;
helpWin. document, write ("Colors are entered as
'-'RGB triplets: a set of ") ;
helpWin. document.write ("red, green, and blue
^•values that comprise the ") ;
helpWin. document, write ("color. Each value
wcan range from 0 to 255. "> ;
helpWin. document, write ("Colors are selected
^for a background color ") ;
helpWin. document, write ("and for a text
^color. " ) ;
helpWin . document. write ( "</bodyX/html>") ;
helpWin.document.close() ;
helpWin.focus() ;
return true ;
// Инициализация
var popWin = null ;
var helpWin = null;
// Конец сценария —>
</script>
</head>
<body bgcolor="#ffffff " text="#000000"
onUnload="closePopWin()">
<hl>Color Checker</hl>
<form name="myform">
<h2>Text Color:</h2>
Red: <input type="text"
size=3
maxlength=3
name="redtxt"
value="
onChange="validateRGB(this)"
onPocus="setPrompt ()"
>onBlur="clearPrompt()">
Green: <input type="text"
size=3
maxlength=3
name="grntxt"
value="
onChange="validateRGB(this)"
onFocus="setPrompt() "
onBlur="clearPrompt () ">
Blue: <input type="text"
size=3
max1engt h= 3
name="blutxt"
value="
onChange="validateR6B(this)"
onFocus="setPrompt()"
onBlur="clearPrompt ()">
<h2>Background Color:</h2>
Red: <input type="text"
size=3
maxlength=3
name="redbg"
value=55"
onChange="validateRGB(this)"
onFocus="setPrompt()"
onBlur="clearPrompt()">
¦Green: <input type="text"
size=3
maxlength=3
name= " grnbg "
value=55"
onChange="validateRGB(this)"
onFocus="setPrompt()"
onBlur="clearPrompt ()">
Blue: <input type="text"
size=3
maxlength=3
name="blubg"
value=5S"
onChange="validateRGB(this)"
onFocus="setPrompt()"
onBlur="clearPrompt()">
<brxbr>
<input type="button"
value="Submit"
onClick="processForm (document.myform) ">
<input type="reset"
value="Clear"
onClick="resetForm(document.myform)">
<input type="button"
value="Help"
name= " HelpBu tton "
onClick="displayHelp()">
</form>
</body>
</html>
Резюме
В JavaScript существенно усовершенствованы базовые
возможности HTML-формы. Если используется JavaScript,
то большинство процессов, выполняемых на строке сер-
сервера, могут проходить на клиентской части. Возможно-
Возможности делятся на следующие группы::
Формы иверификацияданных
Обратная связь с пользователем. JavaScript позволя-
позволяет обеспечивать обратную связь с пользователями за
счет комбинации обработчиков событий и управле-
управления содержимым панели состояния браузера.
Окна сообщений. С помощью окон предупреждений
и диалоговых окон можно передавать пользователю
сообщения, запрашивать подтверждения запроса и
обеспечивать дополнительную информацию перед
отправкой форм.
Верификация данных, введенных пользователем.
Можно проверять поля ввода, группы полей и всю фор-
форму через обработчики событий и функции JavaScript.
Пользователи могут получать информацию обратной
связи в контексте текущей формы (т.е. страница не
Глава 29
заменяется новой страницей с сообщением об ошиб-
ошибке).
• Можно создавать интерактивные формы, в которых
часть процессов, а может быть и все, выполняются
на стороне клиента.
JavaScript несложно задействовать для создания форм,
более простых в использовании и менее подверженных
к ошибкам. В свою очередь, можно создавать формы,
обеспечивающие более быстрый ответ, нежели сервер-
но-ориентированные программы, в особенности если
пользовательская связь с сервером имеет низкую про-
пропускную способность.
13 !
Персонализация и динамические
страницы
В ЭТОЙ ГЛАВЕ
Статические Web-страницы
• Немного о cookie-наборах
• Использование cookie-наборов
• Серверы и браузеры, поддерживающие
механизм cookie-наборов
• Другие способы поддержки информации о
состоянии
Путешествуя по Internet, многие замечали, что в сайты
помещается все больший и больший объем информации,
которая охватывает практически все необходимые темы
и удовлетворяет многие запросы. Дабы оградить пользо-
пользователей от необходимости чтения ненужной информа-
информацией, сайты персонализируют, что, в свою очередь, по-
помогает направить информацию в определенное русло.
Web-сайт знает, что данный пользователь желает про-
просматривать страницы, посвященные только спорту или
курсу акций. На сегодняшний день Web-страницы — это
и друг, и финансовый советчик в одном лице. Времена
замороженных статических Web-страниц давно прошли.
Наступило время динамических Web-страниц!
Когда пользователь посещает любимый онлайновый
книжный магазин, ему предоставляется не просто спи-
список книг, но предлагается литература, которая может
удовлетворить его запросы, базируясь при этом на пре-
предыдущих покупках пользователя. Многие онлайновые
магазины и порталы используют массивные серверные
базы данных, отслеживая личные предпочтения и це-
цепочки покупок. Все это ускоряет процесс персонализа-
ции и способствует проявлению динамических свойств.
Тем не менее, разработчик Web-страниц с использова-
использованием JavaScript может наделить Web-сайт большей при-
привлекательностью и дружественностью по отношению к
посетителям.
В этой главе рассматриваются способы управления
cookie-наборами, параметрами строки запроса URL и
скрытыми переменными формы с помощью JavaScript,
призванные обеспечить персонализацию и динамичес-
динамический характер страницы. Перед тем как приступить к
созданию динамических страниц, стоит разобраться,
почему Web-страницы по своей природе являются ста-
статическими.
Статические Web-страницы
Web-серверы обладают памятью относительно неболь-
небольшой емкости. При получении запроса на страницу сер-
сервер не знает точно, кто вы такой и что вводилось в фор-
форму три страницы назад. Он также не знает, является ли
посещение пользователя первым или, скажем, семьде-
семьдесят пятым. Одной из проблем использования Hypertext
Transfer Protocol (HTTP) является то, что этот протокол
не отслеживает состояние взаимодействия с сервером.
Под состоянием понимается информация о посещениях
Web-сайтов пользователем. Оно поддерживается по мере
передвижения по страницам Web-сайта. Состояние мо-
может использоваться Web-сервером или программой
JavaScript (либо обоими), чтобы подстроить под сайт
все проделанные действия. С помощью такой информа-
информации можно устанавливать приоритеты, значения фор-
формы по умолчанию, подсчитывать количество визитов и
многое другое, что может существенно упростить поиск
и просмотр информации в Web.
Существует множество способов поддержки инфор-
информации о состоянии:
Сохранение ее в cookie-наборах.
Кодирование ее в ссылке URL.
Отправка ее в форме скрытых переменных.
Сохранение ее в переменных других фреймов.
Сохранение ее в Web-сервере
Существует много других проблем, связанных с под-
поддержкой информации о состоянии. Во время просмот-
просмотра сайта пользователь может перейти к другому Web-сай-
Web-сайту и возвратить минуты, часы, дни, чтобы выяснить, что
любая сохраненная информация не зависит от даты или
Персонвлизсщия и динамические страницы
Существует много других проблем, связанных с под-
поддержкой информации о состоянии. Во время просмот-
просмотра сайта пользователь может перейти к другому Web-сай-
Web-сайту и возвратить минуты, часы, дни, чтобы выяснить, что
любая сохраненная информация не зависит от даты или
же не была уничтожена. Можно вернуться, нажав кнопку
Back, при помощи закладки или же просто сделать так,
чтобы закодированная информация URL была перепи-
переписана или потеряна.
Web-разработчик должен поддерживать информа-
информацию о состоянии независимо от того, как пользователь
перемещается по сайту: с помощью кнопок формы или
же URL-ссылок на странице. Это означает, что инфор-
информация добавляется и в скрытые переменные формы, и
в каждый дескриптор <а href...> на странице.
Учитывая все эти трудности, неплохо, чтобы меха-
механизмы поддержки были более удобными в применении.,
К счастью, это так и есть. Существует много преиму-
преимуществ поддержки состояния, они проявляются и при
однократном посещении сайта, и при переходе от од-
одного сайта кдругому. Примите во внимание следующий
сценарий:
• Приложения потребительских корзинок. Пользова-
Пользователь просматривает сайт, выбирая определенные пун-
пункты и перенося их в виртуальную корзину. В любое
время пользователь может просматривать пункты в
данной корзине, изменять ее состав, проводить ее
проверку, а после уже производить покупку. Отсле-
Отслеживание информации о том, какие пользователи ка-
какими корзинами владеют — весьма важная задача.
¦• Персонализированные порталы. Многие Web-сайты
обеспечивают порталы, где пользователь может под-
подстраивать под себя все, что видит. После выбора
пользователем размещения, схемы цветов, установоч-
установочных параметров, предпочтения сохраняются в пользо-
пользовательском компьютере через механизм cookie-наборов.
В любой момент пользователь может вернуться к
сайту и получить ранее сконфигурированную им
страницу.
• Премии за частые посещения. Сохраняя информа-
информацию на клиентском компьютере, приложение может
проследить, сколько раз браузер обращался к данной
странице. Если количество посещений достигает оп-
определенного количества, пользователь получает до-
доступ к службам более высокого уровня, либо же уве-
увеличится количество этих служб.
• Изменение баннеров. Каждый раз когда пользователь
посещает страницу, необходимо изменять графические
баннеры. Этот способ обычно применяется для перио-
периодического просматривания рекламных объявлений.
Закладки. Проверьте, где находился пользователь в
последний раз посещения сайта. Читал ли он рассказ,
Глава 30
заполнял ли анкету или играл в игру? Пусть он нач-
начнет с того места, где остановился.
¦• Игры. Запомните текущее или максимальное количе-
количество очков. Предоставьте новые задачи, основанные
на прошлых действиях и ответах.
Немного о cookie-наборах
¦Cookie-наборы позволяют хранить информацию на кли-
клиентском компьютере для дальнейшего ее восстановления.
Несмотря на то что с ними связаны определенные не-
недостатки, все же cookie-наборы — это мощная техно-
технология поддержки состояния со стороны клиента.
Компания Netscape переняла начальную спецификацию
cookie-наборов. Несмотря на то что наборы называ-
называются cookie — это не основная причина того, почему
было выбрано именно это имя. Страница специфика-
спецификаций cookie-наборов признает, что "объект состояния
назван cookie не по причине принуждения".
Cookie-наборы хранят данные в виде пары name=value
(имя=зиачение). Можно выбрать любое имя и комбина-
комбинацию значений. Очень выгодное свойство cookie-набора
связано с возможностью установки даты завершения
действия, а также того, какие страницы могут просмат-
просматривать cookit-информацию.
Преимущества cookie-наборов
Одним из основных свойств cookie-набора является их
устойчивость. Когда восприятие cookie-наборов уста-
установлено на пользовательском браузере, эти наборы мо-
могут храниться на протяжении многих дней, месяцев и
даже лет. Именно это и упрощает процесс сохранения
информации о последних посещениях и о предпочте-
предпочтениях пользователя. То же свойство обеспечивает доступ
к cookie-наборам каждый раз, когда пользователь воз-
возвращается на страницу.
Эффективность cookie-наборов особенно повышает-
повышается в при работе с JavaScript. С момента появления в
JavaScript функций чтения, добавления и редактирова-
редактирования cookie-наборов, программы JavaScript могут исполь-
использовать cookie-наборы для хранения информации о
пользователе и его маршруте по Web-сайту.
Ограничения и недостатки cookie-наборов
Некоторые ограничения могут показаться весьма про-
проблематичными. Обычно cookie-наборы хранятся на
пользовательском компьютере в специальном файле
cookie. Так же, как и другие файлы, его можно удалить
по случайности или с определенной целью, что унич-
уничтожит всю хранящуюся в нем информацию. Файл cookie
можно защитить от записи. Программные средства бра-
Избранные программные технологии
Часть V
узера могут накладывать ограничения на размер или
количество сохраняемых cookie-наборов. Новые cookie-
наборы могут перезаписывать информацию в старых
наборах.
Cookie-наборы связаны с одним определенным ви-
видом браузера, поэтому когда пользователь переходит с
одного браузера на другой, могут возникать проблемы.
Если коллекция cookie-наборов получена в результате
работы в браузере Netscape Navigator, то при переходе
к Microsoft Internet Explorer доступ к cookie-наборам
будет утерян.
И наконец, если несколько людей используют один
и тот же компьютер и браузер, они смогут найти себя
при помощи cookie-наборов, принадлежащих кому-ни-
кому-нибудь другому. Причина связана с хранением cookie-ин-
cookie-информации в файле и браузер не может найти отличия
между различными пользователями.
Кроме того, существуют проблемы относительно ис-
использования cookie-наборов. Многие браузеры хранят
cookie-информацию в незашифрованном текстовом фай-
файле. Конфиденциальная информация, такая как пароли,
в cookie-файле храниться не должна. В противном слу-
случае, любой, кто получает доступ к компьютеру, сможет
ее прочесть.
Некоторые Web-брузеры обладают возможностью
предупреждения пользователя, когда предпринимается
попытка установки cookie-набора. Браузер можно скон-
сконфигурировать таким образом, чтобы cookie-наборы во-
вообще не устанавливались. Иногда это приводит к нераз-
неразберихе на пользовательской части, когда диалоговое
¦окно сообщает о том, что производятся определенные
действия над каким-то "cookie". Но если механизм
cookie-наборов заблокирован, то тщательно разработан-
разработанные Web-приложения вообще не будут запускаться.
Нельзя установить неограниченное количество
cookie-наборов для каждого Web-браузера, посещающе-
посещающего сайт. Ниже показаны возможные количество и раз-
размеры cookie-наборов:
• Количество cookie-наборов на один сервер или домен:
20
• Общее количество cookie-наборов на браузер: 300
Размер самого большого cookie-набора: 4 Кбайт
(включая оба параметра name и value)
Если эти пределы превышаются, браузер может по-
попытаться избавиться от старых cookie-наборов, отбрасы-
отбрасывая в первую очередь более давно используемые cookie-
наборы.
Мифы о cookie-наборах
Самая большая проблема в данном случае имеет психо-
психологические корни. Некоторые пользователи считают, что
cookie-наборы — инструмент, используемый "старшим
братом" для раскрытия важнейших секретов. Может
быть, это несколько преувеличиваю, cookie-наборы от-
отвечают за хранение информации о страницах, по-
посещаемых пользователем, о количестве посещений, о
просмотренных рекламных баннерах, о том, что было
выбрано и введено в форму. Именно поэтому многие ду-
думают, что нарушается их право на конфиденциальность,
когда cookie-наборы попадают в компьютер.
В действительности, cookie-наборы очень редко ис-
используются с такой целью. Теоретически это возможно,
но на сегодняшний день существует много других, бо-
более простых и доступных способов получения конфи-
конфиденциальной информации. Хотя подобного рода мыс-
мысли могут и не покинуть читателя прямо сейчас, однако
они уже не должны касаться cookie-наборов.
Другие пользователи жалуются на то, что лишняя
информация занимает много места на жестком диске.
Это довольно-таки веское основание. Программные
средства браузера ограничивают общий объем cookie-
файла до 1.2 Мбайт, причем на один сайт приходится
не более 80 Кбайт. Отметим, что это число мало по
сравнению с размерами страниц и графических изобра-
изображений, которые Web-браузер хранит в страничном кэше.
Третья группа пользователей уверена, что если cookie-
набор был установлен на одном сайте, то его можно
будет прочесть с других сайтов. Это полностью невер-
неверно. Программные средства Web-браузера перекрывают
доступ к cookie-набору другого сайта, не участвовавше-
участвовавшего в его создании.
Если пользователи понимают всю пользу примене-
применения cokie-наборов, все эти слухи ни к чему не приве-
приведут.
Компания Netscape переняла начальную спецификацию
cookie-набора. Более подробную информацию можно
найти на Web-сайте компании Netscape по адресу http://
www.netscape.com/newsref/std/cookie_spec.html.
Использование cookie-наборов
До этого момента были рассмотрены все за и против
cookie-наборов и выяснено, что cookie-наборы — это
именно то, что необходимо для создания полноценно-
полноценного Web-приложения. В этом разделе исследуются фун-
функции, необходимые для чтения и установки cookie-на-
cookie-наборов, что окажет помощь в создании динамических
Web-сайтов, а также их персонализации. В разделе так-
также рассказано, как найти справочную информацию о
cookie-наборах.
Лерсонализация и динамические страницы
Получение значений cookie-наборов
Имена и значения cookie-наборов хранятся и устанав-
устанавливаются при помощи свойства cookie объекта Document.
Для сохранения неформатированной строки cookie в
переменной потребуется воспользоваться следующей
командой:
var myCookie=document, cookie
Для отображения ее на Web-странице применяется
следующая команда:
document.write ("Raw Cookies: " +
document.cookie + "<br>") ,•
JavaScript сохраняет cookie-наборы в следующем
форм; те:
namel=valuel; name2=value2; name3=value3
Отдельные пары name=value разделяются точкой с
запятой или пробелом. После последнего значения точ-
точка с запятой не ставится. Процесс вывода cookie-набо-
cookie-наборов упрощается за счет использования программы,
представленной в листинге 30.1.
Листинг 30.1 Функция GetCookie
function GetCookie (name) {
var result = null;
var myCookie = " " + document, cookie + ";";
var searchName = " " + name + "=" ;
var startOfCookie =
myCookie.indexOf(searchName);
var endOfCookie;
if (startOfCookie != -1) {
startOfCookie += searchName.length;
// пропустить последнее имя cookie
endOfCookie = myCookie.indexOf (";",
startOfCookie);
result =
unescape(myCookie.substring(startOfCookie,
endOfCookie));
i
ret.urn result;
В листинге ЗОЛ строка myCookie помогает избежать
граничных условий; при этом следует убедиться, что все
строковые имена cookie-наборов начинаются с пробе-
пробела, а заканчиваются точкой с запятой. Таким образом,
будет несложно отыскать начало части строки name=,
Пропустить ее и вывести все, что находится между точ-
точкой и следующей точкой с запятой.
Установка значений cookie-наборов
В комбинации name=value находится минимальный
объем информации, необходимой для установки cookie-
набора. Однако, имеется есть еще кое-что, необходимое
для cookie. Ниже представлен полный список парамет-
параметров, применяемый для спецификации cookie-набора:
Глава 30
¦ • name=value
expires=date
• path=path
¦ • domain=domainname
secure
Имена и значения cookie
Name и value могут быть чем угодно. Иногда они быва-
бывают пояснением, таким как FavoriteColor=Blue, Зачастую
это код, интерпретируемый программой JavaScript, напри-
например: CurStat=l:2:l:0:0:l:0:3:1:1.
Самая простая форма для установки cookie-набора
выглядит следующим образом:
function SetCookieEZ (name, value) {
document. cookie = name + "=" + escape (value) ;
)
Обратите внимание, что значение кодируется с по-
помощью функции escape(). Ели бы в строке была точка
с запятой, это могло бы уберечь от неожиданных по-
последствий. Функция escape() избавляет нас от подобного
рода проблем.
Кроме того, обратите внимание, что действия свой-
свойства document.cookie отличаются от действий других
свойств. В большинстве случаев применение оператора
присваивания (=) приводит к полному переписыванию
существующего свойства с новым значением. Но это все
не относится к свойству cookie. Здесь любое новое при-
присваиваемое имя (пате) добавляется в активный список
cookie-наборов. Если данное имя присваивается дважды,
первое присваивание заменяется вторым.
Однако, существуют и исключения, которые рас-
рассматриваются в разделе, посвященном path.
Дата истечения
Параметр expires=date сообщает браузеру о времени
существования cookie-набора. Страница спецификации
cookie-наборов на сайте Netscape устанавливает следу-
следующую форму дат:
Wdy, DD-Mon-YY HH:MM:SS GMT
Например:
Mon, 08-Jul-96 03:18:20 GMT
Этот формат основан на Internet RFC 822, о котором
можно узнать по адресу: http://www.w3.org/hypertext/
WWW/Protcols/rfc822/#z28.
Единственное различие между RFC 822 и реализа-
реализацией Netscape заключатся в том, что дата истечения дол-
должна завершаться GMT (Greenwich Mean Time). К счастью,
язык JavaScript обеспечивает такую работу функции.
Используя функцию toGMTString(), можно установить
срок истечения действия cookie-набора в ближайшем или
далеком будущем.
Избранные программные технологии
Несмотря на то что функция toGMTStringl) не соот-
соответствует спецификации Netscape, все же она рабо-
работает В JavaScrip-f.
Если дата истечения не определена, cookie-набор
остается в действии, пока браузер не будет закрыт. Сле-
Следующий фрагмент кода устанавливает дату истечения
cookie-набора через неделю.
var name="foo","
¦var value="bar" ;
var oneWeek = 7 * 24 * 60 * 60 * 1000;
var expDate = new Date () ;
expDate.setTime (expDate.getTime() + oneWeek);
document.cookie = name + "=" + escape(value) +
"; expires=" + expDate. toGMTStringO;
path
По умолчанию cookie-наборы доступны и другим Web-
страницам внутри того же каталога, что и страница, в
которой они были созданы. Параметр ath открывает
доступ к cookie-набору из других каталогов. Если зна-
значение параметра path — это подстрока URL страницы,
то создаваемые с параметром path cookie-набора дос-
доступны на этой странице. Например, cookie-наборы мож-
можно создать с помощью следующей команды:
document.cookie="foo=barl; path=/javascript" ;
Таким образом, cookie-набор foo доступен на каж-
каждой странице в каталоге javascript и его подкаталогах.
Если команда выглядит следующим образом:
document.cookie="foo=bar2; path=/javascript/sam";
TO cookie-набор будет доступен страницам в каталоге
/javascript/sam, но не будет доступен страницам в ка-
каталоге /javascript.
И наконец, чтобы сделать cookie-набор доступным
каждой странице на всем сервере, воспользуйтесь сле-
следующей командой:
document.cookie="foo=bar3; path=/";
а что же произойдет, если в браузере много cookie-на-
cookie-наборов для различных путей, а имена наборов одинако-
одинаковы? Какое из них победит?
В действительности, сильнейшими окажутся все. В
данном случае, лучше иметь несколько cookie-наборов
с одинаковыми именами, но различными значениями.
Например, если страница выдает все команды, перечис-
перечисленные ранее, тогда строка cookie будет выглядеть
следующим образом:
?оо=ЬагЗ ; f oo=bar2 ,- f oo=barl
Чтобы разобраться в ситуации, можно написать про-
программу для подсчета количества значений cookie-набо-
cookie-наборов, связанных с именами, как показано в листинге 30.2.
Листинг 30.2 Функция GetCookieCount
function GetCookieCount (name) {
var result = 0 ;
var myCookie = " " + document.cookie + ";";
var searchName = " " + name + "=";
var nameLength = searchName.length;
var startOfCookie =
myCookie.indexOf(searchName);
while (startOfCookie != -1) {
result += 1;
startOfCookie =
myCookie.indexOf(searchName, startOfCookie +
nameLength);
}
return result;
И конечно же, если существует функция GetCookieCount,
то должна быть и функция GetCookieNum, какая бы
выводила отдельную часть cookie-набора. Эта функция
выглядит так, как показано в листинге 30.3.
Листинг 30.3 Функция GetCookieNum
function GetCookieNum (name, cookieNum) {
var result = null;
.if (cookieNum >= 1) {
var myCookie = " " + document, cookie + ";";
var searchName = " " + name + "=";
var nameDength = searchName. length;
var startOfCookie =
myCookie.indexOf(searchName);
var cntr = 0;
for (cntr = 1; cntr < cookieNum; cntr++)
startOfCookie =
myCookie.indexOf(searchName, startOfCookie
+ nameLength);
if (startOfCookie != -1) {
startOfCookie += nameDength; // пропустить
// последаее имя cookie
var endofCookie = myCookie.indexOf(" ;" ,
startOfCookie);
result =
unescape(myCookie.substring(startOfCookie,
endOfCookie));
return result;
Для уничтожения cookie-набора необходимо, чтобы
имя и путь совпадали с первоначально установленны-
установленными исходными именем и путем.
domain
После того как страница на определенном сервере со-
создает cookie-набор, он становится доступным для стра-
страниц только на этом сервере. Поскольку параметр path
обеспечивает доступ к cookie-набору за пределами ис-
исходного пути, то параметр domain гарантирует доступ к
другим Web-серверам на данном сайте.
Персонализйция и динамические страницы
Можно сгенерировать такой cookie-набор, чтобы все
пользователи, посещающие Internet, смогли его увидеть.
Разработчик может только установить путь внутри до-
домена. Это происходит так, поскольку применение па-
параметра domain предусматривает использование, как
минимум, двух периодов, если ваш домен завершается
на .com, .edu, .net, .org, .gov, .mil, .int (например,
.mydomain.com). В противном случае должно присут-
присутствовать хотя бы три точки (.mydomain.ma.us). Строко-
Строковый параметр domain должен совпадать с окончанием
жмени вашего сервера.
secure
Последний параметр cookie-набора сообщает браузеру
о том, что данный набор должен отправляться только
при условии безопасного соединения с Web-сервером.
Это означает то, что сервер и браузер должны поддер-
поддерживать безопасность уровня HTTPS. (HTTPS — прото-
протокол передачи через Internet зашифрованной информа-
информации.)
Если параметр secure отсутствует, это значит, что
cookie-наборы передаются по сети в незашифрованном
виде.
А сейчас, когда изучены все параметры cookie-набо-
cookie-набора, можно записать подпрограмму на JavaScript, в ко-
которой бы задействовались все параметры (см. листинг
30.4).
Для использования этой подпрограммы ее необхо-
необходимо вызвать с любыми параметрами, которые требу-
требуется установить, и со значениями null для параметров,
которые не принимаются во внимание.
Удаление cookie
Для удаления cookie-набора необходимо установить дату
истечения где-то в прошлом (насколь далеко в прошлое,
значения не имеет). Дабы подстраховаться, работа дол-
должна продолжаться несколько дней. В листинге 30.5 пред-
представлена программа ClearCookie, используемая для уда-
удаления cookie-наборов.
При удалении cookie-набора не имеет значения, ка-
какое использовалось значение. Подойдет любое значение.
Листинг 30.4 Функция SetCookie
Глава 30
ПРЕДУПРЕЖДЕНИЕ
Некоторые версии Netscape некорректно преобразу-
преобразуют время в GMT. Стандартные функции JavaScript для
удаления cookie-наборов предусматривают то, что про-
прошлый период отстает на несколько миллисекунд до те-
текущего времени. Это действительно так, тем не ме-
менее, данный принцип не действует на всех платформах.
Для подстраховки стоит выбрать дату на несколько дней
уходящую в прошлое.
Пример применения cookie-набора
В листинге 30.6 приводится программа на JavaScript,
демонстрирующая использование cookie-наборов. Эта
программа позволяет пользователям создавать персона-
персонализированные страницы "новости дня", содержащие
ссылки на сайты с общей информацией и определен-
определенным количеством различных категорий. Предпочитае-
Предпочитаемые ссылки пользователя хранятся в cookie-наборах. На
рис. 30.1 показано, как выглядит страница Favorites.
ПРЕДУПРЕЖДЕНИЕ
В 1Е3.0 свойство cookie работает, только если стра-
страницы, использующие свойство cookie, получены из
Web-сервера.
::
:¦
д»гдгтал.*уг^татдтлщ
Your Favorites:
:";VmwAi! j :_-¦'_-¦ Sett-f ¦ notes1"'
Comics
Qitettt
General News
Auctions
ebay
This is avery dull page unless youhave a JavaScript embledbrowser.
?1
РИСУНОК 30.1 Страница Favorites
function SetCookie (name, value, expires,
vai:' expstring = ((expires = null) ? '
var pathString = ((path = null) ? ""
var domainstring = ((domain = = null) ?
var securestring = ((secure == true) ?
document, cookie = name + "=" + escape
secureString;
path, domain, secure) {
' : ("; expires=" + expires. toGMTString ())) ;
: <"; path=" + path));
: ("; domain=" + domain) ) ;
secure" :
(value) + expstring + pathString + domains tring +
Избранные программные технологии
Часть V
Листинг 30.5 Функция ClearCookie
function ClearCookie (name) {
var ThreeDays = 3 * 24 * 60 * 60 * 1000;
var expDate = new Date () ;
expDate.setTime (expDate. getTime () ThreeDays);
document.cookie = name + "=ImOutOfHere; expires=" + expDate.toGMTString();
ЛистингЗО.6 Сценарий Favourite_
<htna>
<head>
<script language="JavaScript">
<!— Comment out script from browsers that don't know JavaScript
/ / ===================== =====:
// Стандартные подпрограммы работы с cookie-наборами
// GetCookie - GetCookie возвращает Значение определенного cookie-набор или null,
// если cookie-набор не существует
function GetCookie (name)
С
var result = null;
var myCookie = " " + document. cookie + " ,• " ;
var searchName = " " + name + "=" ;
var startOfCookie = myCookie. indexOf (searchName) ;
var endOf Cookie ;
if (startOfCookie != -1)
1
StartOf Cookie += searchName . length ;
// пропустить последнее имя cookie-набора
endOfCookie = myCookie. indexOf (" ;" , startOfCookie) ;
result unescape (myCookie. substring (startOfCookie , endOf Cookie) ) ;
"')
return result;
}
//- —¦
// SetCookieEz - SetCookieEz быстро устанавливает cookie-набор, который будет
// действовать вплоть до закрытия браузера.
function SetCookieEz (name, value)
{
document . cookie = name + "=" + escape (value) ;
// SetCookie - SetCookie добавляет или заменяет cookie-набор. Null используется
/ / для параметров , не имеющих значений.
function SetCookie (name, value, expires, path, domain, secure)
С
var expString = ((expires == null)? "" : ("; expires=" + expires. toGMTString ()));
var pathString = ((path = null) ? "" : ("; path=" + path));
var domainString = ((domain == null)? "" : ("; domain=" + domain));
var secureString = ((secure = true) ? " ; secure" : "") ;
document . cookie = name + "=" + escape (value) + expString + pathString + domainString+
secureString;
}
II—т
// ClearCookie - ClearCookie удаляет cookie-набор за счет установки даты истечения —
// трех дней в прошлом
function ClearCookie (name)
Персоналюация и динамические страницы
Глава 30
var ThreeDays = 3*24* 60* 60* 1000;
var expDate = new Date ( ) ;
expDate . setTime (expDate.getTime() ThreeDays);
document, cookie = name + "=ImOutOf Here ; expires="+ expDate. toGMTStr ing () ;
// Объект и программы для приложения Favorites
// —
/* Объект "favorite".
Свойства : f ullName - Полное описательное имя.
cook - Код, используемый для cookie-набора
urlpath - Полный URL (http://...) к сайту
Методы: Enabled - Возвращает true, если cookie-набор ссьшки включен
Checked - Возвращает слово "CHECKED" , если cookie-набор ссьшки включен
HrlteAsCheckBox - Отправляет текст в документ в формате флажка
WriteAsWebLink - Отправляет текст в документ в формате <а href . . . >
function favorite (fullName, cook, urlpath)
I
th 1 s . f ul IName = f ul IName ;
this . cook = cook;
this. urlpath = urlpath;
this. Enabled = Enabled;
this. Checked = Checked;
this. WriteAsCheckBox = WriteAsCheckBox;
this.WriteAsWebLink = WriteAsWebLink;
// Enabled - Enabled проверяет, существует ли cookie-набор
// Результат - возвращает true, если cookie-набор существует, и false — если нет
function Enabled ()
'I
var result = false;
var FaveCookle = GetCookie ("Favorites");
If (FaveCookle != null)
¦i
var searchFor = "<" + this, cook + ">";
var startOfCookle = FaveCookie. indexOf (searchFor) ;
If (startOfCookle != -1)
result = true;
1
ret urn result;
// Checked - Checked проверяет, существует ли cookie-набор (с помощью Enabled) .
// Результат - возвращает "CHECKED", если cookie-набор существует, и "" — если нет.
//
function Checked ()
Г
if (this.Enabled() >
return "CHECKED " ;
return "";
>
//
// WriteAsCheckBox - Предпочтение может быть или обычным URL, или заголовком раздела.
// Если путь URL — пустая строка, тогда предпочтение — заголовок
// раздела. В списке определений появятся ссылки в соответствующем формате.
//
function WriteAsCheckBox (}
il
.// Проверить, это заголовок или обычная ссылка
If (this.urlpath = "")
Избранные программные технологии
Часть V
// Это заголовок раздела
result = '<dtxstrong>' + this . f ullName + '</strong>';
»
else
{
// Это обычная ссылка
result = '<ddxinput type="oheckbox" name="'+ this, cook + '" '+ this. Checked() +
•onClick="SetFavoriteEnabled(this.name, this.checked);">'+ this .fullName;
)
document.write(result);
// Глобальная переменная:
// NextHeading - Иногда требуется распечатать только заголовок, если предпочтение
// установлено. Данная переменная помогает это сделать. См. WriteAsWebLink
var NextHeading = " " ;
//
// WriteAsHebLink - Предпочтение может быть либо заголовком раздела, либо
// обычным DRL. Ссылки появляются внутри списка определений
// и соответствующим образом форматируются.
functionWriteAsWebLink { )
¦I
var result = ' ' ;
if (this.urlpath = "")
I
.NextHeading = this. fullName; // Это обычная ссылка
1
else
if <this.Enabled<) || (GetCookie("ViewAll"> == "T"))
¦'{
if (NextHeading != "")
I
result = '<pXdtXstrong>' + NextHeading+ '</strong>' ;
NextHeading = " " ;
j
result = result + '<ddXahref=" ¦ + this.urlpath + '">'+ this. fullName + '</a>' ;
document.write (result);
}
// Глобальные переменные
/* . . . .
FaveList хранит список всех объектов предпочтений, которые объявляются ниже.
Предпочтения с пустым urlpath находятся в заголовках раздела.
var FaveList = new Array () ;
,// Раздел комиксов
FaveList [1] = new favorite ("Comics", "", "") ;
FaveList[2] = new favorite ("Dilbert" , "cdilb", "http://www.unitedmedia.com/comics/dilbert/
FaveList [3] = new favorite ("Doonesbury" , "cdoon",
"http: //www.uexpress . com/cgi-bin/ups/mainindex. cgi?code=db" ) ;
FaveList [4] = new favorite ("Mr. Boffo", "cboff",
"http://www.uexpress . com/cgi-bin/ups/new_mainindex.cgi?code=mb") ,¦
// Раздел общих новостей
FaveList [5] = new favorite ("General News", "", "") ;
FaveList[6] = new favorite ("CNN", "ncnn", "http://www.cnn.com/");
FaveList [7] = new favorite ("NPR" , "nnpr" , "http://www.npr.org/news/") ;
FaveList [8] = new favorite ("Boston Globe", "nbos" , "http://www.boston.com/") ;
// Раздел компьютерной ш^дустрют
FaveList [9] = new favorite ("Computer Industry", "", "") ;
FaveList[10] = new favorite ("PC Week" , "ipcw" , "http://www.pcweek.com/");
Персонализацияи динамические страницы
Глава 30
FaveList[ll] = new favorite ("TechWeb", "icmp", "http://www.techWeb.com/wire/wire.html");
FaveList[12J = new favorite("Netscape", "ntsc","http://devedge.netscape.com/");
FaveList[13] = new favorite("Microsoft", "micr","http://msdn.microsoft.com/");
// Раздел поисковых механизмов
FaveList[14] = new favorite ("Search Engines", "", "") ;
FaveList[15] = new favorite("Yahoo!", "syah","http://www.yahoo.com/");
FaveList[16] = new favorite("Alta Vista", "sav","http://www.altavista.com/");
FaveList [17] = new favorite ("Excite" , "sexc" , "http://www.excite.com/") ,-
// Раздел аукционов
FaveList[18] = new favorite("Auctions", "", "") ;
FaveList[19] = new favorite("ebay", "ebay","http://www.ebay.com/");
FaveList[20] = new favorite("Yahoo Auctions", "yhac", "http://auctions.yahoo.com/");
// Раздел о разном ¦
FaveList[21] = new favorite ("Misc.", ""', "") ;
FaveList[22] = new favorite("Today in History", "mtih", "http://www.thehistorynet.com/today/
today.htm");
FaveList[23] = new favorite ("Merriam-Webster' s Word of the Day" , "mwod" , "http://www.m-w.com/cgi-
bin/mwwod.pl");
FaveList[24] = new favorite ("Quotes of the Day" , "mquot", "http://www.starlingtech.com/quotes/
qotd.html") ;
// Подпрограммы записи страниц.
// SendOptionsPage - Запись страницы выбора предпочтений
function SendOptionsPage ()
document.write ( ' <hl>SelectFavorites</hl>' > ;
document .write ( '<?orramethod=post>' ) ;
.// Кнопка для просмотра страниц Favorites
document.write ( '<input type=button value="Show Favorites" '+ 'onClick="'+ 'ReloadPage()'+';">');
// Ссылки будут выглядеть значительно лучие внутри описания listdocument.write ('<dl>')»"
for (var i = 1; i < FaveList. length; i++)
FaveList[i] .WriteAsCheckBox() ;
// Записать каждый флажок
document.write ( '</dlXp>5 ;
ClearCookie("ViewAll");
document.write ( '</form>') ;
,// LoadOptions - Установка cookie-набора ShowOption, что заставляет страницу выбора
// огтций появляться во время перегрузки страницы
.//
function LoadOptions ()
С
Set.CookieEZ ("ShowOptions", "T") ;
window.open(document.location.href, "_top", "") ;
// ToggleView - Включение и выключение режима ViewAll. При включенном режиме все
// ссылки выводятся на экран. При выключенном режиме будут выводиться
// только выбранные предпочтения пользователя.
function ToggleView()
¦i
if (GetCookie("ViewAll") == "T")
{
ClearCookie("ViewAll");
else
{
var fiveYears = 5 * 365 * 24 * 60 * 60 * 1000;
var expDate = new Date () ;
expDate.setTime (expDate.getTime() + fiveYears);
Избранныепрограммные технологии
SetCookie("ViewAll", "I", expDate, null, null, false);
J
window.open(document, location.href , "_top", " " ) ;
1
// SendPersonalPage - Запись страницы с категориями и ссылкам»!, предпочитаемыми
// пользователей. Отображает только заголовки, если предпочтения разрешены
function SendPersonalPage ()
i
if (GetCookie("ViewAll"> != "T")
document. write < ' <hl>YourFavorites : </hl> ' ) ;
else
document.wxite< '<hl>Links:</hl>") ;
// Кнопки для просмотра опций или страниц "View All"
document.write ( '<fornmethod=post> ' ) ;
if (GetCookie("ViewAll") == "T")
I
document, write ( "<input type=button value="View Favorites" ' + "onClick="ToggleView();">'
)
else
¦i
document, write ( "<input type=button value="View All" ' + 'onClick= " ToggleView <) ;">') ;
)
document, write ( '<input type=button ' + "value="Select Personal Favorites" ' +
' onClick="LoadOptions() ; ">' ) ;
document. wri te ( 1</form>'> ;
// Ссылки будут выглядеть лучше внутри списка определений-
document .write ( ' <dl> ' ) ;
for (var i = 1; i < FaveList. length; i++)
FaveList[i] . WriteAsWebLink ( ) ; // Запись каждой ссылки
document .write ( ' </dlXp> ' ) ;
// Вспомогательные функции
// isEnabled - Возвращает true, если разрешено предпочтение, указанное параметром name
// __ ,_
function isEnabled(name)
1
var result = false;
var FaveCookie = GetCookie("Favorites");
if (FaveCookie != null)
f
var searchFor = "<" + name + ">" ;
var startOfCookie = FaveCookie .indexOf (searchFor) ;
.if (startOf Cookie != -1)
result = true;
It
return result;
// AddFavorite- Разрешает предпочтение, заданное параметром name
//
function AddFavorite(name)
f
if (!isEnabled(name))
{
var fiveYears = 5 * 365 * 24 * 60 * 60 * 1000;
var expDate = new Date();
expDate. setTime (expDate.getTime (> + fiveYears ) ;
SetCookie("Favorites", GetCookie("Favorites")+ "<" + name + ">", expDate, null, null,
Персонализация и динамические страницы
Глава 30
// ClearFavorite - Запрещает предпочтение, заданное параметром name
function ClearFavorite (name)
if (isEnabled(name))
var FaveCookie = GetCookie ("Favorites") ;
¦var searchFor = "<" + name + ">";
var startOfCookie = FaveCookie. indexOf (searchFor) ;
var NewFaves = FaveCookie. substr ing @, startOf Cookie)+
FaveCookie .substring(startOfCookie+searohFor. length,FaveCookie. length);
var fiveYears = 5 * 365 * 24 * 60 * 60 * 1000;
var expDate = new Date ( ) ;
expDate.setTime (expDate.getTime () + fiveYears ) ;
SetCookie ("Favorites", NewFaves, expDate, null, null, false);
I
}
II
// SetFavoriteEnabled - Включает (SetOn=true) или отключает (SetOn=False)
// предпочтение, определенное параметром name
//
function SetFavoriteEnabled(name, SetOn)
¦(
if (SetOn)
AddFavorite (name);
else
ClearFavorite(name) ;
// ReloadPage - Перегрузить страницу
// " - ——
function ReloadPage()
I
window.open(document.location. href, "_top", " ") ;
5
// Конец сценария —>
</script>
</head>
<body>
<script language=" JavaScript">
<!— Сокрытие сценария от не-JavaScript-браузеров
Именно здесь выбирается страница для отправки- Обычно отсылаются персонализированные
страницы предпочтений (при помощи SendPersonalPage) , Однако, если cookie-наборы
ShowOptions установлены, то вместо них отправляется страница выбора оппий (через
вызов SendOptionsPage) .
___. - - ___,
if {GetCookie("ShowOptions") == "T")
i
Cl«arCookie("ShowOptions");
SendOptionsPage();
else
(
SendPersonalPage( ) ;
)
// Конец сценария -->
</script>
<center>
This .is a very dull page unless you have a JavaScript
enabled browser. <br>
¦</cenl:er>
</body>
</html>
Избранные программные технологии
Часть V
Если бы данная операция выполнялась без JavaScript,
она проходила бы на сервере. Каждое обращение пре-
предусматривало бы запуск сервером определенного вида
сценария или программы, с целью прочтения пользо-
пользовательских cookie-наборов и генерации страницы на
лету. Благодаря JavaScript весь процесс проходит на кли-
клиентском браузере, а сервер только загружает статичес-
статическую страницу. Можно обойтись и без этого, поскольку
страница может поступать из локального кэша клиен-
клиента. Когда страница загружена, отправляются все ссыл-
ссылки независимо от того, выбраны они или нет. С помо-
помощью cookie-наборов и JavaScript клиент может решить,
какие из них должны отображаться пользователю.
В программе используются три различных cookie-
набора. В наборе Favorites содержится уникальный код
для каждой предпочитаемой ссылки. Cookie-набор View
All переключается между выводом пользовательских
предпочтений и всех возможных ссылок. Программа
также может вывести на экран одну из двух страниц:
одну — для выбранной ссылки и другую — для изме-
изменения конфигурации и опций. Когда установлен cookie-
набор ShowOption, на экране отображается страница
выбора опций Options. В противном случае выводится
обычная страница. На рис. 30.2 показана страница
конфигурирования.
1'3 C:\My Documentstf)oe«triefits\JE Unleashed\NewLdition\Chapier 3D\Listtn.,. Щ\
Select Favorites
ShowFawiritei
Comics
PDilbert
П Doonesbury
HMr.Boffo
General News
Г CNN
RNPR
H Boston Globe
Computer Industry
П PC Week
DTecHWeb
П Netscape
Г Microsoft
Search Engines
d Yahool
С AJta Vista
Excite
Auctions
Febay
РИСУНОК 30.2. Страница конфигурирования Favorites.
Программа создает объекты, называемые, как не-
несложно догадаться, "предпочтения". Каждое предпочте-
предпочтение, по сути дела, — ссылка на другую страницу. Объект
предпочтения содержит информацию о ссылке (URL),
описание страницы и код, определяющий ее в строке
cookie-набора Favorites. Кроме того, объект знает, как
вывести себя на Web-странице в виде обычной ссылки
для страницы Favorites, либо же в формате флажка для
страницы Options.
Серверы и браузеры,
поддерживающие механизм cookie-
шборов
Если другие способы программирования для Web, такие
как CGI или специальные серверные интерфейсы,
требуют, чтобы сервер и браузер воспринимали
cookie-наборы, то в JavaScript это требование относит-
относится только к браузерам. Это означает, что JavaScript мож-
можно безнаказанно пользоваться до тех пор, пока клиен-
клиенты распознают JavaScript.
Однако, многие Web-приложения могут смешивать
JavaScript с другими средствами разработки, которые
требуют от сервера восприятия cookie-на!
РЕСУРСЫ
Подробная информация, посвященная cookie-наборам
находится на следующих Web-сайтах:
Страница спецификации cookie-наборов компании
Netscape: http://www.netscape.ee
cookie_spec.html
Браузеры, поддерживающие cookies-наборы: http://
www.research.digital.com/nsl/formtest/stats-by-test/
NefscapeCookie.html.
Центр cookie-наборов: http://www.cookiecentral.com/
Web-браузеры, поддерживающие cookie-набора от
Digital: http://www.research.digital.com/nsl/formtest/
sfats-by-test/NetscapeCookie.html.
Robert's Brooks' Cookie Taste Test: http://
www.geocities.com/SoHo/4S35/cookie.html.
Другие способы поддержки
информации о состоянии
Как упоминалось ранее, применению cookie-наборов
присущи свои недостатки. Возможно, будет предпринята
попытка избежать разногласий и найти другой способ
поддержки состояния при переходе с одной страницы на
другую. Существует два пути. Какой будет выбран, за-
зависит от того, каким образом пользователи попадают с
одной страницы на другую в рамках создаваемого сай-
сайта.
Главным ограничением этих методов является то,
что они срабатывают при переходе с одной страницы
на непосредственно следующую за ней. Если информа-
информация о состоянии должна поддерживаться на протяже-
протяжении целой последо! -и страниц, механизм дол-
должен применяться на каждой странице.
Строка запроса
Если вся н; I, в основном, приходится на встро-
встроенные в страницы гипертекстовые ссылки, в конце URL
Персонализация и динамические страницы
потребуется добавить дополнительную информацию. Это
обычно проделывается за счет добавления знака вопро-
вопроса (?) в конце URL Web-страницы, за которым следует
информация в кодированной форме, возвращаемая ме-
методом escape(). Для отделения одной части информации
от другой, используется амперсанд (&).
Например, если разработчик пожелает отправить
вместе с ссылкой параметры color=blue и size=extra
large, ссылку должна выглядеть так:
<а href=
"/mypage.html?color=blueSsize=extra+large">
XL Blue</a>
Этот формат подобен тому, что используется при
передаче работы формы с помощью метода get. Следу-
Следующая страница может считывать эту информацию, ис-
Глава 30
пользуя свойства search объекта Location. Это свойство'
называется search, поскольку многие поисковые серве-
сервера используют эту часть URL для сохранения их поис-
поисковых критерий.
Далее рассматривается пример использования свой-
свойства location.search, В данном примере имя текущей
страницы отправляется как параметр в ссылке на дру-
другую страницу. Другая страница считывает это свойство
с помощью search и определяет, откуда перешел брау-
браузер.
В листинге 30.7 показана первая страница, содержа-
содержащая ссылку.
В листинге 30.8 представлена вторая страница, де-
демонстрирующая использование location.search. В ней
определяется, откуда пришел браузер.
Листинг 30.7 Wherei .html
<html>
<head>
<title>Where Was I? - Page K/title>
</head>
<body>
<M>Where Was I? - Demonstration</hl>
This page sets information which will allow the page it is linked
to out where it came from. It uses values embedded in the link
URL in order to do this
He'll assume that any URL parameters are separated by an ampersand.
Notice that there doesn't need to be any JavaScript code in this page.
And now,
<a href="where2.html?camefrom=Wherel.html?more=needless+stuff
Let's go to Page 2.</a>
</body>
</html>
Листинг 30.8 Where2.html
<html>
<title>Where Was I? - Page 2</title>
<head>
<7head>
<body>
<hl>Where Was I? - Demontration</hl>
This page reads information which allows it to out where it came from.
<p>
<script languages"javascript">
<•— Начало сценария
// WhereWasI
// Считывание строки поиска для вывода того, что предоставила ссылка
function WhereWasI (> {
// Сохранить строку поиска в удобном месте (таким образом, чтобы лишний pas не
// производить набор)
var handyString = window, location, search;
// Найти начало специальной переменной URL
var startOfSource = handyString. indexOf ("camefrom="> ;
// если присутствуем, найти конец переменной
if (StartOfSource != -1) {
var endOfSource = handyString.indexOf ("&", startOfSource+9) ;
var result = handyString. substring(startOfSource+9, endOfSource) ;
J
Избранные программные
Часть V
else
var result = "Source Unknown"; // Невозможно отыскать строку "camefrom"
return result;
_}
if (WhereWasI () != "Source Unknown")
document,write ("You just came from <b>" + WhereWasI () + "</b>.<br>")
else
document.write ("Unfortunately, we don't know where you came from.<br>");
// Конец сценария —>
</script>
</body>
</html>
Скрытые переменные формы
Метод, описываемый в предыдущем разделе, работает,
пока пользователь перемещается по страницам с исполь-
использованием ссылок. Для того чтобы выполнить это же за-
задание, но только с формами, потребуется вместо пара-
параметра location.search прибегнуть к скрытым переменным
формы.
Скрытые переменные формы обладают следующим
форматом:
<input type="hidden" name="H±ddenF±eldName"
value= "HiddenFieldValuf>
Для HiddenFieldNamen HiddeFieldValue можно ука-
указать все, что угодно. Параметр value определять не обя-
обязательно.
Для использования скрытых полей код JavaScript
необязателен. Они определяются в обычном HTML-до-
HTML-документе, а не в дескрипторе <input>. Серверные сцена-
сценарии, такие, как CGl-программы или программы, исполь-
использующие API сервера, для чтения значений скрытых
полей не обязательны.
Форма, содержащая скрытые переменные, передает-
передается в серверные сценарии или даже в функции JavaScript,
которые выдают все, что знают о браузере, в отдельную
Web-страницу, включая информацию о полях формы.
Информация о скрытых полях находится в нижней час-
части страницы. Она выглядит следующим образом;
Form Post Data:
Raw Form Data String:
camefrom=where3.htmSotherStuff=I+don%27t+care
camefrom=where3.htm
otherStuff=1 don't care
Резюме
В главе рассматривались способы создания динамичес-
динамических и персонализированных Web-страниц за счет под-
поддержки информации о состоянии. Оказалось, что самый
эффективный способ заключается в использовании
cookie-наборов.
cookie-наборы позволяют сохранять информацию
на клиентском компьютере и применять ее в приложе-
приложении с целью записи значений и другой важной инфор-
информации. Учитывая широкомасштабность cookie-наборов,
их можно применять как для простейших пар name=value,
так и для более сложных форм.
Хотя cookie-наборы и представляют самый эффек-
эффективный метод поддержки информации о состоянии, су-
существуют и другие способы, например, параметры стро-
строки запроса URL и скрытые поля формы.
Выполнение поиска по шаблону
с использованием регулярных
выражений
В ЭТОЙ ГЛАВЕ
Создание регулярных выражений
Синтаксис регулярных выражений
Использование регулярных выражений
Тестер регулярных выражений
Пример: программа проверки правильности
ввода телефонных номеров
Одно из наиболее важных свойств JavaScript — это
возможность выполнения поиска по шаблону. Поиск по
шаблону в JavaScript осуществляется с помощью регуляр-
регулярных выражений (Regular Expression). Эта идея была взята
из наиболее удобного и доступного современного язы-
языка с подобными возможностями — Perl. Поиск по шаб-
шаблону позволяет отыскивать сложные образцы в строках.
Для поиска по шаблону простейших выражений без ре-
регулярных выражений потребуется очень много строк
кода. В главе рассматривается синтаксис, необходимый
для создания регулярных выражений.
Создание регулярных выражений
Хотя, на первый взгляд, регулярные выражения могут
показаться чем-то необычным, разработчик должен по-
понимать, что это не просто строки, содержащие буквы,
цифры и символы. Специалист создает шаблон, aJavaScript
выполняет поиск. Для упрощения работы регулярные
выражения были помещены в объект RegExp. Создание
регулярных выражений очень напоминает создание
строк при помощи объектного конструктора или опера-
оператора присваивания (=).
Конструктор RegExp()
С тех пор как регулярные выражения приобрели объек-
объектную оболочку в JavaScript, можно просто вводить шаблон
как аргумент в конструктор RegExpQ, а затем присваи-
присваивать результирующий объект переменной. Например,
ниже создается объект RegExp с именем firstName, со-
содержащий шаблон John.
var firstName=new RegExp ("John")
He переживайте, если пока еще не понятно, что оз-
означает понятие шаблон (это обсуждается немного поз-
позже); сфокусируйте внимание на синтаксисе, применяе-
применяемом при создании объекта RegExp.
Оператор присваивания
Второй путь создания регулярных выражений — присва-
присваивание шаблона непосредственно переменной и предо-
предоставление JavaScript возможности проверять, чтобы пе-
переменная была объектом RegExp. Следующая строка
кода создает объект RegExp с именем firstName, содер-
содержащий шаблон John.
var ?irstName=/John/;
Разработчик наверняка заинтересуется, а как же
JavaScript может знать, что firstName должен быть объек-
объектом RegExp, а не объектом String. Различие состоит в
том, что строки заключаются в двойные или одинарные
кавычки, в то время как шаблоны — в символы косых с
правым клоном (/). Заметьте, что конструктор RegExp()
обходится без такого символа поскольку он отличается
от конструктора String().
Синтаксис регулярных выражений
После того как стало понятно создание объектов регу-
регулярных выражений, можно перейти к синтаксису, необ-
необходимому для создания реального шаблона. Как упоми-
упоминалось ранее, синтаксис шаблонов взят непосредственно
из Perl. При наличии определенных знаний по этому
языку, следующие задания покажутся весьма простыми.
В табл. 31.1 перечислены все специальные символы по-
поиска по шаблону.
Избранные программные технологии
Часть V
Таблица 31.1 Символы поиска по шаблону
Символ
Описание
\w Любой символ в слове (алфавитно-цифровой).
\W Неалфавитно-цифровой символ.
\s Любой пробельный символ (символы табуляции, новой строки, возврата каретки, перевода страницы,
вертикальной табуляции).
\S Непробельный символ.
\d Цифровой символ.
\D Нецифрой символ.
[\Ь] Символ забоя.
Любой символ за исключением символа новой строки.
,[...] Любой символ, указанный в скобках.
|[~...] Любой символ, за исключением перечисленного в скобках,
[х-у] Символы в промежутке от х до у.
["х-у] Символы, не входящие в промежуток от х до у.
{х,у} Предыдущий элемент должен быть найден не менее х раз, но не более у раз.
{х,} Предыдущий элемент должен быть найден не менее х раз.
{х} Предыдущий элемент должен быть найден точно х раз.
? Предыдущий элемент должен быть найден однажды или вообще не найден.
+ Предыдущий элемент должен быть найден хотя бы один раз.
* Предыдущий элемент должен быть найден неограниченное количество раз или вообще не найден.
II Должно быть совпадение либо в выражении справа, либо слева от символа |.
(...) Группировка всех элементов в круглых скобках в подшаблон.
\х Поиск тех же символов, что и полученных из подшаблона в группе х. Группы, заданные в круглых скобках,
нумеруются слева направо.
Поиск с начала строки или же с начала первой строки в многострочных данных.
$ Поиск с конца строки или с конца последней строки в многострочных данных.
\Ь Позиция между знаком, входящим в слова, и не входящим в слова.
\В Позиция, не находящаяся между знаком, входящим в слова, и не входящим в слова.
Некоторые их перечисленных выше символов — до-
достаточно просты для понимания, в то время как неко-
некоторые — не столь очевидны. В следующих разделах де-
детально рассматриваются все символы.
\w и \W
Строчная w (\w) определяет любой символ, который
находится в словаре. К таким знакам принадлежат ал-
алфавитно-цифровые символы. Это означает, что им мо-
может быть либо буква (a-z), либо цифра @-9). Прописная
W отличается тем, что определяет символы, не входящие
в слова. Например, шаблон поиска
var pattern=/\w\W/;
находит Ь? в строке поиска, но знак ?Ь не будет найден,
поскольку первым должен быть символ буквы или циф-
цифры, а вторым — символ, не являющийся буквой или
цифрой.
\sn\S
Строчная s находит любой пробельный символ. Про-
Пробельные символы — это символы табуляции, символы
новой строки, возврата каретки, перевода страницы и
вертикальной табуляции. Прописная S (\S) отличается
тем, что находит непробельные символы. Например,
шаблон поиска
var pattern=/\s\S/;
найдет символ возврата каретки, за которым следует g,
но не сможет найти g, за которой следует символ воз-
возврата каретки.
\dn\D
Строчная d (\d) отыскивает любую цифру @—9), а про-
прописная D (\D) является противоположностью, выполняя
поиск любого символа, не являющегося цифрой. Напри-
Например, шаблон поиска
Выполнение поиска по шаблону с использованием регулярных выражений
var pattern=/\d\D/;
найдет 4р в строке поиска, но не сможет найти р4, по-
поскольку цифра должна находиться на первом месте, а не
на втором.
[\Ь]
Строчная b в скобках |\Ь] используется для поиска сим-
символа забоя (backspace). Существует не так уж и много
случаев, когда требуется поиск символа забоя, однако
если уж подобная потребность возникла, постарайтесь
использовать именно этот шаблон.
Точка
Точка (.) применяется для поиска всех знаков, за исклю-
исключением знаков новой строки.
'[...] И [а...]
Скобки используются для поиска одного символа, нахо-
находящегося внутри скобок. Если после левой скобки на-
находится символ Л, выполняется поиск любого символа,
не входящего в перечисленные в скобках. Например,
шаблон поиска
var pattern=/[abc] [Adef]/,-
найдет ag в строке поиска, но не сможет найти ga, по-
поскольку на первом месте должны стоять либо а, либо Ь,
либо с, а на втором — d, e или f.
[х-у] и [лх-у]
Черта внутри скобок используется для определения ди-
диапазона вместо перечисления всех символов. Обнаружи-
Обнаруживается любой символ в рамках диапазона х-у, появляю-
появляющийся в строке поиска. Если сразу после скобки следует
символ л, находится любой символ, не входящий в диа-
диапазон. Предыдущий пример можно переписать следую-
следующим образом:
var pattern=/[a-c] [Ad-f}/;
Этот шаблон найдет в строке поиска ag, но не смо-
сможет найти ga, поскольку на первом месте должны сто-
стоять а, Ь, или с, а на втором — d, e или f.
{х,у}, {х,} и {х}
Существует несколько вариантов синтаксиса с фигурны-
фигурными скобками; всех их связывает повторение символа,
следующего за левой фигурной скобкой. В данном син-
синтаксисе х и у представляют цифры. Если применяется и
х, и у, тогда предыдущий символ должен быть найден,
по меньшей мере, х раз, но не более у раз. Если за х
следует запятая, тогда предыдущий символ должен быть
найден х раз. И наконец, если в скобках находится толь-
только х, но без запятой, тогда предыдущий символ должен
Глава 31
быть найден в точности х раз. Например, шаблон поис-
поиска
var patterns/cho{1,2}se/;
найдет chose и choose в строке поиска, но не сможет
найти chooose, поскольку символ о должен присутство-
присутствовать хотя бы один раз, но не более двух раз.
?, + И *
Существует три операции, выполняющие определенные
действия, связанные с фигурными скобками, а именно:
знак вопроса (?), плюс (+) и звездочка (*). Знак вопро-
вопроса (?) находит предыдущий символ один раз или вооб-
вообще не находит такового. Плюс (+) отыскивает предыду-
предыдущий знак хотя бы раз. И наконец, звездочка (*) находит
предыдущий знак любое количество раз или вообще не
находит. Например, шаблон поиска
var pattern=/ab?c/;
найдет abc или ас в строке, но не сможет найти abbe,
поскольку символ "Ь" должен быть найден один раз или
вообще не найден.
Логическое или (|)
Вертикальная черта (|) действует как логическое ИЛИ
(OR) и отыскивает символ либо справа, либо слева от
вертикальной черты. Например, шаблон поиска
var pattern=/cat|dog/;
найдет в строке cat или dog.
(...)
Круглые скобки позволяют выполнять поиск элементов,
помещенных внутрь других элементов. Например, шаб-
шаблон поиска
var pattern=/f(a|o)r/;
найдет в строке поиска far или for.
\Х
\х в комбинации с круглыми скобками используется для
поиска символов подшаблона с номером группы х. Груп-
Группы обозначаются круглыми скобками и нумерация их
следует слева направо. Например, шаблон поиска
var pattern=/f(a|o)r\l/;
осуществит поиск в строке fara и foro, но не faro и fora.
Когда символ л находится перед текстом, поиск будет
производиться только в том случае, если текст появля-
появляется в начале строки или в начале первой строки мно-
многостроковой последовательности. Например, следующий
шаблон поиска
Избранные программные технологии
Часть V
var pattern=/AThe/;
выполнит поиск слова The, если оно присутствует в на-
начале последовательности или в начале одиночной стро-
строки,
$
Символ $ является полной противоположностью симво-
символу Л. Например, если знак $ помещается перед текстом,
поиск будет происходить в том случае, если текст появ-
появляется в конце поисковой строки или в конце последней
строки в многостроковой последовательности. Следую-
Следующий шаблон поиска
var pattern=/Ahome/;
приведет к поиску слова home, если оно появляется в
конце последовательности или одиночной строки.
Символ Описание
\Ьи \В
Строчная b (b\) находит положение между словарным и
несловарным знаком. Имейте в виду, что словарный знак
является алфавитно-цифровым. Это означает, что он
может быть либо буквой (a—z), либо цифрой @~9). Про-
Прописная В (\В) — напротив, находит позицию, выходя-
выходящую за пределы словарного и несловарного знаков.
Например, шаблон поиска
var pattern=/cat\b/;
найдет слово cat, за которым следует пробел. Пробел
является несловарным символом.
Возможно, возникнет вопрос, а что, если потребует-
потребуется отыскать особый символ, например, символ $? Все
особые символы представляются с использованием на-
наклонной черты влево (\), за которой следует собствен-
собственно символ. В табл. 31.2 перечислены все символы, кон-
конфликтующие с символами поиска по шаблону.
Таблица 31.2 Специальные символы
Символ Описание
\f
\г
\t
\v
V
\\
\.
V
V-
\?
\|
Перевод страницы.
Новая строка.
Возврат каретки.
Табуляция.
'Вертикальная табуляция
Наклонная черта вправо
Наклонная черта влево.
Точка.
Звездочка.
Плюс.
Знак вопроса.
Вертикальная черта.
\( Открывающая круглая скобка.
\) Закрывающая круглая скобка.
\[ Открывающая квадратная скобка.
\] Закрывающая квадратная скобка.
\{ Открывающая фигурная скобка.
\} Закрывающая фигурная скобка.
\ХХХ Символ ASCII, представленный восьмеричным
кодом XXX.
\хНН Символ ASCII, представленный
шестнадцатиричным кодом НН.
\сХ Управляющий символ, представленный X.
И наконец, последняя часть синтаксиса позволяет
устанавливать атрибуты, связанные с регулярными вы-
выражениями. Атрибуты сведены в табл. 31.3.
Таблица 31.3 Атрибуты поиска по шаблону
Символ Описание
g Глобальный поиск. Найти все возможные
совпадения.
i Поиск без учета регистра.
В отличие от ранее рассмотренного синтаксиса, эти
атрибуты устанавливаются за пределами наклонных черт
влево, определяющих шаблон при создании регулярных
выражений. Регулярные выражения для глобального
поиска слова "bear" выглядит следующим образом:
var animalSearch=/bear/g;
В случае создания регулярного выражения с исполь-
использованием конструктора RegExp() атрибуты необходимо
сохранить как строку и передать ее во втором аргументе
конструктора. Регулярное выражение для поиска слова
"bear" без учета регистра выглядит следующим образом:
var animalSearch=new RegExp ("bear", "i");
Использование регулярных выражений
Сейчас, когда необходимый шаблон уже присвоен объек-
объекту RegExp, что же с ним делать дальше? Существует два
пути применения регулярных выражений. Первый зак-
заключается в использовании методов объекта RegExp, a
второй — в использовании методов объекта String. В
конечном итоге регулярные выражения смогут начать
поиск по шаблону внутри строки. Методы поиска по
шаблону, которые обеспечивает объект RegExp, пред-
представлены в табл. 31.4. Обратите внимание, эти методы
требуют передачи в качестве аргумента объекта String,
в котором выполняется поиск.
Выполнение поиска по шаблону с использованием регулярных выражений
Таблица 31.4 Методы поиска по шаблону в
объекте RegExp.
Метод
Описание
exec (s(r) Осуществляет поиск по шаблону sfr и
возвращает результат.
test (sfr) Осуществляет поиск по шаблону str и
возвращает true, если соответствие найдено,
и false — в противном случае.
(sfr) Тоже самое, что и метод exec (sfr).
Методы поиска по шаблону, поддерживаемые объек-
объектом String, перечислены в табл. 31.5. Эти методы требу-
требуют передачи в качестве аргумента объекта RegExp, в
котором совершается поиск.
Таблица 31.5 Методы поиска по шаблону в
объекте String.
Метод
Описание
match (regExpObj) Осуществляет поиск шаблона
regExpObj внутри строки и
возвращает результат.
replace (reqExpObj, sfr) Заменяет все вхождения шаблона
regExpObj на sfr.
Возвращает позицию вхождения
regExpObj внутри строки.
Производит разбиение строки на
max частей в местах, где
встречается вхождение regExpObj.
Подстроки возвращаются в виде
массива.
search (regExpObj, str)
split (regExpObj, max}
ПРИМЕЧАНИЕ
Методы, перечисленные в табл. 31.4 и 31.5, не явля-
являются единственными, связанными с объектами String и
RegExp. Были представлены только наиболее распрос-
распространенные методы, применяемые для поиска и замены.
Тестер регулярных выражений
Замысловатый синтаксис, используемый при создании
шаблонов для регулярных выражений, может несколь-
несколько запутать разработчика, в особенности, если необхо-
необходимо смешивать и находить функции для создания слож-
сложных поисковых шаблонов. Именно по этой причине в
главе рассматривается программа для тестирования ре-
регулярных выражений. Она поможет не только изучить
сам процесс создания регулярных выражений с помощью
конструктора RegExp(), но также и создавать и тестиро-
тестировать собственные шаблоны поиска.
Как показано на рис. 31.1, данная программа выпол-
выполняет поиск и замену в поисковой строке, в строке заме-
замены и шаблоне, который был введен. Преимущество этой
Глава 31
программы заключается в возможности создания стро-
строки поиска и шаблона, а после — тестирования того, что
шаблон работает именно так, как было задумано. Исход-
Исходный код программы показан в листинге 31.1.
Regular Expression Tester
Search String: ja big cat
Replace String: ]T
Attributes: jg
Pattern: jbig
Result: ]«
РИСУНОК 31.1 Тестер регулярных выражений
Листинг 31.1 Тестер регулярных выражений
<html>
<head>
<title>Regular Expression Tester</title>-
<script language="JavaScript">
<!— Начало сценария
// Функция осуществляет поиск по шаблону в
// searchstr
function searchForPattern(searchstr, pattern,
REattributes, theResult)
r
//Создание объекта регулярного выражения
var regExpObj = new
RegExp(pattern,REattributes);
//Заполнение поля результата результатами поиска
theResult.value = regExpObj.exec(searchstr);
1
// Эта функция заменяет на replaceStr все
// вхождения шаблона в searchstr
function replacePattern(searchstr,replaceStr,
pattern,REattributes,theResult)
i
//Создание объекта регулярного выражения
var regExpObj = new
RegExp(pattern,REattributes);
//Заполнение поля результата результатами
//поиска.
theResult.value =
searchstr.replace(regExpObj,replaceStr);
У/ Эта функция очищает все поля страницы
function clearFields(fieldl, field2, field3,
field4, field5)
Избранные программные технологии
Часть V
fieldl.value =
field2.value =
field3.value =
field4 .value =
field5.value =
// Конец сценария —>
</script>
</head>
<body>
<center>
<hl>Regular Expression Tester</hl>
<form name="niyForm"">
<table board=0>
<tr align=right>
<td>Search String:</td>
<tdxinput type="teact" name="searchString"X/td>
</tr>
<tr align=right>
<td>Replace S tring:</td>
<tdxinput type="text" name="replaceString"x/
td>
</tr>
<tr align=right>
<td>Attributes:</td>
<tdxinput type="text" name="REattributes"X/td>
</tr>
<tr align=right>
<td>Pattern: </td>
<td><input type="text" name="pattern"X/td>
</tr>
</table>
<br>
<input type="button"
value="Search for pattern"
onClick="searchForPattern(searchstr ing. value,
pattern.value,
BEattributes.value,
result)">
<input type="button"
value="Replace pattern"
onClick="replacePattern(searchstring.value,
replaces tring. value,
pattern.value,
FEattributes.value,
result) ">
<input type="button"
value="Clear"
onClick="clearFields(searohstring,
replacestring,
pattern,
REattributes,
result)">
<brXhrXbr>
Result: <input type="text" name="result">
</center>
</body>
</html>
Тестер регулярных выражений можно условно раз-
разбить на четыре основные части: пользовательский интер-
интерфейс, функция поиска, функция замены и функция очи-
очистки полей.
Пользовательский интерфейс
Пользовательский интерфейс тестера регулярных выра-
выражений состоит из формы с пятью текстовыми окнами и
трех кнопок. Текстовое окно searchString обеспечива-
обеспечивает место для ввода строки, поиск которой осуществля-
осуществляется по определенному шаблону. Текстовое поле ввода
replaces tring обеспечивает пространство для ввода стро-
строки, используемой для замены частей searchString, где
отыскивается соответствие. Значение из этого поля при-
применяется после щелчка на кнопке Replace Pattern. Та-
Такие атрибуты поиска по шаблону, как глобальный по-
поиск/замена и поиск без учета регистра, помешаются в
текстовом поле ввода attributes. Текстовое поле ввода
pattern обеспечивает место для ввода шаблона регуляр-
регулярного выражения, по которому выполняется поиск в
searchString. После щелчка на кнопках Search for Pattern
или Replace Pattern результат поиска/замены помещает-
помещается в окно result.
Функция поиска
После щелчка на кнопке Search for Pattern обработчик
событий onClick вызывает функцию searchForPattern.
Эта функция передает конструктору шаблон, л также
информацию об атрибутах, введенную в HTML-форму,
с целью создания объекта RegExp с именем regExpObj.
Метод regExpexec() используется для поиска по шабло-
шаблону в поисковой строке, которая была введена в форму.
Результат поиска помещается в текстовое поле result.
Если же соответствие не найдено, упомянутое поле ос-
остается пустым.
Функция замены
После щелчка на кнопке Replace Pattern обработчик со-
событий onClick вызывает функцию replacePattern(). Эта
функция передает конструктору шаблон, а также инфор-
информацию об атрибутах, введенную в HTML-форму, с це-
целью создания объекта RegExp с именем regExpObj. Ме-
Метод replace() объекта searchStr применяется для замены
на repIaceStr вхождений шаблона в searchStr. Затем ре-
результат поиска и замены помещается в текстовое поле
result. Если соответствие не найдено, в текстовое поле
result помещается searchStr.
Функция очистки
После щелчка на кнопке Clear обработчик событий onClick
вызывает функцию clearFields{). Эта функция произво-
производит очистку всех текстовых полей.
Выполнение поиска по шаблону с использованием регулярных выражений
Пример: программа проверки
правильности ввода телефонных
номеров
Итак, читатели уже знакомы с регулярными выражения-
выражениями, знают, как их создавать, а также имеют программу,
которая поможет в определении шаблонов поиска. Но
как применить регулярные выражения для решения ре-
реальных задач? В современном Internet превалирует элек-
электронная коммерция. Поэтому огромную роль играет
проверка ввода телефонных номеров, адресов и номеров
кредитных карточек. Многие виды проверок, например,
кредитных карточек, должны выполняться на серверной
части, однако проверка статической информации может
проводиться и на стороне клиента. Один из видов ин-
информации, проверяемой на серверной части, связан с
территориальными кодами. Поскольку они меняются не
очень часто, их можно поместить на Web-страницу и
выполнять проверку с использованием регулярных вы-
выражений в JavaScript.
В Этом разделе рассказывается применение регуляр-
регулярных выражений для проверки территориальных кодов
перед тем, как разрешить пользователю продолжать ра-
работу. Предположим, что создается Web-сайт для компа-
компании North Caroline, торгующей различным хламом.
Прежде чем пользователь сможет продолжить составлять
заказ, следует убедиться, что компания имеет коррект-
корректный телефонный номер, относящийся к Северной Ка-
Каролине. В противном случае могут возникнуть пробле-
проблемы с отгрузкой товара.
Было бы разумно поместить все номера Северной
Каролины на Web-страницу и с их помощью проверять
корректность введенного номера. Однако можно прове-
проверить правильность ввода территориального кода, который
должен относиться к Северной Каролине. Если клиент
допустил ошибку при вводе кода, его можно предупре-
предупредить и предложить ввести номер Северной Каролины.
Если же код правильный, формирование заказа можно
продолжить.
За счет использования поисковых шаблонов для те-
телефонных номеров Северной Каролины, можно быстро
определить корректность номера введенного пользова-
пользователем. Все телефонные номера состоят из трехцифрового
территориального кода, за которым следует трехцифро-
вая приставка, а за ней — четырехцифровое расширение.
Шаблон будет выглядеть следующим образом: ###-###-
####. Поскольку знак # обозначает цифру, можно при-
прибегнуть к синтаксису регулярных выражений \d для циф-
цифры в этих позициях. Поисковый шаблон станет таковым:
/\d\d\d-\d\d\d-\d\d\d\d/
'Обратите внимание, что наклонная черта вправо ука-
указывает на конец и начало шаблона. Поскольку извест-
Глава 31
но, что в Северной Каролине имеется только шесть ко-
кодов (828, 252, 704, 919, 910, 336), то их можно задейство-
задействовать в шаблоне:
/<828|252j704|919|9101336)-\d\d\d-\d\d\d\d/
Добавьте подшаблоны в основной шаблон, поместив
все возможные территориальные коды в круглые скоб-
скобки и отделив каждый код вертикальной чертой. Верти-
Вертикальная черта означает, что должна предприниматься
попытка поиска значения справа или слева, т.е. логичес-
логическая операция ИЛИ. Если пользователь вводит террито-
территориальный код, определенный в списке, результат поис-
поиска будет положительным.
Теперь, когда составлены все поисковые шаблоны
для телефонных номеров Северной Каролины, потребу-
потребуется построить пользовательский интерфейс и протести-
протестировать шаблоны. Если отыскивается шаблон в строке,
содержащей правильный телефонный номер, то возвра-
возвращается соответствующий телефонный номер. С другой
стороны, если ищется шаблон в строке с неправильным
телефонным номером, будет возвращен NULL. По на-
наличию NULL можно судить, является ли введенный
пользователем номер правильным. Следующая функция
JavaScript реализует описанную выше операцию.
function validatePhone (areaCode,prefix, extension)
i
.//Сборка телефонного номера
var phoneNum = new String (areaCode + "-" +
prefix + "-" + extension) ;
//Создание шаблона регулярного выражения,
//выполняющего поиск телефонного номера с
//территориальными кодами 828, 252, 704, 919,
//336.
var regExpObj = / (82812521 704 | 919 | 910 | 336) -
\d\d\d-\d\d\d\d/;
if (regExpObj .exec (phoneNum) = null)
f
alert (phoneNum + " does not contain a valid
^North Carolina area code ! " ) ;
else
f
alert {"Thank you for your order!");
Если добавить в функцию некоторый HTML-код,
Получится полнофункциональная программа проверки
телефонных номеров. В листинге 31.2 представлен пол-
полный исходный код такой программы.
Листинг 31.2. Проверка введенного телефонного
номера.
<html>
<head>
<title>Phone Number Validation</title>
<script language="JavaScript">
<! — Начало сценария
Избранные программные технологии
Часть V
function validatePhone(areaCode,prefix,extension)
//Сборка телефонного номера
var phoneNum = new String (areaCode + " " +
prefix + " " + extension) ;
//Создание шаблона регулярного выражения,
//выполняюцего поиск телефонного номера с
//территориальными кодами 828, 252, 704, 919,
//910, 336
var regExpObj = / (828
\d\d\d-\d\d\d\d/;
if (regExpObj . exec (phoneNum) = null)
alert (phoneNum + does not contain a valid
~"North Carolina area code'");
I
else
¦I
alert ("Thank you for your order
I
// Конец сценария—>
</script>
</head>
<body>
<center>
<hl>NC Sales Company</hl>
Thanks for your order. Please provide us with
your North Carolina phone number so we can
contact you if tne в are any problems shipping
your order.
<?orm name="forml">
Phone Number: <input type="text"
size=3
maxlength=3
name="area">-
<input type="text"
size=3
maxlength=3
name="prefix">-
<input type="text"
size=4
maxlength=4
name="extension">
<brXbr>
<input type="button"
value="Submi t"
onClick="validatePhone(area.value,
prefix.value,
extension.value)">
</form>
</center>
</body>
</html>
Теперь можно приступить к тестированию програм-
программы. При наборе правильного телефонного номера, на-
например, 919-293-4444, и щелчке на кнопке Submit ото-
отображается окно предупреждения, сообщающее об
обработке заказа. При вводе неправильного номера, ска-
скажем, 918-293-4444, и щелчке на кнопке Submit поиск
завершается неудачей и появляется сообщение об ошиб-
ошибке (см. рис. 31.2).
NC Sales Company
Thanks foryour ore Please provide us withyourNorth Carolina phone
number so we can contact you ifthere are any problems hipping your order.
Phone Number: '|91в1|гэз1 [Л
РИСУНОК 31.2 Программа проверки правильности вб
телефонного номера.
Резюме
Глава была посвящена использованию объекта регуляр-
регулярного выражения. Подробно рассматривались способы
создания шаблонов поиска и объектов RegExp, в кото-
которых эти шаблоны хранятся. Кроме того, исследовались
особенности применения шаблонов, предназначенные
для поиска текста. При этом использовались методы
|бъсктов RegExp и String.
Для иллюстрации работы с регулярными выражени-
выражениями рассматривался тестер таких выражений. Эта ути-
утилита незаменима при создании и тестировании сложных
поисковых шаблонов. Программа проверки правильно-
правильности ввода телефонных номеров продемонстрировала
один из способов реального применения регулярных
выражений.
Технология обработки данных
со стороны клиента
В ЭТОЙ ГЛАВЕ
Определение источника данных: клиент или сервер?
Что такое клиентская таблица?
Создание таблиц поиска
Создание поискового пользовательского интерфейса
Обработка поисковых запросов
Отображение результатов поиска
Запуск приложения
Web предлагает поистине революционный подход к
созданию приложений баз данных, обеспечивая возмож-
возможности доступа к удаленным базам данных через Web-
браузер и возврате результатов в HTML-формате. Не-
Несмотря на то что этот способ практикуется, в основном,
при работе с CGI-сценариями, для получения доступа
к данным можно воспользоваться и JavaScript.
Обычно, когда говорят о доступе к базам данных в
Web, имеют в виду, что данные находятся на сервере.
Однако JavaScript обеспечивает работу с данными и на
стороне клиента. В этой главе рассматривается, как при
помощи JavaScript можно манипулировать данными на
клиентской части, что может оказаться альтернативой
CG1 или другим серверным решениям.
Определение источника данных:
клиент или сервер?
Прежде чем углубиться в сам процесс работы с клиен-
клиентскими данными в JavaScript, стоит разобраться, имеет
ли все это смысл. Несмотря на то что клиентские дан-
данные могут иметь различные типы, они будут рассмат-
рассматриваться как таблицы баз данных. Например, разработ-
разработчик желает получить данные из реляционной базы
данных и преобразовать их в структурированный набор
данных JavaScript, хранящийся в HTML-файле или на
клиентском компьютере. Поскольку в главе использует-
используется подход, ориентированный на базы данных, на набор
данных JavaScript ссылаются как на таблицу клиентс-
клиентской части.
Таблицы клиентской части имеют два главных ог-
ограничения. Первое: базы данных рассчитаны только на
чтение. Поскольку данные внедрены в HTML-код,
пользователи не смогут добавлять, изменять или сохра-
сохранять эти данные на клиентской части. Если появляется
необходимость в корректировке тех же данных на сер-
серверной части, теоретически это возможно. В таком слу-
случае, если происходят какие-либо изменения, клиентс-
клиентскую базу данных потребуется перезагрузить. Так или
иначе, пока разработчик не преодолеет множество пре-
преград, таблица клиентской части будет предназначаться
только для чтения.
Второе ограничение связано с тем, что базы данных
должны иметь относительно небольшие размеры. Дан-
Данные хранятся в HTML-файле. Когда пользователь по-
получает доступ к Web-странице, производится ее полная
загрузка. Вряд ли кто-то пожелает внедрить в файл базу
данных объемом в 100000 записей. Даже если пользо-
пользователь обладает прямым подключением к Internet, все
равно длительность загрузки приведет к некоторым не-
неудобствам.
Максимальный размер набора данных зависит от
контекста. При создании таблицы клиентской части,
которая будет передаваться со скоростью 28.8 Кбит/с
для модема 56 Кбит/с, размер таблицы можно ограни-
ограничить до 1000 записей. Однако, при создании intranet-
решения, которое предусматривает быстрое соединение,
границы можно расширить.
Итак, с ограничениями должно быть все ясно, так
почему же таблицы клиентской части все еще исполь-
используются, если существует множество других способов
работы с различными видами баз данных? На то име-
имеется два объяснения. Во-первых, по ряду причин, с по-
помощью таблицы клиентской части можно получить бо-
Избранные программные технологии
Часть V
лее простые решения, чего нельзя сказать о
нариях и других средствах Web-сервера, принимая во
внимание статичность и относительно малые размеры
набора данных. Во-вторых, поскольку все данные, по-
поисковый механизм и пользовательский интерфейс нахо-
находятся на клиентской части, то доступ к серверной час-
части совершенно не нужен. В результате существенно
увеличивается скорость поиска и минимизируется до-
дополнительная нагрузка на сервер, необходимая для осу-
осуществления поиска.
Многие станут возражать, что несмотря на переме-
перемещение данных на сторону клиента, данные все равно
проходят через серверную часть при загрузке страницы.
И это правда. Однако, сервер не должен выполнять CGI-
поиск, а только отправить клиенту HTML-файл.
Поскольку корпорации разворачивают интрасети, в
Web переносится большое количество маленьких сете-
сетевых приложений. По причине того, что многие из них
ориентированы на базы данных, будет расти трафик
корпоративных Web-серверов. В некоторых случаях таб-
таблицы клиентской минимизируют загрузку сервера. Од-
Одним из примеров является приложение списка телефон-
телефонных номеров компании. Можете назвать компанию,
которая бы не имела такого списка, по крайней мере,
на бумаге? В данной главе рассматривается именно этот
пример, поскольку он более всего соответствует приме-
применению клиентских данных для решения задач современ-
современного бизнеса.
Что такое клиентская таблица?
Для Web-разработчиков термин таблица ассоциирует-
ассоциируется с HTML-таблицами, которые создаются при помо-
помощи дескрипторов <table>. Однако эта тема в данной
главе не затрагивается. Поскольку речь идет о приложе-
приложениях баз данных термин таблица ассоциируется с таб-
таблицей, содержащей строки и столбцы в формате реля-
реляционных баз данных. На рис. 32.1 показана типичная
таблица баз данных. Существует множество различных
способов работы с данными, а также выполнения их
поиска, что в большей части зависит от способности
программных средств управлять базами данных. В этом
разделе под термином таблица подразумевается табли-
таблица базы данных.
К сожалению, работа с реляционными таблицам на
клиентской части JavaScript посредством доступа к ба-
базам данных будет невозможна несмотря на то, что эту
операцию можно проводить на серверной части. Необ-
Необходимо переводить базы данных в структурированный
формат, в котором может работать код JavaScript. В
JavaScript основной используемой организационной
структурой является массив. Можно получить доступ к
любому элементу массива JavaScript и выполнить вы-
вычисления, как это проделывает реляционная Ьаза дан-
данных с каждой записью во время поступления запроса.
На рис. 32.2 проведена параллель между данными в ре-
реляционной таблице и данными в массиве.
¦РИСУНОК 32.1. Таблицареляционной базы данных.
Ordered Set of Tabula-
Data
Relational Table
Best Hovies
Casablanca
Chariots of Fire
African Queen
A Room With a ¦¦ ¦.
!wn. and the Beast
Dances With Wolves
Forrest Gump
JavaScript Array
bestMovies = newArrayG)
>estMovies[1l = "Casablanca"
bestMo\ries[2] = "Chariots of Fire*
bestMovies[3] = "African Queen"
bestMovies[4] = "A Room With a view"
bestMoviesp] = "Beauty and the Beast"
bestMovies[6] = "Dances With Wolves"
bestMoviesp] = "Forrest Gump"
РИСУНОК 32.2. Работа с набором табличных данных в
зависимостиотконтекста.
Создание таблиц поиска
Первый шаг, который потребуется предпринять при
работе с таблицами клиентской части JavaScript — со-
создать саму таблицу. Таблица клиентской части не мо-
может быть внешним файлом, поэтому все данные долж-
должны быть внедрены в HTML-файл. Но для того, чтобы
информация принесла реальную пользу, необходимо
структурировать ее таким образом, чтобы поиск и вос-
восстановление данных проводились при первой же необ-
необходимости.
Как упоминалось ранее, одной из опций для струк-
структурирования клиентских данных является одномерный
массив. Например, если поместить в массив полный
список имен служащих, это будет выглядеть следующим
образом:
var employees = new Array A0)
employees[1] = "Richard"
employees[2] = "David"
employees[3] = "Rachel"
employees[4] = "Mark"
Технология обработки данных со стороны клиента
employees[5] = "Mellon"
employees[6] = "Margo"
employees[7] = "Darius"
employees[8] = "Dan"
employees[9] = "Dave"
employees[10] = "Pepe"
Далее этот массив можно использовать и внутри его
осуществлять поиск отдельных элементов, базируясь на
информации, которая была вынесена из главы ]1. В
данном случае одномерный массив не играет большой
роли, поскольку во многих таблицах поиска находится
большое количество столбцов для прослеживания дан-
данных. В списке телефонов необходимо предусмотреть
имя служащего, название организации, отдел, расшире-
расширение телефонного номера, адрес электронной почты.
Более эффективный способ заключается в создании
пользовательского объекта employee, а после — группи-
группировки данных о служащих в одномерный массив. Это
позволит не только сохранить многочисленные столб-
столбцы в объекте, но и работать с объектами employee как
собирательной группой.
Для определения объекта employee потребуется со-
создать метод конструктора, как показано ниже:
function employee(FirstName, LastName, Title,
Department, PhoneExt, EmailAddress) {
this.FirstName = FirstName;
this. LastName = LastName;
this.Title = Title;
this. Department = Department;
this. PhoneExt = Phone Ext;
this. EmailAddress = EmailAddress;
)
После создания конструктора можно приступить к
созданию объектов employee и помещению их в контей-
контейнерный массив empList. Для каждого служащего будет
достаточно одной строки кода. Ниже показаны приме-
примеры для пяти служащих из всех 105:
empList[l] = new employee("Richard", "Wagner",
"Chief Technology Officer", "RSD", 00",
"rwagner@acadians.com");
empList[2] = new employee("Grady", "Anderson",
"Programmer", "R&D", 98",
"grady@acadians.com");
empList[3] = new employee ("Thomas", "Sprat",
"Marketing Manager", "Marketing", 56",
"tsprat@acadians.com ") ;
empList[4] = new employee("William", "Cleyball",
"Marketing Manager", "Marketing", 51",
"wcal@acadians.com ") ;
¦empList[5] = new employee ("Fred" , "Tortallini" ,
"Marketing Manager", "Marketing", 04",
"t.ort@acadians.com ");
Сейчас все данные о служащих охвачены в структур-
структурном формате, что очень необходимо для JavaScript.
Глава 32
примечание ^ _ ^ ^1Й*^--^<:„ ;Г .t;> '|
Не стоит огорчаться, задумываясь об объеме работы,
необходимой для перевода данных, хранящихся в ре-
реляционных базах данных, в объекты JavaScript или мас-
массивы. Существует много способов создания такой ин-
информации, которые исключают набор текста на
клавиатуре. При частом изменении данных можно со-
создать сценарий CGI или запустить другие серверные
процессы, автоматически генерирующие код за счет
экспорта таблицы баз данных.
Создание поискового
пользовательского интерфейса
¦Способ работы пользователей приложения с таблицей
клиентской части зависит от определенного контекста
приложения. В этом примере производится вызов поль-
пользовательского интерфейса, в котором будет выполнять-
выполняться поиск служащих на основе введенного текста. По-
Поскольку таблица состоит из нескольких полей, можно
предоставить пользователям большую свободу, обеспе-
обеспечив поиск в четырех основных полях таблицы: FirstName,
LastName, Title, Department.
Предположим, что необходимо, чтобы результаты
поиска были помещены в HTML-документ. Чтобы вы-
вывести на экран одновременно определение поиска и
результат, воспользуйтесь мулътифреймовъш окном. С
учетом предоставленной ранее информации, определен
список файлов, относящихся к телефонному списку:
• employeelnfo.html — это родительское мультифрей-
мовое окно, которое содержит базу данных со слу-
служащими и другую глобальную информацию.
• searchfrm.html — самый верхний фрейм, обеспечи-
обеспечивающий пользовательский интерфейс для ввода по-
поискового запроса.
¦• result.html — самый нижний фрейм, выводящий на
экран результаты поиска. По умолчанию он пуст.
На рис. 32.2 показан набор мультифреймовых окон
приложения.
Единственной частью интерфейса, с которой взаи-
взаимодействует пользователь, является поисковое окно
(searchfrm.html). Ниже представлен исходный код HTML
для определения формы поиска в рамках окна:
<body>
<form method="POST" name="form">
<pre>Search By: </pre>
<preXinput
type=radio
name=" searchBy"
value="FirstName">First Name <input
type=radio
checked
Избранные программные технологии
Часть V
name="searchBy"
value="LastName">Last Name <input
type=radio
name—"searchBy"
value="Title">Title <input
type=radio
name="searchBy"
value="Department">Department</pre>
<pre>Text: <input
type=text
size=30
maxlength=30
name="searchByText"Xinput
type=button
size=20
name="findButton"
Find
onClick="doSearch () "Xinput
type=reset
name="Clear"
value=" Clear "
onClick="clearForm() "X/pre>
</form>
</body>
атпда
If,, ы., ** v-
Intranet
S**rch Ну:
г First Нам
Employee-'
Database
\
РИСУНОК 32.3. Пользовательский интерфейс поиска в базе
данных.
Обработка поисковых запросов
Главной возможностью приложения, основанного на
клиентских таблицах, является поиск данных. Напри-
Например, в списке телефонов персонала необходимо опре-
определить поле, по которому будет выполняться поиск, а
затем передать эту информацию вместе с поисковым
запросом в метод, реализующий собственно поиск.
В данном примере обработка поиска проходит в двух
местах. Метод doSearch() в фрейме searchForm подго-
подготавливает поиск, а затем передает информацию в метод
findEmployee() родительского окна.
Чтобы проделать эту операцию, необходимо устано-
установить метод doSearch() в качестве обработчика событий для
кнопки Find. В этой функции выполняется проверка,
какие переключатели отмечены и на основе этой инфор-
информации производится установка значения переменной
searchField. После проверки что в поле searchByText вве-
введено какое-то значение, вызывается метод findEmployeeO
родительского окна с передачей в него в качестве парамет-
параметров переменной searchField и значения поля searchByText:
function doSearch() {
var searchField = "
if (document.form.searchBy[0].checked) {
searchField = "FirstName" }
else {
if (document.form.searchBy[1].checked) {
searchField = "LastName }
else { if
ecked) (
searchField = "Title" }
else { if
(document.form.searchBy[35.checked)
{ searchField = "Department" )
:i
i
if (document.form. searchByText.value =
null || document.form.searchByText.value ==
"") {
alert("Please enter your search criteria before
"¦continuing. ") }
else {
parent.findEmployee(searchField,
document.form.searchByText.value)
В родительском окне (employeelnfo.html) метод
findEmployeeO получает эти два параметра и применя-
применяет их при оценке массива объектов employee. Цикл for
обеспечивает просмотр массива объектов employee,
сравнивая значения поискового запроса (параметр
searchWord) с определенным свойством (параметр
searchField); при этом используется метод объекта стро-
строки indexOf().
Перед тем как перейти к основному коду, рассмот-
рассмотрим еще один пример. Если проводится поиск значения
Richard в свойстве FirstName всех объектов, код будет
выглядеть следующим образом:
for (var i=l; i<empList. length; ) {
if (empListfi] .FirstName. indexOf ( 'Richard'!
'!= -1) {
empListfl] .show() }
Цикл for оценивает каждый объект и возвращает
значение больше 0 при условии, если текст находится
внутри значения свойства FirstName объекта employee.
Если найдено необходимое соответствие, вызывается
метод show() объекта employee. Этот метод будет под-
подробно рассматриваться в одном из следующих разделов
этой главы.
Технология обработки данных со стороны клиента
А теперь, следуя той же логике, возьмемся вновь за
список телефонных номеров. Примите во внимание:
параметр searchField предназначен для представления
имени свойства объекта, а не для строкового значения,
поэтому придется воспользоваться встроенным методом
evalQ. Метод eval() интерпретирует строковое значение
и оценивает его как выражение JavaScript. Если преоб-
преобразовать код JavaScript в отдельную строку, ее можно
оценить с помощью метода eval():
function findEmployee(searchField, searchWord) {
var str = "" ;
// Здесь следует код форматирования
for (var i=l; KempList. length; x++) (
str = "if (empList[" + i + "] ,." +
searchField + ".indexOfC" +
.searchWord + "') != -1) {
empList[" + i + "] .show() }";
eval (str) ;
II Здесь следует код форматирования
Отображение результатов поиска
Последний этап поискового процесса связан с представ-
представлением результатов поиска пользователю. Для вывода
информации на экран используется нижний фрейм
(resultForm). Для этого можно усовершенствовать метод
findEmployee, рассмотренный в предыдущем разделе.
Для того чтобы HTML генерировался "на лету", не-
необходимо воспользоваться объектом Document из result
Form, который послужит "холстом" для записи. Снача-
Сначала подготовьте холст документа с использованием ме-
метода I)ocumentopen(). Затем, для отображения результа-
результатов в табличном формате, можно создать таблицу HTML,
через дескриптор <table> и установить заголовок таб-
таблицы.
window.resultForm.document.open();
window.resultForm.document.wri te(
"<h2>Matches:</h2>");
window.resultForm.document.write(
"<table border=l>");
window.resultForm.document.write("<trxtd
wwidth=10%Xstrong>First. Name</strongX/td>") ,•
window.resultForm.document.write("<td
'-»width=15%Xstrong>Last Name</strongX/td>") ;
window.resultForm.document.write("<td
l~width=20%Xstrong>Title</strongX/td>") ;
window.resultForm.document.write("<td
b»width=15%Xstrong>Department</strongX/td>") ;
window.resultForm.document.wri te("<td
*->width=5%Xstrong>Ext.</strongx/td>");
window.resultForm.document.wri te("<td
^width=15%Xstrong>Email</strongX/tdX/tr>") ;
Сейчас, когда все подготовительные действия завер-
завершены, можно приступить к собственно обработке по-
поиска. Каждый совпадающий служащий вызывается для
Глава 32
выполнения метода show(). Этот метод применяется для
вывода на экран информации как одной записи в таб-
таблице. Поэтому потребуется добавить метод show() в
конструктор объекта employee.
function employee(FirstName, LastName, Title,
Department, PhoneExt, EmailAddress) {
this.FirstName = FirstName;
this.LastName = LastName;
this.Title = Title;
this.Department = Department ;
this.PhoneExt = PhoneExt;
this.EmailAddress = EmailAddress;
this.show = emp show;
J
После вызова метода show() объекта employee запус-
запускается метод emp_show(), который определяет позиции
для размещения форматируемого кода и вывода на эк-
экран текущей информации о служащих. Для помещения
значений каждого из свойств объекта в отдельные ячей-
ячейки таблицы применяется метод write():
function emp_show(J (
window. resultForm. document .write ("<trxtd
1-»width=10%>" + this.FirstName + "</td>") ;
window.resultForm.document.write("<td
1-»width=15%>" + this.LastName + "</td>");
window.resultForm.document.write("<td width=20%>"
+ this.Title + "</td>")
window.resultForm.document.write("<td
4-»width=15%>" + this.Department + "</td>") ;
window.resultForm.document.write("<td
^»width=5%>" + this. PhoneExt + "</td>") ;
window.resultForm.document.write("<td width=15%>"
+ "<a href='mailto:" + this.EmailAddress
+ '">" + this.EmailAddress + "</tdX/tr>") ;
j
Обратите внимание, что для адресов электронной
почты служащих определяется ссылка. Пользователю
достаточно лишь щелкнуть на адресе служащего и со-
сообщение будет отправлено.
Последний код форматирования находится в мето-
методе findEmployeeQ. После обработки всех записей служа-
служащих, метод write() выводит дескриптор завершения таб-
таблицы — </table>. Метод closeQ закрывает холст. Ниже
показан полный исходный код метода findEmployeeQ:
function findEmployee(searchField,
var str = "";
searchWord)
window.resultForm.document.open();
window.resultForm.document.wri te(
"<h2>Matches:</h2>") ,-
window.resultForm.document.write(
"<table border=l>");
window.resultForm.document.write(
"<trxtd width=10%Xstrong>First Name
</strong></td>");
window.resultForm.document.write(
"<td width=15%Xstrong>Last Name
</strongX/td>") ;
window.resultForm.document.write(
"<tdwidth=20%Xstrong>Title</strong>
Избранные программные технологии
Часть V
window.resultForm.document.write(
"<td width=15%Xstrong>Department
</strongX/td>");
window.resultForm.document.write(
"<td width=5%Xstrong>Ext. </strong>
window.resultForm.document.write(
"<td width=15%Xstrong>Email</strong>
*-»</td></ tr>") ,-
for (var i=l; i<=empList.length-1; i++) {
str = "if (empList[" + i + "]." +
searchField + ".indexOf(' " +
searchWord + "') != -1) { empListp +
i + "].show() }";
eval(str);
1
window. resultForm, document. write ( "</table>') ;
window.resultForm. document.close О ;
зан на рис. 32.4. Очистка поисковой формы и фрейма
результатов осуществляется по щелчку на кнопке Clear.
В листинге 32.1 представлен полный исходный код
для родительского окна employeelnfo.html, а в листинге
32.2 — исходный код JavaScript для окна searchfrm.html.
Запуск приложения
Теперь можно протестировать приложение, загрузив в
браузер файл employeelnfo.html. Предположим, что тре-
требуется найти Грейди Андерсона (Grady Anderson). Вве-
Введите Anderson в текстовое поле, выберите переключатель
Last Name и щелкните на кнопке Find. Результат ПОКЙ-
ЛИСТИНГ 32.1 employeelnfo.html
Intranet Employee
SAorch By;
Г First ияыщ f lj.at )|«a# С titl*
Matches
ipirsl Naim
iGrnily
[Ciy'
•Fnuik
jierv .....
а' я_
LastiNamo iTltle
^Anderson .Trosramnic-r
Anderson iSaJesperson
iAnderson ^Salesperson
Anderson i^rogrannner
¦"' SSSSriSs¦'¦ '¦ ¦¦•'-;¦
Database
department
(Sales'
Sales "
.. -_ь. „. —
.,,4
Jem.
1198
[500
ilOO
!1OO
CinaU
comi ¦:¦¦
Hilt!¦--¦¦ : HtL in-,-.- ¦¦¦¦¦
РИСУНОК 32.4. Результаты поиска, отображенные в виде
таблицы.
<html>
<head>
<title>Intranet Employee Database</title>
<script language="JavaScript">
// Сетевая база данных по служащим
/ Глобальные
var i = 1;
var n = 1;
переменные
// Создание объекта Array
var empList = new Array () ;
employee
// Метод show() — метод объекта
function emp_show() {
window.resultForm.document.write ("<trxtd width=10%>"
window.resultForm.document.write("<td width=15%>"
window.resultForm.document.write("<td width=20%>"
window.resultForm.document.write("<td width=15%>"
window.resultForm.document.write("<td width=5%>"
window.resultForm.document.write("<td width=15%>"
+ this .FirstName + "</td>")
+ this.LastName + "</td>");
+• this.Title + "</td>") ;
+ this.Department + "</td>"
*¦ this. PhoneExt + "</td>")
+ "<a href='mailto:"
+ this.KmailAddress + '">" + this.EmailAddress + "</tdx/tr>"> ;
// Конструктор объекта employee
function employee(FirstNami Title, Department, PhoneExt, EmailAddress)
this. FirstName = FirstName;
this.LastName = LastHame;
this.Title = Title;
this .Department = Department;
this . PhoneExt = PhoneExt;
this.EmailAddress = EmailAddress;
this.show = emp_show;
¦
// Поиск служащего на основе поля и введенного слова
Технология обработки данных со стороны клиента
Глава 32
function findEmployee(searchField, searchWord)
var str = "";
window, resultForm. document, open () ;
window. resultForm.document,write ("<h2>Matches:</h2>");
window.resultForm,document.write ("<tableborder=l>") ;
window. resultForm. document, write ("<trxtd width=10%Xstrong>First Name</strongX/td>") ;
window. resultForm, document, write ("<td width=15%Xstrong>Last Name</strongX/td>") ;
window. resultForm. document.write ("<tdwidth=20%Xstrong>Title</strongX/td>") ;
window. resultForm. document.write ("<tdwidth=15%Xstrong>Department</strongX/td>") ;
window . resultForm. document . write ( "<tdwidth=5%Xstrong>Ext . </strongX/td>" ) ;
window. resultForra.document.write ("<tdwidth=15%Xstrong>Email</strongX/tdx/tr>") ;
for (var i=l; i<=empList.length-l; i++) {
str = "if (empList[" + i + "]." + searchField + ".indexOf("'
+ searchWord +"') != -1) { empList[" + i + "] .show() } " ;
eval(str);
)
window, resultForm. document. write ( "</table>" > ;
window, resultForm, document. close < } ;
I
// Создание объектов employee при запуске
empList[l] = new employee (
"Richard", "Wagner", "Chief Technology Officer", "RSD", 00", "rwagner@acadians.com");
empList [2] = new employee (
"Grady" , "Anderson", "Programmer", "R&D", 98", "grady@acadians.com") ;
empList[3] = new employee!
'"Thomas", "Sprat", "Marketing Manager", "Marketing", 56", "tspratt@acadians.com ");
empliiiit[4] = new employee (
"William", "Cleyball", "Marketing Manager", "Marketing", 51", "wcal@acadians.com ") ;
empList[5] = new employee(
"Fred", "Tortallini" , "Marketing Manager", "Marketing", 04", "tort@acadians.com ") ;
empList[6] = new employee f
"Smack", "Hopkins", "Marketing Manager", "Marketing", 06", "smack@acadians.com ") ;
empList[7] = new employee (
"Luey", "Gentry", "Marketing Manager", "Marketing", 50", "luey@acadians.com ") ;
empLi:3t[8] = new employee (
"Erwin", "Waltham" , "Marketing Manager", "Marketing", 45", "ew@acadians.com");
empList[9] = new employee С
"Dallas", "Spanner", "Marketing Manager", "Marketing", 56", "dallas@acadians.com");
empList[10] = new employee(
"Spill", "Hopkins", "Marketing Manager", "Marketing", 20", "spill@acadians.com ") ;
empList[ll] = new employee(
"Huey" , "Wagner", "Marketing Asst" , "Marketing", "854", "huey@acadians.com ") ;
¦empList[12] = new employee (
"Tom", "Longly" , "Marketing Asst", "Marketing", 12", "info@acadians.com ") ;
empLi st[13] = new employee (
"Huck", "Starback", "Marketing Asst" , "Marketing", 12", "info@acadians.com ");
empList[14] = new employee(
"Crazy", "Lags", "Marketing Asst" , "Marketing", 22", "info@acadians.com ") ;
empList[15] = new employee(
"Bart", "Simpson", "Salesperson", "Sales", 00", "info@acadians.com");
empList[16] = new employee(
"Bill", "O'Reilly", "Salesperson", "Sales", 00", "info@acadians.com");
empList[17] = new employee(
'"Sally", "Smatterhorn" , "Salesperson", "Sales", 00", "info@acadians.com");
empList[18] = new employee(
"Kim", "Pakki", "Salesperson", "Sales", 00", "info@acadians.com");
empList[19] = new employee)
"Jacob", "Ladder", "Salesperson", "Sales", 00", "info@acadians.com");
empList[20] = new employee(
"Jared", "Gaspe", "Salesperson", "Sales", 00", "info@acadians.com");
empList[21] = new employee(
"Justus", "Argon", "Salesperson", "Sales", 00", "info@acadians.com");
empList[22] = new employee(
"Jordan", "Basker", "Salesperson", "Sales", 00", "info@acadians.com");
empList[23] = new employee (
"Lisa", "Smith", "Salesperson", "Sales", 00", "info@acadians.com");
Избранные программные технологии
Часть V
empList[92] = new employee (
"Oil", "Larenzo", "Secretary", '"Company", "800", "info@acadians.com");
empList[93] = new employee (
'"Susie", "Que"r "Secretary", "Company", "800", "info@acadians .com") ;
empList[94] = new employee (
"Trista" , "Wagner", "Secretary", "Company", "BOO", "info@acadians.com");
empList[95] = new employee (
"Kimberly" , "Smith", "Secretary", "Company", "800", "info@acadians.com");
empList[96] = new employee (
"Rachel", "McDonald", "Secretary", "Company", "800", "info@acadians.com");
empList[97] = new employee (
"Reena" , "Smiles", "Secretary", "Company", "800" , "info@acadians.com");
empList[98] = new employee (
"Treena", "Miles", "Secretary", "Company", "800" , "info@acadians.com");
empList[99] = new employee!
"Corrina" , "Triles", "Secretary", "Company", "800" , "info@acadians.com");
empList[100] = new employee (
"Rosemarie", "Barlington" , "Secretary", "Company", "800", "info@acadians.com");
empList[101] = new employee (
"II", "Plage", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[102] = new employee {
"Url", "Page", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[103] = new employee (
"Youri", "Basto", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[104] = new employee (
"Pri", "Opeo", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[10S] = new employee (
"Tikki", "Rodreguez" , "HR Manager", "Recruiting", "900", "info@acadians.com");
</script>
</head>
<?rameset rows=S% , 65%">
<frame src="searchfrm.html" name="searchForm" marginwidth=0"
marginheight=0">
<frame name="resultForm" marginwidth=0" marginheight=0">
<noframes>
Sorry, your browser does not support frames.
</noframes>
</frameset>
<body>
</body>
</html>
Листинг 32.2 searchfrm.html
<html>
<head>
<title>Search Form</title>
<script language="JavaScript">
// Сетевая база данных по служащем
function doSearch ( ) (
var searchField = " " ;
if(document, form.searchBy [ 0] .checked) {
.searchField = "FirstName"; }
¦else {
if (document.form.searchBy [1] .checked) (
.searchField = "LastNatne" ; }
else { if (document.form. searchBy [2] .checked) {
searchField = "Title" ; )
else { if (document.form.searchBy[3J .checked) {
searchField = "Department"; }
Технология обработки данных со стороны клиента
Глава 32
function findEmployee (searchField, searchWord) (
var str = "";
window. resultForm. document. open {) ;
window, resultForm.dosument.write ("<h2>Matches:</h2>");
window. resultForm. docviment. wri te ("<tableborder=l>") ;
window, resultForm. document, write ("<trXtdwidth=10%Xstrong>First Name</strongX/td>") ;
window, resultForm. document, write ("<tdwidth=15%Xstrong>Last Name</strongX/td>") ,-
window. result?orm,document.write ("<tdwidth=20%Xstrong>Title</strongX/td>") ;
window. resultForm, document, write ("<tdwidth=15%Xstrong>Department</strongX/td>") ;
window. resultForm,document.write ("<tdwidth=5%Xstrong>Ext.</strongx/td>") ;
window. resultForm, document.write ("<tdwidth=15%Xstrong>Email</strongX/tdX/tr>") ,-
for (var i=l; i<=empList.length-l;
str = "if (empListf" + i + '•]." + searchField + ".indexOf('"
+ searchWord +"') != -1) { empList[" + i + "] .show() }";
eval(str);
)
window, resultForm.document,write ("</table>"Jr
window, resultForm. document. close ( ) ;
i
// Создание объектов employee при запуске
empList[l] = new employee)
"Richard", "Wagner", "Chief Technology Officer", "RSD", 00", "rwagner@acadians.com");
empList[2] = new employee (
"Grady" , "Anderson", "Programmer", "RSD", 98", "grady@acadians.com");
empLiKt[3J = new employee (
"Thomas", "Sprat", "Marketing Manager", "Marketing", 56", "tspratt@acadians.com ") ;
empList[4] = new employee (
"William", "Cleyball", "Marketing Manager", "Marketing", 51", "wcal@acadians.com ");
empList[5] = new employee (
"Fred1, "Tortallini" , "Marketing Manager", "Marketing", 04", "tort@acadians.com ");
empList[6] = new employee (
"Smack", "Hopkins", "Marketing Manager", "Marketing", 06", "smack@acadians.com ") ;
empList[7] = new employee (
"Luey", "Gentry", "Marketing Manager", "Marketing", 50", "luey@acadians.com ") ;
empList[83 = new employee (
"Erwin", "Waltham" , "Marketing Manager", "Marketing", 45", "ew@acadians.com");
empList[9] = new employee (
"Dallas", "Spanner", "Marketing Manager", "Marketing", 56", "dallas@acadians.com");
empList[10] = new employee)
"Spill", "Hopkins", "Marketing Manager", "Marketing", 20", "spill@acadians.com ") ;
empList[ll] = new employee)
"Huey", "Wagner", "Marketing Asst" , "Marketing", "854", "huey@acadians.com ") ;
empList[12] = new employee(
"Tom", "Longly", "Marketing Asst", "Marketing", 12", "info@acadians.com ") ;
empList[13] = new employee)
"Huck" , "Starback", "Marketing Asst" , "Marketing", 12", "info@acadians.com ");
empList[14] = new employee)
"Crazy", "Lags", "Marketing Asst1* , "Marketing", 22", "info@acadians.com ") ;
empList[15] = new employee)
"Bart", "Simpson", "Salesperson", "Sales", 00", "info@acadians.com");
empList[16] = new employee)
"Bill", "O'Reilly", "Salesperson", "Sales", 00", "info@acadians.com");
empList[17] = new employee)
"Sally", "Smatterhorn" , "Salesperson", "Sales", 00", "info@acadians.com");
empList[18] = new employee)
"Kim", "Pakki", "Salesperson", "Sales", 00", "info@acadians.com");
empLi.st[19] = new employee)
"Jacob", "Ladder", "Salesperson", "Sales", 00", "info@acadians.com");
empList[20] = new employee)
"Jared", "Qaspe" , "Salesperson", "Sales", 00", "info@acadians.com");
empList[21] = new employee)
"Justus", "Argon", "Salesperson", "Sales", 00", "info@acadians.com");
empList[22] = new employee)
'"Jordan", "Basker", "Salesperson", "Sales", 00", "info@acadians.com");
empL:.st[23] = new employee)
"Lisa", "Smith", "Salesperson", "Sales", 00", "info@acadians.com");
Избранные программные технологии
Часть V
empList[24] = new employeef
"Cry", "Anderson", "Salesperson", "Sales", 00" , "info@acadians.com");
empList[25] = new employee)
"Ollie", "Ryder", "Salesperson", "Sales", 00", "info@acadians.com");
¦empList[26] = new employee(
"Polly", "Potts", "Salesperson", "Sales", 00", "info@acadians.com");
empList[27] = new employee (
"Xerxes", "Srrdth", "Salesperson", "Sales", '-500" , "info@acadians.com");
empList[28] = new employee(
"Sally Bae", "Srrdth", "Salesperson", "Sales'1, 00", "info@acadians.com")
empList[29] = new employee(
"Golden", "Driscoll", "Salesperson", "Sales", 00", "info@acadians.com")
empList[30] = new employee(
"Frank", "Anderson", "Salesperson", "Sales", 00", "info@acadians.com");
empList[31] = new employee(
"Merv", "Anderson", "Programmer", "RSD", 00", "info@aeadians.com");
empList[32] = new employee(
"Manu", "Waver", "Programmer", "RSD", 00", "info@acadians.com");
empList[33] = new employee)
"Jason", "Driscoll", "Programmer", "RSD", 00", "info@acadians.com");
empList[34] = new employee)
"Ardent", "Matthews", "Programmer", "RSD", 00", "infoSacadians.com");
empList[35] = new employee)
"Ortho", "Dontal", " Prograrrmer", "RSD", 00", "info6acadians.com");
empList[36] = new employee)
"Troy", "Smith", "Programmer", "RSD", 00", "info@acadians.com");
empList[37] = new employee)
"Fred", "Barker", "Programmer", "RSD", 00", "info@acadians.com");
empList[3 8] = new employee)
"Richini", "Barker", "Programmer", "RSD", 00", "info@acadians.com");
empList[39] = new employee)
'"Ricardo", "Bollinger", "Programmer", "RSD", 00", "info@aoadians.com");
empList[40] = new employee)
"Ron", "Bollinger", "Programmer", "RSD", 00", "info@acadians.com");
empList[41] = new employee)
"Ronald", "Barker", "Programmer", '"RSD", 00", "info@acadians.com");
empList[42] = new employee)
"Browser", "Tyler", "Programmer", "RSD", 00", "info@acadians.com");
empList[43] = new employee(
"Serf", "Tyler", "Programmer", "RSD", 00", "info@acadians.com");
empList[44] = new employee)
"Bill", "Tyler", "Programmer", "RSD", 00", "info@acadians.com");
empList[45] = new employee)
"William", "Srrdth", "Programmer", "RSD", 00", "info@acadians.com");
empList[46] = new employee)
"Billy", "Barker", "Programmer", "RSD", 00", "info@acadians.com");
empList[47] = new employee)
"Kurt", "Barker", "Programmer", "RSD", 00", "info@acadians.com");
¦empList[48] = new employee)
"John", "Barker", "Programmer", "RSD", 00", "info@acadians.com");
empList[4 9] = new employee)
"Jonathon", "Anderson", "Programmer", "RSD", 00", "info@acadians.com");
empList[50] = new employee)
"Frederick", "Barker", "Programmer", "RSD", 00", "infofiacadians.com");
empListfSl] = new employee)
"Smitty", "Tyler", "Programmer", "RSD", 00", "info@acadians.com");
empList[52J = new employee)
'"Sargent", "Anderson", "Programmer", "RSD", 00", "infoSacadians.com");
empList[53] = new employee)
"Pepe", "Potts", "Prograrrmer", "RSD", 00", "info@acadians.com");
empList[54] = new employee)
"Leo", "Godfrey", "Programmer", "RSD" , 00", "info@acadians.com");
empList[55] = new employee)
"Geo", "Stewart", "Programmer", "RSD" , 00", "info@acadians.com");
empList[56] = new employee)
"Meo", "Anderson", "Programmer", "RSD", 00', "info@acadians.com");
empl4ist[57] = new employee)
"Oeo", "Orefo", "Programmer", "RSD", 00", "info@acadians.com");
Технология обработки данных со стороны клиента
Глава 32
empList[58] = new employee(
"Jack", "Wagner", "Chief Entertainment Officer", "Exec", 00", "jwagner@acadians.com");
empList[59] = new employee (
"Brady", "Smith", "Programmer", "RSD", 00", "info@acadians.com");
empList[60] = new employee(
"Tristin", "Ryder", "Programmer", "RSD", 00", "info@acadians.com");
empList[61] = new employee(
'"James", "Tyler", "Programmer", "RSD", 00", "info@acadians.com");
empList[62] = new employee(
'"Charles", "Potts", "Programmer", "RSD", 00", "info@acadians.com");
empList[63] = new employee!
'"Bill", "Potts", "Senior Manager", "Management", 00", "info@acadians.com");
empList[64] = new employee (
"Bart", "Anderson", "Senior Manager", "Management", 00", "info@acadians.com");
empList[65] = new employee (
"Ian", "Potts", "Senior Manager", "Management", 00", "info@acadians.com");
empList[66] = new employee (
"Woody", "Smith", "Senior Manager", "Management", 00", "info@acadians.com");
empList[67] = new employee(
"Mark", "Tyler", "Senior Manager", "Management", 00", "info@acadians.com");
empList[6S] = new employee (
'"Andrew", "Driscoll", "Senior Manager", "Management", 00", "info@acadians.com");
empList[69] = new employee )
"Andy", "Potts", "Senior Manager", "Management", 00", "info@acadians.com");
empList[70] = new employee (
'"Dandy", "Driscoll", "Senior Manager", "Management", 00", "info@acadians.com");
empList[71] = new employee (
'"Candy", "Potts", "Senior Manager", "Management", 00", "info@acadians.com");
¦empList[72J = new employee (
"Spander", "Smith", "Senior Manager", "Management", 00", "info@acadians.com");
empList[73] = new employee (
"Landry", "Potts", "Senior Manager", "Management", 00", "info@acadians.com");
¦empList[74] = new employee (
"Permy", "Smith", "Senior Manager", "Management", 00", "info@acadians.com");
empList[75] = new employee (
"Jostin", "Driscoll", "Senior Manager", "Management", 00", "info@acadians.com");
empList[76] = new employee(
"Justin", "Ryder", "Senior Manager", "Management", 00", "info@acadians.com");
empList[77] = new employee)
"Braxel", "Anderson", "Senior Manager", "Management", 00", "info@acadians.com");
empList[78] = new employee(
"Opene", "Smith", "Senior Manager", "Management", 00", "info@acadians.com");
empList[79] = new employee)
"Juan", "Barker", "Senior Manager", "Management", 00", "info@acadians.com");
empList[80] = new employee(
"Julios", "Driscoll", "Senior Manager", "Management", 00", "info@acadians.com");
empLi:;t[81 ] = new employee!
"Andre", "Barker", "Senior Manager", "Management", 00", "info@acadians.com");
empList[82] = new employee)
"Bernard", "Smith", "Senior Manager", "Management", 00", "info@acadians.com");
empLii;t[83) = new employee)
"Susan", "Ryder", "Senior Manager", "Management", 00", "info@acadians.com");
empList[84] = new employee)
"Susanne", "Anderson", "Senior Manager", "Management", 00", "info@acadians.com");
empList[85] = new employee)
"Chelsey", "Barker", "Senior Manager", "Management", 00", "info@acadians.com");
empList[86] = new employee)
"Cosmo", "Krammer", "Senior Manager", "Management", 00", "info@acadians.com");
empList[87] = new employee)
"Kirby", "Tipple", "Senior Manager", "Management", 00", "in?o@acadians. com") ;
empLiiit[88j = new employee)
"George", "Allen", "Senior Manager", "Management", 00", "info@acadians.com");
empLi!it[89] = new employee)
"Boy", "Goeria", "Senior Manager", "Management", 00", "info@acadians.com");
empList[90] = new employee)
"Teddy", "Washington", "Senior Manager", "Management", 00", "info@acadians.com");
empList[91] = new employee)
"Tut", "Kingman", "Senior Manager", "Management", 00", "info@acadians.com");
14 1-158
Избранные программные технологии
¦1Часть V
empList[92] = new employee(
¦"Oil", "Larenzo", "Secretary", "Company", "800", "info@acadians.com");
empList[93] = new employee (
"Susie", "Que", "Secretary", "Company", "800", "info@acadians.com");
empList[94] = new employee (
"Trista", "Wagner", "Secretary", "Company", "800", "info@acadians.com");
empList[95] = new employee(
"Kimberly", "Smith", "Secretary", "Company", "800", "info@acadians.com");
empList[96] = new employee(
"Rachel", "McDonald", "Secretary", "Company", "800", "info@acadians.com");
empList[97] = new employee(
"Reena", "Smiles", "Secretary", "Company", "800", "info@acadians.com");
empList[98] = new employee)
"Treena", "Miles", "Secretary", "Company", "800", "info@acadians.com");
empList[99] = new employee(
'"Corrina", "Triles", "Secretary", "Company", "800", "info@acadians.com");
empList[100] = new employee!
"Rosemarie", "Barlington", "Secretary", "Company", "800", "info@acadians.com"
empList[101] = new employee (
1", "Plage", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[102] = new employee(
"Url", "Page", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[103] = new employee (
"Youri", "Basto", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[104] = new employee(
"Pri", "Opeo", "HR Manager", "Recruiting", "900", "info@acadians.com");
empList[105] = new employee)
"Tikki", "Rodrequez", "HR Manager", "Recruiting", "900", "info@acadians.com")
</script>
</head>
<frameset rows=S%,65%">
<frame src="searchfrm.html" name="searchForm" marginwidth=0"
marginheight=0">
<frajne name="resultForm" marginwidth=0" marginheight=0">
<noframes>
Sorry, your browser does not support frames.
</noframes>
< / frames e t >
<body>
</body>
</html>
Листинг 32.2 searchfrm.html
<htrol>
<head>
<title>Search Form</title>
<script language="JavaScript">
// Сетевая база данных по служащим
function doSearch() {
var searchField = "" ;
if (document, form. searchBy [0] .checked) {
searchField = "FirstName"; >
else {
if (document.form.searchByfl].checked) {
.searchField = "LastName"; )
else ( if (document.form.searchBy[2].checked) (
searchField = "Title"; )
else ( if (document.form.searchBy[3].checked) {
searchField = "Department"; }
Технология обработки данных со стороны клиента
Глава 32
if (document.form.searchByText.value = null || document. form.searchByText. value = "") {
alert ("Please enter your search criteria before continuing,"); }
else {
parent.findEmployee(searchField, document,form.searchByText.value) ;
function clearForm() {
parent.resultForm.do cument.open(> ;
parent, resultForm document, close ( ) ;
</scriptXhlXfont color="#000000"Xem>Intranet Employee Database</ernX/font>
</hl>
</head>
<hr>
<body bgcolor="#FFFFFF">
<form method="POST" name="form">
<pre>Search By: </pre>
<C prexinput
type=radio
name="searchBy"
value="FirstName">First Name <input
type=radio
checked
name=" searchBy"
value="LastName">Last Name <inpufc
type=radio
name=" searchBy "
value="Title">Title <input
type=radio
name="searchBy"
value="Department">Department</pre>
<pre>Text: <input
type=text
size=30
maxlength=3 0
name=" searchByText" xinput
type=button
size=20
name="findButton"
value=" Find "
onClick="doSearch() "Xinput
type=reset
name="Clear"
value=" Clear "
onClick="clearForm () "X/pre>
</form>
</body>
</html>
Резюме
Клиентские базы данных не могут служить в качестве
замены SQL-серверов, и они не являются средством вво-
ввода данных. Однако, несмотря на ограниченность диапа-
диапазона их применения, внедрение баз данных в JavaScript
приведет к расширению их возможностей и добавлению
новых способов уменьшения нагрузки на сервер. Кли-
Клиент может отвечать за поиск во всей базе данных и ви-
визуализацию результатов.
В главе рассматривались вопросы использования
клиентских данных в качестве баз данных. Массивы
JavaScript могут служить контейнерами баз данных,
поиск которых реализуется при помощи встроенных
конструкций языка JavaScript. Основа главы — практи-
практический пример, в котором применение таблицы клиен-
клиентской части стало идеальным вариантом.
Обработка ошибок
В ЭТОЙ ГЛАВЕ
Типы ошибок
Интерпретация сообщений об ошибках
Исправление кода
Тестирование кода
Программирование с использованием
устойчивых технологий
Надежная работа кода
Обработка ошибок, вообще говоря, представляет
собой комбинацию профилактического контроля (иден-
(идентификация и исправление ошибок перед выполнением),
пошагового контроля (идентификация ошибок в процес-
процессе выполнения) и корректирующего контроля (исправле-
(исправление ошибок, найденных во время выполнения). JavaScript
(или более точно — интерпретатор JavaScript, встроен-
встроенный в поддерживающие JavaScript браузеры), обеспечи-
обеспечивает автоматизированный пошаговый контроль ошибок
через диалоговые окна, отображающие информацию об
ошибках. Освоение нового инструмента создания и от-
отладки JavaScript-сценария помогает разработчику вос-
воспользоваться преимуществом более автоматизированного
профилактического и в меньшей степени — корректи-
корректирующего контроля. В главе рассматриваются методы
идентификации, исправления и тестирования JavaScript-
кода, а также методы записи устойчивого и удобного в.
сопровождении кода.
Типы ошибок
Ошибки JavaScript идентифицируются JavaScript-совме-
JavaScript-совместимым браузером сразу же после загрузки HTML-стра-
HTML-страницы. Эти ошибки можно разделить на три разных
типа:
Синтаксические ошибки
Ошибки времени выполнения
Логические ошибки
3ПРЕДОСГЕРЕЖЕНИЕ^Н^;, ' ,] _ ,/'*,.''
Интерпретатор JavaScript не идентифицирует логичес-
логические ошибки. Для идентификации потенциальных ошибок
в логике программы необходимо тестировать функци-
функциональные возможности кода. Например, выполнение
JavaScript-кода обязательно приведет к логической
¦ошибке при попытке выполнить арифметическое дей-
действие над строковой переменной (позже это описыва-
описывается более подробно; см. рис. 33.1).
Синтаксические ошибки
¦Синтаксические ошибки, т.е. некорректная запись кода,
часто связаны с банальными опечатками (не та буква,
пропуск знака пунктуации, незакрытые скобки). Сле-
Следующий пример демонстрирует несколько часто встре-
встречающихся синтаксических ошибок:
fuction errorProneO { // Слово "function"
// записано неверно
var i = о; // переменная инициализируется
// буквой "о" вместо числа "О"
for (i >= 0; I =< 10; i-t-t-) {
// переменная "I" не определена (должна
// использоваться строчная буква "i")
document, write ("The square of " + i \
11 is " + (i*i) + "<br>")
// пропущена " ;"
document.write ("The cube of " + i +
11 is ' + (i*i*i) + "<hr>") ;
// требовались двойные кавычки
li
у/ отсутствует закрывающая фигурная скобка,
J/ завершающая функцию
ПРЕДОСТЕРЕЖЕНИЕ, „ X', .
Язык JavaScript чувствителен к регистру, поэтому сле-
следует быть внимательным при преобразовании букв в
прописные. В частности, при использовании встроен-
встроенных объектов JavaScript (а также их свойств, методов
и событий) лучше убедится в точности синтаксиса с по-
помощью Java ScriptLanguageReferenceGuidef Справоч-
Справочник по языку JavaScript).
Синтаксические ошибки в JavaScript — самые час-
частые и самые простые в исправлении. JavaScript-интер-
Обработка ошибок
Глава 33
ЕШ
Претатор дает хороший результат по идентификации ис-
источника этих ошибок в коде, и для их исправления не
требуется ничего кроме простого редактирования.
ПРИМЕЧАНИЕ
Поскольку JavaScript имеет интерпретируемый харак-
характер и в настоящее время не предлагает средств от-
отладки синтаксиса, синтаксические ошибки идентифици-
идентифицируют, запуская код на выполнение — т.е. загружая
HTML-страницу, содержащую JavaScript, в JavaScript-
браузер.
г... .¦...¦...: .. .¦¦......:... ¦ .. "-¦¦¦-¦---¦»-
Ошибки времени выполнения
Ошибки времени выполнения возникают, если синтак-
синтаксически корректный оператор пытается выполнить за-
задачу, реализовать которую невозможно. К довольно-
таки обычным ошибкам времени выполнения относятся
недопустимые вызовы функций, несоответствие типов
данных, присваивание значения необъявленной пере-
переменной и арифметически некорректные операции (та-
(такие как деление на ноль).
Об ошибках времени выполнения браузер выдает
сообщение, аналогичное сообщениям о синтаксических
ошибках; однако, их исправление часто требует более
тщательного изучения кода. Следующий пример пока-
показывает ошибку времени выполнения программы, выз-
вызванную делением на ноль:
function mismatched() {
var i = 10;
for (i. <=10; i >= 0; i—) {
// этот цикл вызовет деление на ноль
// и результаты будут непредсказуемыми
document.write (i + " divided by twice its
square (" + (i*i*2) +¦¦)="+ (i/(i*i*2))
1
Логические ошибки
Логические ошибки происходят, когда приложение или
функция не исполняют то, на что ее ориентировали
пользователи или разработчики. Другими словами, при-
приложение, которое имеет синтаксически корректный код
и не содержит ошибок времени выполнения, но все еще
выдает некорректные результаты, содержит логические
ошибки. Логические ошибки — самый трудный для
идентификации и исправления тип ошибок. Они обыч-
обычно требуют серьезного тестирования приложения, ана-
анализа результатов и пересмотра всего проекта. Множество
логических ошибок возникает из-за плохого понимания
требований, некачественного проектирования и, как
результат — некорректного кода. Следующий пример
демонстрирует логическую ошибку, вызванную вычис-
вычислением несогласованных типов данных:
function mismatched () {
var Constant = 0";
var i = 10;
for (i <= 10; i > 0; i—
document.write(i + " +
' + (i + Constant) н
Constant
Как видно из рис. 33.1, отображаемые результаты
явно неправильны, даже при том, что код выполнился
успешно. В этом случае JavaScript вычисляет результат
выражения (i + Constant) как строку и выполняет кон-
конкатенацию двух операндов.
Is this correct?
10 + 10- 1010
9+10= i
8 + 10 810
7 + 10 710
6 + 10 = 610 '
5 + 10^510
4 + 10=410
3 + 10 = 310
2 + 10=210
1 + 10 = 110
:
^Ш«ИЯ
РИСУНОК 33.1.Логическая ошибка.
Интерпретация сообщений об ошибках
Как только браузер распознает ошибку (синтаксическую
или времени выполнения), он отображает большое ди-
диалоговое окно, как показано на рис. 33.2. Информация,
содержащаяся в таких диалоговых окнах, помогает
идентифицировать вероятный источник и расположе-
расположение ошибки. Диалоговое окно содержит следующую
информацию:
URL или имя файла, в котором произошла ошибка.
Номер строки в файле, где произошла ошибка. Это
порядковый номер строки от начала HTML- (или JS-)
файла, а не только JavaScript-кода. Не очень-то по-
полагайтесь на достоверность такой информации, по-
поскольку источник ошибки может находиться и в со-
совершенно другом месте.
• Описание ошибки. Вот это, как раз, ценная инфор-
информация в плане идентификации типа требуемого ис-
исправления.
Фактический код, содержащий ошибку. Эта инфор-
информация тоже не всегда будет надежной, т.к. источник
ошибки может находится и до этой строки.
Избранные программные технологии
Часть V
i Указатель места в строке, где произошла ошибка. На
эту информацию также нельзя слишком полагаться;
попытайтесь исследовать близлежащий код.
i missing }
t Err».
ok]
N
•i:\\nui'i2.JitnK line 16: ¦ ....
РИСУНОК 33.2. JavaScript-сообщение, уведомляющее о
синтаксической ошибке.
В табл. 33.1 приводится описание большинства ти-
типичных JavaScript-сообщений об ошибках и их возмож-
возможные причины.
Исправление кода
Даже при том, что сообщения об ошибках полезны для
идентификации многих ошибок программы, обычно
требуется проделать дополнительную поисковую рабо-
работу для исправления всех ошибок, особенно логических.
Этот раздел покажет, как упростить и систематизиро-
систематизировать поисковую работу подобного рода. В главе 34 бу-
будет обсуждаться использование отладчика JavaScript
компании Netscape.
Проверка кода HTML
Поскольку JavaScript обычно взаимодействует с HTML-
кодом, прежде всего необходимо удостовериться, что
файл не содержит ошибок HTML. Ниже приводится
список, который можно рассматривать в качестве руко-
руководства по нахождению таких ошибок:
Проверьте открывающие и закрывающие дескрипто-
дескрипторы <script>.
Проверьте атрибут language = "JavaScript" внутри
пары дескрипторов <script>.
Проверьте HTML-дескрипторы на предмет пропус-
пропусков или орфографических ошибок.
Проверьте угловые скобки (< >), открывающие и
закрывающие дескриптор.
Проверьте связанные пары дескрипторов (например,
<script>...</script>).
Проверьте корректность использования дескрипто-
дескрипторов HTML-комментариев (<! — ... — >), скрываю-
скрывающих JavaScript-сценарий.
• Удостоверьтесь, что имена форм и фреймов, вызы-
вызываемых в JavaScript-коде, соответствуют именам, оп-
определенным в HTML-файлах.
ПРВДОеТЕРЕЖЕНИЕ
Если требуется размещать JavaScript-код в пределах
HTML-таблицы, непомещайтедескрипторы<8спр?>во
внутренние ячейки таблицы (<td> ... </td>). Это —
известная ошибка JavaScript, которая обычно приводит
к зависанию браузера. Вместо этого разместите дес-
дескрипторы <script> внутри необходимыхопределений
строк таблицы (<fr> ... </tr>) и создайте определе-
определение HTML-ячеек (<td> ... </td>) с помощью мето-
метода document.writel).
Использование комментариев для
идентификации проблем
Можно воспользоваться комментариями для последова-
последовательного выделения различных строк (и функциональных
возможностей) кода, чтобы таким образом идентифици-
идентифицировать и установить источник ошибок. Это многошаго-
многошаговый процесс.
Таблица 33.1. Типичные JavaScript-сообщения об ошибках.
Сообщение об ошибке
Возможные причины
item is not defined
item is not a function
item cannot be converted to a function
item has no properties
item is not a numeric literal
'Unterminatedstring literal
missing ) after argument list (и
аналогичные сообщения об ошибках)
Названная переменная не определена. Имя переменной содержит
орфографические ошибки. Названная функция не определена. Незавершенная
строка (рассматривается JavaScript как неопределенная переменная).
Функция не определена. Функция с орфографической ошибкой. Перед
определением функции возникли другие ошибки.
Переменная ошибочно упоминается как вызываемая функция. Имя функции (или
метода встроенного объекта) содержит орфографическую ошибку.
Некорректная ссылка на свойство объекта. Некорректная ссылка на массив.
Переменная не содержит числовых данных. Перед присваиванием переменной
значения присутствуют другие ошибки.
Отсутствие кавычек (для строки). Строка содержит более 250 символов. Строка
содержит символ новой строки.
Пропущена круглая скобка, фигурная скобка или точка с запятой.
Обработка ошибок
В приведенном ниже списке указаны шаги, которые
потребуется предпринять:
Закомментируйте одну или большее количество
строк кода.
Сохраните код.
Перегрузите страницу в браузере.
• Запомните полученный эффект.
• Измените код или закомментируйте большее коли-
количество строк.
Повторяйте перечисленные шаги, пока не найдете
ошибку.
Использование метода alert() для
трассировки кода
Для идентификации некоторых ошибок времени выпол-
выполнения и большинства логических ошибок в коде нужно
уметь следовать за логикой кода и представлять, как он
обрабатывает данные. Многие средства отладки позво-
позволяют выполнять код пошагово, по одной строке в каж-
каждый момент времени, и в боковом окне (под названием
"окно отладки") просматривать результат выполнения
кода. Для моделирования такой среды отладки можно
воспользоваться JavaScript-методом alert(). Метод alert()
отображает диалоговое окно, которое можно легко
запрограммировать на показ различных полезных со-
сообщений и значений, помогающих последовательно
отслеживать выполнение кода. В главе 34 проводится
упражнение по отладке, использующее только методы
alert(). Рассмотрим некоторые способы применения
метода alert():
Используйте alert(" Starting Check") для идентифи-
идентификации отправной точки отладки. По мере выполне-
выполнения отладки его можно перемещать далее по коду.
¦• Используйте а1ег1()для отображения значений пере-
переменных, массивов и возвращений функций. С помо-
помощью простых тестовых сценариев можно быстро оп-
определить, соответствуют ли отображенные значения
ожидаемым.
• ИспользуйтеакгК) для отображения результатов вы-
выражений. Это особенно полезно для отслеживания
логических ошибок, поскольку причиной многих ло-
логических ошибок является некорректное использова-
использование выражений.
Тестирование кода
Глава 33
помощью JavaScript, — за исключением того, что ваше
"производство" — мирового масштаба со множеством
потенциальных пользователей и разными платформами.
С учетом всего этого для проверки JavaScript-кода нужно
использовать множество различных методов тестирова-
тестирования. Потребуется проделать некоторый (небольшой)
объем модификаций, дабы удовлетворить требования
мира JavaScript и Internet. JavaScript — язык програм-
программирования, приспособленный для создания сложных
приложений, поэтому, как и в случае традиционных
языков программирования, он требует надежного тес-
тестирования.
'ПРИМЕЧАНИЕ
Тестирование — это не то же самое, что отладка. Те-
Тестирование — это средство обнаружения ошибок. От-
Отладка — средство определения источника ошибок и ис-
исправления их.
Традиционное тестирование кода подразумевает, что
приложение готовится к производству. Эта концепция
¦будет верна и в том случае, когда речь идет о помеще-
помещении в Internet Web-страниц, усовершенствованных с
При тестировании кода обязательно следует предпо-
предполагать, что ошибки в программе присутствуют. Если
предположить, что ошибок в коде нет вообще, скорее
всего, ни одна ошибка не будет найдена! Практически,
даже наиболее полное тестирование никогда не сможет
доказать отсутствие ошибок (для подобного доказатель-
доказательства пришлось бы выполнить бесконечное количество
тестов); можно только доказать существование ошибок.
Для того чтобы упростить работу по тестированию
кода, стоит подготовить формальный план тестирова-
тестирования, который должен содержать как контрольный спи-
список (одностраничный список всех высокоуровневых
действий по тестированию), так и детальные тестовые
сценарии для проверки кода. Тестовые сценарии долж-
должны содержать список определенных и систематических
испытательных шагов, которые требуется выполнять в
приложении, а также ожидаемые результаты. При про-
проектировании тестовых сценариев необходимо учиты-
учитывать:
¦• Требования для приложения. Необходимо удостове-
удостовериться, что приложение удовлетворяет исходным
функциональным требованиям. Тестирование должно
включать также и получение ответа от пользователя
(или заказчика) о том, насколь точно функциональ-
функциональность приложения соответствует первоначальным
требованиям. Ответ пользователей относительно ос-
основной модели приложения поможет провести иден-
идентификацию и исправление многих логических оши-
ошибок, обусловленных выполнением не тех требований.
• Требования по дизайну. Необходимо удостоверится,
что приложение соответствует предложенному дизай-
дизайну. Это тестирование должно включать получение
ответа от дизайнеров приложения о том, насколь
точно приложение соответствует их проекту. Это те-
Избранные программные технологии
Часть v
стирование также может помочь идентифицировать
потенциальные недостатки проекта.
Шаблоны потоков данных. Необходимо проверить
корректность потока данных в системе, особенно ка-
касающихся дизайна. Это тестирование должно прове-
проверить целостность данных, обрабатываемых приложе-
приложением. Необходимо составить схему потока данных в
приложении от ввода до обработки для пошагового
отслеживания воздействий на данные.
Функции. Необходимо проверить каждую функцию
в приложении на предмет корректной реализации
функциональных возможностей. Это тестирование
должно проверять правильность функциональных
возможностей отдельных функций независимо от ос-
остальной части кода. Успех этого тестирования часто
зависит от того, насколько модульными (сосредото-
(сосредоточенными на одной цели, независимыми) являются
функции. (Модульное программирование рассматри-
рассматривается более подробно позже в этой главе, в разделе
"Написание модульного кода.")
Строки программы. Необходимо протестировать каж-
каждую строку приложения на предмет проверки кор-
корректной реализации функциональных возможностей.
Это может быть сделано путем пошагового прохода
по строкам программы и проверки результатов вы-
выполнения этих строк (для изоляции кода можно вос-
воспользоваться комментариями).
Плохие данные. Необходимо также проследить, как
приложение выполняется при получении плохих
данных (например, недостаточно данных, слишком
много данных, неправильный тип данных или раз-
размеры данных). Это тестирование должно также про-
проверять поведение приложения, когда требуемые или
необязательные данные отсутствуют (например, пу-
пустые поля ввода в форме). Тестирование должно
подтвердить существование методов обработки оши-
ошибок, справляющихся с такими ситуациями.
Краевой анализ. Необходимо проследить, как прило-
приложение исполняется при указании краевых данных,
циклов и итерационных вызовов функций. Это тес-
тестирование должно гарантировать, что приложение
будет правильно обрабатывать минимальные и мак-
максимальные значения переменных, а также что име-
имеется в наличии встроенный метод обработки ошибок
для значений, которые приложение не может обра-
обработать.
Наиболее частые значения. Необходимо проследить,
как приложение исполняется, когда получает инфор-
информацию, чаще всего вводимую пользователем. Это
тестирование должно гарантировать, что приложение
работает безупречно для обычных данных, поскольку
его неудачная работа затронет большинство пользо-
пользователей.
Наиболее частые ошибки. Проверьте, что наиболее
частые или выявленные ранее ошибки исправлены.
Тестирование должно гарантировать, что ошибки,
исправленные ранее, в дальнейшем не возникнут
снова в более поздней версии кода. Самая вероят-
вероятная причина такого типа ошибок — плохое управле-
управление изменениями (или управление версиями), что
может потребовать последующих тестирований этих
процедур с целью идентификации и исправления
ошибок.
• Различные платформы. Протестируйте приложение
на различных аппаратных и программных платфор-
платформах. В Internet присутствует огромное число пользо-
пользователей, работающих с различными аппаратными
(такими как Intel, Macintosh и Sun) и операционны-
операционными системами (Windows 95, Windows 98, Windows
NT и разновидности UNIX и Linux). Создаваемый
код лучше протестировать на как можно большем ко-
количестве различных платформ, чтобы хорошо пони-
понимать его поведение и, в случае необходимости, из-
изменять его.
¦• Минимальные конфигурации. Протестируйте прило-
приложение на клиентских рабочих станциях с минималь-
минимальными конфигурациями. Напомним, что пользовате-
пользователи располагают различными ресурсами. Необходимо
выяснить, какое количество требований приложение
предъявляет машине клиента (например, в терминах
мощности обработки, памяти, пропускной способно-
способности). Это поможет понять, какой должна быть ми-
минимальная конфигурация аппаратной и программной
платформы, на которой данное приложение будет
выполняться успешно. Тестирование должно вклю-
включать проверку выполнения кода для рекомендуемых
минимальных конфигураций, а также обработку
ошибокдля пользователей, имеющих конфигурацию
меньше минимальной.
• Различные браузеры. Протестируйте приложение в
различных браузерах, поддерживающих JavaScript.
Это тестирование поможет увидеть обработку со-
созданного кода различными браузерами, а также со-
совместимость кода. Если совместимость кода отсут-
отсутствует, можно либо изменить существующий код
либо написать дополнительный код обработки оши-
ошибок.
¦• Совместимость HTML со старыми браузерами. Не-
Необходимо гарантировать, что HTML-файл сможет
читаться в старых (неподдерживающих JavaScript)
браузерах. Проверьте работу кода в текстовых или
старых браузерах, чтобы выяснить, как отсутствие
JavaScript повлияет на пользовательскую среду —
Обработка ошибок
например, браузер может подвиснуть или войти в
аварийный режим, или страница может просто не
загрузиться. Проверьте, доступен ли альтернативный
путь чтения содержимого сайта и насколь он эффек-
эффективен и надежен.
В многих случаях из-за требований наличия определен-
определенных функциональных возможностей имеет смысл со-
сознательно проектировать и реализовывать сайт для
браузеровопределенногобазового(ил и минимально-
минимального) уровня. Например, можно потребовать, чтобы
пользователь имел по крайней мере Navigator 4.7 или
Internet Explorer 4.0 для эффективной работы с при-
приложением. В таком случае необходимо сообщить
пользователям об этих требованиях до того, как они
зайдут на сайт, и предоставить гиперссылки на стра-
страницы, где они смогут выгрузить соответствующие бра-
браузеры. Альтернативное решение — можно написать
JavaScript-сценарий для выяснения типа браузера, и
если он не соответствует минимальным требованиям,
отображать предупреждающее сообщение либо авто-
автоматически отсылать пользователя к соответствующе-
соответствующему сайту загрузки браузера. В главах 26 и 27 можно
найти более подробную информацию о таких JavaScript-
кодах .
• Перегрузка. Проверьте поведение приложения при
перезагрузке HTML-страницы. Это тестирование
должно подтвердить, что при перезагрузке код ведет
себя правильно. Если перезагрузка воздействует на
код, то тестирование должно подтвердить существо-
существование кода обработки ошибок и команд, помогаю-
помогающих пользователю избежать проблем.
• Изменение размеров. Проверьте поведение приложе-
приложения при изменении размеров окна браузера. Это те-
тестирование должно подтвердить, что при изменении
размеров код ведет себя правильно. Если это изме-
изменение воздействует на код, то тестирование должно
подтвердить существование кода обработки ошибок
и команд, помогающих пользователю избежать про-
проблем.
.ПРИМЕЧАНИЕ ' :;': V <:,-,... Х'ТХ*?Л'Г *.-¦¦ '"''" '-к^
При изменении размеров окна Netscape Navigator
текущая Web-страница перегружается. Microsoft
Internet Explorer только изменяет размеры окна без
перегрузки текущей Web-страницы.
Испытания в утяжеленном режиме (стресс-тест).
Проверьте поведение приложения в момент, когда
им пользуются сразу много людей. Это тестирование
можно провести при наличии нескольких пользова-
пользователей, выполняющих данный код, следуя определен-
определенному и детально разработанному сценарию, либо за
Глава 33
счет применения некоторой автоматической пуско-
пусковой возможности. Необходимо выполнить монито-
мониторинг, запись и анализ результатов всех испытаний (в
том числе время ответов и сбои поведения). Необхо-
Необходимо также выяснить, как тестируемый код влияет
на остальную часть сайта. В случае необходимости
измените код и проведите повторное тестирование.
Потеря связи. Проверьте поведение приложения в
момент сбоя Internet-соединения либо остановки заг-
загрузки страницы. Пользователи обычно теряют связь
с сайтом или вручную останавливают передачу дан-
данных. Код должен при необходимости изящно справ-
справляться с этим (избегая подвисания браузера и его
аварийного завершения). Проверьте наличие соответ-
соответствующих функциональных возможностей.
С0ВЕТ "" ' .;':'„Д;*л..' V,-*,i/. ,. .*„....' #J
Netscape Navigator имеет встроенный URL, который
можно использовать для быстрой проверки строк
JavaScript-кода. В окне URL браузера Navigator введите
javascript*, код на JavaScript, (mocha: кол на JavaScript
выполняет аналогичный тест.)
Например, при вводе javascript: alert|"Hello World!")
в диалоговом окне alertП отображается строка Hello
World.
Программирование с использованием
устойчивых технологий
Как и любые другие программисты, авторы JavaScript-
кодов могут извлечь большую пользу из изучения и
использования при написании кода приложений устой-
устойчивых технологий программирования. Даже при том,
что JavaScript все еще слишком молод, чтобы иметь
богатый собственный материал по упомянутым техно-
технологиям, можно воспользоваться хорошим набором об-
общих рекомендаций, существующим в других (особенно
объектно-ориентированных) языках программирования.
Следующий список показывает некоторые из методов,,
адаптированных под JavaScript:
• Высокоуровневая разработка кода проекта и деталь-
детальное проектирование.
• Написание модульного кода.
• Написание сильно связанного кода.
Написание слабо связанного кода.
Написание повторно используемого кода.
Написание кода обработки ошибок.
• Использование жестких соглашений по именованию.
Использование комментариев.
• Объявление и инициализация переменных.
Избранные программные технологии
Часть V
Каждый из перечисленных методов кратко объясня-
объясняется в следующих разделах. Однако, не следует забы-
забывать, что последовательное выполнение таких методов
требует подробного изучения, не только из-за уровня
требуемой дисциплины, но также и для того, чтобы
избавиться от некоторых плохих привычек и взамен
приобрести хорошие привычки!
Высокоуровневая разработка кода проекта
и детальное проектирование
Это первый шаг на пути создания качественного кода.
Высокоуровневая разработка поможет идентифициро-
идентифицировать типы функциональных возможностей, требуемых
для различных функций приложения. Детальное про-
проектирование поможет идентифицировать и вызвать от-
отдельные функции и составить схемы их процессов.
Хороший детальный проект (особенно, если он на-
написан на псевдокоде) можно без особых трудностей преоб-
преобразовать в код и комментарии. Необходимо по крайней
мере уметь записывать объявления функций и перемен-
переменных непосредственно из проекта. Кроме того, следует
уметь итеративно разбивать оставшуюся часть детально-
детального проекта на подразделы и преобразовывать каждый из
этих подразделов в код.
Написание модульного кода
Написание мбдульного кода означает разделение при-
приложения на несколько отдельных функций (или моду-
модулей), где каждая функция исполняет только одну зада-
задачу и связывается с другими функциями с помощью
вызовов. Такое модульное кодирование выгоднее по
следующим соображениям:
• Уменьшение сложности. Каждый модуль сосредото-
сосредоточен только на одной задаче, следовательно, большин-
большинство модулей остаются простыми.
¦• Уменьшение дублирования. Если один и тот же тип
функциональных возможностей требуется в несколь-
нескольких местах, соответствующий код будет написан
только один раз (в функции).
• Уменьшение степени влияния изменений. Можно из-
изменять часто используемые функциональные воз-
возможности только в одном месте (в функции, где они
постоянно содержатся) вместо изменений в несколь-
нескольких местах.
• Увеличение степени сокрытия процесса. Детали вы-
выполнения функций скрываются от других функций.
Это означает, что можно изменять способ работы
функции без изменения остальной части кода (под-
(поддерживая один и тот же интерфейс функции).
Увеличение степени повторного использования кода.
Можно повторно использовать отдельные функции
в других программах, требующих того же типа фун-
функциональных возможностей.
• Улучшение удобочитаемости. Модульное програм-
программирование приводит к более простым и совершен-
совершенным компонентам, которые, в свою очередь, делают
программу более удобочитаемой и легко сопровож-
сопровождаемой.
Написание сильно связанного кода
Связность зависит от того, насколь близкими являются
задачи функции. Сильно связанный код означает, что
функция почти полностью ориентирована на достиже-
достижения одной цели. Она должна достигать только одной
цели и делать это хорошо. Пример такой функции —
Math.S(pt(value). Эта функция просто вычисляет квад-
квадратный корень значения, которое получает в качестве
аргумента, и возвращает результат.
Сильная связность ведет к высокой надежности,
поскольку выполняемые задачи каждой функции очень
узко определены, а количество этих задач — очень ог-
ограничено.
Написание слабо связанного кода
Связность зависит от того, насколь близко соотносятся
две функции. Слабо связанный код означает, что отно-
отношения между двумя функциями слабые, видимые и
прямые. Это обеспечивает для любой функции возмож-
возможность вызова другой функции, и при этом независи-
независимость от другой в реализации своих собственных фун-
функциональных возможностей.
Написание повторно используемого кода
Модульное программирование помогает в создании по-
повторно используемого кода. По сути дела, этот код (или
функцию) можно включать в любой другой код с целью
обеспечения тех же функциональных возможностей.
Написание подобного рода кода дает множество выгод:
Высокая надежность. Повторно используемые фун-
функции доказаны и проверены множество раз.
• Низкая стоимость. Не возникает потребности в реа-
реализации новой функции.
Мобильность. Можно легко сделать код доступным
для других платформ.
Сокрытие информации. Внутренние операции кода
скрыты от вызывающих объектов.
Написание кода обработки ошибок
Качественная программа должна быть способна не толь-
только предвидеть необычные и ошибочные события (на-
(например, некорректные данные, необычное поведение
пользователя или прерывание передачи), но также и
справляться с ними как можно более изящно. Это тот
Обработка ошибок
Глава 33
случай, когда хорошо написанный код обработки оши-
ошибок становится жизненно важной проблемой. Обработ-
Обработка ошибок должна быть встроена в код и выполнять, по
крайней мере, некоторые из перечисленных ниже задач:
¦ • Проверять значения всех вводимых данных из вне-
внешних источников. Необходимо проверить правиль-
правильность данных, включая типы, диапазон значений и
завершенность ввода. Если здесь происходит ошиб-
ошибка, программа должна сбросить текущие данные и
запросить отправку новых.
Проверять значения всех параметров функций. Не-
Необходимо проверять правильность данных, получен-
полученных из других функций. В случае ошибки получаю-
получающая функция должна сбросить ошибочные данные и
отправить новый запрос к передающей функции.
• Выполнять обработку исключений. Исключения дол-
должны замечаться программой и регистрироваться в
протоколе исключений. Если решение конкретного
исключения не существует, функция должна краси-
красиво завершиться.
Проверять другие важные ошибки. По возможности,
код обработки ошибок должен предотвращать появ-
появление ошибок.
• Выполнять изящное завершение. Если сбои кода или
пользователь остановят передачу файла до того, как
страница полностью загрузится, браузер должен ос-
остаться в рабочем состоянии (т.е., он не должен за-
зависнуть или аварийно завершиться). Это можно сде-
сделать, написав подпрограмму обработки ошибок,
проверяющую, загружена ли страница успешно, или
же открывая новое окно браузера для приложения,
чтобы в случае возникновения аварийной ситуации
она затронула бы только его собственное окно.
Использование жестких соглашений по
именованию
Использование жестких соглашений по именованию
означает применение соответствующих, согласованных
и значимых имен для всех объявлений (например, объяв-
объявлений объектов, свойств, методов и переменных) в коде.
Жесткие соглашения по именованию помогают упрос-
упростить сопровождение кода, улучшить удобочитаемость,
увеличить ясность кода и устранить рост числа конф-
конфликтующих имен (когда тот же самый объект вызыва-
вызывается с помощью двух разных имен).
В коде можно использовать множество способов раз-
разработки жесткого соглашения по именованию. Ниже
приведен список того, что лучше отчетливо выделить в
коде:
Глобальные переменные
¦• Локальные переменные
• Поименованные константы
¦• Имена функций
¦• Аргументы функций
совет ' '"./ '-' '-''", V- '/ ;, ;:
Используйте отформатированные составные слова для
расширения смысла и удобочитаемости имен. Напри-
Например, воспользуйтесь MaximumWeight = 200 для пере-
переменной или findHeightlnMeters(Height) {... — для фун-
функции.
Использование комментариев
Комментарии могут оказаться очень эффективной фор-
формой связи исходного кода, написанного программистом,
с остальной частью мира, в том числе и с другими про-
программистами, которые, возможно, будут поддерживать
код позже. Насколько хороший комментарий увеличи-
увеличивает удобочитаемость программы, настолько же плохой
комментарий может мешать и вводить в заблуждение.
Для написания полезных комментариев требуется осто-
осторожность и внимание. Ниже приводятся некоторые ре-
рекомендации для написания хороших комментариев:
• Поместите в комментарии важную информацию о
программе с выходными данными (например, авто-
автором, датой последней модификации, целью функций
и последних изменениях). Они могут оказаться един-
единственным доступным или актуальным источником
документации.
Напишите комментарии о коде, который трудно по-
понять с ходу. Комментарии должны добавить смысл,
чтобы пользователь понял больше, чем уже очевид-
очевидное. .
Напишите комментарии о предназначении кода,
объясняющие, почему что-то делается. Это означает,
что комментарии следует помещать в соответствую-
соответствующие места (например, перед или после строки про-
программы) для объяснений целей и способов работы
кода.
¦ • Напишите комментарий по глобальным переменным.
Что они содержат? Когда они были изменены?
¦• Напишите комментарий для нетривиальной или за-
запутанной части кода. Что она делает? Почему ис-
используется?
¦• Помните, что те, кто будет загружать данную Web-
страницу, могут увидеть JavaScript-комментарии,
просто в браузере просматривая исходный код HTML,,
так что не стоит помещать в JavaScript-комментариях
информацию, не предназначенную для чужих глаз.
Избранные программные технологии
Часть V
Объявление и инициализация переменных
Несмотря на то что JavaScript позволяет использовать
необъявленные и неинициализированные переменные в
коде, хорошая практика программирования предпола-
предполагает последовательное объявление и инициализацию
переменных. Объявление переменных в одном общем
для всех месте (обьгано в начале функциональной или
глобальной области) делает отслеживание и поддержа-
поддержание их относительно простым делом. Инициализация
переменных гарантирует, что переменные содержат
корректный тип данных в любом месте программы.
(Например, если var Counter = 0;, это значит, что пе-
переменная Counter имеет числовой тип данных.)
Не используйте в качестве имен переменных зарезер-
зарезервированные ключевые слова JavaScript — это приводит
к ошибкам. Загляните в справочник по JavaScript для
выяснения списка зарезервированных ключевых слов.
Надежная работа кода
JavaScript, подобно другим языкам программирования,
имеет свои нюансы — включая ошибки языка, неясные
особенности и странное поведение — которые потребу-
потребуется изучить перед написанием действительно устойчи-
устойчивого кода. Необходимо также знать различия между
реализацией JavaScript в Netscape Navigator и JScript
(реализация JavaScript от Microsoft) в Microsoft Internet
Explorer. Даже при том, что они в основном идентич-
идентичны, каждая из них обладает такими функциональными
возможностями, которыми не обладает другая. Вместо
того чтобы исписывать страницу за страницей, внося в
список ошибки, туманные особенности и странные
моменты поведения различных браузеров только для
того, чтобы выяснить, что они были установлены в
последней версии кода, стоит лишь подчеркнуть, что
JavaScript (и, следовательно, JScript) — все еще разви-
развивающийся язык. Это означает, что нужно знать уровень
браузера(ов), которые выбираются для обеспечения
базовых (или минимальных) требований к сайту, а так-
также отличия этих браузеров от других версий.
Для получения списка последних наиболее извест-
известных ошибок JavaScript и методики их обработки мож-
можно посетить страницу Netscape JavaScript Known Bugs no
адресу http://developer.netscape.com/support/bugs/
known/.
Актуальная информация по JScript находится на страни-
странице Scripting Technologies по адресу http://nisdn.inicrosoft.coni/
scripting/default. htm?/scripting/jscript/.
В случае если необходимая информация не найде-
найдена ни на одном из упомянутых сайтов, стоит поучаство-
поучаствовать в конференциях, посвященных JavaScript (напри-
(например, в телеконференции comp.Iang.javascript в Usenet).
Наконец, чтобы значительно повысить шансы на хоро-
хорошее написание кода, работающего в обоих браузерах,
следует убедиться, что код протестирован в обоих бра-
браузерах и не использует такой JavaScript-код, который
работает в одном браузере и не работает в другом.
Резюме
Глава была посвящена анализу трех типов ошибок Java-
JavaScript (синтаксические, ошибки времени выполнения и
логические) и представила стандартные JavaScript-сооб-
JavaScript-сообщения об ошибках, а также об их возможных причинах.
Кроме того, рассматривались способы исправления
кода и идентификации ошибок. Также обсуждался си-
систематизированный подход к тестированию кода, состо-
состоящий из плана тестирования и детализации тестовых
сценариев, а также определенные пункты создания сце-
сценариев тестирования.
Были продемонстрированы способы формирования
и предварительного контроля кода (с целью уменьше-
уменьшения времени на отладку) с апробированными методами
реализации устойчивого и удобочитаемого кода. Эти
методы в конечном счете помогают сохранить многие
часы рабочего времени и качественнее спроектировать
код.
В заключение в главе были кратко представлены
некоторые из последних ошибок JavaScript и способы
их обработки, обеспечивающие надежное функциони-
функционирование кода.
Отладка
В ЭТОЙ ГЛАВЕ
Использование отладчика сценариев Microsoft
Использование JavaScript-отладчика Netscape
Использование метода alert()
Хотя отладку исходного кода зачастую не относят к
элементам программирования, ее можно назвать базо-
базовым элементом создания приложений в любом языке
программирования. Не исключением является и JavaScript.
Теперь, когда JavaScript нашел свое место в семей-
семействе кодов, мы, наконец, получили среду со всесторон-
всесторонней поддержкой средств написания и отладки сценариев,
аналогичную таковой в зрелых языках программирова-
программирования (C++, Visual Basic и Java). Эти инструментальные
средства можно отнести к следующим трем категориям:
Инструменты интегрированной среды разработки
(Integrated Development Environment — IDE). Они
помогают быстро создавать функциональные и дина-
динамические Web-сайты, в том числе страницы, исполь-
использующие JavaScript.
• Инструменты написания JavaScript-сценариев. Они
помогают более эффективно разрабатывать страни-
страницы с JavaScript с помощью интуитивно понятного
визуального интерфейса и технологий редактирова-
редактирования. Примером такого инструмента может служить
Infuse Acadia.
• Инструменты отладки JavaScript-сценариев. Они по-
помогают более эффективно выполнять отладку, ис-
исправление и тестирование кода с использованием
графического интерфейса и стандартных методов от-
отладки (типа точек останова и пошагового выполне-
выполнения). Примером такого инструмента может служить
JavaScript Debugger от Netscape.
Появление новых инструментов создания и отладки
JavaScript-сценариев обеспечивают разработчикам воз-
возможность пользоваться преимуществами более автома-
автоматизированных предварительных и (в меньшей степени)
корректирующих средств контроля. Если доступ к
JavaScript-средствам отладки отсутствует, либо объем
работы по отладке достаточно невелик, то в качестве
средства отладки можно применять простое сигнальное
окно JavaScript. В этой главе рассматриваются три дос-
доступных варианта отладки JavaScript-кода, которые все-
всегда имеются в распоряжении.
Использование отладчика сценариев
Microsoft
Отладчик сценариев Microsoft (Microsoft Script Debugger,
MSSD) — свободно выгружаемое средство отладки сце-
сценариев, которое работает как интегрированная часть
Internet Explorer (в версиях 3.01 и выше). MSSD можно
использовать для написания и, что более важно, для
отладки кода JavaScript (JScript в исполнении Microsoft)
или Visual Basic Script (VBScript). Преимущество MSSD
заключается в его в способности обрабатывать требова-
требования отладки ActiveX, Java, JScript и VBScript. (MSSD
можно выгрузить из сайта http://msdn.microsoft.com/
scripting/.)
Обзор возможностей отладчика сценариев
Microsoft
Ниже приведены основные возможности отладчика сце-
сценариев Microsoft:
• Динамическое представление структуры HTML. Как
видно из рис. 4.1, MSSD позволяет рассматривать
полную структуру страницы в окне Project Explorer, a
отдельные HTML-файлы (например, для фреймов) -
в специально выделенных окнах.
• Многоязыковая интеграция. Можно выполнять от-
отладку JavaScript, VBScript и Java в одном и том же
документе.
Избранные программные технологии
Часть V
F.<i-m:.
П?Г : .¦:.:¦¦¦¦•;/:.:¦:; ; .- ..: Ш
'Ш '.'¦'¦¦ ¦¦¦¦: ¦:¦¦¦¦¦¦¦ ¦¦ ¦¦¦:¦.:.¦ ..-.._ :¦:. . ¦ •: •¦• . ^й!
-' --'I ¦.•.4-:.;,:a,::.!--,:~:L,i.:.ii. ib-.Ji;, : ii '.i : V:,.. .,. - .ДЙ8ЯВДИ1ИМ|Д1М
РИСУНОК 34.1. Просмотр HTML-файлов в отладчике
сценариев Microsoft.
• Выделение цветом синтаксиса. MSSD отображает код
со стандартными цветами отладки, что помогает луч-
лучше идентифицировать состав кода и упрощает про-
процесс отладки.
Точки останова. Можно проставлять точки останова
в любых местах сценария, обеспечивая останов вы-
выполнения отладки.
• Пошаговое выполнение кода. MSSD позволяет поша-
пошагово (с паузами после каждого шага) выполнять код —
по одной строке на каждом шаге.
• Пошаговое выполнение блоков кода. Позволяет по-
пошагово выполнять код, но при этом процедуры вы-
вызываются как один модуль (без пошагового выполне-
выполнения кода внутри них), и переходить к следующему
оператору.
• Пошаговое выполнение кода внутри блоков. В отли-
отличие от пошагового выполнения блоков кода, здесь
выполняются остающиеся строки (начиная от точки
выполнения) вызванной процедуры, и затем про-
программа переходит на следующий после вызова дан-
данной процедуры оператор.
• Интегрированный стек вызовов. MSSD интегрирует
стеки вызс IB (как VBScript, так и Script) в коде в
один стек вызовов.
• Окно непосредственного выполнения выражений.
Это окно позволяет быстро вычислять выражение в
пределах стека вызовов либо тестировать новый код.
Окно отображает результат выполнения строки про-
программы.
Использование отладчика сценариев
Microsoft для отладки файлов
В этом разделе пошагово демонстрируется пример се-
сеанса отладки в MSSD. В течение этого сеанса макси-
максимальное внимание будет уделяться возможностям MSSD
и их применению, и в меньшей степени — содержимо-
содержимому и функциональности примера. Предполагается, что
в качестве браузера используется Microsoft Internet
Explorer (версии 3.01 и выше), а также наличие установ-
установленного MSSD.
Запуск отладчика сценариев Microsoft
Единственный способ запуска MSSD предполагает пер-
первоначальное открытие Internet Explorer и загрузку в него
необходимого исходного HTML-файла. Затем можно
активизировать MSSD, выбрав View ' Source (Вид -»
Источник).
ПРИМЕЧАНИЕ :
Если MSSD не установлен, то выбор View -
откроет исходный файл в редакторе Notepad.
Для запуска процесса отладки выберите Edit Break
at Next Statement (Правка • Останов на следующем
операторе) в Internet Explorer (или же Debug > Break at
Next Statement (Отладка • Останов на следующем опе-
операторе) в MSSD) и запустите сценарий. Отладчик за-
запускается и останавливается на первом операторе теку-
текущего сценария.
Использование команды "Break at Next Statement
Команда "Break at Next Statement" (которая присутствует
в опции "Script Debugger" меню "View" (Вид) в [i
Explorer и меню "Debug" (Отладка) в MSSD) аналогич-
аналогична команде выполнения шага (при которой отладчик
выполняет один оператор в сценарии и затем останав-
останавливается), за исключением того, что ее можно также
использовать без запуска сценария.
Это важная особенность отладки MSSD, поскольку
'большое количество JavaScript-кода обычно объявляет-
объявляется в разделе заголовка (или <HEAD>) HTML-файла, и
эта команда представляет собой единственный способ
отладки такого кода. Так происходит потому, что код в
заголовочном раздела файла к моменту загрузки HTML-
файла уже выполнен (вспомните, что JavaScript — ин-
интерпретируемый язык). Кроме того, любой набор точек
останова, загруженных после HTML-файла, при пере-
перегрузке страницы теряется.
Вычисление выражений
Выражение можно вычислить в окне непосредственно-
непосредственного вычисления (окно Im •} MSSD, а также с ис-
использованием следующих двух методов:
• Debug.write(string). Этот метод записывает указан-
указанную строку (обычно значение переменной) в окно
Immediate без пробелов и символов новой строки
между строками.
Отладка
• Debug.writeln([string]). Этот метод идентичен преды-
предыдущему за исключением того, что после каждой
строки вставляется символ новой строки. Аргумент
строки здесь необязателен. Если он не указан, в окно
Immediate записывается только символ новой стро-
строки.
На рис. 34.2 показан пример использования окна
Immediate для вычисления выражений (или значений
переменных).
РИСУНОК 34.2. Использование окна Immediate для вычисления
выражений.
Разбор примера
Для более четкого понимания возможностей MSSD необ-
необходимо попрактиковаться в использовании его для от-
отладки кода. Следующее упражнение дает хорошую от-
ную точку для такой тренировки:
Откройте Internet Explorer.
2. Выберите Edit > Break at Next Statement.
3. Откройте HTML-файл, приведенный в листинге
34.1. Для этого можно набрать его URL, перетащить
файл в окно браузера либо воспользоваться пунктом
меню File -» Open. В этом файле потребуется заме-
заменить имена WAV-файлов на имена и пути звуковых
файлов, доступных в вашей системе:
Листинг 34.1. Использование JavaScript-события для
воспроизведения звука.
<html>
<head>
<title>Sound on JS events</title>
<script language="javascript">
<! - - Скрыть код от старых браузеров
function playSound(sfile) {
// Загрузка и воспроизведение звукового файла
window.location, href=sfile;
Глава 34
// Конец сокрытия —>
</script>
<body onLoad="playSound('Type.wav');"
onUnLoad="playSound('Glass.wav');">
<font size=+2>Sounds on JS Events</font>
<br>
<hr>
The following are example of JS event handlers
used to play sounds.
<hr>
<a href="#" onClick="playSound('Cashreg.wav');">
Click here for sound</a>
<brxbr>
<form name="forml">
<input type="button" value="Press Button to
play a sound"
onClick="playSound('Gunshot.wav');">
</form>
</body>
</html>
4. Когда файл открыт, активизируется MSSD, и пос-
после выполнения первого оператора происходит оста-
останов, как показано на рис. 34.3.
РИСУНОК 34.3. Останов MSSD после чтения первого
оператора.
5. Теперь можно пошагово проходить код, чтобы уви-
увидеть последовательность действий программы. Для
пошагового прохождения кода используются пик-
пиктограммы инструментальной панели Step Into, Step
Over и Step Out. Рис. 34.4 показывает следующую
строку программы, которая выполняется при нажа-
нажатии на кнопку "Step Into".
СОВЕТ
Названия пиктограмм инструментальной панели MSSD
можно увидеть, поместив на них курсор мыши и не
выполняя щелчок одну-две секунды. Более детальное
описание всех пиктограмм и возможностей MSSD на-
находится в справочной системе.
- . . ... . : ,н ; ...
6. После перехода (возможно, при помощи пиктограм-
пиктограммы Continue) к завершению вызова события onLoad,
Избранные программные технологии
Часть V
можно будет услышать звуковой файл, который за-
запустит система (если компьютер имеет соответству-
соответствующие аудиовозможности). Возможно, потребуется
явно разрешить браузеру открывать звуковой файл,
в зависимости от конфигурации Internet Explorer.
Эта мера принимается для защиты от открытия не-
неизвестного и потенциально опасного (содержащего
вирус) не-НТМЬ-файла. На рис. 34.5 показан файл
после его полной загрузки в браузер.
РИСУНОК 34.4. Прохождение кода с использованием
пиктограмм инструментальной панели MSSD.
3 are ехв
РИСУНОК 34.5. Результат загрузки кода излистинга 34.1.
7. Выберите Edit * Break at Next Statement для оста-
останова выполнения кода после следующего операто-
оператора. Щелкните на кнопке Press a Button to Play a Song
на HTML-странице. Отладчик остановится на обра-
обработчике событий onClick. Можно теперь отслежи-
отслеживать вызовы процедур, открыв окно Call Stack (Стек
вызовов), как показано на рис. 34.6, и пошагово
выполняя код.
. Можно также просматривать значения выражений
или строк программы (не пустых и не строк ком-
комментариев) в окне Immediate:
1. Щелкните из MSSD внутри функции playSound
в коде (это первая функция, объявленная в заго-
заголовке).
2. Если попытаться напечатать что-нибудь внутри
функции, MSSD отобразит панель с вопросом,
потребуется редактировать документ. Щелкните
на Yes и напечатайте Debug.writeln (sfile); прямо
перед фигурной скобкой (}), закрывающей фун-
функцию.
3. Сохраните отредактированный файл, используя
File Save (Файл Сохранить) (или нажав на
пиктограмму Save в инструментальной панели).
РИСУНОК 34.6. Использование окна Call Stack для
отображения активных вызовов процедур.
4. Можно также проставить вручную точку остано-
останова в строке Debug. Нажмите F9 для установки
(или снятия) точки останова. (Строка точки ос-
останова выделяется красным цветом и слева от нее
проставляется красная точка.)
5. Теперь переключитесь на браузер и обновите (пе-
(перегрузите) HTML-файл. (Помните, что в таком
случае набор точек останова теряется, поэтому,
если требуется остановить код на определенной
строке, нажмите F9 для добавления точки оста-
останова в MSSD.)
9. Когда файл начнет выполняться, откройте окно
Immediate в MSSD для визуализации текущего со-
содержания выражения Debug. Если продолжить по-
пошаговое прохождение кода, можно заметить, что
содержимое окна Immediate модифицируется каж-
каждый раз при вызове функции Debug.writeln (см. рис.
34.7).
РИСУНОК 34.7. Использование MemodaDebug.\mte\nu
вычисление выражения в окне Immediate.
Заключительные слова об отладчике
сценариев Microsoft
Отладчик сценариев Microsoft обеспечивает полезную
среду для автоматизированного выполнения отладки и
тестирования JavaScript-кода. Инструменты MSSD очень
похожи на инструменты, которые обычно присутству-
присутствуют в средах зрелых языков программирования, таких как
Visual Basic и C++. К тому же, интерфейс, установка и
инсталляция MSSD являются интуитивно понятными
и дружественными к пользователю.
Однако, MSSD обладает и некоторыми ограничени-
ограничениями, например, в процессе отладки требуется часто
переключаться между Internet Explorer и MSSD, и нет
возможности вывода печать исходного кода. Если необ-
необходимо большее количество функциональных возмож-
возможностей, чем может предложить MSSD, обратитесь к
Microsoft Visual InterDev 6.0. Эта программа реализует
все перечисленные здесь возможности отладки сценари-
сценариев плюс зрелую среду для Web-разработки.
Наконец, MSSD — это инструмент, который стоит
иметь в своем арсенале; кроме того, важно, что он рас-
распространяется свободно. Однако, он никоим образом не
заменяет запись устойчивого кода и систематическое его
тестирование.
Использование JavaScript-отладчика
Netscape
Как и отладчик сценариев Microsoft, JavaScript-отлад-
JavaScript-отладчик Netscape — свободно распространяемое средство
отладки JavaScript, которое работает как интегрирован-
интегрированная часть Netscape Navigator. (Его можно выгрузить из
сайта http://devedge.netscape.com/software/tools/
index, html.)
Отладка
Глава 34
Исследование возможностей JavaScript-
отладчика Netscape
Ниже перечислены основные возможности JavaScript-
отладчика Netscape:
Окно Source View (Исходный код). Позволяет про-
просматривать исходный код отлаживаемой HTML-стра-
HTML-страницы.
¦• Прерывание. Позволяет останавливать выполнение
кода отладчиком в любой момент времени.
Точки останова. Позволяет вставлять точки остано-
останова в любые места сценария для приостановки отлад-
отладчика в этих точках.
• Пошаговое выполнение кода. MSSDiiO3bojihct поша-
пошагово (с паузами после каждого шага) выполнять код —
по одной строке за шаг.
• Пошаговое выполнение блоков кода. Позволяет по-
пошагово выполнять код, но при этом процедуры вы-
вызываются как один модуль (без пошагового выполне-
выполнения кода внутри них), и переходить к следующему
оператору.
• Пошаговое выполнение кодов внутри блоков. В от-
отличие от пошагового выполнения блоков кода, здесь
выполняются остающиеся строки (начиная от точки
выполнения) вызванной процедуры, и затем про-
программа переходит на следующий оператор после
вызова данной процедуры.
• Окно Console (Консоль). Обеспечивает область для
визуализации вычислений JavaScript-выражений
активного в данный момент фрейма.
Инспектор объектов. Позволяет просматривать и ра-
работать со значениями свойств объекта.
• Окно наблюдения. Позволяет просматривать выраже-
выражения каждый раз, когда интерпретатор останавливает
и активизирует отладчик.
• Окно Call stack (Стек вызовов). Отображает располо-
расположение текущей команды.
• Диалоговое окно Error Reporter (Генератор отчетов об
ошибках). Отображает информацию о синтаксичес-
синтаксических ошибках и ошибках времени выполнения в
JavaScript-коде.
Использование JavaScript-отладчика
Netscape для отладки файлов
В этом разделе пошагово демонстрируется пример се-
сеанса отладки в JavaScript-отладчике Netscape. Предпо-
Предполагается, что в качестве текущего браузера используется
Netscape Navigatorc установленным JavaScript-отладчи-
JavaScript-отладчиком Netscape.
Избранные программные технологии
Часть V
Запуск JavaScript-отладчика Netscape
Для того чтобы открыть исходный HTML-файл для
отладки его в JavaScript-отладчике Netscape, необходи-
необходимо выполнить следующие шаги:
1. Начните с загрузки страницы JSDebugger.html, рас-
расположенной в каталоге Netscape\Communicator\
Program\JSDebug, и нажмите на ссылку для запус-
запуска отладчика.
2. В браузере Navigator откройте страницу, которую
требуется отлаживать.
3. С помощью кнопки Open (Открыть) в инструмен-
инструментальной панели отладчика выберите страницу из
списка страниц, открывшихся в Navigator после
запуска отладчика. Страница отобразится в окне
Source View.
4. Установите в отладчике желаемый набор точек ос-
останова.
.5. Щелкните на кнопке Reload (Обновить) в Netscape
Navigator для запуска отладки страницы.
ПРИМЕЧАНИЕ
При любой остановке JavaScript-отладчика Netscape
применение браузера Netscape Navigator для просмот-
просмотра Web-страниц невозможно.
Разбор примера
Для более глубокого понимания возможностей JavaScript-
отладчика Netscape неплохо потренироваться в практи-
практическом использовании его для отладки кода. Следующее
упражнение обеспечивает хорошую отправную точку:
I. Откройте HTML-файл, показанный в листинге
34.2, напечатав соответствующий URL в Netscape
Navigator. Откройте тот же файл в JavaScript-отлад-
JavaScript-отладчике Netscape.
Листинг 34.2. Отображаемый код.
<html>
<title>vehiele_test.html</title>
<body>
<script language="JavaScript">
//Объявление двух глобальных переменных дпя
// описания транспорт) > средства
var vehicleColor;
var vehicleType;
ипа транспортного средства
function setType()
<
return(vehicleType="truck");
//Установка цвета транспортного средства
function setColor()
)
return(vehicleColor="blue");
//Уведомление пользователя, если тип и цвет
// транспортного средства не установлены
// корректно.
if(setType() II setColor ())
' + vehicleType + " is '
+ vehicleColor)
else
alert("The vehicle type and color could not
^be set") ;
</script>
</body>
</html>
2. После открытия и запуска файла полученная в
результате Web-страница должна иметь вид, по-
показанный на рис. 34.8. С первого же взгляда мож-
можно понять, что возникли некоторые проблемы.
Предполагалось, что сценарий должен установить
тип транспортного средства в truck с помощью фун-
функции setType() и его цвет — в blue с помощью фун-
функции setColor(). Если эти две функции работают
должным образом, строка должна выводиться на
экран; в противном случае отображается сигнальное
сообщение, говорящее, что одна из операций при-
присваивания потерпела неудачу. В данном случае сиг-
сигнальное сообщение не было отображено, но все же
переменная, представляющая цвет транспортного
средства, не получила значение blue.
РИСУНОК 34.8. Результат загрузки листинга 34.2.
3. Поскольку нас интересуют значения переменных
vehicleType и vehicleColor, добавим эти две перемен-
переменные в список наблюдения в отладчике.
4. Для начала остановите отладчик, щелкнув на пик-
пиктограмме Interrupt (Прерывание). Обновите окно
Netscape Navigator, чтобы начать отладку.
5. Начните пошаговое прохождение кода программы
строка за строкой, щелкая на пиктограмме Into. Пос-
После выполнения каждой строки контролируйте зна-
значения двух переменных, которые появляются в окне
Console (Консоли). Прежде чем отладчик дойдет до
оператора if, можно будет заметить, что обе пере-
переменные не были определены, как следовало бы
ожидать. После оператора if отладчик перейдет на
Отладка-
функцию setType() (если продолжать щелкать на
пиктограмме Into). После перехода на функцию
setType() переменная vehicleType устанавливается в
truck. В этой точке планировался переход на функ-
функцию setColor(), но вместо этого программа перехо-
переходит на метод document.write() (см. рис. 34.9). Что же
заставило оператор if пропустить вызов функции
se1:Color()? Более детальное исследование операто-
оператора if показывает, что первый аргумент в логической
операции OR вычисляет true, после чего второй
аргумент не вычисляется вообще. Поскольку функ-
функция setType() вернула true, функция setColor() вы-
выполнятся уже не будет. Для коррекции проблемы
следует просто заменить логическую операцию OR
на логическую операцию AND. Правильная версия
сценария показана в листинге 34.3. Результат выпол-
выполнения файла представлен на рис. 34.10.
Глава 34
return(vehicleColor="blue");
//Уведомление пользователя, если тип и цвет
// транспортного средства не установлены
// корректно.
if(setType() && setColor())
+ vehicleColor) ;
I
else
+ vehicleType + " is
alert("The vehicle type and color could not
^>be set") ;
</script>
</body>
</html>
Vl-п- return(vehiclcCoJ.Qr-'*blueB);
21:J
22:
alevc(The vehicle type end color cuui i oar, ttfc э«"): Ш
I
РИСУНОК 34.9. JavaScript-отладчик Netscape после выполнения
действия.
Листинг 34.3. Исправленный код.
<html>
<title>vehicle_correct.html</title>
<body>
<script language="JavaScript">
//Объявление двух глобальных переменных для
// описания транспортного средства
var vehicleColor;
var vehicleType;
//Установка типа транспортного средства
function setType()
i
return (vehicleType="truck") ,¦
//Установка цвета транспортного средства
function setColor()
niiL?
The truck is blue
я
РИСУНОК 34.10. Результат загрузки листинга 34.3,
Заключительные слова о JavaScript-
отладчике Netscape
JavaScript-отладчик Netscape обеспечивает полезную
среду для автоматизированного проведения отладки и
тестирования JavaScript-кода. Инструменты JavaScript-
отладчика Netscape очень похожи на инструменты,
обычно имеющиеся в средах зрелых языков программи-
программирования, таких как Visual Basic и C++. Интерфейс, ус-
установка и инсталляция JavaScript-отладчика Netscape
интуитивно понятны и дружественны к пользователю.
¦Однако JavaScript-отладчик Netscape обладает и ря-
рядом ограничений. Среди наиболее значимых ограниче-
ограничений — необходимость частого переключения между
Netscape Navigator и JavaScript-отладчиком Netscape в
процессе отладки, а также невозможность создания,
изменения и вывода на печать исходного кода.
Использование метода alertf)
Если вам не доступен полный набор возможностей
JavaScript-отладчикалибо вы ограничены во времени и
не хотите запускать JavaScript-отладчик для решения
простой проблемы, связанной с функциональностью,
Избранные программные технологии
Часть V
можно найти и другой выход. То, кто когда-либо созда-
создавал программу на каком-либо языке программирования,
тот знает, что один из наиболее простых и самых быс-
быстрых способов отладки проблем функциональности —
это отображение значений основных переменных на раз-
различных стадиях выполнения программы. Таким спосо-
способом можно выяснить, выполняется ли код так, как было
задумано.
В JavaScript есть удобный метод под названием alert(),
который может приостанавливать выполнение сценария
с целью визуализации значения переменной. Немного
поразмыслив и надлежащим образом разместив этот
метод, можно быстро отследить проблемы функцио-
функциональных возможностей в сценариях.
Разбор примера
Для того чтобы проиллюстрировать использование ме-
метода alertQ для отладки JavaScript-кода, возьмем тот же
самый сценарий, который использовался в примере с
JavaScript-отладчиком Netscape (см. листинг 34.3), что-
чтобы можно было затем сравнить эти два метода.
1. Откройте JavaScript-браузер.
2. Откройте HTML-файл листинга 34.2, напечатав его
URL в Netscape Navigator.
3. После открытия и запуска файла получившаяся в
результате Web-страница должна иметь вид, пока-
показанный на рис. 34.8. С первого же взгляда видно
присутствие некоторых проблем. Предполагалось,
что сценарий должен устанавливать тип транспорт-
транспортного средства в truck с помощью функции setType() и
его цвет — в blue с помощью функции setColor().
Если эти две функции работают должным образом,
строка должна выводиться на экран; в противном
случае отображается сигнальное сообщение, говоря-
говорящее, что одна из операций присваивания потерпе-
потерпела неудачу. В данном случае сигнальное сообщение
не было отображено, но все же переменная, пред-
представляющая цвет транспортного средства, не полу-
получила значение blue.
4. Поскольку нас интересуют значения переменных
vehicleType и vehicleCoIor, отобразим значения этих
двух переменных в вызовах alert(). Необходимо ак-
аккуратно поместить методы alert() в точки кода, что
поможет точно определить проблемную область.
Например, метод alert() B каждой из устанавлива-
устанавливающих переменные функций может уведомить, чтс»
функция была выполнена. Метод alert() до и после
оператора if сообщит, как вычисляется условное
выражение. Загрузите в браузер код из листинга
.34.4, который содержит эти дополнительные мето-
методы alert().
Листинг 34.4 Отладка с использованием alert().
<html>
<title>vehicle_debug.html</title>
<body>
<script language="JavaScript">
//Объявление двух глобальных переменных для
// описания транспортного средства
var vehicleColor;
var vehicleType;
//Установка типа транспортного средства
function setType ()
i_l
alert("Inside the setType function.");
//Оператор отладки
return<vehicleType="truck") ;
J
//Установха цвета транспортного средства
function setColor()
'{
alert("Inside the setColor function.");
//Оператор отладки
return(vehicleColor="blue">;
.!
//Оператор отладки
alert("Before if statement: type="+vehicleType+"
color="+vehicleColor);
//Уведомление пользователя, если тип и цвет
// транспортного средства не установлены
// корректно,
if (setType () | | setColor ())
t
//Оператор отладки
alert("After if statement:
type="+vehicleType+" color="+vehicleColor);
document.write("The '
+ vehicleCoIor) ;
vehicleType
else
alert ("The vehicle type and color could not
set") ;
</script>
</body>
</html>
Убедитесь, что каждый вызов alert(J содержит доста-
достаточно информации, чтобы можно было выяснять мес-
место остановки в коде только за счет чтения текста в сиг-
сигнальном окне.,
5. Когда файл открыт и запущен, посмотрите, какие
сигнальные окна отображены и какие — нет, а так-
также — каковы значения переменных на каждом эта-
этапе выполнения. Первое отображаемое сигнальное
окно показывает, что обе переменные не были ой-
Отладка
ределены перед выполнением оператора if, как и
ожидалось. Следующее сигнальное окно показыва-
показывает, что функция setType() была выполнена. И пос-
последнее сигнальное окно отображает набор типов
транспортных средств truck, но цвет после операто-
оператора if все еще не определен, как видно из рис. 34.11,
Что же случилось с функцией setColor()? Метод
ali;rt() в функции setColor(), которая не была вы-
выполнена, сообщает, что функция setColor() не была
вызвана в операторе if. Ясно, что проблема — в опе-
операторе if.
РИСУНОК 34.11. Результат загрузки листинга 34.4.
6. Более детальное рассмотрение оператора if показы-
показывает, что первый аргумент в логической операции
OR вычисляется как true, в результате чего второй
аргумент не вычисляется вообще. Поскольку функ-
функция setType() вернула true, функция setColor() уже
не будет выполнятся. Для исправления проблемы
надо просто заменить логическую операцию OR на
логическую операцию AND. He забудьте удалить
методы alert(), которые были добавлены для целей
отладки. Правильная версия сценария приведена в
листинге 34.3. Результат выполнения файла показан
на рис. 34.10.
Глава 34
ПРВДО-ГЕРЕЖЕНЙЕ
Не забудьте удалить методы alertf), которые были
добавлены для целей отладки.
Итоговые слова об использовании метода
alert()
Как было показано выше, метод alcrt() может оказать-
оказаться удобным средством отладки для быстрого решения
небольших проблем с функциональностью. При отлад-
отладке сложных проблем с функциональностью либо про-
проблем с синтаксисом метод alert() будет больше мешать,
нежели помогать в плане экономии времени. При всей
своей полезности метод alertQ не должен рассматри-
рассматриваться в качестве альтернативы полнофункциональных
средств отладки наподобие JavaScript-отладчика Netscape.
Резюме
В глава были представлены три средства отладки
JavaScript-кода. Отладчик сценариев Microsoft и JavaScript-
отладчик Netscape позволяют отлаживать сложные
JavaScript-коды. Оба инструментальных средства стоит
поместить в свой арсенал средств, и важно помнить, что
распространяются они совершенно бесплатно. Хотя об
этом не упоминалось в данной главе, на рынке присут-
присутствует множество других инструментальных средств
отладки с полным набором возможностей, однако зача-
зачастую они стоят достаточно дорого. В последней части
главы рассматривалось применение сигнальных окон
как дополнительного средства отладки, когда нет дос-
доступа к средствам отладки Netscape или Microsoft. Но
даже с этими новыми инструментальными средствами
ответственность за полное тестирование и отладку
JavaScript-кода лежит на разработчике. Ни одно из
средств отладки, обсужденных в этой главе, не может
заменить написание устойчивого кода и систематичес-
систематическое его тестирование.
JavaScript и безопасность в Web
В ЭТОЙ ГЛАВЕ
Концепции безопасности в клиентской части
JavaScript
Максимизация надежности защиты
Концепции безопасности в серверной части
JavaScript
Java и безопасность
JavaScript предоставляет разработчику Web-сайта
возможность расширять статические HTML-страницы с
помощью динамического, управляемого событиями
языка программирования. Web-страница с JavaScript-
кодом обеспечивает интерактивные функциональные
возможности, выполняя фрагменты JavaScript-кода в кли-
клиентском Web-браузере. Включение фрагментов JavaScript-
кода в страницу документа требует принятия мер по
защите как целостности кода интерпретатора сценари-
сценариев браузера, так и самого сценария. Просмотр страни-
страницы, поддерживающей JavaScript, подвергает пользова-
пользователя большей опасности, нежели выполнение чистого
HTML-документа, поскольку из-за выполняемых фраг-
фрагментов кода возникает еще один уровень сложности в
программе браузера.
В случае традиционного программного обеспечения
между пользователем и программным обеспечением
существует четкие соглашения. Установка и использо-
использование программ требует от пользователей явных дей-
действий и решений. JavaScript-код не соответствует при-
принятым соглашениям. Код сценария загружается из
удаленного источника и выполняется без подтвержде-
подтверждения пользователя. Выполнение непроверенного кода из
удаленного источника аналогично поеданию яблока, по-
полученного по почте от неизвестного отправителя. В ис-
исполняющую JavaScript-код систему должны быть поме-
помещены определенные проверки и ограничения, дабы
уберечь компьютер пользователя от преднамеренных
или неумышленных посягательств на ценную информа-
информацию и приложения. Ни один пользователь не захочет
предоставить всему миру доступ к своему компьютеру,
поэтому знания особенностей JavaScript-кода, которые
могут повредить клиентскую или серверную машины,
крайне необходимы.
Web была разработана как открытая система для
публикации графического гипертекстового содержимого
в Internet. Разработчики сайтов получили возможность
расширять статические HTML-документы динамичес-
динамическими, интерактивными возможностями за счет включе-
включения в Web-документы языков создания сценариев. Язы-
Языки создания сценариев могут выполняться на серверной
машине или же загружаться на клиентскую машину и
выполняться как удаленный код. Меры безопасности
становятся крайне необходимыми, поскольку JavaScript
и Java получают все большее распространение, стано-
становясь таким образом более привлекательными целями для
атак.
Безопасность в подключенной к Internet компьютер-
компьютерной сети может быть оценена в терминах уровня "кон-
"конфиденциальности" передачи. Получающая сторона дол-
должна быть уверена, что переданная информация была
действительно послана указанным отправителем. Кро-
Кроме того, сообщение не должно по пути изменяться. В
гетерогенной компьютерной сети, коей является Internet,
подобная конфиденциальность в настоящее время не
может быть абсолютной. Internet задумывался и разра-
разрабатывался как распределенная система, посредством
которой поток информации в сети должен пройти че-
через огромное количество различных машин, чтобы доб-
добраться до указанного адресата. Проходя через множество
хостов, трафик подвергается модификациям или заме-
заменам множество раз. Адрес отправителя может быть вы-
вымышленным (подставным). Хотя всеобщая доступность
и электронная структура незащищенных передач суще-
существенно затрудняет учет, однако шифрование, цифро-
цифровые подписи и проверка исходного кода — все это от-
относится к попыткам противостоять атакам.
Пользователь должен быть уверен, что код приложе-
приложения будет вести себя надлежащим образом и не разру-
avaScriptu безопасность в Web
шит пользовательскую систему. В типичной настольной
среде код, постоянно находящийся на локальном жес-
жестком диске, считается заслуживающим доверия, в то
время как код, полученный из сетевых ресурсов (уда-
(удаленный код) может претендовать на гораздо более низ-
низкий уровень доверия — в зависимости от источника (кор-
(корпоративная сеть или сайт хакера вирусов). В прошлом
доверие обычно зависело от происхождения кода при-
приложения. Риск при установке пакета, купленного в роз-
розничной продаже и произведенного известной фирмой,
минимален по сравнению с риском при загрузке самой
новой игры, свободно распространяемой в Internet. Ус-
Установка электронных распределительных каналов для
лриложений (JavaScript и кода Java) требует принятия
новой технологии и процедур, а также обучения потен-
потенциальных потребителей.
Компьютерная промышленность движется к назна-
назначению цифровых сигнатур разработчиков и к созданию
подписанных аплетов, способных определять безопас-
безопасность для JavaScript-кода. Идентификацией JavaScript-
разработчика будет, вероятно, передача на Web-браузер
цифровой сигнатуры, добавленной в конце файла сце-
сценария. Пользователи, имеющие более новые браузеры,
на основе полученной сигнатуры смогут решать, при-
принимать ли загрузку кода с сайта. Рисунок 35.1 показы-
показывает типичное диалоговое окно, отображающее инфор-
информацию, которая содержится в цифровом сертификате.
РИСУНОК 35.1. Типовой вид цифрового сертификата.
Шифрование используется для предотвращения из-
изменения передаваемых данных в пути. Слой безопас-
безопасных сокетов (Secure Sockets Layer, SSL) и протокол
безопасной передачи гипертекстов (Secure Hypertext
Transport Protocol, SHTTP) гарантируют, что фрагмен-
фрагменты JavaScript-кода в процессе передачи не изменялись.
Наконец, проверка исходного кода — критичный фак-
Глава 35
тор для обеспечения безопасной среды. Проверки на ви-
вирусы расширены и устанавливают, что JavaScript-код не
содержит никаких опасных подпрограмм.
Стоимость и сложность мер безопасности, осуществ-
осуществляемых для защиты компьютерной системы пользова-
пользователя, должна учитывать затруднения, налагаемые их
существованием. Ниже приводится список областей
уязвимости машины клиента при выполнении кода сце-
сценария:
Изменение файловой системы
•• Чтение/запись в файл
• Чтение/запись системной памяти
Отправка по сети приватной информации
• Связь с другими сетевыми ресурсами
Выполнение/завершение программ на локальном ком-
компьютере или внешнем хосте
Использование чрезмерных системных ресурсов (ата-
(атаки типа "Отказа в обслуживании")
• Авария программы хоста (Web-браузера)
Языки программирования создавались, чтобы предо-
предоставить разработчикам инструментальные средства для
конструирования приложений. Для обеспечения мер
безопасности, связанных с выполнением кода у сетевых
клиентов, компания Netscape разработала JavaScript, не
содержащий многие функции традиционных языков
программирования. Отсутствие некоторых возможнос-
возможностей обеспечивает в Web еще один уровень защиты от
атак, однако препятствует созданию изящного содержи-
содержимого приложения. В этой главе рассматриваются воз-
возможности JavaScript- и Java-кода по нарушению безо-
безопасности, а также шаги, которые можно предпринять в
плане предотвращения атак подобного рода.
Концепции безопасности в клиентской
части JavaScript
Наиболее распространенная в настоящее время опас-
опасность на локальных машинах, имеющих доступ в Internet,
связана с выполнением у клиента удаленного JavaScript-
кода. Использование клиентского JavaScript допустимо
при условии выяснения источника документа. Суще-
Существование HTML-дескриптора <SCRIPT> указывает на
то, что данная страница содержит клиентский код, а
необязательный атрибут дескриптора LANGUAGE=
"JAVASCRIPT" определяет, что страница содержит код
на языке JavaScript.
JavaScript-код может быть встроен в исходный
HTML-документ либо находиться в отдельном фай-
файле, на который ссылаются при помощи другого нео-
необязательного атрибута дескриптора <SCRIPT> -
Избранные программные технологии
Часть V
SRC="javqfile.js"Если выполнение JavaScript в данном
Web-браузере разрешено, сценарий может выполнить-
выполниться немедленно после загрузки страницы и ее обработ-
обработки с помощью интерпретатора сценариев или JIT- (Just-
In-Time) транслятором. Некоторые браузеры содержат
опцию предупреждения пользователя прежде, чем сце-
сценарий начнет выполняться и предлагают пользователю
возможность выделить определенные заслуживающие
доверия сайты.
С точки зрения традиционных программистов на-
настольных систем в настоящее время безопасность при
выполнении клиентского JavaScript обеспечивается
драконовскими мерами. При выполнении в Netscape
Navigator на JavaScript-код накладываются следующие
ограничения:
• Отсутствие возможности читать или записывать фай-
файлы.
Отсутствие доступа к информации файловой систе-
системы.
JavaScript не может выполнять программы и систем-
системные команды.
• JavaScript не может подключаться к другим компь-
компьютерам, кроме той машины, из которой аплет был
выгружен.
• Ограничения доступа к данным <FORM>.
JavaScript-приложения не могут сохранять пользо-
пользовательскую информацию на локальном жестком диске,
кроме как через механизм cookie-наборов, связь с под-
подключаемым модулем и одной кодовой уловкой. Уловка
основана на передаче информации вспомогательному
приложению. Если пользователь указал вспомогательное
приложение для MIME-типа, JavaScript-код может от-
открыть окно сообщения и вывести информацию о вспо-
вспомогательном приложении. Пользователь тогда сможет
явно сохранить информацию на клиентской машине с
помощью опции вспомогательного приложения File -»
Save. На рис. 35.2 показано, что происходит после пе-
передачи данных notepad.exe на примере кода test_stream.
Следующий код описывает функции, необходимые для
выполнения такой операции:
function fcest_streamO
¦:<
msgwindow = window.open("","hiwin","");
// или
// text/sams для определения нового MIME-типа
msgwindow.document.write("JavaScript data, save
"to sick drive \nA, 100, 3S\nH);
// вывести какой-то текст
sgwindow.document.write("Choose File I Save to
^create a data file") ;
msgwindow.document.close();
msgwindow. close () ;
Saue info to disk 1Л.1oo.OICImose ftlelSjue to save data File
РИСУНОК 35.2. Загрузка клиенту данных из JavaScript.
ПРЕДОСТЕРЕЖЕНИЕ
Если в document.open передается параметр (mime-
type), определяемый как "Ask User" или "Save" в под-
.меню "Helper", сценарий не сохранит информацию и
сгенерирует ошибку Out of Memory.
'Поскольку document.write в настоящее время не мо-
может записывать null (\0) в поток данных, в этом при-
примере используются только двоичные файлы.
Правильное понимание клиентских ограничений,
которые могут затрагивать операции сценария, критич-
критично для доступа кода сценария к информации о среде
пользовательского браузера. Сценарий может произве-
произвести запрос класса navigator, чтобы выяснить вид систем-
системной платформы или версию и тип браузера. Подобным
же образом можно получить список зарегистрирован-
зарегистрированных MIME-типов и подключаемых модулей. Свойства
navigator предназначены только для чтения и поэтому
не требуют принятия дополнительных мер безопасно-
безопасности. Системные свойства, которые могут быть получе-
получены за счет доступа к классу navigator, сведены в табл..
35.1.
Таблица 35.1. Свойства класса navigator.
Имя свойства
Описание
navigator.appCodeName
navigator. appName
navigator.appVersion
navigator. mimeTypes[]
navigator.plugins[]
navigator.userAgent
Кодовое имя браузера
Приложение браузера
Версия браузера
Доступные MIME-i
Установленные подключаемые
модули
Строка HTTP agent
ПРИМЕЧАНИЕ
Строка HTTP agent отправляется серверу в течение
HTTP-запросов. Как Netscape Navigator, так и Microsoft
Internet Explorer обеспечивают доступ к классу navigator.
JavaScript не используется для создания приложений,
ответственных за управление доступом. Поскольку пользо-
пользователь может просматривать весь JavaScript-код в окне
исходного документа (или фрейма), совершенно не-
несложно вскрыть алгоритм защиты. Все файлы, загружен-
загруженные с помощью необязательного дескриптора исходно-
avaScript и безопасность в Web
го файла, доступны для пользовательской загрузки и
шифрования.
Атаки на службы
Атаки на службы приносят наибольший ущерб, по-
поскольку пользователь не может завершить выполняю-
выполняющийся JavaScript-код. Атаки на службы могут заблоки-
заблокировать пользовательский интерфейс и потребовать,
чтобы пользователь завершил сеанс браузера. Наиболее
частыми атаками являются:
Переполнение стека
Бесконечные циклы
Бесконечные модальные диалоги
Использование всей доступной памяти
Переполнение стека
Состояние переполнения стека — наиболее простая в
плане предотвращения атака на службы, которую лег-
легко перехватить всеми браузерами. В этом случае отобра-
отображается окно ошибки JavaScript с сообщением "Out of
Stack Space or Stack overflow in function_x" (см. рис.
35.3). Приведенный ниже код демонстрирует, как созда-
создавать переполнение стека, многократно вызывая рекур-
рекурсивную функцию:
<НТМ1.ХНЕМ»
<TITI,E> Create Recursive Function Call
Condition</TITLE>
¦ Файл lockstack.htm -->
<scr::pt>
function stack_lockup(){
stack_lockup() ;)
</SCRIPTX/HEADXBODY>
Entering Recursive Function Call
<SCRIPT LANGUAGE="JavaScript">
комментарий, который обеспечивает
//невозможность отображения кода В браузерах,
//не поддерживающих Javascript
stack_lockup();//эта строка выполняется
// немедленно после загрузки документа не
// забывайте использовать HTML-комментарий —>
</SCRIPTX/BODYX/HTML>
РИСУНОК 35.3. Окн, ошибки Netscape 1
переполнении стека.
при
Глава 35
Бесконечные циклы
Бесконечные циклы — головная боль для всех програм-
программистов, и разработчикам JavaScript-кодов не избежать
этой участи. Следующий кодовый фрагмент подвесит
браузер:
for(var i=O
document.write("End this message");
ПРВДОСПРЕЖЕНЙЕ
JavaScript-код, выполняющий бесконечные циклы, бло-
блокирует все окна браузера, включая окно загрузки
файлов. По утверждению Netscape, JavaScript-код дол-
должен завершаться после выполнения 100000 проходов
цикла, а пользователи должны иметь возможность на-
нажать на кнопку "Stop". Однако, я НИ разу не замечал,
чтобы браузеры выполняли второе условие.
Бесконечные модальные диалоги
JavaScript-код, многократно отображающий сигнальные
окна, может служить примером атаки методом бесконеч-
бесконечного модального диалогового окна. Следующий фраг-
фрагмент кода подвесит пользовательский интерфейс брау-
браузера:
for(var i=0;;i++>
alert("Why can't i kill this script");
Использованиевсей доступной памяти
Netscape Navigator не ограничивает объем памяти, ко-
которую может распределить JavaScript. В конце концов,
эта атака переполняет виртуальную память и замедля-
замедляет машину:
for(var i=0;;i++)
str = str + "why doesn't everyone play nice";
В большинстве своем такие атаки очевидны и мог-
могли бы быть остановлены, если бы пользователь имел воз-
возможность завершить выполнение сценария (особен-
(особенность, в настоящее время исследуемая Netscape). Более
изощренная атака основана на постепенном разрушении
службы. Код-преступник на JavaScript не занимает ма-
машину, а только накапливает ресурсы в одной точке так,
что все другие окна браузера кажутся застывшими.
Проблемы Netscape Navigator 2.0
ПРИМЕЧАНИЕ
Поскольку Netscape 2.0 и Internet Explorer 3.0 в насто-
настоящий момент не особенно популярны, многое из при-
приведенной ниже информации устарело.
Браузер Netscape Navigator 2.0 демонстрирует кон-
консервативный подход к уравновешиванию потребностей
разработчика с потребностями защиты пользователя
путем введения мер безопасности. Так как большинство
Избранные программные технологии
Часть V
дыр в защите в более поздних версиях Netscape Navigator
было устранено, корректный JavaScript-код, разработан-
разработанный для версии 2.x, часто не выполняется должным
образом в более поздних версиях.
Баланс между приватным и общим доступом к
JavaScript-информации в Navigator 2.0 был вполне ясен.
Navigator автоматически предотвращал доступ сценария
из одного сервера к свойствам документов, постоянно
находящихся на другом сервере. Эти меры безопаснос-
безопасности не допускали, чтобы сценарий выбирал приватную
информацию, которую пользователь не хотел бы обна-
обнародовать. Начиная с версии Navigator 2.0, появилась
возможность низкоуровневой перезаписи кода, про-
проблемного с точки зрения безопасности. Наиболее важ-
важно здесь то, что правила, связанные с согласованием
сценариев разных серверов, были ослаблены и оформ-
оформлены в виде новой методологии — преднамеренного ис-
искажения данных.
Необходимо знать наиболее важные ошибки в вер-
версии Netscape Navigator 2.x и модифицировать браузер,
используя самые последние его обновления. Netscape
исправил большинство ошибок в версиях 2.01 и 2.02. В
основном, это касалось ликвидации дыр в защите, свя-
связанных с выполнением Java. Было бы неплохо, чтобы
пользователи и разработчики воспользовались как мож-
можно более новыми версиями Netscape Navigator.
Более поздние версии Navigator
Основная модификация интерпретатора JavaScript из-
изменила определение допустимого кода по сравнению с
более ранними версиями. Меры безопасности для бра-
браузеров Netscape постоянно изменяются с учетом разви-
развития правильного равновесия между возможностями язы-
языка и уровнем пользовательской секретности.
Операция вызова document была изменена с целью
обеспечения гарантии того, что JavaScript-код не будет
записываться поверх исходного сценария. Наличие вы-
вызовов функций document.open или document.write фун-
функции вне дескрипторов <BODY>, не ссылающихся на
новое окно, приводит к ошибке. Ниже приведен при-
пример недопустимого сценария:
<SCRIPT LANGUAGE="Javascript">
var i;
function initialize_app()
t
i = "I";
function setup (>
document.open();
document.write ("My test app equals",i);
initialize_app();
document.close();
j
</SCRIPT>
<BODY onload="setup()"></BODY>
В данном случае браузер создает новый контекст
документа и тем самым сбрасывает старый JavaScript.
В результате выводится сообщение об ошибке
"initialize_app is not defined" (initialize_app не определе-
определена), поскольку JavaScript-интерпретатор больше не име-
имеет доступа к функции. Необходимыми для обеспечения
безопасности действиями в данном случае будет либо
запись всего текста после завершения функции onload,
либо же запись нового документа в другой фрейм. Сле-
Следующий пример демонстрирует первый из упомянутых
вариантов:
<SCRIPT>
function setup О
i
initialize_app();
i
</SCRIPT>
<BODY onload="setup() ">
</BODY>
<SCRIPT>
document.write("My test app equals",i);
</SCRIPT>
Преднамеренное искажение данных
Концепция искажения данных была помещена в язык
как механизм совместного использования данных для
окон, открытых из различных серверов. Искажение дан-
данных можно осуществить, устанавливая системную пе-
переменную NS_ENABLE_TAINT в любое значение.
Когда искажение данных разрешено, все JavaScript-
объекты и свойства становятся общедоступными. Данная
возможность необходима для совместного использования
разными окнами информации от разных серверов. Окна
могут получать "чужую" информацию от других доступ-
доступных окон, но когда эта информация посылается на сер-
сервер, всплывает диалог подтверждения, позволяющий
отменить или подтвердить операцию post. Если систем-
системная переменная не установлена, ссылки на данные
форм на других серверах будут генерировать сообщения
об ошибке "access disallowed from scripts at VRLl.himto
documents at C/R/,2.htm"^ocTyn из сценария по URLl .htm
в документы по URL2.htm запрещен).
СОВЕТ
<::iw
Даже когда искажение данных заблокировано, окна
имеют возможность обращаться к функциям, загру-
загруженным в другие окна с других серверов. Например,
framel, загруженный с serveri, может вызвать функ-
функцию frame2, загруженную с server!.
JavaScript предоставляет функции, позволяющие
устанавливать или удалять искажение данных в объек-
объектах. Функция taint() возвращает искаженную ссылку на
свойство, a untaint() — ее неискаженную копию. Напри-
Например, следующий код возвращает копию приватных дан-
данных, которые можно отправить на сервер через URL
либо операцию POST формы:
avaScriptu безопасность в Web
unmarked =
untaint(document.forms[0].element[0] .value) ;
ПРЕДОСТЕРЕЖЕНИЕ
Когда системная переменная NS_ENABLE_TAINT уста-
новгена, JavaScript-код в одном из окон видит все
свойства документов из других окон, включая приват-
приватные данные и информацию списка посещений в тече-
течение данного сеанса.
Механизм искажения в настоящее время содержит
много ошибок, связанных с безопасностью, и должен
применяться весьма осторожно. Многие разработчики
создавали код, обходящий механизм защиты за счет
обновления данных через последовательность манипу-
манипуляций с ними.
.Internet Explorer 3.x
Поскольку возможность выполнения JavaScript- и Java-
аплетов только недавно была включена в Internet Explorer
Microsoft, независимые эксперты еще не успели подго-
подготовить широкий обзор его механизмов безопасности.
Обзор интерфейса приложения показывает хорошо про-
продуманный подход к безопасности. Меры обеспечения
секретности и регистрация аплетов были встроены в
браузер и работают с пользователем, гарантируя, что
информация будет передаваться на сервер только явно.
На рис. 35.4 показано диалоговое окно, содержащее все
возможности по обеспечению секретности, доступные
в Internet Explorer.
Geneial ] Connection | Navigation | Programs Security (Advanced |
Piivacy
^fc*>. Г }*/frn me betaejetidi" over an open
Г Warrj me before crossing zdnst
f7 Wan me .about invalid .site certificate?
Г Warn mebetoi«etcepting"?ODkiet'*
es
Use certificates la positively identify sites, pubd'sheis am
yourself.
Penonal.. 1 . I Pubfchws.
e conlcnt
Kl ^*°° can c^loose ^at '^P® °f «ftwaeWeb sues can
P dovvnload and run on your computer.
P AHcw dowrfo&inQ of act/ve content
Enable ActiveX corttots and plugim
P RunActiveXscripIs
P EnableJavapiogfarTB Safety Level.
РИСУНОК 35.4. Возможности обеспечения безопасности в
Microsoft Internet Explorer,
Интерфейс приложения также включает возмож-
возможность ограничения загрузки кода только серверами, зас-
заслуживающими доверия. Эта особенность основывается
на использовании сервером сертификатов безопасности
Глава 35
для идентификации при просмотре сайтов, заслужива-
заслуживающих доверия. Internet Explorer имеет диалоговое окно,,
которое может отображать сайтыу которым доверяет
клиентский браузера (см. рис. 35.5).
Trusted Publbhef * and Issu
You have d-ygn.ited the following ^oi M
agencies as means
initaB and use softwaie van these pufab
these agencies without «kjng you first.
^^
I pJ3lJshers and с
а can
d by
Г" Consider all ccmfneicial sottwate publishers
ttrth
РИСУНОК 35.5. Диалоговое окно Windows SoftwareSecurity,
Максимизация надежности защиты
Прежде чем отправляться в плаванье по неизведанным
водам, можно предпринять шаги по уменьшению воз-
воздействия атак на безопасность из-за "предательства" Java-
или JavaScript-кода. Можно определить, какой уровень
защиты необходимо задействовать, опираясь на объем
доверия для данного источника. При посещении новых
сайтов (либо уже просмотренных сайтов после запроса
virus hackers) желательно полностью удалить возмож-
возможность выполнения языков создания сценариев в браузе-
браузере. Кроме того, сетевой администратор может выбрать
нисходящий подход к безопасности, отключив выпол-
выполнение Java-классов, полученных из Internet. Сетевая
безопасность может конфигурироваться для удаления
возможности передачи файлов Java-классов через про-
прокси-сервер во внутреннюю сеть. Если отслеживаются
сводки и советы по безопасности, должно быть хорошее
представление о риске обхода сетевой защиты.
Безопасные сеансы и цифровые сигнатуры
Как упоминалось ранее, безопасные сеансы иницииру-
инициируются браузером; при этом устанавливается шифрован-
шифрованный поток передачи данных между сервером и браузером.
Шифрование основывается на цифровых сертификатах,
хранящихся на сервере. Дальнейшая защита достигает-
достигается за счет использования цифровых подписей для каж-
каждого файла, загруженного клиенту. Авторитетные службы
проверки, такие как Verisign, трудятся бок о бок с раз-
разработчиками браузеров с целью создания структуры для
добавления цифровых сигнатур в файлы сценариев и
аплетов. Более поздние версии Netscape Navigator и
Internet Explorer, в дополнение к экранным визуальным
Избранные программные технологии
Часть V
подсказкам, обеспечивают информацию о текущем
уровне безопасности документов или фреймов.
Для просмотра уровня безопасности документа (или
фрейма) в Netscape Navigator выберите View ' Page Info
("Document Info" в старых версиях) или View -* Frame
Info. Строка Security дает текущий уровень безопасно-
безопасности. На рис. 35.6 показана информации о безопасности
в Netscape Navigator.
Для просмотра уровня безопасности документа (или
фрейма) в Microsoft Internet Explorer выберите File
Properties, а затем — вкладку Security, либо щелкните
на кнопке Certificates, в зависимости от используемой
версии Internet Explorer. На рис. 35.7 показана инфор-
информация о безопасности в Internet Explorer.
NetA-t
File MIME Type:
Sour»:
Local cacho rae:
fctip^'totwonh tfjJicwft''
texUhtml
MOOWJVH
La.t Modified: Monday. 29-Ji&9< 17W IOL*c«ltk«
Last Modified:
CoivtenrlengUi:
Expires
Cbanetr
Severity:
Cattificm№
Monday. ?9-Jul-S»6 21 04;1fl dMT
3307
No date gWen
ITas is a secure document that use: a rnednm-grade encryption key suited for TJ ^ezpul
ffi.C4-Eaport. 128bitwiA40secreO.
rU*C*rtife>hb*b4i « TO» Ccrtlflntonabnnlhr;
mt*nithgiJtc3# Stein Зн-лгСмьАмЦоп Anthoiijr
tJALTT«etnologi»i,![ie H3A DaU3*cuniy Inc
PUUtnxeb. Ркшу^ш». US US
Serial Nurohen 02:78 00:0* 9A
Thii Certificate i»»afid freitk Мои .Ы 22,195* to Sun Jw» 26,1997
Certificate Fittfcatprinti
РИСУНОК 35.6. Информационное окно Netscape Navigator,
сообщающее о защищенности документа.
Отключение языков создания сценариев в
браузере
На уровне индивидуального клиента наиболее эффек-
эффективный способ защиты пользователя от повреждения
кодовых фрагментов должен просто убирать возмож-
возможность выполнения браузером кода создания сценария.
Недостаток подобного подхода состоит в том, что тог-
тогда из Web-сайта будут удалены многие возможности,
поэтому Web-сайт не сможет работать, как задумыва-
задумывалось. Эти параметры следует использовать только при
посещении непроверенных сайтов.
JavaScript
Для отключения JavaScript в Netscape Navigator 2.01
выберите Options-» Security Preferences и вкладку General.
Отметьте флажок Disable JavaScript (Запретить JavaScript)
и затем щелкните на кнопке ОК.
ПРИМЕЧАНИЕ
В Netscape Navigator 2.0 отключить JavaScript нельзя.
rfam4t№«bojtit!
bdbK
Ceililicate HamAm
L-Pittsbugh
O"GALT Technologies. Inc
:N-netwoithgaK.cmi
isuer
0-RSAOataSecuity, te.
DUs S Cft
Sarwturp Type
E lie typt ion Type.
Pifvacy Strength:
Effective pata 7/23^3612;00:00 ДМ
E Kpiration D ate: 1 /26/9? 11 ?333FW
Security Pioiccol: SSL го
nSA/MD5
RC4
Low D0 b*f(
J
РИСУНОК 35.7. Информационное диалоговое окно Internet
Explorer, сообщающее о защищенности документа.
Для отключения JavaScript в более поздних версиях
Netscape Navigator выберите Edit ¦* Preferences (см. рис.
35.8) и выберите опцию Advanced. Удалите отметку на
флажке Enable JavaScript (Разрешить JavaScript) и затем
щелкните на кнопке ОК.
! f"
i sitsi ижа:
[IcH'-.i .Mi'.^4.1 e.tv
:"гигк-.:,..,
> ebss
j r;v2i
¦ ¦ ¦ ¦ ¦
.r «.—r
-
¦ ¦¦ ..
ад,:
' Ai
K0I №¦ Web
¦
РИСУНОК 35.8. Отключение JavaScript в более поздних версиях
Netscape Navigator.
Для отключения JavaScript в Internet Explorer 4 или
более поздних версиях выберите Tools -» Internet Options
и вкладку Security. Щелкните на кнопке Custom Level,
отыщите Active Scripting (см. рис. 35.9) и выберите Disable.
В Internet Explorer 3 отключить JavaScript нельзя.
Java
Для отключения JavaScript в Netscape Navigator 2.01
выберите Options -» Security Preferences и вкладку General.
Отметьте флажок Disable Java и щелкните на кнопке
ОК.
avaScriptu безопасность в Web
Для отключения Java в более поздних версиях Netscape
Navigator выберите Edit -* Preferences (см. рис. 35.8) и
выберите опцию "Advanced". Снимите отметку флажка
Enable Java и затем щелкните на ОК.
Для отключения JavaScript в Internet Explorer выбе-
выберите Tools -* Internet Options и вкладку Security. Щел-
Щелкните на кнопке Custom Level, отыщите Java. Выбери-
Выберите Disable, а затем щелкните на кнопке ОК. На рис.
35.10 показано диалоговое окно Internet Explorer, кото-
которое используется для запрещения Java-программ.
FireusmnJa' й:>,^
HlPtTW CD«t«tlMllV
LUHoiau
О Ем
Nl_ J=
РИСУНОК 35.9. Отключение JavaScript в Internet Explorer.
РИСУНОК 35.10. Отключение Java в Internet Explorer.
Фильтрация через брандмауэр
Бранлмауэры (firewall) и прокси-серверы обычно пред-
представляют собой первую линию защиты между Internet
и внутренней сетью (WAN, LAN или удаленной маши-
машиной). Сетевые администраторы могут конфигурировать
маршрутизаторы брандмауэра с целью фильтрации се-
сетевого потока данных, базируясь на различных парамет-
Глава 35
pax, и таким образом гарантировать, что пользователь
не сможет загрузить файл, вызывающий нарушение бе-
безопасности. Однако, уровень фильтрации должен быть
определен с учетом баланса выгод, достигаемых при
более высоком уровне безопасности, и стоимости реа-
реализации такого решения. Реализация решений по безо-
безопасности для маршрутизатора или прокси-сервера вообще
дорого обходится в плане затрат ресурсов и финансов,
поэтому следует предварительно убедиться, что подоб-
подобного рода защита действительно необходима.
HTTP-запросы используются клиентским браузером
для запрашивания фрагментов JavaScript и Java-кодов.
Поскольку HTTP также используется для нормального
функционирования Web-браузера, прокси-сервер не
может запретить доступ ко всем HTTP-запросам, по-
поскольку это бы привело к недоступности Web для браузе-
браузера. Технология фильтрации (которая может использо-
использоваться для удаления загрузки Java) должна фильтровать
URL для блокировки всех файлов, имеющих расшире-
расширение .class или .cla. Фильтрация JavaScript-кода более
сложна, так как исходным файлам разрешено исполь-
использовать любые расширения, а кодовые фрагменты могут
быть внедрены во внутренние Web-страницы.
Информационные ресурсы о безопасности
для JavaScript и Java
В Internet имеется множество сайтов, содержащих ин-
информацию по проблемам безопасности. Сбор информа-
информации об актуальных мерах безопасности — неплохое
начало для принятия правильных решений о риске,
возникающем при использовании последних техноло-
технологий.
Наиболее точная информация содержится на следу-
следующих Web-сайтах:
• Netscape:http://developer.netscape.com/docs/manuals/
index.html
Информация, связанная с продукцией Netscape: Sun на
http://java.javasoft.com/sfaq/
Информация, связанная с Java: CERT на http://
www.cert.org
• Независимые консультации о текущих нарушениях
безопасности: CERT FTP на ftp://info.cert.org/pub/
certadvisories
• Поисковый каталог для файлов, содержащих слово
Java: Safe Internet Programming на http://
www.cs.princeton.edu/sip/. Этот сайт создан исследо-
исследовательской группой Принстонского университета,
которая занимается расширением Internet-сценариев.
Именно они обнаружили самые последние проколы
в защите Java.
Избранные программные технологии
Часть V
Концепции безопасности в серверной
части JavaScript
Функциональные возможности Web-серверов можно
расширить через выполнение подпрограмм JavaScript и
Java, а также CGI-программ и серверных модулей. Сер-
Серверное расширение JavaScript применяет существующие
возможности языка JavaScript для создания приложе-
приложений, которые могут обращаться к базам данных и другим
ресурсам, постоянно находящимся на сервере. Возмож-
Возможность выполнения серверного расширения JavaScript на
сервере Netscape в настоящее время описана как техно-
технология LiveWire и допускается через администратора
сервера. На рис. 35.11 показано окно Enterprise Server,
которое используется для активизации серверного рас-
расширения JavaScript (LiveWire).
Activate LiveYVirf
n '.Linage?п n Jittn:Vrrt bi
РИСУНОК 35.11. Активизация серверного расширения JavaScript.
Важно знать, что возможности серверного расшире-
расширения JavaScript должны отображаться на определенные
каталоги на сервере. Потребность санкционирования
каталогов сервера, выполняющих серверное расширение
JavaScript, помогает защитить сервер, изолируя облас-
области, которые могли бы вызвать нарушения безопаснос-
безопасности. На рис. 35.12 показано окно сервера, используемое
для активизации LiveWire для указанного подкаталога
сервера.
Технология LiveWire предоставляет четыре новых
объекта JavaScript для применения на сервере: request,
client, project и server. Объект request содержит свойство
request.ip, которое позволяет серверу определять IP-
адрес, от которого исходит клиентский запрос. Этот
объект используется для проверки заслуживающих до-
доверия клиентов, которым может быть предоставлен до-
доступ к конфиденциальной информации. Объект гло-
глобальных данных приложения project, должен быть
заблокирован прежде, чем будут изменяться (еремен-
ные значения данных, иначе целостность переменных
и счетчиков приложения не будет синхронизирована
между клиентскими процессами.
¦-•-- -¦¦•¦
РИСУНОК 3 5.12. Активизация катсыогов Live И in • для
выполнения JavaScript.
Наибольшего внимания требуют меры безопасности
для возможностей серверного расширения JavaScript
читать и записывать информацию непосредственно на
жесткий диск. Определенным образом отформатирован-
отформатированные данные могут часто разрушать программы, которые
читают или записывают файлы. Код серверного сцена-
сценария необходимо тщательно протестировать, дабы обре-
обрести уверенность, что перед записью на диск данные
пользователя переводятся в допустимый формат. Также
обязательно, чтобы код серверного JavaScript содержал
механизмы закрытия файлов, учитывая, что многие
;сы выполняются на главном сервере. Наиболее
простой механизм блокировки предполагает переимено-
переименование файла перед открытием его для файлового ввода-
вывода. Во всех операционных системах команда
rename, как и следовало ожидать, будет элементарной
операцией. Следующий код иллюстрирует it прин-
принцип:
while (rename (,)) // лереиме ювать файл для
// целей блокировки
// заблокировать доступ к файлу
else
{
// выполнить файловый ввод/вывод
mame ( ,) ; // восстановить оригинальное
/ / имя файла
}
Серверный код не должен записывать файлы на диск
в общедоступные каталоги, для которых установлена
возможность запуска. Обычная хакерская уловка состоит
avaScriptu безопасность в Web
в применении заслуживающей доверия серверной про-
программы для создания файла на сервере, который позже
может использоваться для атаки. Например,
грамма, которая загружает текстовые файлы от клиен-
клиента на сервер, может послужить для создания выполня-
выполняемого файла сценария. Когда атакующий обращается к
загруженному файлу через Web-браузер, серверный код
выполняется и может натворить бед на сервере.
Администраторы Web-сайтов и разработчики кода
должны знать, что серверный JavaScript вполне может
разрушить промышленный сервер. Чрезмерное исполь-
использование системной памяти, некорректная блокировка
объектов, бесконечные циклы и неверный файловый
ввод-вывод может привести к аварийному останову сер-
сервера. Весь код сценария должен быть полностью про-
протестирован на сервере динамически перед запуском его
в работу. Кроме того, код потребуется опытным путем
проверить на возможные тупиковые ситуации.
ПРВДОСгеРЕЖЁНИЕ
Клиентское расширение JavaScript может попытаться
обратится к любому порту на исходном сервере. По-
Потребуется выполнить проверку безопасности, которая
бы гарантировала, что между сервером и internet при-
присутствует надлежащая сетевая защита.
.:
Интерпретатор Java необходимо явно активизировать
для каталогов сервера. Управление приложениями сер-
сервера используется для определения каталогов, которые
могут выполнять Java-модули.
На рис. 35.13 показана страница управления прило-
приложением, используемая для активизации Java для опре-
определенного подкаталога сервера.
РИСУНОК 35.13. Активизация каталогов Java на сервере.
Java и безопасность
Язык Java предлагает намного больше возможностей,
нежели JavaScript. Более поздние версии Netscape
Глава 35
позволяют разработчику реализовать смешанные Java-
и JavaScript-коды внутри Java-аплетов (технология
LiveConnect). К тому же, JavaScript может напрямую
обращаться к функциям Java-аплетов, передавая пара-
параметры и получая возвращаемые значения. Эти два язы-
языка могут использоваться в тандеме для создания исчер-
исчерпывающих решений для удаленных клиентов.
Знание истории Java важно в плане преодоления
возможных проблем безопасности, связанных с его те-
текущей реализацией. Язык копирует C++ во многих от-
отношениях — он имеет тот же синтаксис, похожие клю-
ключевые слова и поддержку объектно-ориентированной
методологии, включая и наследование. Java отличается
от C++ в том, что добавляет в язык гибкость и пытается
создавать более безопасную среду: код не может подде-
подделывать указатели, сборка мусора осуществляется авто-
автоматически, реализуется только одиночное наследование.
Машино-независимая структура Java изолирует програм-
программиста от операционной системы целевой машины. Ос-
Основные стандартные блоки программирования расши-
расширены предварительно подготовленными пакетами,,
способными определять систему клиента и сервера.
Язык Java первоначально предназначался для созда-
создания встроенных приложений на персональных прибо-
приборах (настольные телевизоры, персональные коммуника-
коммуникаторы, карманные компьютеры и т. п.). Возможность атак
на эти закрытые системы намного ниже, чем при соеди-
соединении с самой большой общедоступной сетью с откры-
открытыми стандартами.
Программный интерфейс приложения, предложен-
предложенный Sun Microsystems для языка Java, в процессе обще-
общественной стадии тестирования был достаточно устойчив,
чтобы обрабатывать большинство задач, необходимых
в традиционных настольных компьютерных приложе-
приложениях. Цель состояла в том, чтобы разрешить заслужи-
заслуживающему доверия браузеру или заслуживающей доверия
Java-среде обрабатывать непроверенные компоненты
Java-класса. Текущая реализация Java потеряла такое
разрешение, так как его механизмы безопасности не
соответствуют основным промышленным стандартам
безопасности для заслуживающих доверия систем. Сам
по себе язык Java не может считаться безопасным, по-
поскольку не имеет самых базовых компонентов безопас-
безопасной архитектуры.
Java не содержит основных механизмов безопасно-
безопасности, таких как возможность проверки в загрузчике клас-
классов в документ модулей, загруженных в процессе ата-
атаки. Поскольку аплеты могут существовать вне контекста
Web-документа, который их загрузил, аплет-жулик мо-
может проводить атаку без того, что пользователь заметит
его существование. Определяемая пользователем поли-
политика проверки должна быть доступна, что позволяет
регистрировать выполнение аплета, сетевой адрес аплета
и байт-код аплета.
Избранные программные технологии
Часть V
Добавим, что реализации Java не доказали, что он
является безопасным языком, как предполагали его со-
создатели. Большинство подсистем содержат ошибки за-
защиты, которые не были полностью исправлены, что
приводит к повторяющимся сигналам об ошибках защи-
защиты. Таблица 35.2 подробно описывает наиболее важные
из них, которые зарегистрированы Sun Microsystems на
странице Applet Security FAQ (http://java.sun.com/sfaq/).
Исследователи, которые обнаружили эти ошибки
защиты, публично заявили, что Java придется радикаль-
радикально изменить, чтобы достичь их определения безопасной
среды. Атака с использованием незаконного приведения
типа успешно обходит механизм безопасного приведе-
приведения типа в Java. Успешные атаки на механизм приведе-
приведения типа позволяют Java-объектам подменять свой тип.
Разработка хакерами жульнического загрузчика класса
означает, что непроверенный код приложения потенци-
потенциально может быть загружен и выполнен из непроверен-
непроверенного источника без ведома браузера.
Компоненты защиты
Механизмы защиты, управляющие Java-объектами, ре-
реализованы на Java. При запуске рабочей системы брау-
браузера не возникает никаких ограничений по защите.
Класс SecuntyManager, контролирующий безопасность,
загружается из каталога, содержащегося в клиентской
системной переменной CLASSPATH. Такие заслужива-
заслуживающие доверия файлы класса (MOZxxx.ZIP в Netscape
Navigator 2.0 и JAVxxx.ZIP в Netscape Navigator 3.x)
должны быть защищены частыми проверками на виру-
вирусы и содержать пометку "только для чтения".
Верификатор байт-кода
Когда Java-класс выгружается из удаленного хоста, код
проверяется верификатором байт-кода. Этот важный
шаг гарантирует, что код Java соответствует известным
кодам операций языка и что стек операндов не подвер-
Таблица 35.2. Некоторые ошибки защиты Java.
Дата
гнут переполнению или потере значимости. Все досту-
доступы к объектам класса проверяются на соблюдение ме-
механизма защиты, определенного для членов объектов
(приватный, защищенный, общедоступный). Кроме
того, код проверяется на отсутствие каких-либо неза-
незаконных преобразований данных. После того как вери-
верификатор исполнит свою работу, код преобразовывает-
преобразовывается рабочим Java-компилятором в машинный код.
Управление защитой
Класс SecurityManager используется рабочей системой
Java для доступа к разрешению управления Java-клас-
Java-классами. Поскольку SecurityManager реализован как Java-
объект, когда начинается выполнение, управление бе-
безопасностью защищается системой Java-типов. Если
система типов доказала безопасность, и файловая сис-
система не была поставлена под угрозу, SecurityManager
считается заслуживающим доверия классом.
Трансляторы Java отвечают за компиляцию исход-
исходного Java-кода (файл с расширением Java) в машино-
независимый байт-код (файл с расширением .class).
Байт-код передается по сети на локальную машину и
интерпретируется либо компилируется в первоначаль-
первоначальный код системой выполнения Java. Проверка байт-кода
Java является критическим шагом в определении цело-
целостности Java-аплета. Таким же образом, как текущие
программы проверки на вирусы ищут незаконные про-
процессы и системные вызовы, байт-код проверяется на
отсутствие каких-либо атак на безопасность. Байт-коды
должны оцениваться в контексте их типов. Например,
тип SecurityManager должен иметь меньшее количество
ограничений по сравнению с типом, определяемым
пользователем.
Недостаток формального определения для системы
типов Java и необходимость полного анализа всей ра-
рабочей последовательности программы приводит к тому,
что оценка выполняется текущими верификаторами,
сложными и ненадежными.
Проблема
Состояние
26 марта 1999 г. Непроверенный код
22 июля 1998 г. Принстонская атака загрузчика класса
2 июля 1996 г. Атака с применением незаконного приведения типа
18 мая 1996 г. Новая версия предыдущей атаки загрузчика класса
Апрель 1996 г. Атака разрешения имени URL
Март 1996 г. Ошибка выполнения верификатора
Март 1996 г. Ошибка выполнения загрузчика класса
Февраль 1996 г. Атака DNS
Исправлена в JDK 1.1.8
Исправлена в JDK 1.2
Исправлена в JDK 1.1
Исправлена в Netscape 3.0Ь4
Исправлена в Netscape З.ОЬ4
Исправлена в Netscape 2.02
Исправлена в Netscape 2.01
Исправлена в Netscape 2.01
avaScript и безопасность в Web
Методы защиты аплетов предписывается концепци-
концепцией пространства имен (named space). Каждый Java-аплет
должен иметь уникальное имя, в зависимости от источ-
источника, из которого он был загружен. Документация Java
утверждает, что пространство имен объектов системного'
уровня имеет возможность совместного использования
всеми другими пространствами имен (аплетами), и что
загрузчик класса во время выполнения всегда ишет спи-
список системных пространств имен, дабы уберечь загру-
загруженный код от перезаписи системного класса. Стоит
добавить, что подделка пространств имен хеша, кото-
которые заменяют жизненно важные системные компонен-
компоненты класса, такие как загрузчик класса, было одной из
первых ошибок защиты, найденных в Java. Ошибки заг-
загрузчика класса были подробно задокументированы ис-
исследователями Принстонского университета.
Ограничения защиты
Базовое подмножество языка Java было расширено за
счет многих важных пакетов классов, которые уберега-
уберегают программистов от повторного изобретения основных
интерфейсов. Реализация пакета может освободить про-
программиста от связанных с платформой проблем, но так-
также может ограничить доступ к некоторым компонентам
нижнего уровня. Определенная реализация Java оказы-
оказывает влияние на базовый доступ к машинным подсис-
подсистемам, ответственным за сетевую связь, файловому вво-
вводу-выводу, доступу к памяти и системным ресурсам. В
настоящее время серверный Java-код имеет меньшее
количество ограничений защиты по сравнению с кли-
клиентским Java-кодом.
СОВЕТ . ;
iB Java-коде сообщения об ошибках, включающие тер-
термин Security Except ion, указывают на нарушение огра-
ограничений защиты.
Сетевая связь
Использование концепции совместной работы Sandbox
"песочницы"служит для ограничения возможностей свя-
связи для кода аплета с другими машинами. Подобного рода
аплет может связываться только с сервером, из которо-
которого он исходит. Ограничение кода "игрой только в своей
песочнице" — первая линия защиты от жульнического
аплета. Менеджер безопасности ограничивает сетевые
вызовы так, что они могут только открывать каналы
связи между клиентом и исходным DNS-адресом апле-
аплета. Поскольку в вопросе проверки адреса методология
полагается на DNS-подсистему, компромиссы сервера
DNS, з свою очередь, сводят на нет эффективность
механизма безопасности.
Согласно документации, аплеты могут открывать
каналы связи с сервером через любой порт. В действи-
|5 1-158
Глава 35
тельности, выполнение Java в Netscape устанавливает
недокументированные ограничения, определяющее до-
доступность разных портов.
Наличие аплета в наборе инструментов, который де-
делает запрос всех сокет-портов и возвращает возмож-
возможные каналы связи, экономит достаточно много времени
при определении портов, поддерживаемых конкретной
реализацией Java.
Файловый ввод-вывод
Текущие реализации клиентских расширений Java не
разрешают чтение и запись на жесткий диск клиента. На
клиентской машине вызовы для открытия, чтения, за-
записи и закрытия файлов генерируют уведомление
SecurityExceptions или IOExceptions. Приложение Applet
Viewer от Sun Microsystems использует файл управления
доступом, чтобы предоставить чтение и разрешение за-
записи на диск клиента. Вероятно, что некоторые опера-
операции из этой схемы будут в будущем приняты новым
браузером Netscape. Как упоминалось ранее в главе,
серверное расширение Java может обращаться к жест-
жесткому диску хоста для выполнения операций с файлами.
Доступ в память
В Java исходный код не имеет концепции указателей
памяти. Это существенно упрощает использование язы-
языка и уменьшает количество ошибок кода. Поскольку
указателями не ссылаются на структуры данных, мно-
много сторонников Java полагают, что он должен быть бо-
более безопасным языком по сравнению с C++. К тому
же, программисты Java не могут подделывать указате-
указатели на функции.
Системные ресурсы
Возможность блокирования системных ресурсов явля-
является риском безопасности в Java. Например, в реализа-
реализации Netscape блокирование класса java.net.InetAddress
приводит к блокированию всех новых сетевых подклю-
подключений.
Как Java, так и JavaScript — революционные языки,
которые помогают разработчикам Web-сайтов создавать,
интерактивное содержимое. Однако, возможность запус-
запуска удаленного кода на клиентских машинах должна рас-
рассматриваться и с точки зрения потенциального нанесе-
нанесения ущерба среде пользователя.
Цель сообщества поставщиков программного обеспе-
обеспечения под Internet заключается в создании заслужива-
заслуживающей доверия среды, в которой пользователей не дол-
должно волновать, что действия могут повлечь за собой
разрушительные последствия. В идеале пользователь
также должен знать, что операция собирается произой-
произойти, и иметь возможность предотвратить это.
Избранные программные технологии
Часть V
Механизмы все еще развиваются с целью создания
более безопасной подключенной к сети среды, интуи-
интуитивно понятной пользователю. Меры безопасности, ин-
инкапсулированные в JavaScript-код, еще не готовы к ис-
использованию в критических средах, однако быстрый
рост Internet-технологий приближает реализацию реше-
решений.
Резюме
Поскольку компьютерные пользователи выходят за рам-
рамки настольных систем и связываются с деловыми парт-
партнерами и друзьями по всему миру, проблемы, связан-
связанные с компьютерной безопасностью и секретностью
становятся проблемами первостепенной важности. В
главе рассматривались клиентские области, которые
должны быть защищены от преднамеренных атак, и
было показано, как пользователи могут уберечь свои
машины при выполнении программ на JavaScript и Java.
Методологии безопасности пребывают в настоящее вре-
время в состоянии разработки. Запуск удаленного кода на
клиентских машинах в текущих реализациях строго ог-
ограничен, так как потребности пользователя и разработ-
разработчика сбалансированы мерами, направленными против
потенциально некорректного употребления. Знание ог-
ограничений и особенностей текущей технологии критич-
критично при установке требуемого уровня доверия и распро-
распространении динамических и изящных приложений и
содержимого в Internet.
Приложение
ЧАСТЬ
в этой части
А. Десять основных ресурсов в Web,
посвященных JavaScript
•• f
Десять основных ресурсов
в Web, посвященных
JavaScript
Netscape DevEdge Online
http://developer.netscape.com
Это центральный Web-сайт компании Netscape для всех
его технологий разработки. Здесь можно найти офици-
официальную документацию Netscape no JavaScript, а также
статьи и информационные бюллетени, отражающие все,
что Netscape делает в мире JavaScript. Сайт включает
следующие страницы:
• JavaScript Authoring Guide по адресу http://
developer.netscape.com/docs/manuals/communicator/
jsguide4/index. htm
• JavaScript Developer Central по адресу http://
developer.netscape.com/tech/javascript/index.html
• Official JavaScript Language Specification по адресу
ftp://ftp.netscape.com/pub/review/jsspec.ps.gz ;
Технологии написания сценариев
Microsoft
http://msdn.microsoft.com/scripting/default.htm
Это главный Web-сайт компании Microsoft, содержащий
информацию по JScript и VBScript. Здесь можно выгрузить
самую новую версию сценарного механизма Microsoft,
а также найти документацию и примеры применения
JScript и VBScript. Сайт включает следующие страницы:
JScript Language Reference по адресу http://
msdn.microsoft.com/scripting/jscript/doc/jstoc.htm
JScript FAQ по адресу http://msdn.microsoft.com/
scripting/jscript/techinfo/jsfaq.htm
JScript Samples по адресу http://msdn.microsoft.com/
scripting/jscript/samples/jssamp.htni
Введение в JavaScript от Voodoo
http://rummelplatz.uni-mannheim.de/~skoch/js/
script.htm
Введение в JavaScript от Voodoo — обучающая программа
в 12 частях, охватывающая все популярные аспекты
JavaScript. Она пригодна как для новичков, так и для
экспертов. Часть 1 объясняет, что такое JavaScript и как
он используется, а следующие части рассматривают
применения слоев и динамического HTML.
llrt.org
http://www.irt.org/articles/script.htm
Irt.org (Internet Related Technologies) содержит огромное
количество высококачественных статей по всем раз-
разделам, включая ASP, HTML, динамический HTML,
VBScript, CSS, XML, JavaScript и т.д. Приведенный
выше URL определяет непосредственно раздел JavaScript,
где можно отыскать множество полезных статей в удоб-
удобно организованном каталоге.
Focus on JavaScript
http://javascript.about.com
Этот сайт поддерживается Нейтом Кассебаумом (Nate
Kassebaum), одним из соавторов этой книги. Здесь мож-
можно найти еженедельные статьи, посвященные JavaScript,
а также ссылки на последнюю информацию на других
сайтах. Сайт содержит следующие страницы:
About.com JavaScript Tutorial по адресу http://
javascript.about.com/library/bl_tutorial.htm
Focus on JavaScript Newsletter по адресу http://
javascript.about.com/gi/pages/mmail.htm
JavaScriptu Worldwide Web
SuperScripter
http://www.builder.com/Programming/Scripter/
Это раздел, посвященный JavaScript, на Builder.com в.
C|NET. Каждую неделю JavaScript-гуру Builder.com пишет
статью, рассматривающую какой-либо аспект JavaScript.
Архив содержит лучшие статьи и примеры, доступные
в Web.
JavaScripts.com
http://www.javascripts.com
JavaScripts.com содержит тысячи готовых примеров
JavaScript-кода для использования при создании Web-
страниц. Сайт предназначен только для членов, однако
членство на нем свободное и все, что требуется — это
указать свой адрес электронной почты.
JavaScript Source
http://javascript.internet.com
JavaScript Source является прежде всего библиотекой
примеров кода JavaScript, но он также содержит форум
Приложение А
и раздел по книгам, посвященным JavaScript. Библио-
Библиотека кодов очень хороша и содержит свыше 500 высо-
высококачественных сценариев.
Webcoder.com
http://www.Webcoder.com
Webcoder.com содержит примеры сценариев, статьи с
практическими рекомендациями, ссылки на JavaScript
и динамический HTML, а также демонстрационные
страницы для многих популярных и новых JavaScript-
приложений.
Website Abstraction
http://www.wsabstract.com
Website Abstraction — большой каталог свободно доступ-
доступных JavaScript-кодов и обучающих программ JavaScript.
Сайт также содержит информацию и примеры других
Web-технологий, таких как Java и динамический HTML.
Сопровождающий CD-ROM
Сопровождающий CD-ROM содержит много полез-
полезных инструментальных средств и утилит, плюс исход-
исходные коды и примеры, рассмотренные в книге.
Установка на компьютерах Macintosh
1. Вставьте CD-ROM в дисковод.
2. Когда пиктограмма CD-ROM появится на рабочем
столе, откройте CD-ROM, дважды щелкнув на его
пиктограмме.
3. Дважды щелкните на пиктограмме Guide на CD-ROM
и следуйте выводимым инструкциям.
Установка под управлением
Windows 98
1. Вставьте CD-ROM в дисковод.
2. Дважды щелкните на пиктограмме My Computer
(Мой компьютер) на рабочем столе.
3. Дважды щелкните на пиктограмме, представляющей
дисковод CD-ROM.
4. Дважды щелкните на пиктограмме SETUP.EXE для
запуска программы установки.
5. Программа установки создает программную группу
с именем "JavaScript Unleashed 3", содержащую пик-
пиктограммы, которые можно использовать для про-
просмотра CD-ROM.
- примечание;1!"¦"" '"'" ¦ ¦ '^ЙЖ * * *'* ' '
Если на компьютере установлена Windows 98 и раз-
разрешена возможность AutoPlay (Автозапуск), программа
SETUP.EXE будет автоматически запускаться после
помещения CD-ROM дисковод.
Установка под управлением
Windows NT
1. Вставьте CD-ROM в дисковод.
2. Выберите File -> Run (Файл -* Запуск) в провод-
проводнике.
3. Введите drive:\SETUP.EXEk нажмите Enter (drive
соответствует имени дисковода CD-ROM).
4. Программа установки создает программную груп-
группу с именем "JavaScript Unleashed 3", которая содер-
содержит пиктограммы, используемые для просмотра
CD-ROM.
Предметный указатель
Символы Opera 28, 44
I 74 '0Рега З'х 19
* 404 Sun's HotJava 3.0 28
* He-JavaScript 47, 49
* /b старые 39
&& 74
(...) 403 B
* 403 Ввод пользовательский 210
+ 73 403 Верификация данных 367, 373
--> 33, 66 Визуальные эффекты 277
4оз Внедрение сценариев 55
I зз Внешние файлы 303
// 39 Выделение текста (onSelect) 193
< зз Вызов Java-методов 335
<!-- 33 66 Выражение 64
«76' Выход из документа (onUnload) 197
= gi Выход из фокуса (onBlur) 192
== 50 72 Вычисляемые поля 377
> 33 ' 1Г
»76 Генерация событий
>» 77 программная 198
? 403 Графический пользовательский
[...] 403 интерфейс (GUI) 103
["•¦¦] 403 д
} Декремент 70
76' 403 Денежные значения 379
76'403 Дескриптор
I" 74 <applet> 20, 24, 330
A <BASE> 254
Агрегирование 106 <ЫУ> 33
Т^ 20'ofa. <*> ?99,312
Аргумент 93, 94 <form> 319
Архитектура клиент/сервер 163 <FRAME> 242 255
Атрибут 34, 104 <FRAMESET> 242
Class 34 <head> 33
Id 34 <hr> 33
Name 34 <html> 33
Style 34 <iframe> 293, 299, 303
Атрибуты DOM 186 <ilayer> 33, 293, 305
R <layer> 33, 293, 305
<link> 287
Баннер 277, 278 <marquee> 33
Бегущая строка 277 <meta> 36
Библиотека <noscript> 47
классов 106 <object> 330
объектов 106 <script> 29, 34, 46, 55
Блок данных 299 <span> 289
Браузер 18, 28, 39, 44, 47 <style> 287
Be'sNetPositive2.1 28 <table> 312
HotJava 44 <td> 33
Microsoft Internet Explorer 18, 44 закрывающий 33
Navigator 200 контейнерный 33
NCSA Mosaic 21 одиночный 33
NetF'osffive 44 открывающий 33
Netscaoe Naviaator 18. 44 пустой 33
Диалоговое окно Prompt 49
Диалоговые окна 208
Динамическая инструментальная
панель 360
Динамическая подмена (rollover) 272
Динамический HTML (DHTML) 311
Документ HTML 167
Доступ к Java из JavaScript 330
Доступ к JavaScript из Java 331
Дочерний (child) элемент 286
3
Загрузка документа (onLoad) 196
Замена обработчиков событий 198
Запрос 164, 412
HTTP 165
клиентский 164
поисковый 412
Запуск приложения 414
Зарезервированное слово 58
Захват данных с помощью
объекта Textarea 231
И
.Идентификатор 57
Изменение данных (onChange) 191
Изоморфизм 186
Инициализация переменных 428
Инкапсуляция 106
Инкремент 70
Инсталляция приложений 170
Инструментальные панели 317
Интерфейс 164, 411
поисковый пользовательский 411
пользовательский 164
Источник данных 409
К
Карта изображения 252
Кеширование файлов 252
Класс 106, 107
Ключевое слово 58
Код 48
помещение во внешний файл 48
Кодирование URL 166
Командные кнопки 277, 282
анимированные 277
Комментарии 66, 286
Компания 16, 53
Apple 17
Borland 17
Digital 17
Informix 17
Oracle 17
Microsoft 17
Netscape 16, 53
JavaScript. Энциклопедия пользователя
Sun 16, 53
Sun Misrosystems 24
Sybase 17
Константа 63
Конструктор 108, 151
RegExp() 401, 405
Косвенная установка фокуса 207
Кредитные карточки 380
Л
Лексема 57
Литерал 58
логический 59
с плавающей точкой 58
строковый 59
целочисленный 58
Логическое или (|) 403
М
Массив 141, 151
Меню 311
Метка 89
Метод
Alert() 208, 423
CloneNode 268
Close() 204
Confirm!) 210
ConfirmOrder() 190
ConvertToUppercase() 191
DailyTaskf) 199
Focusf) 191
llnsertBefore 269
Open() 189, 201
Prompt 49
Prompt)) 210
RemoveNode 269
SelectContentsf) 192
Setlnterval 198
SetTmneoutO 199, 277
SwapNode 269
Writef) 215, 251
Writelnf) 215
итератор 111
конструктор 111
модификатор 111
общедоступный 106
приватный 106
Методы DOM 184
CloneNodef) 184
RemoveNodeQ 184
Модель 29, 186
объектная 29
структурная 186
Н
Навигация
между окнами 200, 207
то документу 186, 187
по сайту 360
по списку посещений 262
Наследование (inheritance) 286
Обработка ошибок (опЕггог) 188, 197, 420
Обработчик событий 50, 198
Onload 50
Замена 198
Обработчик событий
(event handler) 50, 188, 198
onAbort 198
onBlur 192
onChange 191
onClick 189
onError 197
onFocus 191
onLoad 196
onMouseQut 193
onMouseOver 193
onReset 190
onSelect 193
onSubmit 190
onUnload 197
Объект
Anchor 122, 214, 223
Applet 122
Area 122
Array 141
BLOB 180
Boolean 148
Button 126, 225, 231, 361
Checkbox 126, 225, 233
Client 173
Connection 179
Cursor 179
Database 178
Date 144
DbPool 178
Document 119, 182, 214
File 175
FileUpload 126
Form 122, 182, 225
Frame 120, 182, 200, 242
Function 149
Global 131
Hidden 126, 225, 239
History 120, 200, 242, 360, 365
Image 123, 214, 223
Layer 124
Link 125, 214, 218
Location 121, 200, 242, 262
Lock 175
Math 147
Mimetype 115
Navigator 114, 200, 242, 264
Number 149
Option 130
Password 126, 225, 238
Plugin 115, 125
Project 173
Radio 126, 225, 234
RegExp 141
Request 174
Reset 128
Resultset 180
Select 128, 225, 235
SendMail 177
Server 172
Stproc 180
String 131
Text 129, 225, 229
Textarea 129, 231
Toolbar 361
Window 116, 182, 200
простой 156
составн 157
Объектная модель 29
Объектная модель
документа (DOM) 182, 266
Объявление переменных 428
Окно
Upgrade Notice 196
браузера 201
закрытие 204
косвенная установка фокуса 207
навигация между окнами 207
определение атрибутов окна 202
открытие и закрытие 201
ссылки на окна 202
Оператор 40, 50, 82
Document.write() 40
lf..else 50
Switch 91
With 90
организации цикла 85
Break 88
Continue 88
Do..while 88
For 85
Fon.in 87
While 88
условный 82:
If 82
If..else 84
Try..catch 85
присваивания 401
Операции 60, 69, 70
арифметические 70
булевы 74
декремента 70
инкремента 70
конкатенации 73
поразрядные 75
поразрядные логические 76
поразрядные сдвига 76
приоритеты выполнения 79
присваивания 70
со структурами данных 75
сравнения 711
строковые 73
условные 74
Определение слоев 312
Открытие нового URL 260
Отладка 170
Отношение "целое-часть" 106
Отношения содержания 110
Отправка формы (onSubmit) 190
Предметный указатель
Ошибки 171, 353, 420
времени выполнения 421
логические 421
синтаксические 420
сообщения об ошибках 421
П
Панели инструментов DHTML 311
Передача по значению 95
Переключатель 126
Переменная экземпляра 108
Переменные 60, 93
глобальные 62
локальные 62
область действия 62
Перемещение мыши по объектам 193
Лерсонапизация 386
Подключаемые модули 25, 54
Java 330
браузера 326
Подпрограмма 30
Получение фокуса (onFocus) 191
Пользовательский ввод 210
Поля
вычисляемые 377
Помещение кода во внешний файл 48
Преобразование строк и чисел 140
ParseRoatf) 140
Parsaint() 140
Прерывание загрузки
изображения (onAbort) 198
Приложение 22
клиентское 22, 27
Программирование
модульное 318
Программная генерация событий 198
Протокол
TCP/IP 25
Р
Регулярные выражения 401
Рекурсия 101
Родительский (parent) элемент 286
С
Сайт 47
Сброс формы (onReset) 190
Свойства 19, 104, 151, 251
объекта 111
Location.href 251
Селектор 289
смешивание 289
Сервер 25, 164
Apache 25
Microsoft Internet Information Server (IIS) 25
Netscape Enyerprise Server (NES) 25
Синтаксис 57
Синхронизация фреймов 247
Слои 293, 312
Событие 56, 113, 272
blur 192
click 56, 189
focus 191
load 196
mouseOut 193
mouseover 56, 193
onFocus 191
onMouseDown 272
onMouseOver 272
onMouseUp 272
select 193
submit 190
unload 197
таймера 188, 198
Создание изображений 318
Сокрытие информации 107
Сообщение 107
Сообщения об ошибках 421
Состояние 104
Специальные символы 59, 139
Среда 20
Microsoft Active Server Pages 20
Netscape Enterprise Server 20
Ссылки 250
на окна 202
на фреймы 254
Стандарт 285
MIME 326
ЕСМА 17
Стили 286
Страницы
динамические 386
статические 386
Строка 104, 131,379
преобразование 140
форматирование 135
запроса 398
Структурная модель 186
Структурный изоморфизм 186
Сценарий
внедрение 55
Т
Таблица 410
поиска 410
стилей 285
Каскадная 285
Текст 33
Текстовый редактор 42
BBEdit 43
TextPad 43
Тестирование кода 423
Технология перетаскивания
(drag-and-drop) 43
Тип 61
MIME 326
браузера 356
данных 64
Boolean 64
Function 64
Number 64
Object 64
String 64
Точечная нотация (.) 109, 403
Трансляция типов данных 334
У
Уведомление
простое 208
Управление
сеансами 165
событиями 188
Условный оператор 82
If 82
If. .else 84
Try. .catch 85
Установка Java-свойств 335
Ф
Файл 36, 48, 54, 166
.js 36, 48, 168
Acrobat 54
Cookie 166
HTML 167
VRML 54
аудио- 54
библиотечный 168
видео- 54
Флажок 126
Форма 122, 367, 400
скрытая переменная 400
создание интерактивных форм 376
Фрейм 120, 201, 242
вложенный 245
обновлени 249
синхронизация фреймов 247
Функция
ChangeState() 302
CheckBrowserO 302
DailyTask() 199
JSMarqueef) 277
OnLoad 38
Opendoc() 38
Process() 322
Repaintf) 279
RolllmageO 320
TakeBrowser() 3211
TheHref() 250
вызов 75
определение 75
передача по значению 95
рекурсивная 101
замены 406
очистки 406
поиска 406
ц
Цвет 63, 281
постепенное изменение 281
документа 216
Целые числа 378
Ш
Шаблон 49
Э
Экземпляр 20, 108, 153
JavaScript. Энциклопедия пользователя
Элемент
дочерний (child) 286
Элементы управления ActiveX
24, 27, 326, 328
Эффект 299
мультипликационный 299
Я
Язык сценариев 16
Язык программирования 53
AppletScript 53
С/О 53
Perl 53
Visual Basic 53
Иностранные термины
А
Active Server Pages (ASP) 17, 26, 163
ActiveX 20, 24, 328
Apache 25
Apple 17
AppletScript 53
Application Manager 170, 171
Application programming interfaces - API
26, 183, 312
IB
Be's NetPositive 2.1 28
Borland 17
Borland IntraBuilder 45
С
C/C+ 53
CGI - Common Gateway Interface
16, 20, 26, 53
CGI-программа 53
CGI-сценарий 16, 21
Client-side imagemaps, CSIM 252
cookie-набор 165, 386, 387
CSS 285
CSS positioning, CSS-P 285
CSS-свойства 295
Bottom 295
Height 295
Left 295
Right 295
Top 295
Visibility 298
Z-index 296
D
DHTML 183, 184, 311
Digital 17
DLL 26
DOM 182, 266
-браузер 266
-документ 266
-метод 266
-модель 266
Е
ЕСМА (European Computer Manufacturer's
Association) 17
ECMAScript 17, 46
G
GUI 103
H
HP 17
HTML 16, 17, 29, 32, 183
встроенный 29
HTML 4 19
HTML-документ 21, 32, 55, 167
активный 22
динамический 21
HTML-код 318
HTML-комментарий 33
HTML-редактор 43
Allaire HomeSite 43
FrontPage 44
WYSIWYG 44
визуальный 43
текстовый 43
HTML-страница 20
HTTP-запрос 165
1
IBM 17
IDE 42
IIS 44
Informix 17
Interface Definition Language - IDL 183
Internet Explorer 3.0 17
Internet Requests For Comment (RFC) 326
IP-адрес 166
ISAPI 26
J
Java 16, 20, 26, 54
Java Server Pages (JSP) 26,163
Java-аплеты 20, 27, 326, 330
JavaScript 16, 28, 53
JavaScript от Netscape 342
JScript 17
JScript от Microsoft 348
L
UveAudio 326, 336
UveScript 16, 53
LreWire 163
M
Microsoft Active Server Pages 20
Microsoft Internet Explorer 17, 18, 44
Microsoft Internet Explorer 3.x 19
Microsoft Internet Information
Server (IIS) 25
MIME 25
N
NCSA Mosaic 21
Netscape 16, 53, 252
подключаемые модули 24
Netscape Enterprise Server 20
¦Netscape Enyerprise Server (NES) 25
Netscape Navigator 18, 28, 44
Netscape Navigator 2.x 19
Netscape Navigator 3.0 17
Netscape SSJS (Server-Side JavaScript) 26
NSAPI 26
ID
Object Management Group - OMG 183
OCX 24
OOP - object-oriented programming 19
Opera 28
Opera 3.x 19
Oracle 17
P
Perl 53
R
RGB 217
Rollover-эффект 273, 320
S
Server-Side JavaScript (SSJS) 17,45, 169
Slide Show 364
SSJS 26, 163, 166
Sun 16, 53
Sun Misrosystems 24
Sun's HotJava 3.0 28
Sybase 17
T
TCP/IP 25
U
URL 166
V
VBScript 17, 25, 28, 29
подпрограмма 30
программирование 30
тип данных
Variant 29
типы данных 29
функция 30
Visual Basic 17, 28, 53
Visual Basic for Applications 28
W
W3C 32
Web 22
Web-браузер 44
Web-мастер 16
Web-приложение 22, 163
Web-сервер 20, 25
Web-страница 53, 386
Window Script Host (WSH) 20
World Wide Web 21
X
XHTML 18, 32
XML 32, 183
УДК 004.43@31)
ББК 32.973.26-018.1
В 14
ВАЙКАллен та шш.
В14 JavaScript. Перекл.з англ./Аллен Вайк.—К.: ТОВ"ТВД" ДС", 2001.—480 с. Енциклопед1я користувача
ISBN 966-7992-00-04
Книга JavaScript. ЕнциклопеЫя користувача являеться найбшьш повним учбовим та довщниковим KepiB-
ництвом по yciM версшм мови JavaScript, у тому числ1 JavaScript 1.5 i JScript 5.0. На сьогодшшнш день
JavaScri pt e найбшьш розповсюджена мова для написания сценарпв, яю забезпечують гадтримку штерактив-
ного BMicTyWeb-CTOpiHOK. В книз! анал1зуеться широкий спектр питань, починаючи з основ мови 1закшчую-
чи складними питаниями практичного використання технологш Web-дизайну. Докладно розглядаються:
взаемод!я JavaScript та HTML; типи даних, операци, вирази i оператори; основи об'ектно-ор1ентовано1 мето-
методологи та и реал1защя в JavaScript; об'екти 3i сторони юпента та сервера; DHTML; технолопя написания
стшкого та надшного коду; методика В1дладки коду. Особлива увага придшяеться питаниям досягнення без-
пеки Web-програм.
У книз1 е багато практичиих прикладов, ЯК1 вщповщають специф1чним особливостям розробки \УеЬ-сайт1в
з використанням JavaScript. Довщник по базовим мовним об'ектам робить з книги справжне настшьне
кер1вництво.
CD-ROM, який надходить разом з книгою, М1стить коди ycix проанал!зованихприклад1в, а також багато
1ншо1 корисно? 1нформацн.
JavaScript. ЕнциклопеЫя користувача розрахована на широку аудиторпо розробникш програмного забезпе-
чення для Web.
Аллен Вайк и др.
JAVASCRIPT. ЭНЦИКЛОПЕДИЯ ПОЛЬЗОВАТЕЛЯ
торгэдо«издательский дом
DiaSoft
Киев • Москва • Санкт-Петербург
2001